OpenWrt – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <libgen.h>
5 #include "mktitanimg.h"
6  
7  
8 struct checksumrecord
9 {
10 unsigned int magic;
11 unsigned int chksum; /* The checksum for the complete header.
12 Excepting the
13 checksum block */
14 };
15 /***************************************************************************
16 * void print_help(void)
17 ***************************************************************************/
18 void print_help(void)
19 {
20 static char* help_page[]=
21 {
22 "mknspimg version 1.0, Texas Instruments, 2004",
23 "Syntax:",
24 " mknspimg -o outfile -i image1 image2 -a align1 align2 [-v] [-b] [-p prod_id] [-r rel_id] [-s rel_name] [-f flags]",
25 "Example:",
26 " mknspimg -o nsp_image.bin -i kernel.bin files.img -a 0 4096",
27 "This generates 'nsp_image.bin' from two input files aligning first to 0 and second to 4096 bytes."
28 };
29  
30 int num_lines = sizeof(help_page)/sizeof(char*);
31 int i;
32 for(i=0; i < num_lines; i++) {
33 printf("%s\n", help_page[i]);
34 }
35 }
36  
37 /***************************************************************************
38 * void mknspimg_print_hdr(NSP_IMG_HDR* p_img_hdr)
39 ***************************************************************************/
40 void mknspimg_print_hdr(struct nsp_img_hdr *hdr)
41 {
42 struct nsp_img_hdr_chksum *chksum;
43 struct nsp_img_hdr_section_info *sect_info;
44 struct nsp_img_hdr_sections *section;
45 int i;
46  
47 printf("****************** NSP Image Summary ******************\n");
48 printf("Magic: 0x%x\n", hdr->head.magic);
49 printf("Image Header Size: 0x%x bytes\n", hdr->head.hdr_size);
50 printf("Total Image Size: %d bytes\n", hdr->head.image_size);
51 printf("Product ID: 0x%x\n", hdr->head.prod_id);
52 printf("Release ID: 0x%x\n", hdr->head.rel_id);
53 printf("Version ID: 0x%x\n", hdr->head.version);
54  
55 printf("Offset Info: 0x%x\n", hdr->head.info_offset);
56 printf("Offset Sect info: 0x%x\n", hdr->head.sect_info_offset);
57 printf("Offset Sections: 0x%x\n", hdr->sect_info.sections_offset);
58  
59 chksum=(struct nsp_img_hdr_chksum *)(hdr+hdr->head.chksum_offset);
60 printf("Header Checksum: 0x%x\n", chksum->hdr_chksum);
61  
62 printf("+++ Section Information +++\n");
63 printf("# of sections: %u\n", hdr->sect_info.num_sects);
64 section=&(hdr->sections);
65 for(i = 0; i < hdr->sect_info.num_sects; i++, section++) {
66 printf("+++++ Section %d +++++\n", i);
67 printf("Total size: %u bytes\n", section->total_size);
68 printf("Raw Size: %u bytes\n", section->raw_size);
69 printf("Offset: 0x%x\n", section->offset);
70 printf("Type: 0x%x\n", section->type);
71 printf("Name: %s\n", section->name);
72 }
73 printf("*******************************************************\n");
74 }
75  
76 CMDLINE_CFG cmd_line_cfg =
77 {
78 {
79 /* MIN MAX FLAGS OPTION */
80 { 2, 2, (CMDLINE_OPTFLAG_ALLOW | CMDLINE_OPTFLAG_MANDAT) }, /* '-a' align1 align2 */
81 { 0, 0, CMDLINE_OPTFLAG_ALLOW }, /* '-b' bootstrap */
82 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-c' */
83 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-d' */
84 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-e' */
85 { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-f' flags */
86 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-g' */
87 { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-h' */
88 { 2, 2, (CMDLINE_OPTFLAG_ALLOW | CMDLINE_OPTFLAG_MANDAT) }, /* '-i arg1 arg2 ' */
89 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-j' */
90 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-k' */
91 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-l' */
92 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-m' */
93 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-n' */
94 { 1, 1, (CMDLINE_OPTFLAG_ALLOW | CMDLINE_OPTFLAG_MANDAT) }, /* '-o arg' */
95 { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-p' PROD_ID */
96 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-q' */
97 { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-r' REL_ID */
98 { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-s' "Release XXX.XXX" */
99 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-t' */
100 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-u' */
101 { 0, 0, CMDLINE_OPTFLAG_ALLOW }, /* '-v' control VERBOSE/NON-VERBOSE mode */
102 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-w' */
103 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-x' */
104 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-y' */
105 { 0, 0, !CMDLINE_OPTFLAG_ALLOW } /* '-z' */
106 },
107 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* global arguments */
108 };
109  
110 /***************************************************************************
111 * int nsp_img_write(void* image, char* file, int padding)
112 * Write out the image.
113 ***************************************************************************/
114 int main(int argc, char* argv[], char* env[])
115 {
116 FILE* nsp_image = NULL;
117 int header_version=1;
118 int cmdline_err;
119 char* cmdline_error_msg;
120  
121 char* filen_kernel;
122 char* filen_files;
123 char* filen_out;
124  
125 int i,count; /* loop variables */
126 int num_sects = 2; /* We require exactly two image with -i option
127 (see CMDLINE_CFG structure above) */
128 int desc_count=0;
129 int total = 0;
130  
131 int header_size=0;
132 struct nsp_img_hdr_head *img_hdr_head; /* Start of image header */
133 struct nsp_img_hdr_info *img_hdr_info;
134 struct nsp_img_hdr_section_info *img_hdr_section_info ;
135 struct nsp_img_hdr_sections *img_hdr_sections, *section; /* Section pointers */
136  
137  
138 /* Configure the command line. */
139 cmdline_configure(&cmd_line_cfg);
140  
141 /* Read and parse the command line. */
142 cmdline_err = cmdline_read(argc, argv);
143  
144 /* Check for parsing errors. */
145 if(cmdline_err != 0) {
146 /* Get the parse error message */
147 cmdline_error_msg = cmdline_error(cmdline_err);
148  
149 /* Print it out */
150 printf("%s\n", cmdline_error_msg);
151  
152 /* Print our help too */
153 print_help();
154 return -1;
155 }
156 if(cmdline_getopt_count('h') > 0)
157 {
158 header_version=atoi(argv[cmdline_getarg(cmdline_getarg_list('h'),0)]);
159 }
160 /* Set up arguments */
161 filen_kernel = argv[cmdline_getarg(cmdline_getarg_list('i'),0)];
162 filen_files = argv[cmdline_getarg(cmdline_getarg_list('i'),1)];
163 filen_out = argv[cmdline_getarg(cmdline_getarg_list('o'),0)];
164 /* Command line arguments have been parsed. Start doing our work. */
165  
166 /* Caculate the header size, and allocate the memory, and assign the sub pointers */
167 header_size = sizeof(struct nsp_img_hdr_head) + /* This has a single section
168 desc block already */
169 (header_version==1?0:4) +
170 sizeof(struct nsp_img_hdr_info) +
171 sizeof(struct nsp_img_hdr_section_info) +
172 sizeof(struct nsp_img_hdr_sections) * num_sects ;
173  
174 img_hdr_head = (struct nsp_img_hdr_head *)malloc(header_size);
175 memset(img_hdr_head, 0x0, header_size);
176 img_hdr_info = (struct nsp_img_hdr_info*)((char *)img_hdr_head + sizeof(struct nsp_img_hdr_head) + (header_version==1?0:4));
177 img_hdr_section_info = (struct nsp_img_hdr_section_info*)((char *)img_hdr_info + sizeof(struct nsp_img_hdr_info));
178 img_hdr_sections = (struct nsp_img_hdr_sections*)((char *)img_hdr_section_info + sizeof(struct nsp_img_hdr_section_info));
179 section = img_hdr_sections;
180 memset(img_hdr_head, 0xff, (void*)img_hdr_info - (void*)img_hdr_head);
181  
182 img_hdr_head->hdr_version = header_version;
183 img_hdr_head->hdr_size = header_size;
184 img_hdr_head->info_offset = (void*)img_hdr_info - (void*)img_hdr_head;
185 img_hdr_head->sect_info_offset = (void*)img_hdr_section_info - (void*)img_hdr_head;
186  
187 img_hdr_section_info->num_sects = num_sects;
188 img_hdr_section_info->sect_size = sizeof(struct nsp_img_hdr_sections);
189 img_hdr_section_info->sections_offset = (void*)img_hdr_sections - (void*)img_hdr_head;
190  
191 /* chksum = (struct nsp_img_hdr_chksum *)
192 ((unsigned int)image_hdr + header_size - sizeof(struct nsp_img_hdr_chksum));*/
193  
194 /* Open the out file */
195 nsp_image = fopen(filen_out,"wb+");
196 if(nsp_image==NULL) {
197 printf("ERROR: can't open %s for writing.\n", filen_out);
198 return -1;
199 }
200  
201 /* Skip image header. We'll come back to it after we've written out the images. */
202 fseek(nsp_image,header_size,SEEK_SET);
203 total = ftell(nsp_image);
204 total = header_size;
205 printf("total=%x\n",total);
206 {
207 int align;
208 int padding;
209 char * buf;
210 align = (header_version==1?0x10000:0x4000);
211 if(align==0) {
212 /* The user indicated no padding */
213 padding = 0;
214 } else {
215 /* Calculate number padding bytes */
216 if((total %align) ==0)
217 padding=0;
218 else
219 padding = align - (total % align);
220 }
221 if(padding>0)
222 {
223 buf=malloc(padding);
224 memset(buf, 0xff, padding);
225 if(fwrite((void*)buf,1,padding,nsp_image)!=padding) {
226 printf("ERROR: can't write to %s.\n", filen_out);
227 free(buf);
228 return -1;
229 }
230 free(buf);
231  
232 }
233 total+=padding;
234  
235  
236 }
237 /* Write out all specified images (with -i option) */
238 for(i=0; i < num_sects; i++) {
239 char* file_name; /* input file name */
240 FILE* filep; /* input file pointer */
241 int padding; /* number of padding bytes to prepend */
242 int align; /* align factor from command line */
243 int result; /* intermediate result */
244 char * buf;
245  
246 /* Open the specified image for reading */
247 file_name = argv[cmdline_getarg(cmdline_getarg_list('i'),i)];
248 filep = fopen(file_name, "rb");
249 if(filep==NULL) {
250 printf("ERROR: can't open file %s for reading.\n", file_name);
251 return -1;
252 }
253 section->flags = ~0x00;
254 /* Determine file size */
255 fseek(filep,0,SEEK_END);
256 section->raw_size=ftell(filep);
257 fseek(filep,0,SEEK_SET);
258 cs_calc_sum(filep,(unsigned long *)&section->chksum,0);
259 fseek(filep,0,SEEK_SET);
260  
261 /* Retrieve the alignment constant */
262 /* Set image offset from the beginning of the out file */
263 section->offset=total;// + padding;
264  
265 //total += padding;
266  
267 /* Copy the image file into nsp_image */
268 count = section->raw_size;
269 buf=malloc(count);
270 result=fread(buf, 1, count, filep);
271 fwrite(buf, 1, result, nsp_image);
272 free(buf);
273  
274 /* HACK: This is a hack to get the names and types to the files.
275 TODO: Fix this to be a real method */
276 if(i==0){
277 section->type=NSP_IMG_SECTION_TYPE_KERNEL;
278 strncpy(section->name, "kernel", 16);
279 } else if(i==1){
280 section->type=NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT;
281 strncpy(section->name, "root", 16);
282 }
283  
284 /* Account for the total */
285 align = strtoul(argv[cmdline_getarg(cmdline_getarg_list('a'),i)],NULL,0);
286 if(i==0){
287 if(align==0 || (((section->raw_size+ section->offset)%align)==0))
288 padding=0;
289 else
290 padding = align - ((section->raw_size+ section->offset) % align);
291  
292 section->total_size=section->raw_size + padding;
293 }
294 else{
295 #define EXTRA_BLOCK 0x10000
296 unsigned int squash_padding;
297 squash_padding = EXTRA_BLOCK - section->raw_size % EXTRA_BLOCK;
298 buf=malloc(EXTRA_BLOCK + 4);
299 memset(buf, 0, squash_padding);
300 fwrite(buf, 1, squash_padding, nsp_image);
301 memset(buf, 0, EXTRA_BLOCK + 4);
302 *((unsigned int *)buf)=0xdec0adde;
303 *((unsigned int *)(buf+EXTRA_BLOCK))=0xdec0adde;
304 fwrite(buf, 1, EXTRA_BLOCK+4, nsp_image);
305 free(buf);
306  
307 if(align==0 || (((section->raw_size + (EXTRA_BLOCK + 4 + squash_padding)) %align)==0))
308 padding=0;
309 else
310 padding = align - ((section->raw_size + (EXTRA_BLOCK + 4 + squash_padding)) % align);
311 section->total_size=section->raw_size + (EXTRA_BLOCK + 4 + squash_padding) + padding;
312 }
313 if(padding>0){
314 buf=malloc(padding);
315 memset(buf, 0xff, padding);
316 fwrite(buf, 1, padding, nsp_image);
317 free(buf);
318 }
319 printf("*****padding is %d\ttotal_size=%d\traw_size=%d\n",padding, section->total_size, section->raw_size);
320  
321 //total += section->raw_size;
322 total = section->total_size + section->offset;
323 printf("total=0x%x\n",total);
324 /* Close the input file */
325 fclose(filep);
326  
327 /* Move the section pointer to the next slot */
328 section++;
329 }
330  
331 /* Take care of the NSP image header fields */
332  
333 /* head fields */
334 img_hdr_head->magic = NSP_IMG_MAGIC_NUMBER;
335 img_hdr_head->boot_offset = img_hdr_sections->offset;
336 img_hdr_head->flags = ~0x00; /* Set to all 1's */
337  
338 if(cmdline_getopt_count('b'))
339 img_hdr_head->flags &= ~(NSP_IMG_FLAG_FAILBACK_5 | NSP_IMG_FLAG_FAILBACK_1);
340  
341 if(cmdline_getopt_count('f'))
342 img_hdr_head->flags = strtoul(argv[cmdline_getarg(cmdline_getarg_list('f'),0)], 0, 16);
343  
344 #if 0
345 img_hdr_head->hdr_version = 2;
346 img_hdr_head->hdr_size = header_size;
347 #endif
348  
349 if(cmdline_getopt_count('p'))
350 img_hdr_head->prod_id = strtoul(argv[cmdline_getarg(cmdline_getarg_list('p'),0)], 0, 16);
351 else
352 img_hdr_head->prod_id = 0x4C575943;
353  
354 if(cmdline_getopt_count('r'))
355 img_hdr_head->rel_id = strtoul(argv[cmdline_getarg(cmdline_getarg_list('r'),0)], 0, 0);
356 else
357 img_hdr_head->rel_id = 0x10203040;
358  
359 if(cmdline_getopt_count('s'))
360 img_hdr_head->version = strtoul(argv[cmdline_getarg(cmdline_getarg_list('s'),0)], 0, 0);
361 else
362 img_hdr_head->version = 0x0b040000;
363 img_hdr_head->image_size = total;
364 #if 0
365 img_hdr_head->info_offset = (unsigned int)(&(image_hdr->info)) -
366 (unsigned int)image_hdr;
367 img_hdr_head->sect_info_offset= (unsigned int)(&(image_hdr->sect_info)) -
368 (unsigned int)image_hdr;
369 #endif
370 // image_hdr->head.chksum_offset = (unsigned int)chksum - (unsigned int)image_hdr;
371 img_hdr_head->chksum_offset = 0xffffffff;
372 // image_hdr->head.pad1 = 0xffffffff;
373 /* info fields */
374 /* TODO: Fix. Do nothing yet */
375 // strncpy(nsp_img_hdr.id.prod_info,NSP_PRODINFO_STRING,sizeof(NSP_PRODINFO_STRING));
376 strcpy(img_hdr_info->image_filename, (const char *)basename(filen_out));
377 /* section fields */
378 #if 0
379 img_hdr_section_info->num_sects= num_sects;
380 img_hdr_section_info->sect_size= sizeof(struct nsp_img_hdr_sections);
381 img_hdr_section_info->sections_offset= (unsigned int)(&(image_hdr->sections)) -
382 (unsigned int)image_hdr;
383 #endif
384  
385 /* Calculate checksum(s) */
386 #if 0
387 chksum->hdr_chksum = cs_calc_buf_sum((char*)image_hdr,
388 header_size - sizeof(struct nsp_img_hdr_chksum));
389 #endif
390 /* Write out the NSP header. */
391 fseek(nsp_image,0,SEEK_SET);
392 count = fwrite((void*)img_hdr_head, header_size, 1, nsp_image);
393 if(count!=1) {
394 printf("ERROR: can't write to %s.\n", filen_out);
395 return -1;
396 }
397  
398 /* Check if -v option was specified (no arg needed) */
399 if(cmdline_getopt_count('v') > 0)
400 {
401 struct nsp_img_hdr_head head;
402 struct nsp_img_hdr *hdr;
403  
404 /* Rewind the file back to the beginning */
405 fseek(nsp_image,0,SEEK_SET);
406  
407 /* Read header from the file */
408 fread((void*)&head, sizeof(struct nsp_img_hdr_head),
409 1, nsp_image);
410  
411 /* Get memory to store the complete header */
412 hdr = (struct nsp_img_hdr *)malloc(head.hdr_size);
413  
414 /* Read header from the file */
415 fseek(nsp_image,0,SEEK_SET);
416 fread((void*)hdr, head.hdr_size, 1, nsp_image);
417  
418 /* Print it out */
419 mknspimg_print_hdr(hdr);
420 printf("Generated total %d bytes\n",total);
421 free(hdr);
422 }
423  
424 free(img_hdr_head);
425  
426 {
427 struct checksumrecord cr;
428 cr.magic=CKSUM_MAGIC_NUMBER;
429 cs_calc_sum(nsp_image, (unsigned long *)&cr.chksum, 0);
430 fseek(nsp_image,0, SEEK_END);
431 fwrite(&cr, 1, sizeof(cr), nsp_image);
432 }
433 {
434 FILE * non_web;
435 char fname[256];
436 char * img_buf;
437 unsigned int len;
438 strcpy(fname, filen_out);
439 strcat(fname, ".non_web");
440 non_web = fopen(fname,"wb+");
441 fseek(nsp_image, 0, SEEK_END);
442 len = ftell(nsp_image);
443 img_buf=malloc(len);
444 fseek(nsp_image, 0, SEEK_SET);
445 fread(img_buf, 1, len, nsp_image);
446 img_buf[0xb] = 0x17;
447 fwrite(img_buf, 1, len-sizeof(struct checksumrecord), non_web);
448 fclose(non_web);
449 free(img_buf);
450 }
451 /* Close NSP image file */
452 fclose(nsp_image);
453  
454 /* return result */
455 return(0);
456 }
457  
458 #ifdef DMALLOC
459 #include <dmalloc.h>
460 #endif /* DMALLOC */
461  
462 #define BUFLEN (1 << 16)
463  
464 static unsigned long crctab[256] =
465 {
466 0x0,
467 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B,
468 0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6,
469 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
470 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC,
471 0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, 0x6ED82B7F,
472 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A,
473 0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
474 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0xBE2B5B58,
475 0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033,
476 0xA4AD16EA, 0xA06C0B5D, 0xD4326D90, 0xD0F37027, 0xDDB056FE,
477 0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
478 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4,
479 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, 0x34867077, 0x30476DC0,
480 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5,
481 0x2AC12072, 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16,
482 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, 0x7897AB07,
483 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C,
484 0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1,
485 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
486 0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B,
487 0xBB60ADFC, 0xB6238B25, 0xB2E29692, 0x8AAD2B2F, 0x8E6C3698,
488 0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D,
489 0x94EA7B2A, 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E,
490 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, 0xC6BCF05F,
491 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34,
492 0xDC3ABDED, 0xD8FBA05A, 0x690CE0EE, 0x6DCDFD59, 0x608EDB80,
493 0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB,
494 0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A,
495 0x58C1663D, 0x558240E4, 0x51435D53, 0x251D3B9E, 0x21DC2629,
496 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C,
497 0x3B5A6B9B, 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF,
498 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, 0xF12F560E,
499 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65,
500 0xEBA91BBC, 0xEF68060B, 0xD727BBB6, 0xD3E6A601, 0xDEA580D8,
501 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3,
502 0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2,
503 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, 0x9B3660C6, 0x9FF77D71,
504 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74,
505 0x857130C3, 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640,
506 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, 0x7B827D21,
507 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A,
508 0x61043093, 0x65C52D24, 0x119B4BE9, 0x155A565E, 0x18197087,
509 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC,
510 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D,
511 0x2056CD3A, 0x2D15EBE3, 0x29D4F654, 0xC5A92679, 0xC1683BCE,
512 0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB,
513 0xDBEE767C, 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18,
514 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4, 0x89B8FD09,
515 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662,
516 0x933EB0BB, 0x97FFAD0C, 0xAFB010B1, 0xAB710D06, 0xA6322BDF,
517 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4
518 };
519  
520 int cs_is_tagged(FILE *fp)
521 {
522 char buf[8];
523  
524 fseek(fp, -8, SEEK_END);
525 fread(buf, 8, 1, fp);
526 if(*(unsigned long*)buf == CKSUM_MAGIC_NUMBER)
527 return 1;
528 return 0;
529 }
530  
531 unsigned long cs_read_sum(FILE *fp)
532 {
533 char buf[8];
534  
535 fseek(fp, -8, SEEK_END);
536 fread(buf, 8, 1, fp);
537 return *((unsigned long*)&buf[4]);
538 }
539  
540 int cs_calc_sum(FILE *fp, unsigned long *res, int tagged)
541 {
542 unsigned char buf[BUFLEN];
543 unsigned long crc = 0;
544 uintmax_t length = 0;
545 size_t bytes_read;
546  
547 fseek(fp, 0, SEEK_SET);
548  
549 while((bytes_read = fread(buf, 1, BUFLEN, fp)) > 0)
550 {
551 unsigned char *cp = buf;
552  
553 if(length + bytes_read < length)
554 return 0;
555  
556 if(bytes_read != BUFLEN && tagged)
557 bytes_read -= 8;
558  
559 length += bytes_read;
560 while(bytes_read--)
561 crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
562 }
563  
564 if(ferror(fp))
565 return 0;
566  
567 for(; length; length >>= 8)
568 crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF];
569  
570 crc = ~crc & 0xFFFFFFFF;
571  
572 *res = crc;
573  
574 return 1;
575 }
576  
577 unsigned long cs_calc_buf_sum(char *buf, int size)
578 {
579 unsigned long crc = 0;
580 char *cp = buf;
581 unsigned long length = size;
582  
583 while(size--)
584 crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
585  
586 for(; length; length >>= 8)
587 crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF];
588  
589 crc = ~crc & 0xFFFFFFFF;
590  
591 return crc;
592 }
593  
594 unsigned long cs_calc_buf_sum_ds(char *buf, int buf_size, char *sign, int sign_len)
595 {
596 unsigned long crc = 0;
597 char *cp = buf;
598 unsigned long length = buf_size+sign_len;
599  
600 while(buf_size--)
601 crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
602  
603 cp = sign;
604 while(sign_len--)
605 crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
606  
607  
608 for(; length; length >>= 8)
609 crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF];
610  
611 crc = ~crc & 0xFFFFFFFF;
612  
613 return crc;
614 }
615  
616 int cs_set_sum(FILE *fp, unsigned long sum, int tagged)
617 {
618 unsigned long magic = CKSUM_MAGIC_NUMBER;
619  
620 if(tagged)
621 fseek(fp, -8, SEEK_END);
622 else
623 fseek(fp, 0, SEEK_END);
624  
625 if(fwrite(&magic, 1, 4, fp) < 4)
626 return 0;
627 if(fwrite(&sum, 1, 4, fp) < 4)
628 return 0;
629  
630 return 1;
631 }
632  
633 void cs_get_sum(FILE *fp, unsigned long *sum)
634 {
635 unsigned long magic = 0;
636  
637 fseek(fp, -8, SEEK_END);
638  
639 fread(&magic, 4, 1, fp);
640 fread(sum, 4, 1, fp);
641 }
642  
643 int cs_validate_file(char *filename)
644 {
645 FILE *pFile = NULL;
646 unsigned long sum = 0, res = 0;
647  
648 if((pFile = fopen(filename, "r")) == NULL)
649 return 0;
650  
651 if(!cs_is_tagged(pFile))
652 {
653 fclose(pFile);
654 return 0;
655 }
656 if(!cs_calc_sum(pFile, &sum, 1))
657 {
658 fclose(pFile);
659 return 0;
660 }
661 cs_get_sum(pFile, &res);
662 fclose(pFile);
663  
664 if(sum != res)
665 return 0;
666 return 1;
667 }
668  
669 /* ********* Library internal data ********* */
670 #define CMDLINE_TRUE 1
671 #define CMDLINE_FALSE 0
672  
673 typedef enum CMDLINE_ERR
674 {
675 CMDLINE_ERR_OK = 0, /* No Error (OK) */
676 CMDLINE_ERR_ERROR = -1, /* Unspecified error */
677 CMDLINE_ERR_INVKEY = -3, /* Invalid option key */
678 CMDLINE_ERR_MANYARG = -4, /* Too many arguments */
679 CMDLINE_ERR_FEWARG = -5, /* Too few arguments */
680 CMDLINE_ERR_ILLOPT = -6, /* Option not allowed (illegal option) */
681 CMDLINE_ERR_NOMEM = -7, /* No memory */
682 CMDLINE_ERR_OPTMIS = -8 /* A mandatory option is missing */
683 } CMDLINE_ERR;
684  
685 /* Argument list */
686 typedef struct CMDLINE_ARG
687 {
688 int index; /* Index of the argument in the command line */
689 struct CMDLINE_ARG* p_next; /* Next node in the linked list */
690 } CMDLINE_ARG;
691  
692 /* Master control block for an option */
693 typedef struct CMDLINE_ARGS
694 {
695 int argc; /* Total count of arguments found */
696 int optc; /* Total count of options found */
697 CMDLINE_ARG* list; /* Argument list */
698 } CMDLINE_ARGS;
699  
700 /* Master control block for all found arguments */
701 typedef struct CMDLINE_DATA
702 {
703 CMDLINE_ARGS opt_args[26]; /* Array of MCBs for each option ('a' through 'z') */
704 CMDLINE_ARGS glb_args; /* Global arguments */
705 int parsed; /* Internal flag to prevent client calls if library is not initialized */
706 } CMDLINE_DATA;
707  
708 /* ********* Local Data ********* */
709 static CMDLINE_CFG cmdline_cfg;
710 static CMDLINE_DATA cmdline_data;
711  
712 char* cmdline_errmsg = "CMDLINE ERROR";
713  
714 /* ***************************************************************
715 * Print all found command line options and their arguments
716 ****************************************************************** */
717 void* cmdline_getarg_list(char opt)
718 {
719 int index = (opt - 'a');
720  
721 /* Check the validity of the index */
722 if((index < 0) || (index > 25))
723 {
724 /* ERROR: Wrong option */
725 return NULL;
726 }
727  
728 /* Return a pointer to the ARGS control structure */
729 return((void*)(&cmdline_data.opt_args[index]));
730 }
731  
732 /* ***************************************************************
733 * Print all found command line options and their arguments
734 ****************************************************************** */
735 int cmdline_getarg_count(void* list)
736 {
737 CMDLINE_ARGS* p_args = (CMDLINE_ARGS*)list;
738  
739 /* Return number of arguments for this option */
740 return(p_args->argc);
741 }
742  
743 /* ***************************************************************
744 * Print all found command line options and their arguments
745 ****************************************************************** */
746 int cmdline_getopt_count(char opt)
747 {
748 int index;
749  
750 /* Calculate index value */
751 index = opt - 'a';
752 if(index < 0 || index > 25) return -1;
753  
754 /* Return number of arguments for this option */
755 return(cmdline_data.opt_args[index].optc);
756 }
757  
758 /* ***************************************************************
759 * Print all found command line options and their arguments
760 ****************************************************************** */
761 int cmdline_getarg(void* list, int num)
762 {
763 int i;
764 CMDLINE_ARGS* p_args = (CMDLINE_ARGS*)list;
765 CMDLINE_ARG* p_arg;
766  
767 /* Search the 'num' argument in the list for this option */
768 for(i=0,p_arg=p_args->list; (p_arg!=NULL) && (i<p_args->argc); i++, p_arg=p_arg->p_next)
769 {
770 /* if num matches i, we found it */
771 if(i==num) return(p_arg->index);
772 }
773 /* We did not find the specified argument or the list was empty */
774 return -1;
775 }
776  
777 /* ***************************************************************
778 * Print all found command line options and their arguments
779 ****************************************************************** */
780 int cmdline_configure(CMDLINE_CFG* p_cfg)
781 {
782 /* reset global data */
783 memset(&cmdline_cfg,0,sizeof(cmdline_cfg));
784 memset(&cmdline_data,0,sizeof(cmdline_data));
785  
786 /* Copy the user's config structure */
787 cmdline_cfg = *p_cfg;
788 return 0;
789 }
790  
791 /* ***************************************************************
792 * Print all found command line options and their arguments
793 ****************************************************************** */
794 char* cmdline_error(int err)
795 {
796 /* TODO: implement a table of error messages */
797 return(cmdline_errmsg);
798 }
799  
800 /* ***************************************************************
801 * Print all found command line options and their arguments
802 ****************************************************************** */
803 static void cmdline_print_args(CMDLINE_ARGS* p_arglist, char* argv[])
804 {
805 CMDLINE_ARG* p_arg;
806  
807 printf(" Number of times option was specified: %d\n", p_arglist->optc);
808 printf(" Number of Arguments: %d\n", p_arglist->argc);
809  
810 if(p_arglist->argc > 0)
811 {
812 printf(" Argument List: ");
813  
814 for(p_arg=p_arglist->list; p_arg != NULL; p_arg=p_arg->p_next)
815 printf("%s ", argv[p_arg->index]);
816 }
817  
818 printf("\n");
819 }
820  
821 /* ***************************************************************
822 * Print all found command line options and their arguments
823 ****************************************************************** */
824 void cmdline_print(char* argv[])
825 {
826 int i;
827  
828 /* Check if the command line was parsed */
829 if(cmdline_data.parsed != CMDLINE_TRUE)
830 {
831 printf("The command line has not been parsed yet.\n");
832 return;
833 }
834  
835 /* Print out option arguments */
836 for( i = 0; i < 26; i++ )
837 {
838 /* Check if the option was specified */
839 if(cmdline_data.opt_args[i].optc !=0 )
840 {
841 /* Print out option name and arguments */
842 printf("Option: -%c\n", (char)('a'+i));
843 cmdline_print_args(&(cmdline_data.opt_args[i]), argv);
844 }
845 }
846  
847 /* Print out global arguments */
848 printf("Global arguments:\n");
849 cmdline_print_args(&(cmdline_data.glb_args), argv);
850 }
851  
852 /* ***************************************************************
853 * Print configuration
854 ****************************************************************** */
855 void cmdline_print_cfg(void)
856 {
857  
858 }
859  
860 static void cmdline_argadd(CMDLINE_ARGS* p_arglist, CMDLINE_ARG* p_arg)
861 {
862 CMDLINE_ARG* p_list;
863 CMDLINE_ARG* p_prev=NULL;
864  
865 /* See if we had anything in the list */
866 if(p_arglist->argc == 0)
867 {
868 /* Link the argument in */
869 p_arglist->list = p_arg;
870 }
871 else
872 {
873 /* Find the tail of the list */
874 for(p_list=p_arglist->list; p_list != NULL; p_list=p_list->p_next)
875 p_prev = p_list;
876  
877 /* Link the argument in */
878 p_prev->p_next=p_arg;
879 }
880  
881 /* Keep track of arg number */
882 p_arglist->argc++;
883 }
884  
885 /* ***************************************************************
886 * cmdline_read()
887 * Read and parse command line arguments
888 ****************************************************************** */
889 int cmdline_read(int argc, char* argv[])
890 {
891 int i, option=0;
892  
893 /* Process every command line argument in argv[] array */
894 for( i = 1; i < argc; i++ )
895 {
896 /* Does the argument start with a dash? */
897 if( *argv[i] == '-' )
898 {
899 /* The argument must be two characters: a dash, and a letter */
900 if( strlen(argv[i]) != 2 )
901 {
902 /* ERROR: option syntax (needs to be a dash and one letter) */
903 return(CMDLINE_ERR_ERROR);
904 }
905  
906 /* Check validity of the option key ('a' through 'z') */
907 if( ((*(argv[i] + 1)) < 'a') || ((*(argv[i] + 1)) > 'z') )
908 {
909 /* ERROR: option sysntax (invalid option key) */
910 return(CMDLINE_ERR_INVKEY);
911 }
912  
913 /* Calculate the option index */
914 option = (*(argv[i] + 1)) - 'a';
915 if((option < 0) || (option > 25)) return(CMDLINE_ERR_INVKEY);
916  
917 /* Check to see if the option is allowed */
918 if( cmdline_cfg.opts[option].flags & CMDLINE_OPTFLAG_ALLOW )
919 {
920 /* Option allowed. */
921 cmdline_data.opt_args[option].optc++;
922 continue;
923 }
924 else
925 {
926 /* ERROR: Option is not allowed */
927 return(CMDLINE_ERR_ILLOPT);
928 }
929 }
930 else
931 {
932 /* Read the arguments for the option */
933 CMDLINE_ARG* p_arg;
934  
935 /* Allocate space for the argument node */
936 p_arg = (CMDLINE_ARG*)calloc(1,sizeof(CMDLINE_ARG));
937 if( p_arg== NULL )
938 {
939 /* ERROR: Can't allocate memory for the argument index */
940 return(CMDLINE_ERR_NOMEM);
941 }
942  
943 /* Initialize the argument */
944 p_arg->index = i;
945 p_arg->p_next = NULL;
946  
947 /* Check if we can add to the list of arguments for this option */
948 if( (option < 0) /* Do we have to add to the global list? */
949 || (cmdline_data.opt_args[option].argc == cmdline_cfg.opts[option].max) /* Did we reach MAX arguments? */
950 )
951 {
952 /* This option does not require arguments. Keep the argument in the global list. */
953 cmdline_argadd(&(cmdline_data.glb_args), p_arg);
954 continue;
955 }
956 else
957 {
958 /* See if the current count has reached max for this option */
959 if( cmdline_data.opt_args[option].argc == cmdline_cfg.opts[option].max )
960 {
961 /* ERROR: too many arguments for an option */
962 return(CMDLINE_ERR_MANYARG);
963 }
964 else
965 {
966 /* Link the argument to the arg list of the option */
967 cmdline_argadd(&(cmdline_data.opt_args[option]), p_arg);
968 continue;
969 }
970 }
971 }
972 }
973  
974 /* ****** We read the complete command line. See if what we collected matches the configuration ******* */
975  
976 /* Check every collected option against its configuration */
977 for( i=0; i < 26; i++ )
978 {
979 /* Check if this option was allowed */
980 if(cmdline_cfg.opts[i].flags & CMDLINE_OPTFLAG_ALLOW)
981 {
982 /* See if it was mandatory */
983 if(cmdline_cfg.opts[i].flags & CMDLINE_OPTFLAG_MANDAT)
984 {
985 /* Check if we really collected this option on the command line. */
986 if(cmdline_data.opt_args[i].optc == 0)
987 {
988 /* ERROR: a missing mandatory option */
989 return(CMDLINE_ERR_OPTMIS);
990 }
991 else
992 {
993 /* Option was there. Check how many args we got for it. */
994 if(cmdline_data.opt_args[i].argc < cmdline_cfg.opts[i].min)
995 {
996 /* ERROR: too few arguments for an option */
997 return(CMDLINE_ERR_FEWARG);
998 }
999 else
1000 {
1001 /* This mandatory option was proper. */
1002 continue;
1003 }
1004 }
1005 }
1006 else /* This is non-mandatory option: */
1007 {
1008 /* Check if the option was specified on the command line */
1009 if(cmdline_data.opt_args[i].optc == 0)
1010 {
1011 /* option wasn't specified, go to the next */
1012 continue;
1013 }
1014 else
1015 {
1016 /* Option was there. Check how many args we collected for it. */
1017 if(cmdline_data.opt_args[i].argc < cmdline_cfg.opts[i].min)
1018 {
1019 /* ERROR: too few arguments for a non-mandatory option */
1020 return(CMDLINE_ERR_FEWARG);
1021 }
1022 else
1023 {
1024 /* This non-mandatory option was proper. */
1025 continue;
1026 }
1027 }
1028 }
1029 }
1030 else /* Option was not allowed. */
1031 {
1032 /* We should not get here as the non-allowed options should have been
1033 trapped eariler. */
1034 }
1035 }
1036  
1037 /* Command line was proper as far as the number of options and their arguments */
1038 cmdline_data.parsed = CMDLINE_TRUE;
1039 return(CMDLINE_ERR_OK);
1040 }