4 #include "mktitanimg.h"
10 unsigned int chksum; /* The checksum for the complete header.
14 /***************************************************************************
15 * void print_help(void)
16 ***************************************************************************/
19 static char* help_page[]=
21 "mknspimg version 1.0, Texas Instruments, 2004",
23 " mknspimg -o outfile -i image1 image2 -a align1 align2 [-v] [-b] [-p prod_id] [-r rel_id] [-s rel_name] [-f flags]",
25 " mknspimg -o nsp_image.bin -i kernel.bin files.img -a 0 4096",
26 "This generates 'nsp_image.bin' from two input files aligning first to 0 and second to 4096 bytes."
29 int num_lines = sizeof(help_page)/sizeof(char*);
31 for(i=0; i < num_lines; i++) {
32 printf("%s\n", help_page[i]);
36 /***************************************************************************
37 * void mknspimg_print_hdr(NSP_IMG_HDR* p_img_hdr)
38 ***************************************************************************/
39 void mknspimg_print_hdr(struct nsp_img_hdr *hdr)
41 struct nsp_img_hdr_chksum *chksum;
42 struct nsp_img_hdr_section_info *sect_info;
43 struct nsp_img_hdr_sections *section;
46 printf("****************** NSP Image Summary ******************\n");
47 printf("Magic: 0x%x\n", hdr->head.magic);
48 printf("Image Header Size: 0x%x bytes\n", hdr->head.hdr_size);
49 printf("Total Image Size: %d bytes\n", hdr->head.image_size);
50 printf("Product ID: 0x%x\n", hdr->head.prod_id);
51 printf("Release ID: 0x%x\n", hdr->head.rel_id);
52 printf("Version ID: 0x%x\n", hdr->head.version);
54 printf("Offset Info: 0x%x\n", hdr->head.info_offset);
55 printf("Offset Sect info: 0x%x\n", hdr->head.sect_info_offset);
56 printf("Offset Sections: 0x%x\n", hdr->sect_info.sections_offset);
58 chksum=(struct nsp_img_hdr_chksum *)((unsigned int)hdr+hdr->head.chksum_offset);
59 printf("Header Checksum: 0x%x\n", chksum->hdr_chksum);
61 printf("+++ Section Information +++\n");
62 printf("# of sections: %u\n", hdr->sect_info.num_sects);
63 section=&(hdr->sections);
64 for(i = 0; i < hdr->sect_info.num_sects; i++, section++) {
65 printf("+++++ Section %d +++++\n", i);
66 printf("Total size: %u bytes\n", section->total_size);
67 printf("Raw Size: %u bytes\n", section->raw_size);
68 printf("Offset: 0x%x\n", section->offset);
69 printf("Type: 0x%x\n", section->type);
70 printf("Name: %s\n", section->name);
72 printf("*******************************************************\n");
75 CMDLINE_CFG cmd_line_cfg =
78 /* MIN MAX FLAGS OPTION */
79 { 2, 2, (CMDLINE_OPTFLAG_ALLOW | CMDLINE_OPTFLAG_MANDAT) }, /* '-a' align1 align2 */
80 { 0, 0, CMDLINE_OPTFLAG_ALLOW }, /* '-b' bootstrap */
81 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-c' */
82 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-d' */
83 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-e' */
84 { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-f' flags */
85 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-g' */
86 { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-h' */
87 { 2, 2, (CMDLINE_OPTFLAG_ALLOW | CMDLINE_OPTFLAG_MANDAT) }, /* '-i arg1 arg2 ' */
88 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-j' */
89 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-k' */
90 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-l' */
91 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-m' */
92 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-n' */
93 { 1, 1, (CMDLINE_OPTFLAG_ALLOW | CMDLINE_OPTFLAG_MANDAT) }, /* '-o arg' */
94 { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-p' PROD_ID */
95 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-q' */
96 { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-r' REL_ID */
97 { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-s' "Release XXX.XXX" */
98 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-t' */
99 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-u' */
100 { 0, 0, CMDLINE_OPTFLAG_ALLOW }, /* '-v' control VERBOSE/NON-VERBOSE mode */
101 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-w' */
102 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-x' */
103 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-y' */
104 { 0, 0, !CMDLINE_OPTFLAG_ALLOW } /* '-z' */
106 { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* global arguments */
109 /***************************************************************************
110 * int nsp_img_write(void* image, char* file, int padding)
111 * Write out the image.
112 ***************************************************************************/
113 int main(int argc, char* argv[], char* env[])
115 FILE* nsp_image = NULL;
116 int header_version=1;
118 char* cmdline_error_msg;
124 int i,count; /* loop variables */
125 int num_sects = 2; /* We require exactly two image with -i option
126 (see CMDLINE_CFG structure above) */
131 struct nsp_img_hdr_head *img_hdr_head; /* Start of image header */
132 struct nsp_img_hdr_info *img_hdr_info;
133 struct nsp_img_hdr_section_info *img_hdr_section_info ;
134 struct nsp_img_hdr_sections *img_hdr_sections, *section; /* Section pointers */
137 /* Configure the command line. */
138 cmdline_configure(&cmd_line_cfg);
140 /* Read and parse the command line. */
141 cmdline_err = cmdline_read(argc, argv);
143 /* Check for parsing errors. */
144 if(cmdline_err != 0) {
145 /* Get the parse error message */
146 cmdline_error_msg = cmdline_error(cmdline_err);
149 printf("%s\n", cmdline_error_msg);
151 /* Print our help too */
155 if(cmdline_getopt_count('h') > 0)
157 header_version=atoi(argv[cmdline_getarg(cmdline_getarg_list('h'),0)]);
159 /* Set up arguments */
160 filen_kernel = argv[cmdline_getarg(cmdline_getarg_list('i'),0)];
161 filen_files = argv[cmdline_getarg(cmdline_getarg_list('i'),1)];
162 filen_out = argv[cmdline_getarg(cmdline_getarg_list('o'),0)];
163 /* Command line arguments have been parsed. Start doing our work. */
165 /* Caculate the header size, and allocate the memory, and assign the sub pointers */
166 header_size = sizeof(struct nsp_img_hdr_head) + /* This has a single section
167 desc block already */
168 (header_version==1?0:4) +
169 sizeof(struct nsp_img_hdr_info) +
170 sizeof(struct nsp_img_hdr_section_info) +
171 sizeof(struct nsp_img_hdr_sections) * num_sects ;
173 img_hdr_head = (struct nsp_img_hdr_head *)malloc(header_size);
174 memset(img_hdr_head, 0x0, header_size);
175 img_hdr_info = (struct nsp_img_hdr_info*)((char *)img_hdr_head + sizeof(struct nsp_img_hdr_head) + (header_version==1?0:4));
176 img_hdr_section_info = (struct nsp_img_hdr_section_info*)((char *)img_hdr_info + sizeof(struct nsp_img_hdr_info));
177 img_hdr_sections = (struct nsp_img_hdr_sections*)((char *)img_hdr_section_info + sizeof(struct nsp_img_hdr_section_info));
178 section = img_hdr_sections;
179 memset(img_hdr_head, 0xff, (void*)img_hdr_info - (void*)img_hdr_head);
181 img_hdr_head->hdr_version = header_version;
182 img_hdr_head->hdr_size = header_size;
183 img_hdr_head->info_offset = (void*)img_hdr_info - (void*)img_hdr_head;
184 img_hdr_head->sect_info_offset = (void*)img_hdr_section_info - (void*)img_hdr_head;
186 img_hdr_section_info->num_sects = num_sects;
187 img_hdr_section_info->sect_size = sizeof(struct nsp_img_hdr_sections);
188 img_hdr_section_info->sections_offset = (void*)img_hdr_sections - (void*)img_hdr_head;
190 /* chksum = (struct nsp_img_hdr_chksum *)
191 ((unsigned int)image_hdr + header_size - sizeof(struct nsp_img_hdr_chksum));*/
193 /* Open the out file */
194 nsp_image = fopen(filen_out,"wb+");
195 if(nsp_image==NULL) {
196 printf("ERROR: can't open %s for writing.\n", filen_out);
200 /* Skip image header. We'll come back to it after we've written out the images. */
201 fseek(nsp_image,header_size,SEEK_SET);
202 total = ftell(nsp_image);
204 printf("total=%x\n",total);
209 align = (header_version==1?0x10000:0x4000);
211 /* The user indicated no padding */
214 /* Calculate number padding bytes */
215 if((total %align) ==0)
218 padding = align - (total % align);
223 memset(buf, 0xff, padding);
224 if(fwrite((void*)buf,1,padding,nsp_image)!=padding) {
225 printf("ERROR: can't write to %s.\n", filen_out);
236 /* Write out all specified images (with -i option) */
237 for(i=0; i < num_sects; i++) {
238 char* file_name; /* input file name */
239 FILE* filep; /* input file pointer */
240 int padding; /* number of padding bytes to prepend */
241 int align; /* align factor from command line */
242 int result; /* intermediate result */
245 /* Open the specified image for reading */
246 file_name = argv[cmdline_getarg(cmdline_getarg_list('i'),i)];
247 filep = fopen(file_name, "rb");
249 printf("ERROR: can't open file %s for reading.\n", file_name);
252 section->flags = ~0x00;
253 /* Determine file size */
254 fseek(filep,0,SEEK_END);
255 section->raw_size=ftell(filep);
256 fseek(filep,0,SEEK_SET);
257 cs_calc_sum(filep,(unsigned long *)§ion->chksum,0);
258 fseek(filep,0,SEEK_SET);
260 /* Retrieve the alignment constant */
261 /* Set image offset from the beginning of the out file */
262 section->offset=total;// + padding;
266 /* Copy the image file into nsp_image */
267 count = section->raw_size;
269 result=fread(buf, 1, count, filep);
270 fwrite(buf, 1, result, nsp_image);
273 /* HACK: This is a hack to get the names and types to the files.
274 TODO: Fix this to be a real method */
276 section->type=NSP_IMG_SECTION_TYPE_KERNEL;
277 strncpy(section->name, "kernel", 16);
279 section->type=NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT;
280 strncpy(section->name, "root", 16);
283 /* Account for the total */
284 align = strtoul(argv[cmdline_getarg(cmdline_getarg_list('a'),i)],NULL,0);
286 if(align==0 || (((section->raw_size+ section->offset)%align)==0))
289 padding = align - ((section->raw_size+ section->offset) % align);
291 section->total_size=section->raw_size + padding;
294 #define EXTRA_BLOCK 0x10000
295 unsigned int squash_padding;
296 squash_padding = EXTRA_BLOCK - section->raw_size % EXTRA_BLOCK;
297 buf=malloc(EXTRA_BLOCK + 4);
298 memset(buf, 0, squash_padding);
299 fwrite(buf, 1, squash_padding, nsp_image);
300 memset(buf, 0, EXTRA_BLOCK + 4);
301 *((unsigned int *)buf)=0xdec0adde;
302 *((unsigned int *)(buf+EXTRA_BLOCK))=0xdec0adde;
303 fwrite(buf, 1, EXTRA_BLOCK+4, nsp_image);
306 if(align==0 || (((section->raw_size + (EXTRA_BLOCK + 4 + squash_padding)) %align)==0))
309 padding = align - ((section->raw_size + (EXTRA_BLOCK + 4 + squash_padding)) % align);
310 section->total_size=section->raw_size + (EXTRA_BLOCK + 4 + squash_padding) + padding;
314 memset(buf, 0xff, padding);
315 fwrite(buf, 1, padding, nsp_image);
318 printf("*****padding is %d\ttotal_size=%d\traw_size=%d\n",padding, section->total_size, section->raw_size);
320 //total += section->raw_size;
321 total = section->total_size + section->offset;
322 printf("total=0x%x\n",total);
323 /* Close the input file */
326 /* Move the section pointer to the next slot */
330 /* Take care of the NSP image header fields */
333 img_hdr_head->magic = NSP_IMG_MAGIC_NUMBER;
334 img_hdr_head->boot_offset = img_hdr_sections->offset;
335 img_hdr_head->flags = ~0x00; /* Set to all 1's */
337 if(cmdline_getopt_count('b'))
338 img_hdr_head->flags &= ~(NSP_IMG_FLAG_FAILBACK_5 | NSP_IMG_FLAG_FAILBACK_1);
340 if(cmdline_getopt_count('f'))
341 img_hdr_head->flags = strtoul(argv[cmdline_getarg(cmdline_getarg_list('f'),0)], 0, 16);
344 img_hdr_head->hdr_version = 2;
345 img_hdr_head->hdr_size = header_size;
348 if(cmdline_getopt_count('p'))
349 img_hdr_head->prod_id = strtoul(argv[cmdline_getarg(cmdline_getarg_list('p'),0)], 0, 16);
351 img_hdr_head->prod_id = 0x4C575943;
353 if(cmdline_getopt_count('r'))
354 img_hdr_head->rel_id = strtoul(argv[cmdline_getarg(cmdline_getarg_list('r'),0)], 0, 0);
356 img_hdr_head->rel_id = 0x10203040;
358 if(cmdline_getopt_count('s'))
359 img_hdr_head->version = strtoul(argv[cmdline_getarg(cmdline_getarg_list('s'),0)], 0, 0);
361 img_hdr_head->version = 0x0b040000;
362 img_hdr_head->image_size = total;
364 img_hdr_head->info_offset = (unsigned int)(&(image_hdr->info)) -
365 (unsigned int)image_hdr;
366 img_hdr_head->sect_info_offset= (unsigned int)(&(image_hdr->sect_info)) -
367 (unsigned int)image_hdr;
369 // image_hdr->head.chksum_offset = (unsigned int)chksum - (unsigned int)image_hdr;
370 img_hdr_head->chksum_offset = 0xffffffff;
371 // image_hdr->head.pad1 = 0xffffffff;
373 /* TODO: Fix. Do nothing yet */
374 // strncpy(nsp_img_hdr.id.prod_info,NSP_PRODINFO_STRING,sizeof(NSP_PRODINFO_STRING));
375 strcpy(img_hdr_info->image_filename, (const char *)basename(filen_out));
378 img_hdr_section_info->num_sects= num_sects;
379 img_hdr_section_info->sect_size= sizeof(struct nsp_img_hdr_sections);
380 img_hdr_section_info->sections_offset= (unsigned int)(&(image_hdr->sections)) -
381 (unsigned int)image_hdr;
384 /* Calculate checksum(s) */
386 chksum->hdr_chksum = cs_calc_buf_sum((char*)image_hdr,
387 header_size - sizeof(struct nsp_img_hdr_chksum));
389 /* Write out the NSP header. */
390 fseek(nsp_image,0,SEEK_SET);
391 count = fwrite((void*)img_hdr_head, header_size, 1, nsp_image);
393 printf("ERROR: can't write to %s.\n", filen_out);
397 /* Check if -v option was specified (no arg needed) */
398 if(cmdline_getopt_count('v') > 0)
400 struct nsp_img_hdr_head head;
401 struct nsp_img_hdr *hdr;
403 /* Rewind the file back to the beginning */
404 fseek(nsp_image,0,SEEK_SET);
406 /* Read header from the file */
407 fread((void*)&head, sizeof(struct nsp_img_hdr_head),
410 /* Get memory to store the complete header */
411 hdr = (struct nsp_img_hdr *)malloc(head.hdr_size);
413 /* Read header from the file */
414 fseek(nsp_image,0,SEEK_SET);
415 fread((void*)hdr, head.hdr_size, 1, nsp_image);
418 mknspimg_print_hdr(hdr);
419 printf("Generated total %d bytes\n",total);
426 struct checksumrecord cr;
427 cr.magic=CKSUM_MAGIC_NUMBER;
428 cs_calc_sum(nsp_image, (unsigned long *)&cr.chksum, 0);
429 fseek(nsp_image,0, SEEK_END);
430 fwrite(&cr, 1, sizeof(cr), nsp_image);
437 strcpy(fname, filen_out);
438 strcat(fname, ".non_web");
439 non_web = fopen(fname,"wb+");
440 fseek(nsp_image, 0, SEEK_END);
441 len = ftell(nsp_image);
443 fseek(nsp_image, 0, SEEK_SET);
444 fread(img_buf, 1, len, nsp_image);
446 fwrite(img_buf, 1, len-sizeof(struct checksumrecord), non_web);
450 /* Close NSP image file */
461 #define BUFLEN (1 << 16)
463 static unsigned long crctab[256] =
466 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B,
467 0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6,
468 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
469 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC,
470 0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, 0x6ED82B7F,
471 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A,
472 0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
473 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0xBE2B5B58,
474 0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033,
475 0xA4AD16EA, 0xA06C0B5D, 0xD4326D90, 0xD0F37027, 0xDDB056FE,
476 0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
477 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4,
478 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, 0x34867077, 0x30476DC0,
479 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5,
480 0x2AC12072, 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16,
481 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, 0x7897AB07,
482 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C,
483 0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1,
484 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
485 0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B,
486 0xBB60ADFC, 0xB6238B25, 0xB2E29692, 0x8AAD2B2F, 0x8E6C3698,
487 0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D,
488 0x94EA7B2A, 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E,
489 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, 0xC6BCF05F,
490 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34,
491 0xDC3ABDED, 0xD8FBA05A, 0x690CE0EE, 0x6DCDFD59, 0x608EDB80,
492 0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB,
493 0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A,
494 0x58C1663D, 0x558240E4, 0x51435D53, 0x251D3B9E, 0x21DC2629,
495 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C,
496 0x3B5A6B9B, 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF,
497 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, 0xF12F560E,
498 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65,
499 0xEBA91BBC, 0xEF68060B, 0xD727BBB6, 0xD3E6A601, 0xDEA580D8,
500 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3,
501 0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2,
502 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, 0x9B3660C6, 0x9FF77D71,
503 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74,
504 0x857130C3, 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640,
505 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, 0x7B827D21,
506 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A,
507 0x61043093, 0x65C52D24, 0x119B4BE9, 0x155A565E, 0x18197087,
508 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC,
509 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D,
510 0x2056CD3A, 0x2D15EBE3, 0x29D4F654, 0xC5A92679, 0xC1683BCE,
511 0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB,
512 0xDBEE767C, 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18,
513 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4, 0x89B8FD09,
514 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662,
515 0x933EB0BB, 0x97FFAD0C, 0xAFB010B1, 0xAB710D06, 0xA6322BDF,
516 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4
519 int cs_is_tagged(FILE *fp)
523 fseek(fp, -8, SEEK_END);
524 fread(buf, 8, 1, fp);
525 if(*(unsigned long*)buf == CKSUM_MAGIC_NUMBER)
530 unsigned long cs_read_sum(FILE *fp)
534 fseek(fp, -8, SEEK_END);
535 fread(buf, 8, 1, fp);
536 return *((unsigned long*)&buf[4]);
539 int cs_calc_sum(FILE *fp, unsigned long *res, int tagged)
541 unsigned char buf[BUFLEN];
542 unsigned long crc = 0;
543 uintmax_t length = 0;
546 fseek(fp, 0, SEEK_SET);
548 while((bytes_read = fread(buf, 1, BUFLEN, fp)) > 0)
550 unsigned char *cp = buf;
552 if(length + bytes_read < length)
555 if(bytes_read != BUFLEN && tagged)
558 length += bytes_read;
560 crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
566 for(; length; length >>= 8)
567 crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF];
569 crc = ~crc & 0xFFFFFFFF;
576 unsigned long cs_calc_buf_sum(char *buf, int size)
578 unsigned long crc = 0;
580 unsigned long length = size;
583 crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
585 for(; length; length >>= 8)
586 crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF];
588 crc = ~crc & 0xFFFFFFFF;
593 unsigned long cs_calc_buf_sum_ds(char *buf, int buf_size, char *sign, int sign_len)
595 unsigned long crc = 0;
597 unsigned long length = buf_size+sign_len;
600 crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
604 crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
607 for(; length; length >>= 8)
608 crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF];
610 crc = ~crc & 0xFFFFFFFF;
615 int cs_set_sum(FILE *fp, unsigned long sum, int tagged)
617 unsigned long magic = CKSUM_MAGIC_NUMBER;
620 fseek(fp, -8, SEEK_END);
622 fseek(fp, 0, SEEK_END);
624 if(fwrite(&magic, 1, 4, fp) < 4)
626 if(fwrite(&sum, 1, 4, fp) < 4)
632 void cs_get_sum(FILE *fp, unsigned long *sum)
634 unsigned long magic = 0;
636 fseek(fp, -8, SEEK_END);
638 fread(&magic, 4, 1, fp);
639 fread(sum, 4, 1, fp);
642 int cs_validate_file(char *filename)
645 unsigned long sum = 0, res = 0;
647 if((pFile = fopen(filename, "r")) == NULL)
650 if(!cs_is_tagged(pFile))
655 if(!cs_calc_sum(pFile, &sum, 1))
660 cs_get_sum(pFile, &res);
668 /* ********* Library internal data ********* */
669 #define CMDLINE_TRUE 1
670 #define CMDLINE_FALSE 0
672 typedef enum CMDLINE_ERR
674 CMDLINE_ERR_OK = 0, /* No Error (OK) */
675 CMDLINE_ERR_ERROR = -1, /* Unspecified error */
676 CMDLINE_ERR_INVKEY = -3, /* Invalid option key */
677 CMDLINE_ERR_MANYARG = -4, /* Too many arguments */
678 CMDLINE_ERR_FEWARG = -5, /* Too few arguments */
679 CMDLINE_ERR_ILLOPT = -6, /* Option not allowed (illegal option) */
680 CMDLINE_ERR_NOMEM = -7, /* No memory */
681 CMDLINE_ERR_OPTMIS = -8 /* A mandatory option is missing */
685 typedef struct CMDLINE_ARG
687 int index; /* Index of the argument in the command line */
688 struct CMDLINE_ARG* p_next; /* Next node in the linked list */
691 /* Master control block for an option */
692 typedef struct CMDLINE_ARGS
694 int argc; /* Total count of arguments found */
695 int optc; /* Total count of options found */
696 CMDLINE_ARG* list; /* Argument list */
699 /* Master control block for all found arguments */
700 typedef struct CMDLINE_DATA
702 CMDLINE_ARGS opt_args[26]; /* Array of MCBs for each option ('a' through 'z') */
703 CMDLINE_ARGS glb_args; /* Global arguments */
704 int parsed; /* Internal flag to prevent client calls if library is not initialized */
707 /* ********* Local Data ********* */
708 static CMDLINE_CFG cmdline_cfg;
709 static CMDLINE_DATA cmdline_data;
711 char* cmdline_errmsg = "CMDLINE ERROR";
713 /* ***************************************************************
714 * Print all found command line options and their arguments
715 ****************************************************************** */
716 void* cmdline_getarg_list(char opt)
718 int index = (opt - 'a');
720 /* Check the validity of the index */
721 if((index < 0) || (index > 25))
723 /* ERROR: Wrong option */
727 /* Return a pointer to the ARGS control structure */
728 return((void*)(&cmdline_data.opt_args[index]));
731 /* ***************************************************************
732 * Print all found command line options and their arguments
733 ****************************************************************** */
734 int cmdline_getarg_count(void* list)
736 CMDLINE_ARGS* p_args = (CMDLINE_ARGS*)list;
738 /* Return number of arguments for this option */
739 return(p_args->argc);
742 /* ***************************************************************
743 * Print all found command line options and their arguments
744 ****************************************************************** */
745 int cmdline_getopt_count(char opt)
749 /* Calculate index value */
751 if(index < 0 || index > 25) return -1;
753 /* Return number of arguments for this option */
754 return(cmdline_data.opt_args[index].optc);
757 /* ***************************************************************
758 * Print all found command line options and their arguments
759 ****************************************************************** */
760 int cmdline_getarg(void* list, int num)
763 CMDLINE_ARGS* p_args = (CMDLINE_ARGS*)list;
766 /* Search the 'num' argument in the list for this option */
767 for(i=0,p_arg=p_args->list; (p_arg!=NULL) && (i<p_args->argc); i++, p_arg=p_arg->p_next)
769 /* if num matches i, we found it */
770 if(i==num) return(p_arg->index);
772 /* We did not find the specified argument or the list was empty */
776 /* ***************************************************************
777 * Print all found command line options and their arguments
778 ****************************************************************** */
779 int cmdline_configure(CMDLINE_CFG* p_cfg)
781 /* reset global data */
782 memset(&cmdline_cfg,0,sizeof(cmdline_cfg));
783 memset(&cmdline_data,0,sizeof(cmdline_data));
785 /* Copy the user's config structure */
786 cmdline_cfg = *p_cfg;
790 /* ***************************************************************
791 * Print all found command line options and their arguments
792 ****************************************************************** */
793 char* cmdline_error(int err)
795 /* TODO: implement a table of error messages */
796 return(cmdline_errmsg);
799 /* ***************************************************************
800 * Print all found command line options and their arguments
801 ****************************************************************** */
802 static void cmdline_print_args(CMDLINE_ARGS* p_arglist, char* argv[])
806 printf(" Number of times option was specified: %d\n", p_arglist->optc);
807 printf(" Number of Arguments: %d\n", p_arglist->argc);
809 if(p_arglist->argc > 0)
811 printf(" Argument List: ");
813 for(p_arg=p_arglist->list; p_arg != NULL; p_arg=p_arg->p_next)
814 printf("%s ", argv[p_arg->index]);
820 /* ***************************************************************
821 * Print all found command line options and their arguments
822 ****************************************************************** */
823 void cmdline_print(char* argv[])
827 /* Check if the command line was parsed */
828 if(cmdline_data.parsed != CMDLINE_TRUE)
830 printf("The command line has not been parsed yet.\n");
834 /* Print out option arguments */
835 for( i = 0; i < 26; i++ )
837 /* Check if the option was specified */
838 if(cmdline_data.opt_args[i].optc !=0 )
840 /* Print out option name and arguments */
841 printf("Option: -%c\n", (char)('a'+i));
842 cmdline_print_args(&(cmdline_data.opt_args[i]), argv);
846 /* Print out global arguments */
847 printf("Global arguments:\n");
848 cmdline_print_args(&(cmdline_data.glb_args), argv);
851 /* ***************************************************************
852 * Print configuration
853 ****************************************************************** */
854 void cmdline_print_cfg(void)
859 static void cmdline_argadd(CMDLINE_ARGS* p_arglist, CMDLINE_ARG* p_arg)
862 CMDLINE_ARG* p_prev=NULL;
864 /* See if we had anything in the list */
865 if(p_arglist->argc == 0)
867 /* Link the argument in */
868 p_arglist->list = p_arg;
872 /* Find the tail of the list */
873 for(p_list=p_arglist->list; p_list != NULL; p_list=p_list->p_next)
876 /* Link the argument in */
877 p_prev->p_next=p_arg;
880 /* Keep track of arg number */
884 /* ***************************************************************
886 * Read and parse command line arguments
887 ****************************************************************** */
888 int cmdline_read(int argc, char* argv[])
892 /* Process every command line argument in argv[] array */
893 for( i = 1; i < argc; i++ )
895 /* Does the argument start with a dash? */
896 if( *argv[i] == '-' )
898 /* The argument must be two characters: a dash, and a letter */
899 if( strlen(argv[i]) != 2 )
901 /* ERROR: option syntax (needs to be a dash and one letter) */
902 return(CMDLINE_ERR_ERROR);
905 /* Check validity of the option key ('a' through 'z') */
906 if( ((*(argv[i] + 1)) < 'a') || ((*(argv[i] + 1)) > 'z') )
908 /* ERROR: option sysntax (invalid option key) */
909 return(CMDLINE_ERR_INVKEY);
912 /* Calculate the option index */
913 option = (*(argv[i] + 1)) - 'a';
914 if((option < 0) || (option > 25)) return(CMDLINE_ERR_INVKEY);
916 /* Check to see if the option is allowed */
917 if( cmdline_cfg.opts[option].flags & CMDLINE_OPTFLAG_ALLOW )
919 /* Option allowed. */
920 cmdline_data.opt_args[option].optc++;
925 /* ERROR: Option is not allowed */
926 return(CMDLINE_ERR_ILLOPT);
931 /* Read the arguments for the option */
934 /* Allocate space for the argument node */
935 p_arg = (CMDLINE_ARG*)calloc(1,sizeof(CMDLINE_ARG));
938 /* ERROR: Can't allocate memory for the argument index */
939 return(CMDLINE_ERR_NOMEM);
942 /* Initialize the argument */
944 p_arg->p_next = NULL;
946 /* Check if we can add to the list of arguments for this option */
947 if( (option < 0) /* Do we have to add to the global list? */
948 || (cmdline_data.opt_args[option].argc == cmdline_cfg.opts[option].max) /* Did we reach MAX arguments? */
951 /* This option does not require arguments. Keep the argument in the global list. */
952 cmdline_argadd(&(cmdline_data.glb_args), p_arg);
957 /* See if the current count has reached max for this option */
958 if( cmdline_data.opt_args[option].argc == cmdline_cfg.opts[option].max )
960 /* ERROR: too many arguments for an option */
961 return(CMDLINE_ERR_MANYARG);
965 /* Link the argument to the arg list of the option */
966 cmdline_argadd(&(cmdline_data.opt_args[option]), p_arg);
973 /* ****** We read the complete command line. See if what we collected matches the configuration ******* */
975 /* Check every collected option against its configuration */
976 for( i=0; i < 26; i++ )
978 /* Check if this option was allowed */
979 if(cmdline_cfg.opts[i].flags & CMDLINE_OPTFLAG_ALLOW)
981 /* See if it was mandatory */
982 if(cmdline_cfg.opts[i].flags & CMDLINE_OPTFLAG_MANDAT)
984 /* Check if we really collected this option on the command line. */
985 if(cmdline_data.opt_args[i].optc == 0)
987 /* ERROR: a missing mandatory option */
988 return(CMDLINE_ERR_OPTMIS);
992 /* Option was there. Check how many args we got for it. */
993 if(cmdline_data.opt_args[i].argc < cmdline_cfg.opts[i].min)
995 /* ERROR: too few arguments for an option */
996 return(CMDLINE_ERR_FEWARG);
1000 /* This mandatory option was proper. */
1005 else /* This is non-mandatory option: */
1007 /* Check if the option was specified on the command line */
1008 if(cmdline_data.opt_args[i].optc == 0)
1010 /* option wasn't specified, go to the next */
1015 /* Option was there. Check how many args we collected for it. */
1016 if(cmdline_data.opt_args[i].argc < cmdline_cfg.opts[i].min)
1018 /* ERROR: too few arguments for a non-mandatory option */
1019 return(CMDLINE_ERR_FEWARG);
1023 /* This non-mandatory option was proper. */
1029 else /* Option was not allowed. */
1031 /* We should not get here as the non-allowed options should have been
1036 /* Command line was proper as far as the number of options and their arguments */
1037 cmdline_data.parsed = CMDLINE_TRUE;
1038 return(CMDLINE_ERR_OK);