Add externs to avoid multiple definitions, and then add missing definitions.
[rrq/maintain_lilo.git] / src / common.c
1 /* common.c  -  Common data structures and functions
2  * 
3  * Copyright 1992-1998 Werner Almesberger
4  * Copyright 1999-2005 John Coffman
5  * Copyright 2009-2015 Joachim Wiedorn
6  * All rights reserved.
7  * 
8  * Licensed under the terms contained in the file 'COPYING'
9  * in the source directory.
10  */
11
12 #define _GNU_SOURCE
13 #include <unistd.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdarg.h>
18
19 #include "lilo.h"
20 #include "common.h"
21
22 #ifndef SHS_MAIN
23 LILO_EXTRA extra;
24 char *identify = NULL;
25 int boot_dev_nr, raid_index, do_md_install;
26 int verbose = 0, test = 0, compact = 0, linear = 0, raid_flags = 0, zflag = 0,
27       ireloc = 0, force_fs = 0, force_raid = 0, extended_pt = 0, query = 0,
28       nowarn = 0, lba32 = 0, autoauto = 0, passw = 0, geometric = 0, eflag = 0;
29 int colormax = 15, warnings = 0;
30 DL_BIOS bios_passes_dl = DL_NOT_SET;
31
32 #if !__MSDOS__
33 FILE *pp_fd = NULL;
34 int bios_boot, bios_map;
35 unsigned short drv_map[DRVMAP_SIZE+1]; /* fixup maps ... */
36 int curr_drv_map;
37 unsigned int prt_map[PRTMAP_SIZE+1];
38 int curr_prt_map;
39 #endif /* !__MSDOS__ */
40
41 /*volatile*/ void pdie(const char *msg)
42 {
43     fflush(stdout);
44 #if !__MSDOS__
45     perror(msg);
46 #else
47     fprintf(errstd, "%s\n", msg);
48 #endif /* !__MSDOS__ */
49     exit(1);
50 }
51
52
53 /*volatile*/ void __attribute__ ((format (printf, 1, 2))) die(const char *fmt,...)
54 {
55     va_list ap;
56
57     fflush(stdout);
58     fprintf(errstd,"Fatal: ");       /* JRC */
59     va_start(ap,fmt);
60     vfprintf(errstd,fmt,ap);
61     va_end(ap);
62     fputc('\n',errstd);
63     exit(1);
64 }
65
66
67 /*volatile*/ void warn(char *fmt,...)
68 {
69     va_list ap;
70
71     warnings++;
72     if (nowarn > 0) return;
73     
74     fflush(stdout);
75     fprintf(errstd,"Warning: ");
76     va_start(ap,fmt);
77     vfprintf(errstd,fmt,ap);
78     va_end(ap);
79     fputc('\n',errstd);
80     
81     return;
82 }
83
84
85 void *alloc(int size)
86 {
87     void *this;
88
89     if ((this = malloc(size)) == NULL) pdie("Out of memory");
90     memset(this, 0, size);      /* insure consistency */
91
92     return this;
93 }
94
95
96 void *ralloc(void *old,int size)
97 {
98     void *this;
99
100     if ((this = realloc(old,size)) == NULL) pdie("Out of memory");
101     return this;
102 }
103
104
105 char *stralloc(const char *str)
106 {
107     char *this;
108
109     if ((this = strdup(str)) == NULL) pdie("Out of memory");
110     return this;
111 }
112
113
114 int to_number(char *num)
115 {
116     int number;
117     char *end;
118
119     number = strtol(num,&end,0);
120     if (end && *end) die("Not a number: \"%s\"",num);
121     return number;
122 }
123
124
125 int timer_number(char *num)
126 {
127     int number;
128     char *end;
129
130     number = strtol(num,&end,0);
131     if (end && *end) {
132         switch (*end) {
133             case 'h':
134             case 'H':
135                 number *= 60;
136             case 'm':
137             case 'M':
138                 number *= 60;
139             case 's':
140             case 'S':
141                 number *= 10;           /* convert seconds to tenths */
142             case 't':
143             case 'T':
144                 break;
145             default:
146                 number = -1;
147         }
148     }
149     if (number < 0  ||  number > 36000)  die("Not a valid timer value: \"%s\"",num);
150     return number;
151 }
152
153
154 static char *name(int stage)
155 {
156     switch (stage) {
157         case STAGE_FIRST:
158             return "First boot sector";
159         case STAGE_SECOND:
160             return "Second boot sector";
161         case STAGE_CHAIN:
162             return "Chain loader";
163         default:
164             die("Internal error: Unknown stage code %d",stage);
165     }
166     return NULL; /* for GCC */
167 }
168
169
170 void check_version(BOOT_SECTOR *sect,int stage)
171 {
172     int bs_major, bs_minor;
173
174     if (!strncmp(sect->par_1.signature-4,"LILO",4))
175         die("%s has a pre-21 LILO signature",name(stage));
176     if (strncmp(sect->par_1.signature,"LILO",4))
177         die("%s doesn't have a valid LILO signature",name(stage));
178     if ((sect->par_1.stage&0xFF) != stage)
179         die("%s has an invalid stage code (%d)",name(stage),sect->par_1.stage);
180
181     bs_major = sect->par_1.version & 255;
182     bs_minor = sect->par_1.version >> 8;
183     if (sect->par_1.version != VERSION)
184         die("%s is version %d.%d. Expecting version %d.%d.",name(stage),
185             bs_major,bs_minor, VERSION_MAJOR,VERSION_MINOR);
186 }
187
188
189 #if !__MSDOS__
190 int stat_equal(struct stat *a,struct stat *b)
191 {
192     return a->st_dev == b->st_dev && a->st_ino == b->st_ino;
193 }
194 #endif /* !__MSDOS__ */
195
196 #endif  /*  !SHS_MAIN */
197
198
199 #if !__MSDOS__
200 /* accumulate a partial CRC-32 */
201
202 unsigned int crc32partial(unsigned char *cp, int nsize,
203                         unsigned int polynomial, unsigned int *accum)
204 {
205    unsigned int poly, crc;
206    int i;
207    unsigned char ch;
208
209    crc = ~*accum;
210    while (nsize--) {
211       ch = *cp++;
212       for (i=0; i<8; i++) {
213          if ( ( (crc>>31) ^ (ch>>(7-i)) ) & 1) poly = polynomial;
214          else poly = 0UL;
215          crc = (crc<<1) ^ poly;
216       }
217    }
218    return (*accum = ~crc);
219 }
220
221
222 /* calculate a CRC-32 polynomial */
223
224 unsigned int crc32 (unsigned char *cp, int nsize, unsigned int polynomial)
225 {
226     unsigned int crc = 0;
227     return crc32partial(cp, nsize, polynomial, &crc);
228 }
229
230
231 /* show what a link resolves to */
232
233 void show_link(char *name)
234 {
235     int count;
236     char lname[1024];
237     
238     count = readlink(name, lname, sizeof(lname)-1);
239     if (count>0) {
240         lname[count] = 0;
241         printf(" -> %s", lname);
242     }
243 }
244 #else /* __MSDOS__ */
245 char * strerror(int err)
246 {
247     return NULL;
248 }
249 #endif /* !__MSDOS__ */
250
251
252 #ifdef SHS_MAIN
253 #include <fcntl.h>
254
255 int main(int argc, char *argv[])
256 {
257     unsigned char buf[4096];
258     int fd, n;
259     unsigned int crc;
260     
261     fd = open(argv[1],O_RDONLY);
262     crc = 0;
263     n = read(fd,buf,sizeof(buf));
264     while (n>0) {
265         crc32partial(buf, n, CRC_POLY1, &crc);
266         n = read(fd,buf,sizeof(buf));
267     }
268     close(fd);
269
270     printf("0x%08x\n", (int)crc);
271     if (sizeof(short)!=2) {
272         fprintf(stderr,"***Fatal:  SHORT != 2\n");
273         return 1;
274     }
275     if (sizeof(int)!=4) {
276         fprintf(stderr, "*****Fatal:  INT != 4\n");
277         return 1;
278     }
279     if (sizeof(int32_t)>sizeof(int))
280         fprintf(stderr, "**Note:  LONG is bigger than INT\n");
281         
282     return 0;
283 }
284 #endif  /* SHS_MAIN */