• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firmware-utils/src/mktitanimg.c

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <string.h>
  5 #include <libgen.h>
  6 #include "mktitanimg.h"
  7 
  8 
  9 struct checksumrecord
 10 {
 11                 unsigned int magic;
 12         unsigned int    chksum;     /* The checksum for the complete header.
 13  Excepting the
 14                                            checksum block */
 15 };
 16 /***************************************************************************
 17  * void print_help(void)
 18  ***************************************************************************/
 19 void print_help(void)
 20 {
 21         static char* help_page[]=
 22         {
 23                 "mknspimg version 1.0, Texas Instruments, 2004",
 24                 "Syntax:",
 25                 "        mknspimg -o outfile -i image1 image2 -a align1 align2 [-v] [-b] [-p prod_id] [-r rel_id] [-s rel_name] [-f flags]",
 26                 "Example:",
 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."
 29         };
 30 
 31         int num_lines = sizeof(help_page)/sizeof(char*);
 32         int i;
 33         for(i=0; i < num_lines; i++) {
 34                 printf("%s\n", help_page[i]);
 35         }
 36 }
 37 
 38 /***************************************************************************
 39  * void mknspimg_print_hdr(NSP_IMG_HDR* p_img_hdr)
 40  ***************************************************************************/
 41 void mknspimg_print_hdr(struct nsp_img_hdr *hdr)
 42 {
 43         struct nsp_img_hdr_chksum       *chksum;
 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_out;
122 
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) */
126         int     total = 0;
127 
128         int     header_size=0;
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 */
133         
134 
135         /* Configure the command line. */
136         cmdline_configure(&cmd_line_cfg);
137 
138         /* Read and parse the command line. */
139         cmdline_err = cmdline_read(argc, argv);
140 
141         /* Check for parsing errors. */
142         if(cmdline_err != 0) {
143                 /* Get the parse error message */
144                 cmdline_error_msg = cmdline_error(cmdline_err);
145 
146                 /* Print it out */
147                 printf("%s\n", cmdline_error_msg);
148 
149                 /* Print our help too */
150                 print_help();
151                 return -1;
152         }
153         if(cmdline_getopt_count('h') > 0)
154         {
155                 header_version=atoi(argv[cmdline_getarg(cmdline_getarg_list('h'),0)]);
156         }
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. */
160 
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 ;
168 
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);
176         
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;
181         
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;
185         
186 /*      chksum = (struct nsp_img_hdr_chksum *)
187                         ((unsigned int)image_hdr + header_size - sizeof(struct nsp_img_hdr_chksum));*/
188 
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);
193                 return -1;
194         }
195 
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);
199         total = header_size;
200         printf("total=%x\n",total);
201         {
202                 int align;
203                 int     padding;
204                 char * buf;
205                 align = (header_version==1?0x10000:0x4000);
206                 if(align==0) {
207                         /* The user indicated no padding */
208                         padding = 0;
209                 } else {
210                         /* Calculate number padding bytes */
211                         if((total %align) ==0)
212                                 padding=0;
213                         else
214                                 padding = align - (total % align);
215                 }
216                 if(padding>0)
217                 {
218                         buf=malloc(padding);
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);
222                                 free(buf);
223                                 fclose(nsp_image);
224                                 return -1;
225                         }
226                         free(buf);
227                         
228                 }
229                 total+=padding;
230                 
231 
232         }
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 */
240                 char * buf;
241 
242                 /* Open the specified image for reading */
243                 file_name       = argv[cmdline_getarg(cmdline_getarg_list('i'),i)];
244                 filep           = fopen(file_name, "rb");
245                 if(filep==NULL) {
246                         printf("ERROR: can't open file %s for reading.\n", file_name);
247                         return -1;
248                 }
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 *)&section->chksum,0);
255                 fseek(filep,0,SEEK_SET);
256 
257                 /* Retrieve the alignment constant */
258                 /* Set image offset from the beginning of the out file */
259                 section->offset=total;// + padding;
260 
261                 //total += padding;
262 
263                 /* Copy the image file into nsp_image */
264                 count = section->raw_size;
265                 buf=malloc(count);
266                 result=fread(buf, 1, count, filep);
267                 fwrite(buf, 1, result, nsp_image);
268                 free(buf);
269                 
270                 /* HACK: This is a hack to get the names and types to the files.
271                         TODO: Fix this to be a real method */
272                 if(i==0){
273                         section->type=NSP_IMG_SECTION_TYPE_KERNEL;
274                         strncpy(section->name, "kernel", 16);
275                 } else if(i==1){
276                         section->type=NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT;
277                         strncpy(section->name, "root", 16);
278                 }
279 
280                 /* Account for the total */
281                 align   =  strtoul(argv[cmdline_getarg(cmdline_getarg_list('a'),i)],NULL,0);
282                 if(i==0){
283                         if(align==0 || (((section->raw_size+ section->offset)%align)==0))
284                                 padding=0;
285                         else
286                                 padding = align - ((section->raw_size+ section->offset) % align);
287 
288                         section->total_size=section->raw_size + padding;
289                 }
290                 else{
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);
301                         free(buf);
302                         
303                         if(align==0 || (((section->raw_size + (EXTRA_BLOCK + 4 + squash_padding)) %align)==0))
304                                 padding=0;
305                         else
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;
308                 }
309                 if(padding>0){
310                         buf=malloc(padding);
311                         memset(buf, 0xff, padding);
312                         fwrite(buf, 1, padding, nsp_image);
313                         free(buf);
314                 }
315                 printf("*****padding is %d\ttotal_size=%d\traw_size=%d\n",padding, section->total_size, section->raw_size);
316 
317                 //total += section->raw_size;
318                 total = section->total_size + section->offset;
319                 printf("total=0x%x\n",total);
320                 /* Close the input file */
321                 fclose(filep);
322 
323                 /* Move the section pointer to the next slot */
324                 section++;
325         }
326 
327         /* Take care of the NSP image header fields */
328 
329         /* head 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 */
333 
334         if(cmdline_getopt_count('b'))
335                 img_hdr_head->flags     &= ~(NSP_IMG_FLAG_FAILBACK_5 | NSP_IMG_FLAG_FAILBACK_1);
336 
337         if(cmdline_getopt_count('f'))
338                 img_hdr_head->flags     = strtoul(argv[cmdline_getarg(cmdline_getarg_list('f'),0)], 0, 16);
339 
340 #if 0
341         img_hdr_head->hdr_version       = 2;
342         img_hdr_head->hdr_size  = header_size;
343 #endif
344 
345         if(cmdline_getopt_count('p'))
346                 img_hdr_head->prod_id           = strtoul(argv[cmdline_getarg(cmdline_getarg_list('p'),0)], 0, 16);
347         else
348                 img_hdr_head->prod_id           = 0x4C575943;
349 
350         if(cmdline_getopt_count('r'))
351                 img_hdr_head->rel_id            = strtoul(argv[cmdline_getarg(cmdline_getarg_list('r'),0)], 0, 0);
352         else
353                 img_hdr_head->rel_id            = 0x10203040;
354 
355         if(cmdline_getopt_count('s'))
356                 img_hdr_head->version           = strtoul(argv[cmdline_getarg(cmdline_getarg_list('s'),0)], 0, 0);
357         else
358                 img_hdr_head->version           = 0x0b040000;
359         img_hdr_head->image_size        = total;
360 #if 0
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;
365 #endif
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;
369         /* info fields */
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));
373         /* section fields */
374 #if 0
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;
379 #endif
380 
381         /* Calculate checksum(s) */
382 #if 0
383         chksum->hdr_chksum = cs_calc_buf_sum((char*)image_hdr,
384                         header_size - sizeof(struct nsp_img_hdr_chksum));
385 #endif
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);
389         if(count!=1) {
390                 printf("ERROR: can't write to %s.\n", filen_out);
391                 return -1;
392         }
393 
394         /* Check if -v option was specified (no arg needed) */
395         if(cmdline_getopt_count('v') > 0)
396         {
397                 struct nsp_img_hdr_head head;
398                 struct nsp_img_hdr      *hdr;
399 
400                 /* Rewind the file back to the beginning */
401                 fseek(nsp_image,0,SEEK_SET);
402 
403                 /* Read header from the file */
404                 fread((void*)&head, sizeof(struct nsp_img_hdr_head),
405                                 1, nsp_image);
406 
407                 /* Get memory to store the complete header */
408                 hdr = (struct nsp_img_hdr *)malloc(head.hdr_size);
409 
410                 /* Read header from the file */
411                 fseek(nsp_image,0,SEEK_SET);
412                 fread((void*)hdr, head.hdr_size, 1, nsp_image);
413 
414                 /* Print it out */
415                 mknspimg_print_hdr(hdr);
416                 printf("Generated total %d bytes\n",total);
417                 free(hdr);
418         }
419 
420         free(img_hdr_head);
421 
422       {
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);
428           }
429           {
430                 FILE * non_web;
431                 char fname[256];
432                 char * img_buf;
433                 unsigned int len;
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);
439                 img_buf=malloc(len);
440                 fseek(nsp_image, 0, SEEK_SET);
441                 fread(img_buf, 1, len, nsp_image);
442                 img_buf[0xb] = 0x17;
443                 fwrite(img_buf, 1, len-sizeof(struct checksumrecord), non_web);
444                 fclose(non_web);
445                 free(img_buf);
446           }
447           /* Close NSP image file */
448         fclose(nsp_image);
449 
450         /* return result */
451         return(0);
452 }
453 
454 #ifdef DMALLOC
455 #include <dmalloc.h>
456 #endif /* DMALLOC */
457 
458 #define BUFLEN (1 << 16)
459 
460 static unsigned long crctab[256] =
461 {
462         0x0,
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
514 };
515 
516 int cs_is_tagged(FILE *fp)
517 {
518         char buf[8];
519 
520         fseek(fp, -8, SEEK_END);
521         fread(buf, 8, 1, fp);
522         if(*(unsigned long*)buf == CKSUM_MAGIC_NUMBER)
523                 return 1;
524         return 0;
525 }
526 
527 unsigned long cs_read_sum(FILE *fp)
528 {
529         char buf[8];
530 
531         fseek(fp, -8, SEEK_END);
532         fread(buf, 8, 1, fp);
533         return *((unsigned long*)&buf[4]);
534 }
535 
536 int cs_calc_sum(FILE *fp, unsigned long *res, int tagged)
537 {
538         unsigned char buf[BUFLEN];
539         unsigned long crc = 0;
540         uintmax_t length = 0;
541         size_t bytes_read;
542 
543         fseek(fp, 0, SEEK_SET);
544 
545         while((bytes_read = fread(buf, 1, BUFLEN, fp)) > 0)
546         {
547                 unsigned char *cp = buf;
548 
549                 if(length + bytes_read < length)
550                         return 0;
551 
552                 if(bytes_read != BUFLEN && tagged)
553                         bytes_read -= 8;
554 
555                 length += bytes_read;
556                 while(bytes_read--)
557                         crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
558         }
559 
560         if(ferror(fp))
561                 return 0;
562 
563         for(; length; length >>= 8)
564                 crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF];
565 
566         crc = ~crc & 0xFFFFFFFF;
567 
568         *res = crc;
569 
570         return 1;
571 }
572 
573 unsigned long cs_calc_buf_sum(char *buf, int size)
574 {
575         unsigned long crc = 0;
576         char *cp = buf;
577         unsigned long length = size;
578 
579         while(size--)
580                 crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
581 
582         for(; length; length >>= 8)
583                 crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF];
584 
585         crc = ~crc & 0xFFFFFFFF;
586 
587         return crc;
588 }
589 
590 unsigned long cs_calc_buf_sum_ds(char *buf, int buf_size, char *sign, int sign_len)
591 {
592         unsigned long crc = 0;
593         char *cp = buf;
594         unsigned long length = buf_size+sign_len;
595 
596         while(buf_size--)
597                 crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
598 
599         cp = sign;
600         while(sign_len--)
601                 crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
602 
603 
604         for(; length; length >>= 8)
605                 crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF];
606 
607         crc = ~crc & 0xFFFFFFFF;
608 
609         return crc;
610 }
611 
612 int cs_set_sum(FILE *fp, unsigned long sum, int tagged)
613 {
614         unsigned long magic = CKSUM_MAGIC_NUMBER;
615 
616         if(tagged)
617                 fseek(fp, -8, SEEK_END);
618         else
619                 fseek(fp, 0, SEEK_END);
620 
621         if(fwrite(&magic, 1, 4, fp) < 4)
622                 return 0;
623         if(fwrite(&sum, 1, 4, fp) < 4)
624                 return 0;
625 
626         return 1;
627 }
628 
629 void cs_get_sum(FILE *fp, unsigned long *sum)
630 {
631         unsigned long magic = 0;
632 
633         fseek(fp, -8, SEEK_END);
634 
635         fread(&magic, 4, 1, fp);
636         fread(sum, 4, 1, fp);
637 }
638 
639 int cs_validate_file(char *filename)
640 {
641         FILE *pFile = NULL;
642         unsigned long sum = 0, res = 0;
643 
644         if((pFile = fopen(filename, "r")) == NULL)
645                 return 0;
646 
647         if(!cs_is_tagged(pFile))
648         {
649                 fclose(pFile);
650                 return 0;
651         }
652         if(!cs_calc_sum(pFile, &sum, 1))
653         {
654                 fclose(pFile);
655                 return 0;
656         }
657         cs_get_sum(pFile, &res);
658         fclose(pFile);
659 
660         if(sum != res)
661                 return 0;
662         return 1;
663 }
664 
665 /* ********* Library internal data ********* */
666 #define CMDLINE_TRUE                    1
667 #define CMDLINE_FALSE                   0
668 
669 typedef enum CMDLINE_ERR
670 {
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 */
679 } CMDLINE_ERR;
680 
681 /* Argument list */
682 typedef struct CMDLINE_ARG
683 {
684         int                             index;          /* Index of the argument in the command line */
685         struct CMDLINE_ARG*     p_next; /* Next node in the linked list */
686 } CMDLINE_ARG;
687 
688 /* Master control block for an option */
689 typedef struct CMDLINE_ARGS
690 {
691         int                             argc;           /* Total count of arguments found */
692         int                             optc;           /* Total count of options found */
693         CMDLINE_ARG*    list;           /* Argument list */
694 } CMDLINE_ARGS;
695 
696 /* Master control block for all found arguments */
697 typedef struct CMDLINE_DATA
698 {
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 */
702 } CMDLINE_DATA;
703 
704 /* ********* Local Data ********* */
705 static CMDLINE_CFG cmdline_cfg;
706 static CMDLINE_DATA cmdline_data;
707 
708 char*   cmdline_errmsg = "CMDLINE ERROR";
709 
710 /* ***************************************************************
711 * Print all found command line options and their arguments
712 ****************************************************************** */
713 void* cmdline_getarg_list(char opt)
714 {
715         int index = (opt - 'a');
716 
717         /* Check the validity of the index */
718         if((index < 0) || (index > 25))
719         {
720                 /* ERROR: Wrong option */
721                 return NULL;
722         }
723 
724         /* Return a pointer to the ARGS control structure */
725         return((void*)(&cmdline_data.opt_args[index]));
726 }
727 
728 /* ***************************************************************
729 * Print all found command line options and their arguments
730 ****************************************************************** */
731 int cmdline_getarg_count(void* list)
732 {
733         CMDLINE_ARGS*   p_args = (CMDLINE_ARGS*)list;
734 
735         /* Return number of arguments for this option */
736         return(p_args->argc);
737 }
738 
739 /* ***************************************************************
740 * Print all found command line options and their arguments
741 ****************************************************************** */
742 int cmdline_getopt_count(char opt)
743 {
744         int                             index;
745 
746         /* Calculate index value */
747         index = opt - 'a';
748         if(index < 0 || index > 25) return -1;
749 
750         /* Return number of arguments for this option */
751         return(cmdline_data.opt_args[index].optc);
752 }
753 
754 /* ***************************************************************
755 * Print all found command line options and their arguments
756 ****************************************************************** */
757 int cmdline_getarg(void* list, int num)
758 {
759         int i;
760         CMDLINE_ARGS*   p_args = (CMDLINE_ARGS*)list;
761         CMDLINE_ARG*    p_arg;
762 
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)
765         {
766                 /* if num matches i, we found it */
767                 if(i==num) return(p_arg->index);
768         }
769         /* We did not find the specified argument or the list was empty */
770         return -1;
771 }
772 
773 /* ***************************************************************
774 * Print all found command line options and their arguments
775 ****************************************************************** */
776 int cmdline_configure(CMDLINE_CFG* p_cfg)
777 {
778         /* reset global data */
779         memset(&cmdline_cfg,0,sizeof(cmdline_cfg));
780         memset(&cmdline_data,0,sizeof(cmdline_data));
781 
782         /* Copy the user's config structure */
783         cmdline_cfg = *p_cfg;
784         return 0;
785 }
786 
787 /* ***************************************************************
788 * Print all found command line options and their arguments
789 ****************************************************************** */
790 char* cmdline_error(int err)
791 {
792         /* TODO: implement a table of error messages */
793         return(cmdline_errmsg);
794 }
795 
796 /* ***************************************************************
797 * Print all found command line options and their arguments
798 ****************************************************************** */
799 static void cmdline_print_args(CMDLINE_ARGS* p_arglist, char* argv[])
800 {
801         CMDLINE_ARG*    p_arg;
802 
803         printf("   Number of times option was specified: %d\n", p_arglist->optc);
804         printf("   Number of Arguments:                  %d\n", p_arglist->argc);
805 
806         if(p_arglist->argc > 0)
807         {
808                 printf("   Argument List: ");
809 
810                 for(p_arg=p_arglist->list; p_arg != NULL; p_arg=p_arg->p_next)
811                         printf("%s ", argv[p_arg->index]);
812         }
813 
814         printf("\n");
815 }
816 
817 /* ***************************************************************
818 * Print all found command line options and their arguments
819 ****************************************************************** */
820 void cmdline_print(char* argv[])
821 {
822         int i;
823 
824         /* Check if the command line was parsed */
825         if(cmdline_data.parsed != CMDLINE_TRUE)
826         {
827                 printf("The command line has not been parsed yet.\n");
828                 return;
829         }
830 
831         /* Print out option arguments */
832         for( i = 0; i < 26; i++ )
833         {
834                 /* Check if the option was specified */
835                 if(cmdline_data.opt_args[i].optc !=0 )
836                 {
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);
840                 }
841         }
842 
843         /* Print out global arguments */
844         printf("Global arguments:\n");
845         cmdline_print_args(&(cmdline_data.glb_args), argv);
846 }
847 
848 /* ***************************************************************
849 * Print configuration
850 ****************************************************************** */
851 void cmdline_print_cfg(void)
852 {
853 
854 }
855 
856 static void cmdline_argadd(CMDLINE_ARGS* p_arglist, CMDLINE_ARG* p_arg)
857 {
858         CMDLINE_ARG*    p_list;
859         CMDLINE_ARG*    p_prev=NULL;
860 
861         /* See if we had anything in the list */
862         if(p_arglist->argc == 0)
863         {
864                 /* Link the argument in */
865                 p_arglist->list = p_arg;
866         }
867         else
868         {
869                 /* Find the tail of the list */
870                 for(p_list=p_arglist->list; p_list != NULL; p_list=p_list->p_next)
871                         p_prev = p_list;
872 
873                 /* Link the argument in */
874                 p_prev->p_next=p_arg;
875         }
876 
877         /* Keep track of arg number */
878         p_arglist->argc++;
879 }
880 
881 /* ***************************************************************
882 * cmdline_read()
883 * Read and parse command line arguments
884 ****************************************************************** */
885 int cmdline_read(int argc, char* argv[])
886 {
887         int i, option=0;
888 
889         /* Process every command line argument in argv[] array */
890         for( i = 1; i < argc; i++ )
891         {
892                 /* Does the argument start with a dash? */
893                 if( *argv[i] == '-' )
894                 {
895                         /* The argument must be two characters: a dash, and a letter */
896                         if( strlen(argv[i]) != 2 )
897                         {
898                                 /* ERROR: option syntax (needs to be a dash and one letter) */
899                                 return(CMDLINE_ERR_ERROR);
900                         }
901 
902                         /* Check validity of the option key ('a' through 'z') */
903                         if( ((*(argv[i] + 1)) < 'a') || ((*(argv[i] + 1)) > 'z') )
904                         {
905                                 /* ERROR: option sysntax (invalid option key) */
906                                 return(CMDLINE_ERR_INVKEY);
907                         }
908 
909                         /* Calculate the option index */
910                         option = (*(argv[i] + 1)) - 'a';
911                         if((option < 0) || (option > 25)) return(CMDLINE_ERR_INVKEY);
912 
913                         /* Check to see if the option is allowed */
914                         if( cmdline_cfg.opts[option].flags & CMDLINE_OPTFLAG_ALLOW )
915                         {
916                                 /* Option allowed. */
917                                 cmdline_data.opt_args[option].optc++;
918                                 continue;
919                         }
920                         else
921                         {
922                                 /* ERROR: Option is not allowed */
923                                 return(CMDLINE_ERR_ILLOPT);
924                         }
925                 }
926                 else
927                 {
928                         /* Read the arguments for the option */
929                         CMDLINE_ARG*    p_arg;
930 
931                         /* Allocate space for the argument node */
932                         p_arg = (CMDLINE_ARG*)calloc(1,sizeof(CMDLINE_ARG));
933                         if( p_arg== NULL )
934                         {
935                                 /* ERROR: Can't allocate memory for the argument index */
936                                 return(CMDLINE_ERR_NOMEM);
937                         }
938 
939                         /* Initialize the argument */
940                         p_arg->index    = i;
941                         p_arg->p_next   = NULL;
942 
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? */
946                                 )
947                         {
948                                 /* This option does not require arguments. Keep the argument in the global list. */
949                                 cmdline_argadd(&(cmdline_data.glb_args), p_arg);
950                                 continue;
951                         }
952                         else
953                         {
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 )
956                                 {
957                                         /* ERROR: too many arguments for an option */
958                                         return(CMDLINE_ERR_MANYARG);
959                                 }
960                                 else
961                                 {
962                                         /* Link the argument to the arg list of the option */
963                                         cmdline_argadd(&(cmdline_data.opt_args[option]), p_arg);
964                                         continue;
965                                 }
966                         }
967                 }
968         }
969 
970         /* ****** We read the complete command line. See if what we collected matches the configuration ******* */
971 
972         /* Check every collected option against its configuration */
973         for( i=0; i < 26; i++ )
974         {
975                 /* Check if this option was allowed */
976                 if(cmdline_cfg.opts[i].flags & CMDLINE_OPTFLAG_ALLOW)
977                 {
978                         /* See if it was mandatory */
979                         if(cmdline_cfg.opts[i].flags & CMDLINE_OPTFLAG_MANDAT)
980                         {
981                                 /* Check if we really collected this option on the command line. */
982                                 if(cmdline_data.opt_args[i].optc == 0)
983                                 {
984                                         /* ERROR: a missing mandatory option */
985                                         return(CMDLINE_ERR_OPTMIS);
986                                 }
987                                 else
988                                 {
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)
991                                         {
992                                                 /* ERROR: too few arguments for an option */
993                                                 return(CMDLINE_ERR_FEWARG);
994                                         }
995                                         else
996                                         {
997                                                 /* This mandatory option was proper. */
998                                                 continue;
999                                         }
1000                                 }
1001                         }
1002                         else    /* This is non-mandatory option: */
1003                         {
1004                                 /* Check if the option was specified on the command line */
1005                                 if(cmdline_data.opt_args[i].optc == 0)
1006                                 {
1007                                         /* option wasn't specified, go to the next */
1008                                         continue;
1009                                 }
1010                                 else
1011                                 {
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)
1014                                         {
1015                                                 /* ERROR: too few arguments for a non-mandatory option */
1016                                                 return(CMDLINE_ERR_FEWARG);
1017                                         }
1018                                         else
1019                                         {
1020                                                 /* This non-mandatory option was proper. */
1021                                                 continue;
1022                                         }
1023                                 }
1024                         }
1025                 }
1026                 else    /* Option was not allowed. */
1027                 {
1028                         /* We should not get here as the non-allowed options should have been
1029                         trapped eariler. */
1030                 }
1031         }
1032 
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);
1036 }
1037 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt