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