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 *)§ion->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