5 #include "mktitanimg.h"
11 unsigned int chksum
; /* The checksum for the complete header.
15 /***************************************************************************
16 * void print_help(void)
17 ***************************************************************************/
20 static char* help_page
[]=
22 "mknspimg version 1.0, Texas Instruments, 2004",
24 " mknspimg -o outfile -i image1 image2 -a align1 align2 [-v] [-b] [-p prod_id] [-r rel_id] [-s rel_name] [-f flags]",
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."
30 int num_lines
= sizeof(help_page
)/sizeof(char*);
32 for(i
=0; i
< num_lines
; i
++) {
33 printf("%s\n", help_page
[i
]);
37 /***************************************************************************
38 * void mknspimg_print_hdr(NSP_IMG_HDR* p_img_hdr)
39 ***************************************************************************/
40 void mknspimg_print_hdr(struct nsp_img_hdr
*hdr
)
42 struct nsp_img_hdr_chksum
*chksum
;
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
*)(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
;
122 int i
,count
; /* loop variables */
123 int num_sects
= 2; /* We require exactly two image with -i option
124 (see CMDLINE_CFG structure above) */
128 struct nsp_img_hdr_head
*img_hdr_head
; /* Start of image header */
129 struct nsp_img_hdr_info
*img_hdr_info
;
130 struct nsp_img_hdr_section_info
*img_hdr_section_info
;
131 struct nsp_img_hdr_sections
*img_hdr_sections
, *section
; /* Section pointers */
134 /* Configure the command line. */
135 cmdline_configure(&cmd_line_cfg
);
137 /* Read and parse the command line. */
138 cmdline_err
= cmdline_read(argc
, argv
);
140 /* Check for parsing errors. */
141 if(cmdline_err
!= 0) {
142 /* Get the parse error message */
143 cmdline_error_msg
= cmdline_error(cmdline_err
);
146 printf("%s\n", cmdline_error_msg
);
148 /* Print our help too */
152 if(cmdline_getopt_count('h') > 0)
154 header_version
=atoi(argv
[cmdline_getarg(cmdline_getarg_list('h'),0)]);
156 /* Set up arguments */
157 filen_out
= argv
[cmdline_getarg(cmdline_getarg_list('o'),0)];
158 /* Command line arguments have been parsed. Start doing our work. */
160 /* Caculate the header size, and allocate the memory, and assign the sub pointers */
161 header_size
= sizeof(struct nsp_img_hdr_head
) + /* This has a single section
162 desc block already */
163 (header_version
==1?0:4) +
164 sizeof(struct nsp_img_hdr_info
) +
165 sizeof(struct nsp_img_hdr_section_info
) +
166 sizeof(struct nsp_img_hdr_sections
) * num_sects
;
168 img_hdr_head
= (struct nsp_img_hdr_head
*)malloc(header_size
);
169 memset(img_hdr_head
, 0x0, header_size
);
170 img_hdr_info
= (struct nsp_img_hdr_info
*)((char *)img_hdr_head
+ sizeof(struct nsp_img_hdr_head
) + (header_version
==1?0:4));
171 img_hdr_section_info
= (struct nsp_img_hdr_section_info
*)((char *)img_hdr_info
+ sizeof(struct nsp_img_hdr_info
));
172 img_hdr_sections
= (struct nsp_img_hdr_sections
*)((char *)img_hdr_section_info
+ sizeof(struct nsp_img_hdr_section_info
));
173 section
= img_hdr_sections
;
174 memset(img_hdr_head
, 0xff, (void*)img_hdr_info
- (void*)img_hdr_head
);
176 img_hdr_head
->hdr_version
= header_version
;
177 img_hdr_head
->hdr_size
= header_size
;
178 img_hdr_head
->info_offset
= (void*)img_hdr_info
- (void*)img_hdr_head
;
179 img_hdr_head
->sect_info_offset
= (void*)img_hdr_section_info
- (void*)img_hdr_head
;
181 img_hdr_section_info
->num_sects
= num_sects
;
182 img_hdr_section_info
->sect_size
= sizeof(struct nsp_img_hdr_sections
);
183 img_hdr_section_info
->sections_offset
= (void*)img_hdr_sections
- (void*)img_hdr_head
;
185 /* chksum = (struct nsp_img_hdr_chksum *)
186 ((unsigned int)image_hdr + header_size - sizeof(struct nsp_img_hdr_chksum));*/
188 /* Open the out file */
189 nsp_image
= fopen(filen_out
,"wb+");
190 if(nsp_image
==NULL
) {
191 printf("ERROR: can't open %s for writing.\n", filen_out
);
195 /* Skip image header. We'll come back to it after we've written out the images. */
196 fseek(nsp_image
,header_size
,SEEK_SET
);
197 total
= ftell(nsp_image
);
199 printf("total=%x\n",total
);
204 align
= (header_version
==1?0x10000:0x4000);
206 /* The user indicated no padding */
209 /* Calculate number padding bytes */
210 if((total
%align
) ==0)
213 padding
= align
- (total
% align
);
218 memset(buf
, 0xff, padding
);
219 if(fwrite((void*)buf
,1,padding
,nsp_image
)!=padding
) {
220 printf("ERROR: can't write to %s.\n", filen_out
);
232 /* Write out all specified images (with -i option) */
233 for(i
=0; i
< num_sects
; i
++) {
234 char* file_name
; /* input file name */
235 FILE* filep
; /* input file pointer */
236 int padding
; /* number of padding bytes to prepend */
237 int align
; /* align factor from command line */
238 int result
; /* intermediate result */
241 /* Open the specified image for reading */
242 file_name
= argv
[cmdline_getarg(cmdline_getarg_list('i'),i
)];
243 filep
= fopen(file_name
, "rb");
245 printf("ERROR: can't open file %s for reading.\n", file_name
);
248 section
->flags
= ~0x00;
249 /* Determine file size */
250 fseek(filep
,0,SEEK_END
);
251 section
->raw_size
=ftell(filep
);
252 fseek(filep
,0,SEEK_SET
);
253 cs_calc_sum(filep
,(unsigned long *)§ion
->chksum
,0);
254 fseek(filep
,0,SEEK_SET
);
256 /* Retrieve the alignment constant */
257 /* Set image offset from the beginning of the out file */
258 section
->offset
=total
;// + padding;
262 /* Copy the image file into nsp_image */
263 count
= section
->raw_size
;
265 result
=fread(buf
, 1, count
, filep
);
266 fwrite(buf
, 1, result
, nsp_image
);
269 /* HACK: This is a hack to get the names and types to the files.
270 TODO: Fix this to be a real method */
272 section
->type
=NSP_IMG_SECTION_TYPE_KERNEL
;
273 strncpy(section
->name
, "kernel", 16);
275 section
->type
=NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT
;
276 strncpy(section
->name
, "root", 16);
279 /* Account for the total */
280 align
= strtoul(argv
[cmdline_getarg(cmdline_getarg_list('a'),i
)],NULL
,0);
282 if(align
==0 || (((section
->raw_size
+ section
->offset
)%align
)==0))
285 padding
= align
- ((section
->raw_size
+ section
->offset
) % align
);
287 section
->total_size
=section
->raw_size
+ padding
;
290 #define EXTRA_BLOCK 0x10000
291 unsigned int squash_padding
;
292 squash_padding
= EXTRA_BLOCK
- section
->raw_size
% EXTRA_BLOCK
;
293 buf
=malloc(EXTRA_BLOCK
+ 4);
294 memset(buf
, 0, squash_padding
);
295 fwrite(buf
, 1, squash_padding
, nsp_image
);
296 memset(buf
, 0, EXTRA_BLOCK
+ 4);
297 *((unsigned int *)buf
)=0xdec0adde;
298 *((unsigned int *)(buf
+EXTRA_BLOCK
))=0xdec0adde;
299 fwrite(buf
, 1, EXTRA_BLOCK
+4, nsp_image
);
302 if(align
==0 || (((section
->raw_size
+ (EXTRA_BLOCK
+ 4 + squash_padding
)) %align
)==0))
305 padding
= align
- ((section
->raw_size
+ (EXTRA_BLOCK
+ 4 + squash_padding
)) % align
);
306 section
->total_size
=section
->raw_size
+ (EXTRA_BLOCK
+ 4 + squash_padding
) + padding
;
310 memset(buf
, 0xff, padding
);
311 fwrite(buf
, 1, padding
, nsp_image
);
314 printf("*****padding is %d\ttotal_size=%d\traw_size=%d\n",padding
, section
->total_size
, section
->raw_size
);
316 //total += section->raw_size;
317 total
= section
->total_size
+ section
->offset
;
318 printf("total=0x%x\n",total
);
319 /* Close the input file */
322 /* Move the section pointer to the next slot */
326 /* Take care of the NSP image header fields */
329 img_hdr_head
->magic
= NSP_IMG_MAGIC_NUMBER
;
330 img_hdr_head
->boot_offset
= img_hdr_sections
->offset
;
331 img_hdr_head
->flags
= ~0x00; /* Set to all 1's */
333 if(cmdline_getopt_count('b'))
334 img_hdr_head
->flags
&= ~(NSP_IMG_FLAG_FAILBACK_5
| NSP_IMG_FLAG_FAILBACK_1
);
336 if(cmdline_getopt_count('f'))
337 img_hdr_head
->flags
= strtoul(argv
[cmdline_getarg(cmdline_getarg_list('f'),0)], 0, 16);
340 img_hdr_head
->hdr_version
= 2;
341 img_hdr_head
->hdr_size
= header_size
;
344 if(cmdline_getopt_count('p'))
345 img_hdr_head
->prod_id
= strtoul(argv
[cmdline_getarg(cmdline_getarg_list('p'),0)], 0, 16);
347 img_hdr_head
->prod_id
= 0x4C575943;
349 if(cmdline_getopt_count('r'))
350 img_hdr_head
->rel_id
= strtoul(argv
[cmdline_getarg(cmdline_getarg_list('r'),0)], 0, 0);
352 img_hdr_head
->rel_id
= 0x10203040;
354 if(cmdline_getopt_count('s'))
355 img_hdr_head
->version
= strtoul(argv
[cmdline_getarg(cmdline_getarg_list('s'),0)], 0, 0);
357 img_hdr_head
->version
= 0x0b040000;
358 img_hdr_head
->image_size
= total
;
360 img_hdr_head
->info_offset
= (unsigned int)(&(image_hdr
->info
)) -
361 (unsigned int)image_hdr
;
362 img_hdr_head
->sect_info_offset
= (unsigned int)(&(image_hdr
->sect_info
)) -
363 (unsigned int)image_hdr
;
365 // image_hdr->head.chksum_offset = (unsigned int)chksum - (unsigned int)image_hdr;
366 img_hdr_head
->chksum_offset
= 0xffffffff;
367 // image_hdr->head.pad1 = 0xffffffff;
369 /* TODO: Fix. Do nothing yet */
370 // strncpy(nsp_img_hdr.id.prod_info,NSP_PRODINFO_STRING,sizeof(NSP_PRODINFO_STRING));
371 strcpy(img_hdr_info
->image_filename
, (const char *)basename(filen_out
));
374 img_hdr_section_info
->num_sects
= num_sects
;
375 img_hdr_section_info
->sect_size
= sizeof(struct nsp_img_hdr_sections
);
376 img_hdr_section_info
->sections_offset
= (unsigned int)(&(image_hdr
->sections
)) -
377 (unsigned int)image_hdr
;
380 /* Calculate checksum(s) */
382 chksum
->hdr_chksum
= cs_calc_buf_sum((char*)image_hdr
,
383 header_size
- sizeof(struct nsp_img_hdr_chksum
));
385 /* Write out the NSP header. */
386 fseek(nsp_image
,0,SEEK_SET
);
387 count
= fwrite((void*)img_hdr_head
, header_size
, 1, nsp_image
);
389 printf("ERROR: can't write to %s.\n", filen_out
);
393 /* Check if -v option was specified (no arg needed) */
394 if(cmdline_getopt_count('v') > 0)
396 struct nsp_img_hdr_head head
;
397 struct nsp_img_hdr
*hdr
;
399 /* Rewind the file back to the beginning */
400 fseek(nsp_image
,0,SEEK_SET
);
402 /* Read header from the file */
403 fread((void*)&head
, sizeof(struct nsp_img_hdr_head
),
406 /* Get memory to store the complete header */
407 hdr
= (struct nsp_img_hdr
*)malloc(head
.hdr_size
);
409 /* Read header from the file */
410 fseek(nsp_image
,0,SEEK_SET
);
411 fread((void*)hdr
, head
.hdr_size
, 1, nsp_image
);
414 mknspimg_print_hdr(hdr
);
415 printf("Generated total %d bytes\n",total
);
422 struct checksumrecord cr
;
423 cr
.magic
=CKSUM_MAGIC_NUMBER
;
424 cs_calc_sum(nsp_image
, (unsigned long *)&cr
.chksum
, 0);
425 fseek(nsp_image
,0, SEEK_END
);
426 fwrite(&cr
, 1, sizeof(cr
), nsp_image
);
433 strcpy(fname
, filen_out
);
434 strcat(fname
, ".non_web");
435 non_web
= fopen(fname
,"wb+");
436 fseek(nsp_image
, 0, SEEK_END
);
437 len
= ftell(nsp_image
);
439 fseek(nsp_image
, 0, SEEK_SET
);
440 fread(img_buf
, 1, len
, nsp_image
);
442 fwrite(img_buf
, 1, len
-sizeof(struct checksumrecord
), non_web
);
446 /* Close NSP image file */
457 #define BUFLEN (1 << 16)
459 static unsigned long crctab
[256] =
462 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B,
463 0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6,
464 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
465 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC,
466 0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, 0x6ED82B7F,
467 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A,
468 0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
469 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0xBE2B5B58,
470 0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033,
471 0xA4AD16EA, 0xA06C0B5D, 0xD4326D90, 0xD0F37027, 0xDDB056FE,
472 0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
473 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4,
474 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, 0x34867077, 0x30476DC0,
475 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5,
476 0x2AC12072, 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16,
477 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, 0x7897AB07,
478 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C,
479 0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1,
480 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
481 0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B,
482 0xBB60ADFC, 0xB6238B25, 0xB2E29692, 0x8AAD2B2F, 0x8E6C3698,
483 0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D,
484 0x94EA7B2A, 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E,
485 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, 0xC6BCF05F,
486 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34,
487 0xDC3ABDED, 0xD8FBA05A, 0x690CE0EE, 0x6DCDFD59, 0x608EDB80,
488 0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB,
489 0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A,
490 0x58C1663D, 0x558240E4, 0x51435D53, 0x251D3B9E, 0x21DC2629,
491 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C,
492 0x3B5A6B9B, 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF,
493 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, 0xF12F560E,
494 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65,
495 0xEBA91BBC, 0xEF68060B, 0xD727BBB6, 0xD3E6A601, 0xDEA580D8,
496 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3,
497 0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2,
498 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, 0x9B3660C6, 0x9FF77D71,
499 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74,
500 0x857130C3, 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640,
501 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, 0x7B827D21,
502 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A,
503 0x61043093, 0x65C52D24, 0x119B4BE9, 0x155A565E, 0x18197087,
504 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC,
505 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D,
506 0x2056CD3A, 0x2D15EBE3, 0x29D4F654, 0xC5A92679, 0xC1683BCE,
507 0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB,
508 0xDBEE767C, 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18,
509 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4, 0x89B8FD09,
510 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662,
511 0x933EB0BB, 0x97FFAD0C, 0xAFB010B1, 0xAB710D06, 0xA6322BDF,
512 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4
515 int cs_is_tagged(FILE *fp
)
519 fseek(fp
, -8, SEEK_END
);
520 fread(buf
, 8, 1, fp
);
521 if(*(unsigned long*)buf
== CKSUM_MAGIC_NUMBER
)
526 unsigned long cs_read_sum(FILE *fp
)
530 fseek(fp
, -8, SEEK_END
);
531 fread(buf
, 8, 1, fp
);
532 return *((unsigned long*)&buf
[4]);
535 int cs_calc_sum(FILE *fp
, unsigned long *res
, int tagged
)
537 unsigned char buf
[BUFLEN
];
538 unsigned long crc
= 0;
539 uintmax_t length
= 0;
542 fseek(fp
, 0, SEEK_SET
);
544 while((bytes_read
= fread(buf
, 1, BUFLEN
, fp
)) > 0)
546 unsigned char *cp
= buf
;
548 if(length
+ bytes_read
< length
)
551 if(bytes_read
!= BUFLEN
&& tagged
)
554 length
+= bytes_read
;
556 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ *cp
++) & 0xFF];
562 for(; length
; length
>>= 8)
563 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ length
) & 0xFF];
565 crc
= ~crc
& 0xFFFFFFFF;
572 unsigned long cs_calc_buf_sum(char *buf
, int size
)
574 unsigned long crc
= 0;
576 unsigned long length
= size
;
579 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ *cp
++) & 0xFF];
581 for(; length
; length
>>= 8)
582 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ length
) & 0xFF];
584 crc
= ~crc
& 0xFFFFFFFF;
589 unsigned long cs_calc_buf_sum_ds(char *buf
, int buf_size
, char *sign
, int sign_len
)
591 unsigned long crc
= 0;
593 unsigned long length
= buf_size
+sign_len
;
596 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ *cp
++) & 0xFF];
600 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ *cp
++) & 0xFF];
603 for(; length
; length
>>= 8)
604 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ length
) & 0xFF];
606 crc
= ~crc
& 0xFFFFFFFF;
611 int cs_set_sum(FILE *fp
, unsigned long sum
, int tagged
)
613 unsigned long magic
= CKSUM_MAGIC_NUMBER
;
616 fseek(fp
, -8, SEEK_END
);
618 fseek(fp
, 0, SEEK_END
);
620 if(fwrite(&magic
, 1, 4, fp
) < 4)
622 if(fwrite(&sum
, 1, 4, fp
) < 4)
628 void cs_get_sum(FILE *fp
, unsigned long *sum
)
630 unsigned long magic
= 0;
632 fseek(fp
, -8, SEEK_END
);
634 fread(&magic
, 4, 1, fp
);
635 fread(sum
, 4, 1, fp
);
638 int cs_validate_file(char *filename
)
641 unsigned long sum
= 0, res
= 0;
643 if((pFile
= fopen(filename
, "r")) == NULL
)
646 if(!cs_is_tagged(pFile
))
651 if(!cs_calc_sum(pFile
, &sum
, 1))
656 cs_get_sum(pFile
, &res
);
664 /* ********* Library internal data ********* */
665 #define CMDLINE_TRUE 1
666 #define CMDLINE_FALSE 0
668 typedef enum CMDLINE_ERR
670 CMDLINE_ERR_OK
= 0, /* No Error (OK) */
671 CMDLINE_ERR_ERROR
= -1, /* Unspecified error */
672 CMDLINE_ERR_INVKEY
= -3, /* Invalid option key */
673 CMDLINE_ERR_MANYARG
= -4, /* Too many arguments */
674 CMDLINE_ERR_FEWARG
= -5, /* Too few arguments */
675 CMDLINE_ERR_ILLOPT
= -6, /* Option not allowed (illegal option) */
676 CMDLINE_ERR_NOMEM
= -7, /* No memory */
677 CMDLINE_ERR_OPTMIS
= -8 /* A mandatory option is missing */
681 typedef struct CMDLINE_ARG
683 int index
; /* Index of the argument in the command line */
684 struct CMDLINE_ARG
* p_next
; /* Next node in the linked list */
687 /* Master control block for an option */
688 typedef struct CMDLINE_ARGS
690 int argc
; /* Total count of arguments found */
691 int optc
; /* Total count of options found */
692 CMDLINE_ARG
* list
; /* Argument list */
695 /* Master control block for all found arguments */
696 typedef struct CMDLINE_DATA
698 CMDLINE_ARGS opt_args
[26]; /* Array of MCBs for each option ('a' through 'z') */
699 CMDLINE_ARGS glb_args
; /* Global arguments */
700 int parsed
; /* Internal flag to prevent client calls if library is not initialized */
703 /* ********* Local Data ********* */
704 static CMDLINE_CFG cmdline_cfg
;
705 static CMDLINE_DATA cmdline_data
;
707 char* cmdline_errmsg
= "CMDLINE ERROR";
709 /* ***************************************************************
710 * Print all found command line options and their arguments
711 ****************************************************************** */
712 void* cmdline_getarg_list(char opt
)
714 int index
= (opt
- 'a');
716 /* Check the validity of the index */
717 if((index
< 0) || (index
> 25))
719 /* ERROR: Wrong option */
723 /* Return a pointer to the ARGS control structure */
724 return((void*)(&cmdline_data
.opt_args
[index
]));
727 /* ***************************************************************
728 * Print all found command line options and their arguments
729 ****************************************************************** */
730 int cmdline_getarg_count(void* list
)
732 CMDLINE_ARGS
* p_args
= (CMDLINE_ARGS
*)list
;
734 /* Return number of arguments for this option */
735 return(p_args
->argc
);
738 /* ***************************************************************
739 * Print all found command line options and their arguments
740 ****************************************************************** */
741 int cmdline_getopt_count(char opt
)
745 /* Calculate index value */
747 if(index
< 0 || index
> 25) return -1;
749 /* Return number of arguments for this option */
750 return(cmdline_data
.opt_args
[index
].optc
);
753 /* ***************************************************************
754 * Print all found command line options and their arguments
755 ****************************************************************** */
756 int cmdline_getarg(void* list
, int num
)
759 CMDLINE_ARGS
* p_args
= (CMDLINE_ARGS
*)list
;
762 /* Search the 'num' argument in the list for this option */
763 for(i
=0,p_arg
=p_args
->list
; (p_arg
!=NULL
) && (i
<p_args
->argc
); i
++, p_arg
=p_arg
->p_next
)
765 /* if num matches i, we found it */
766 if(i
==num
) return(p_arg
->index
);
768 /* We did not find the specified argument or the list was empty */
772 /* ***************************************************************
773 * Print all found command line options and their arguments
774 ****************************************************************** */
775 int cmdline_configure(CMDLINE_CFG
* p_cfg
)
777 /* reset global data */
778 memset(&cmdline_cfg
,0,sizeof(cmdline_cfg
));
779 memset(&cmdline_data
,0,sizeof(cmdline_data
));
781 /* Copy the user's config structure */
782 cmdline_cfg
= *p_cfg
;
786 /* ***************************************************************
787 * Print all found command line options and their arguments
788 ****************************************************************** */
789 char* cmdline_error(int err
)
791 /* TODO: implement a table of error messages */
792 return(cmdline_errmsg
);
795 /* ***************************************************************
796 * Print all found command line options and their arguments
797 ****************************************************************** */
798 static void cmdline_print_args(CMDLINE_ARGS
* p_arglist
, char* argv
[])
802 printf(" Number of times option was specified: %d\n", p_arglist
->optc
);
803 printf(" Number of Arguments: %d\n", p_arglist
->argc
);
805 if(p_arglist
->argc
> 0)
807 printf(" Argument List: ");
809 for(p_arg
=p_arglist
->list
; p_arg
!= NULL
; p_arg
=p_arg
->p_next
)
810 printf("%s ", argv
[p_arg
->index
]);
816 /* ***************************************************************
817 * Print all found command line options and their arguments
818 ****************************************************************** */
819 void cmdline_print(char* argv
[])
823 /* Check if the command line was parsed */
824 if(cmdline_data
.parsed
!= CMDLINE_TRUE
)
826 printf("The command line has not been parsed yet.\n");
830 /* Print out option arguments */
831 for( i
= 0; i
< 26; i
++ )
833 /* Check if the option was specified */
834 if(cmdline_data
.opt_args
[i
].optc
!=0 )
836 /* Print out option name and arguments */
837 printf("Option: -%c\n", (char)('a'+i
));
838 cmdline_print_args(&(cmdline_data
.opt_args
[i
]), argv
);
842 /* Print out global arguments */
843 printf("Global arguments:\n");
844 cmdline_print_args(&(cmdline_data
.glb_args
), argv
);
847 /* ***************************************************************
848 * Print configuration
849 ****************************************************************** */
850 void cmdline_print_cfg(void)
855 static void cmdline_argadd(CMDLINE_ARGS
* p_arglist
, CMDLINE_ARG
* p_arg
)
858 CMDLINE_ARG
* p_prev
=NULL
;
860 /* See if we had anything in the list */
861 if(p_arglist
->argc
== 0)
863 /* Link the argument in */
864 p_arglist
->list
= p_arg
;
868 /* Find the tail of the list */
869 for(p_list
=p_arglist
->list
; p_list
!= NULL
; p_list
=p_list
->p_next
)
872 /* Link the argument in */
873 p_prev
->p_next
=p_arg
;
876 /* Keep track of arg number */
880 /* ***************************************************************
882 * Read and parse command line arguments
883 ****************************************************************** */
884 int cmdline_read(int argc
, char* argv
[])
888 /* Process every command line argument in argv[] array */
889 for( i
= 1; i
< argc
; i
++ )
891 /* Does the argument start with a dash? */
892 if( *argv
[i
] == '-' )
894 /* The argument must be two characters: a dash, and a letter */
895 if( strlen(argv
[i
]) != 2 )
897 /* ERROR: option syntax (needs to be a dash and one letter) */
898 return(CMDLINE_ERR_ERROR
);
901 /* Check validity of the option key ('a' through 'z') */
902 if( ((*(argv
[i
] + 1)) < 'a') || ((*(argv
[i
] + 1)) > 'z') )
904 /* ERROR: option sysntax (invalid option key) */
905 return(CMDLINE_ERR_INVKEY
);
908 /* Calculate the option index */
909 option
= (*(argv
[i
] + 1)) - 'a';
910 if((option
< 0) || (option
> 25)) return(CMDLINE_ERR_INVKEY
);
912 /* Check to see if the option is allowed */
913 if( cmdline_cfg
.opts
[option
].flags
& CMDLINE_OPTFLAG_ALLOW
)
915 /* Option allowed. */
916 cmdline_data
.opt_args
[option
].optc
++;
921 /* ERROR: Option is not allowed */
922 return(CMDLINE_ERR_ILLOPT
);
927 /* Read the arguments for the option */
930 /* Allocate space for the argument node */
931 p_arg
= (CMDLINE_ARG
*)calloc(1,sizeof(CMDLINE_ARG
));
934 /* ERROR: Can't allocate memory for the argument index */
935 return(CMDLINE_ERR_NOMEM
);
938 /* Initialize the argument */
940 p_arg
->p_next
= NULL
;
942 /* Check if we can add to the list of arguments for this option */
943 if( (option
< 0) /* Do we have to add to the global list? */
944 || (cmdline_data
.opt_args
[option
].argc
== cmdline_cfg
.opts
[option
].max
) /* Did we reach MAX arguments? */
947 /* This option does not require arguments. Keep the argument in the global list. */
948 cmdline_argadd(&(cmdline_data
.glb_args
), p_arg
);
953 /* See if the current count has reached max for this option */
954 if( cmdline_data
.opt_args
[option
].argc
== cmdline_cfg
.opts
[option
].max
)
956 /* ERROR: too many arguments for an option */
957 return(CMDLINE_ERR_MANYARG
);
961 /* Link the argument to the arg list of the option */
962 cmdline_argadd(&(cmdline_data
.opt_args
[option
]), p_arg
);
969 /* ****** We read the complete command line. See if what we collected matches the configuration ******* */
971 /* Check every collected option against its configuration */
972 for( i
=0; i
< 26; i
++ )
974 /* Check if this option was allowed */
975 if(cmdline_cfg
.opts
[i
].flags
& CMDLINE_OPTFLAG_ALLOW
)
977 /* See if it was mandatory */
978 if(cmdline_cfg
.opts
[i
].flags
& CMDLINE_OPTFLAG_MANDAT
)
980 /* Check if we really collected this option on the command line. */
981 if(cmdline_data
.opt_args
[i
].optc
== 0)
983 /* ERROR: a missing mandatory option */
984 return(CMDLINE_ERR_OPTMIS
);
988 /* Option was there. Check how many args we got for it. */
989 if(cmdline_data
.opt_args
[i
].argc
< cmdline_cfg
.opts
[i
].min
)
991 /* ERROR: too few arguments for an option */
992 return(CMDLINE_ERR_FEWARG
);
996 /* This mandatory option was proper. */
1001 else /* This is non-mandatory option: */
1003 /* Check if the option was specified on the command line */
1004 if(cmdline_data
.opt_args
[i
].optc
== 0)
1006 /* option wasn't specified, go to the next */
1011 /* Option was there. Check how many args we collected for it. */
1012 if(cmdline_data
.opt_args
[i
].argc
< cmdline_cfg
.opts
[i
].min
)
1014 /* ERROR: too few arguments for a non-mandatory option */
1015 return(CMDLINE_ERR_FEWARG
);
1019 /* This non-mandatory option was proper. */
1025 else /* Option was not allowed. */
1027 /* We should not get here as the non-allowed options should have been
1032 /* Command line was proper as far as the number of options and their arguments */
1033 cmdline_data
.parsed
= CMDLINE_TRUE
;
1034 return(CMDLINE_ERR_OK
);