1 // SPDX-License-Identifier: GPL-2.0-only
6 #include "mktitanimg.h"
12 unsigned int chksum
; /* The checksum for the complete header.
16 /***************************************************************************
17 * void print_help(void)
18 ***************************************************************************/
21 static char* help_page
[]=
23 "mknspimg version 1.0, Texas Instruments, 2004",
25 " mknspimg -o outfile -i image1 image2 -a align1 align2 [-v] [-b] [-p prod_id] [-r rel_id] [-s rel_name] [-f flags]",
27 " mknspimg -o nsp_image.bin -i kernel.bin files.img -a 0 4096",
28 "This generates 'nsp_image.bin' from two input files aligning first to 0 and second to 4096 bytes."
31 int num_lines
= sizeof(help_page
)/sizeof(char*);
33 for(i
=0; i
< num_lines
; i
++) {
34 printf("%s\n", help_page
[i
]);
38 /***************************************************************************
39 * void mknspimg_print_hdr(NSP_IMG_HDR* p_img_hdr)
40 ***************************************************************************/
41 void mknspimg_print_hdr(struct nsp_img_hdr
*hdr
)
43 struct nsp_img_hdr_chksum
*chksum
;
44 struct nsp_img_hdr_sections
*section
;
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
);
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
);
59 chksum
=(struct nsp_img_hdr_chksum
*)(hdr
+hdr
->head
.chksum_offset
);
60 printf("Header Checksum: 0x%x\n", chksum
->hdr_chksum
);
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
);
73 printf("*******************************************************\n");
76 CMDLINE_CFG cmd_line_cfg
=
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' */
107 { 0, 0, !CMDLINE_OPTFLAG_ALLOW
}, /* global arguments */
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
[])
116 FILE* nsp_image
= NULL
;
117 int header_version
=1;
119 char* cmdline_error_msg
;
123 int i
,count
; /* loop variables */
124 int num_sects
= 2; /* We require exactly two image with -i option
125 (see CMDLINE_CFG structure above) */
129 struct nsp_img_hdr_head
*img_hdr_head
; /* Start of image header */
130 struct nsp_img_hdr_info
*img_hdr_info
;
131 struct nsp_img_hdr_section_info
*img_hdr_section_info
;
132 struct nsp_img_hdr_sections
*img_hdr_sections
, *section
; /* Section pointers */
135 /* Configure the command line. */
136 cmdline_configure(&cmd_line_cfg
);
138 /* Read and parse the command line. */
139 cmdline_err
= cmdline_read(argc
, argv
);
141 /* Check for parsing errors. */
142 if(cmdline_err
!= 0) {
143 /* Get the parse error message */
144 cmdline_error_msg
= cmdline_error(cmdline_err
);
147 printf("%s\n", cmdline_error_msg
);
149 /* Print our help too */
153 if(cmdline_getopt_count('h') > 0)
155 header_version
=atoi(argv
[cmdline_getarg(cmdline_getarg_list('h'),0)]);
157 /* Set up arguments */
158 filen_out
= argv
[cmdline_getarg(cmdline_getarg_list('o'),0)];
159 /* Command line arguments have been parsed. Start doing our work. */
161 /* Caculate the header size, and allocate the memory, and assign the sub pointers */
162 header_size
= sizeof(struct nsp_img_hdr_head
) + /* This has a single section
163 desc block already */
164 (header_version
==1?0:4) +
165 sizeof(struct nsp_img_hdr_info
) +
166 sizeof(struct nsp_img_hdr_section_info
) +
167 sizeof(struct nsp_img_hdr_sections
) * num_sects
;
169 img_hdr_head
= (struct nsp_img_hdr_head
*)malloc(header_size
);
170 memset(img_hdr_head
, 0x0, header_size
);
171 img_hdr_info
= (struct nsp_img_hdr_info
*)((char *)img_hdr_head
+ sizeof(struct nsp_img_hdr_head
) + (header_version
==1?0:4));
172 img_hdr_section_info
= (struct nsp_img_hdr_section_info
*)((char *)img_hdr_info
+ sizeof(struct nsp_img_hdr_info
));
173 img_hdr_sections
= (struct nsp_img_hdr_sections
*)((char *)img_hdr_section_info
+ sizeof(struct nsp_img_hdr_section_info
));
174 section
= img_hdr_sections
;
175 memset(img_hdr_head
, 0xff, (void*)img_hdr_info
- (void*)img_hdr_head
);
177 img_hdr_head
->hdr_version
= header_version
;
178 img_hdr_head
->hdr_size
= header_size
;
179 img_hdr_head
->info_offset
= (void*)img_hdr_info
- (void*)img_hdr_head
;
180 img_hdr_head
->sect_info_offset
= (void*)img_hdr_section_info
- (void*)img_hdr_head
;
182 img_hdr_section_info
->num_sects
= num_sects
;
183 img_hdr_section_info
->sect_size
= sizeof(struct nsp_img_hdr_sections
);
184 img_hdr_section_info
->sections_offset
= (void*)img_hdr_sections
- (void*)img_hdr_head
;
186 /* chksum = (struct nsp_img_hdr_chksum *)
187 ((unsigned int)image_hdr + header_size - sizeof(struct nsp_img_hdr_chksum));*/
189 /* Open the out file */
190 nsp_image
= fopen(filen_out
,"wb+");
191 if(nsp_image
==NULL
) {
192 printf("ERROR: can't open %s for writing.\n", filen_out
);
196 /* Skip image header. We'll come back to it after we've written out the images. */
197 fseek(nsp_image
,header_size
,SEEK_SET
);
198 total
= ftell(nsp_image
);
200 printf("total=%x\n",total
);
205 align
= (header_version
==1?0x10000:0x4000);
207 /* The user indicated no padding */
210 /* Calculate number padding bytes */
211 if((total
%align
) ==0)
214 padding
= align
- (total
% align
);
219 memset(buf
, 0xff, padding
);
220 if(fwrite((void*)buf
,1,padding
,nsp_image
)!=padding
) {
221 printf("ERROR: can't write to %s.\n", filen_out
);
233 /* Write out all specified images (with -i option) */
234 for(i
=0; i
< num_sects
; i
++) {
235 char* file_name
; /* input file name */
236 FILE* filep
; /* input file pointer */
237 int padding
; /* number of padding bytes to prepend */
238 int align
; /* align factor from command line */
239 int result
; /* intermediate result */
242 /* Open the specified image for reading */
243 file_name
= argv
[cmdline_getarg(cmdline_getarg_list('i'),i
)];
244 filep
= fopen(file_name
, "rb");
246 printf("ERROR: can't open file %s for reading.\n", file_name
);
249 section
->flags
= ~0x00;
250 /* Determine file size */
251 fseek(filep
,0,SEEK_END
);
252 section
->raw_size
=ftell(filep
);
253 fseek(filep
,0,SEEK_SET
);
254 cs_calc_sum(filep
,(unsigned long *)§ion
->chksum
,0);
255 fseek(filep
,0,SEEK_SET
);
257 /* Retrieve the alignment constant */
258 /* Set image offset from the beginning of the out file */
259 section
->offset
=total
;// + padding;
263 /* Copy the image file into nsp_image */
264 count
= section
->raw_size
;
266 result
=fread(buf
, 1, count
, filep
);
267 fwrite(buf
, 1, result
, nsp_image
);
270 /* HACK: This is a hack to get the names and types to the files.
271 TODO: Fix this to be a real method */
273 section
->type
=NSP_IMG_SECTION_TYPE_KERNEL
;
274 strncpy(section
->name
, "kernel", 16);
276 section
->type
=NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT
;
277 strncpy(section
->name
, "root", 16);
280 /* Account for the total */
281 align
= strtoul(argv
[cmdline_getarg(cmdline_getarg_list('a'),i
)],NULL
,0);
283 if(align
==0 || (((section
->raw_size
+ section
->offset
)%align
)==0))
286 padding
= align
- ((section
->raw_size
+ section
->offset
) % align
);
288 section
->total_size
=section
->raw_size
+ padding
;
291 #define EXTRA_BLOCK 0x10000
292 unsigned int squash_padding
;
293 squash_padding
= EXTRA_BLOCK
- section
->raw_size
% EXTRA_BLOCK
;
294 buf
=malloc(EXTRA_BLOCK
+ 4);
295 memset(buf
, 0, squash_padding
);
296 fwrite(buf
, 1, squash_padding
, nsp_image
);
297 memset(buf
, 0, EXTRA_BLOCK
+ 4);
298 *((unsigned int *)buf
)=0xdec0adde;
299 *((unsigned int *)(buf
+EXTRA_BLOCK
))=0xdec0adde;
300 fwrite(buf
, 1, EXTRA_BLOCK
+4, nsp_image
);
303 if(align
==0 || (((section
->raw_size
+ (EXTRA_BLOCK
+ 4 + squash_padding
)) %align
)==0))
306 padding
= align
- ((section
->raw_size
+ (EXTRA_BLOCK
+ 4 + squash_padding
)) % align
);
307 section
->total_size
=section
->raw_size
+ (EXTRA_BLOCK
+ 4 + squash_padding
) + padding
;
311 memset(buf
, 0xff, padding
);
312 fwrite(buf
, 1, padding
, nsp_image
);
315 printf("*****padding is %d\ttotal_size=%d\traw_size=%d\n",padding
, section
->total_size
, section
->raw_size
);
317 //total += section->raw_size;
318 total
= section
->total_size
+ section
->offset
;
319 printf("total=0x%x\n",total
);
320 /* Close the input file */
323 /* Move the section pointer to the next slot */
327 /* Take care of the NSP image header fields */
330 img_hdr_head
->magic
= NSP_IMG_MAGIC_NUMBER
;
331 img_hdr_head
->boot_offset
= img_hdr_sections
->offset
;
332 img_hdr_head
->flags
= ~0x00; /* Set to all 1's */
334 if(cmdline_getopt_count('b'))
335 img_hdr_head
->flags
&= ~(NSP_IMG_FLAG_FAILBACK_5
| NSP_IMG_FLAG_FAILBACK_1
);
337 if(cmdline_getopt_count('f'))
338 img_hdr_head
->flags
= strtoul(argv
[cmdline_getarg(cmdline_getarg_list('f'),0)], 0, 16);
341 img_hdr_head
->hdr_version
= 2;
342 img_hdr_head
->hdr_size
= header_size
;
345 if(cmdline_getopt_count('p'))
346 img_hdr_head
->prod_id
= strtoul(argv
[cmdline_getarg(cmdline_getarg_list('p'),0)], 0, 16);
348 img_hdr_head
->prod_id
= 0x4C575943;
350 if(cmdline_getopt_count('r'))
351 img_hdr_head
->rel_id
= strtoul(argv
[cmdline_getarg(cmdline_getarg_list('r'),0)], 0, 0);
353 img_hdr_head
->rel_id
= 0x10203040;
355 if(cmdline_getopt_count('s'))
356 img_hdr_head
->version
= strtoul(argv
[cmdline_getarg(cmdline_getarg_list('s'),0)], 0, 0);
358 img_hdr_head
->version
= 0x0b040000;
359 img_hdr_head
->image_size
= total
;
361 img_hdr_head
->info_offset
= (unsigned int)(&(image_hdr
->info
)) -
362 (unsigned int)image_hdr
;
363 img_hdr_head
->sect_info_offset
= (unsigned int)(&(image_hdr
->sect_info
)) -
364 (unsigned int)image_hdr
;
366 // image_hdr->head.chksum_offset = (unsigned int)chksum - (unsigned int)image_hdr;
367 img_hdr_head
->chksum_offset
= 0xffffffff;
368 // image_hdr->head.pad1 = 0xffffffff;
370 /* TODO: Fix. Do nothing yet */
371 // strncpy(nsp_img_hdr.id.prod_info,NSP_PRODINFO_STRING,sizeof(NSP_PRODINFO_STRING));
372 strcpy(img_hdr_info
->image_filename
, (const char *)basename(filen_out
));
375 img_hdr_section_info
->num_sects
= num_sects
;
376 img_hdr_section_info
->sect_size
= sizeof(struct nsp_img_hdr_sections
);
377 img_hdr_section_info
->sections_offset
= (unsigned int)(&(image_hdr
->sections
)) -
378 (unsigned int)image_hdr
;
381 /* Calculate checksum(s) */
383 chksum
->hdr_chksum
= cs_calc_buf_sum((char*)image_hdr
,
384 header_size
- sizeof(struct nsp_img_hdr_chksum
));
386 /* Write out the NSP header. */
387 fseek(nsp_image
,0,SEEK_SET
);
388 count
= fwrite((void*)img_hdr_head
, header_size
, 1, nsp_image
);
390 printf("ERROR: can't write to %s.\n", filen_out
);
394 /* Check if -v option was specified (no arg needed) */
395 if(cmdline_getopt_count('v') > 0)
397 struct nsp_img_hdr_head head
;
398 struct nsp_img_hdr
*hdr
;
400 /* Rewind the file back to the beginning */
401 fseek(nsp_image
,0,SEEK_SET
);
403 /* Read header from the file */
404 fread((void*)&head
, sizeof(struct nsp_img_hdr_head
),
407 /* Get memory to store the complete header */
408 hdr
= (struct nsp_img_hdr
*)malloc(head
.hdr_size
);
410 /* Read header from the file */
411 fseek(nsp_image
,0,SEEK_SET
);
412 fread((void*)hdr
, head
.hdr_size
, 1, nsp_image
);
415 mknspimg_print_hdr(hdr
);
416 printf("Generated total %d bytes\n",total
);
423 struct checksumrecord cr
;
424 cr
.magic
=CKSUM_MAGIC_NUMBER
;
425 cs_calc_sum(nsp_image
, (unsigned long *)&cr
.chksum
, 0);
426 fseek(nsp_image
,0, SEEK_END
);
427 fwrite(&cr
, 1, sizeof(cr
), nsp_image
);
434 strcpy(fname
, filen_out
);
435 strcat(fname
, ".non_web");
436 non_web
= fopen(fname
,"wb+");
437 fseek(nsp_image
, 0, SEEK_END
);
438 len
= ftell(nsp_image
);
440 fseek(nsp_image
, 0, SEEK_SET
);
441 fread(img_buf
, 1, len
, nsp_image
);
443 fwrite(img_buf
, 1, len
-sizeof(struct checksumrecord
), non_web
);
447 /* Close NSP image file */
458 #define BUFLEN (1 << 16)
460 static unsigned long crctab
[256] =
463 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B,
464 0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6,
465 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
466 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC,
467 0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, 0x6ED82B7F,
468 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A,
469 0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
470 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0xBE2B5B58,
471 0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033,
472 0xA4AD16EA, 0xA06C0B5D, 0xD4326D90, 0xD0F37027, 0xDDB056FE,
473 0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
474 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4,
475 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, 0x34867077, 0x30476DC0,
476 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5,
477 0x2AC12072, 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16,
478 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, 0x7897AB07,
479 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C,
480 0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1,
481 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
482 0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B,
483 0xBB60ADFC, 0xB6238B25, 0xB2E29692, 0x8AAD2B2F, 0x8E6C3698,
484 0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D,
485 0x94EA7B2A, 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E,
486 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, 0xC6BCF05F,
487 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34,
488 0xDC3ABDED, 0xD8FBA05A, 0x690CE0EE, 0x6DCDFD59, 0x608EDB80,
489 0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB,
490 0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A,
491 0x58C1663D, 0x558240E4, 0x51435D53, 0x251D3B9E, 0x21DC2629,
492 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C,
493 0x3B5A6B9B, 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF,
494 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, 0xF12F560E,
495 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65,
496 0xEBA91BBC, 0xEF68060B, 0xD727BBB6, 0xD3E6A601, 0xDEA580D8,
497 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3,
498 0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2,
499 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, 0x9B3660C6, 0x9FF77D71,
500 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74,
501 0x857130C3, 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640,
502 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, 0x7B827D21,
503 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A,
504 0x61043093, 0x65C52D24, 0x119B4BE9, 0x155A565E, 0x18197087,
505 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC,
506 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D,
507 0x2056CD3A, 0x2D15EBE3, 0x29D4F654, 0xC5A92679, 0xC1683BCE,
508 0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB,
509 0xDBEE767C, 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18,
510 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4, 0x89B8FD09,
511 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662,
512 0x933EB0BB, 0x97FFAD0C, 0xAFB010B1, 0xAB710D06, 0xA6322BDF,
513 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4
516 int cs_is_tagged(FILE *fp
)
520 fseek(fp
, -8, SEEK_END
);
521 fread(buf
, 8, 1, fp
);
522 if(*(unsigned long*)buf
== CKSUM_MAGIC_NUMBER
)
527 unsigned long cs_read_sum(FILE *fp
)
531 fseek(fp
, -8, SEEK_END
);
532 fread(buf
, 8, 1, fp
);
533 return *((unsigned long*)&buf
[4]);
536 int cs_calc_sum(FILE *fp
, unsigned long *res
, int tagged
)
538 unsigned char buf
[BUFLEN
];
539 unsigned long crc
= 0;
540 uintmax_t length
= 0;
543 fseek(fp
, 0, SEEK_SET
);
545 while((bytes_read
= fread(buf
, 1, BUFLEN
, fp
)) > 0)
547 unsigned char *cp
= buf
;
549 if(length
+ bytes_read
< length
)
552 if(bytes_read
!= BUFLEN
&& tagged
)
555 length
+= bytes_read
;
557 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ *cp
++) & 0xFF];
563 for(; length
; length
>>= 8)
564 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ length
) & 0xFF];
566 crc
= ~crc
& 0xFFFFFFFF;
573 unsigned long cs_calc_buf_sum(char *buf
, int size
)
575 unsigned long crc
= 0;
577 unsigned long length
= size
;
580 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ *cp
++) & 0xFF];
582 for(; length
; length
>>= 8)
583 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ length
) & 0xFF];
585 crc
= ~crc
& 0xFFFFFFFF;
590 unsigned long cs_calc_buf_sum_ds(char *buf
, int buf_size
, char *sign
, int sign_len
)
592 unsigned long crc
= 0;
594 unsigned long length
= buf_size
+sign_len
;
597 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ *cp
++) & 0xFF];
601 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ *cp
++) & 0xFF];
604 for(; length
; length
>>= 8)
605 crc
=(crc
<< 8) ^ crctab
[((crc
>> 24) ^ length
) & 0xFF];
607 crc
= ~crc
& 0xFFFFFFFF;
612 int cs_set_sum(FILE *fp
, unsigned long sum
, int tagged
)
614 unsigned long magic
= CKSUM_MAGIC_NUMBER
;
617 fseek(fp
, -8, SEEK_END
);
619 fseek(fp
, 0, SEEK_END
);
621 if(fwrite(&magic
, 1, 4, fp
) < 4)
623 if(fwrite(&sum
, 1, 4, fp
) < 4)
629 void cs_get_sum(FILE *fp
, unsigned long *sum
)
631 unsigned long magic
= 0;
633 fseek(fp
, -8, SEEK_END
);
635 fread(&magic
, 4, 1, fp
);
636 fread(sum
, 4, 1, fp
);
639 int cs_validate_file(char *filename
)
642 unsigned long sum
= 0, res
= 0;
644 if((pFile
= fopen(filename
, "r")) == NULL
)
647 if(!cs_is_tagged(pFile
))
652 if(!cs_calc_sum(pFile
, &sum
, 1))
657 cs_get_sum(pFile
, &res
);
665 /* ********* Library internal data ********* */
666 #define CMDLINE_TRUE 1
667 #define CMDLINE_FALSE 0
669 typedef enum CMDLINE_ERR
671 CMDLINE_ERR_OK
= 0, /* No Error (OK) */
672 CMDLINE_ERR_ERROR
= -1, /* Unspecified error */
673 CMDLINE_ERR_INVKEY
= -3, /* Invalid option key */
674 CMDLINE_ERR_MANYARG
= -4, /* Too many arguments */
675 CMDLINE_ERR_FEWARG
= -5, /* Too few arguments */
676 CMDLINE_ERR_ILLOPT
= -6, /* Option not allowed (illegal option) */
677 CMDLINE_ERR_NOMEM
= -7, /* No memory */
678 CMDLINE_ERR_OPTMIS
= -8 /* A mandatory option is missing */
682 typedef struct CMDLINE_ARG
684 int index
; /* Index of the argument in the command line */
685 struct CMDLINE_ARG
* p_next
; /* Next node in the linked list */
688 /* Master control block for an option */
689 typedef struct CMDLINE_ARGS
691 int argc
; /* Total count of arguments found */
692 int optc
; /* Total count of options found */
693 CMDLINE_ARG
* list
; /* Argument list */
696 /* Master control block for all found arguments */
697 typedef struct CMDLINE_DATA
699 CMDLINE_ARGS opt_args
[26]; /* Array of MCBs for each option ('a' through 'z') */
700 CMDLINE_ARGS glb_args
; /* Global arguments */
701 int parsed
; /* Internal flag to prevent client calls if library is not initialized */
704 /* ********* Local Data ********* */
705 static CMDLINE_CFG cmdline_cfg
;
706 static CMDLINE_DATA cmdline_data
;
708 char* cmdline_errmsg
= "CMDLINE ERROR";
710 /* ***************************************************************
711 * Print all found command line options and their arguments
712 ****************************************************************** */
713 void* cmdline_getarg_list(char opt
)
715 int index
= (opt
- 'a');
717 /* Check the validity of the index */
718 if((index
< 0) || (index
> 25))
720 /* ERROR: Wrong option */
724 /* Return a pointer to the ARGS control structure */
725 return((void*)(&cmdline_data
.opt_args
[index
]));
728 /* ***************************************************************
729 * Print all found command line options and their arguments
730 ****************************************************************** */
731 int cmdline_getarg_count(void* list
)
733 CMDLINE_ARGS
* p_args
= (CMDLINE_ARGS
*)list
;
735 /* Return number of arguments for this option */
736 return(p_args
->argc
);
739 /* ***************************************************************
740 * Print all found command line options and their arguments
741 ****************************************************************** */
742 int cmdline_getopt_count(char opt
)
746 /* Calculate index value */
748 if(index
< 0 || index
> 25) return -1;
750 /* Return number of arguments for this option */
751 return(cmdline_data
.opt_args
[index
].optc
);
754 /* ***************************************************************
755 * Print all found command line options and their arguments
756 ****************************************************************** */
757 int cmdline_getarg(void* list
, int num
)
760 CMDLINE_ARGS
* p_args
= (CMDLINE_ARGS
*)list
;
763 /* Search the 'num' argument in the list for this option */
764 for(i
=0,p_arg
=p_args
->list
; (p_arg
!=NULL
) && (i
<p_args
->argc
); i
++, p_arg
=p_arg
->p_next
)
766 /* if num matches i, we found it */
767 if(i
==num
) return(p_arg
->index
);
769 /* We did not find the specified argument or the list was empty */
773 /* ***************************************************************
774 * Print all found command line options and their arguments
775 ****************************************************************** */
776 int cmdline_configure(CMDLINE_CFG
* p_cfg
)
778 /* reset global data */
779 memset(&cmdline_cfg
,0,sizeof(cmdline_cfg
));
780 memset(&cmdline_data
,0,sizeof(cmdline_data
));
782 /* Copy the user's config structure */
783 cmdline_cfg
= *p_cfg
;
787 /* ***************************************************************
788 * Print all found command line options and their arguments
789 ****************************************************************** */
790 char* cmdline_error(int err
)
792 /* TODO: implement a table of error messages */
793 return(cmdline_errmsg
);
796 /* ***************************************************************
797 * Print all found command line options and their arguments
798 ****************************************************************** */
799 static void cmdline_print_args(CMDLINE_ARGS
* p_arglist
, char* argv
[])
803 printf(" Number of times option was specified: %d\n", p_arglist
->optc
);
804 printf(" Number of Arguments: %d\n", p_arglist
->argc
);
806 if(p_arglist
->argc
> 0)
808 printf(" Argument List: ");
810 for(p_arg
=p_arglist
->list
; p_arg
!= NULL
; p_arg
=p_arg
->p_next
)
811 printf("%s ", argv
[p_arg
->index
]);
817 /* ***************************************************************
818 * Print all found command line options and their arguments
819 ****************************************************************** */
820 void cmdline_print(char* argv
[])
824 /* Check if the command line was parsed */
825 if(cmdline_data
.parsed
!= CMDLINE_TRUE
)
827 printf("The command line has not been parsed yet.\n");
831 /* Print out option arguments */
832 for( i
= 0; i
< 26; i
++ )
834 /* Check if the option was specified */
835 if(cmdline_data
.opt_args
[i
].optc
!=0 )
837 /* Print out option name and arguments */
838 printf("Option: -%c\n", (char)('a'+i
));
839 cmdline_print_args(&(cmdline_data
.opt_args
[i
]), argv
);
843 /* Print out global arguments */
844 printf("Global arguments:\n");
845 cmdline_print_args(&(cmdline_data
.glb_args
), argv
);
848 /* ***************************************************************
849 * Print configuration
850 ****************************************************************** */
851 void cmdline_print_cfg(void)
856 static void cmdline_argadd(CMDLINE_ARGS
* p_arglist
, CMDLINE_ARG
* p_arg
)
859 CMDLINE_ARG
* p_prev
=NULL
;
861 /* See if we had anything in the list */
862 if(p_arglist
->argc
== 0)
864 /* Link the argument in */
865 p_arglist
->list
= p_arg
;
869 /* Find the tail of the list */
870 for(p_list
=p_arglist
->list
; p_list
!= NULL
; p_list
=p_list
->p_next
)
873 /* Link the argument in */
874 p_prev
->p_next
=p_arg
;
877 /* Keep track of arg number */
881 /* ***************************************************************
883 * Read and parse command line arguments
884 ****************************************************************** */
885 int cmdline_read(int argc
, char* argv
[])
889 /* Process every command line argument in argv[] array */
890 for( i
= 1; i
< argc
; i
++ )
892 /* Does the argument start with a dash? */
893 if( *argv
[i
] == '-' )
895 /* The argument must be two characters: a dash, and a letter */
896 if( strlen(argv
[i
]) != 2 )
898 /* ERROR: option syntax (needs to be a dash and one letter) */
899 return(CMDLINE_ERR_ERROR
);
902 /* Check validity of the option key ('a' through 'z') */
903 if( ((*(argv
[i
] + 1)) < 'a') || ((*(argv
[i
] + 1)) > 'z') )
905 /* ERROR: option sysntax (invalid option key) */
906 return(CMDLINE_ERR_INVKEY
);
909 /* Calculate the option index */
910 option
= (*(argv
[i
] + 1)) - 'a';
911 if((option
< 0) || (option
> 25)) return(CMDLINE_ERR_INVKEY
);
913 /* Check to see if the option is allowed */
914 if( cmdline_cfg
.opts
[option
].flags
& CMDLINE_OPTFLAG_ALLOW
)
916 /* Option allowed. */
917 cmdline_data
.opt_args
[option
].optc
++;
922 /* ERROR: Option is not allowed */
923 return(CMDLINE_ERR_ILLOPT
);
928 /* Read the arguments for the option */
931 /* Allocate space for the argument node */
932 p_arg
= (CMDLINE_ARG
*)calloc(1,sizeof(CMDLINE_ARG
));
935 /* ERROR: Can't allocate memory for the argument index */
936 return(CMDLINE_ERR_NOMEM
);
939 /* Initialize the argument */
941 p_arg
->p_next
= NULL
;
943 /* Check if we can add to the list of arguments for this option */
944 if( (option
< 0) /* Do we have to add to the global list? */
945 || (cmdline_data
.opt_args
[option
].argc
== cmdline_cfg
.opts
[option
].max
) /* Did we reach MAX arguments? */
948 /* This option does not require arguments. Keep the argument in the global list. */
949 cmdline_argadd(&(cmdline_data
.glb_args
), p_arg
);
954 /* See if the current count has reached max for this option */
955 if( cmdline_data
.opt_args
[option
].argc
== cmdline_cfg
.opts
[option
].max
)
957 /* ERROR: too many arguments for an option */
958 return(CMDLINE_ERR_MANYARG
);
962 /* Link the argument to the arg list of the option */
963 cmdline_argadd(&(cmdline_data
.opt_args
[option
]), p_arg
);
970 /* ****** We read the complete command line. See if what we collected matches the configuration ******* */
972 /* Check every collected option against its configuration */
973 for( i
=0; i
< 26; i
++ )
975 /* Check if this option was allowed */
976 if(cmdline_cfg
.opts
[i
].flags
& CMDLINE_OPTFLAG_ALLOW
)
978 /* See if it was mandatory */
979 if(cmdline_cfg
.opts
[i
].flags
& CMDLINE_OPTFLAG_MANDAT
)
981 /* Check if we really collected this option on the command line. */
982 if(cmdline_data
.opt_args
[i
].optc
== 0)
984 /* ERROR: a missing mandatory option */
985 return(CMDLINE_ERR_OPTMIS
);
989 /* Option was there. Check how many args we got for it. */
990 if(cmdline_data
.opt_args
[i
].argc
< cmdline_cfg
.opts
[i
].min
)
992 /* ERROR: too few arguments for an option */
993 return(CMDLINE_ERR_FEWARG
);
997 /* This mandatory option was proper. */
1002 else /* This is non-mandatory option: */
1004 /* Check if the option was specified on the command line */
1005 if(cmdline_data
.opt_args
[i
].optc
== 0)
1007 /* option wasn't specified, go to the next */
1012 /* Option was there. Check how many args we collected for it. */
1013 if(cmdline_data
.opt_args
[i
].argc
< cmdline_cfg
.opts
[i
].min
)
1015 /* ERROR: too few arguments for a non-mandatory option */
1016 return(CMDLINE_ERR_FEWARG
);
1020 /* This non-mandatory option was proper. */
1026 else /* Option was not allowed. */
1028 /* We should not get here as the non-allowed options should have been
1033 /* Command line was proper as far as the number of options and their arguments */
1034 cmdline_data
.parsed
= CMDLINE_TRUE
;
1035 return(CMDLINE_ERR_OK
);