| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. | 2 * Copyright (C) 2010 Google Inc. |
| 3 * | 3 * |
| 4 * This program is free software; you can redistribute it and/or | 4 * This program is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU General Public License | 5 * modify it under the terms of the GNU General Public License |
| 6 * as published by the Free Software Foundation; either version 2 | 6 * as published by the Free Software Foundation; either version 2 |
| 7 * of the License, or (at your option) any later version. | 7 * of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "lib/flashrom.h" | 27 #include "lib/flashrom.h" |
| 28 #include "lib/fmap.h" | 28 #include "lib/fmap.h" |
| 29 #include "lib/lib_vpd.h" | 29 #include "lib/lib_vpd.h" |
| 30 #include "lib/lib_smbios.h" | 30 #include "lib/lib_smbios.h" |
| 31 #include "lib/vpd.h" | 31 #include "lib/vpd.h" |
| 32 #include "lib/vpd_tables.h" | 32 #include "lib/vpd_tables.h" |
| 33 | 33 |
| 34 /* The buffer length. Right now the VPD partition size on flash is 128KB. */ | 34 /* The buffer length. Right now the VPD partition size on flash is 128KB. */ |
| 35 #define BUF_LEN (128 * 1024) | 35 #define BUF_LEN (128 * 1024) |
| 36 | 36 |
| 37 static uint8_t flashrom_tmp_file[] = "/tmp/vpd.flashrom.XXXXXX"; | 37 /* temp filename for partial read area. */ |
| 38 static uint8_t tmp_part_file[] = "/tmp/vpd.flashrom.XXXXXX"; |
| 39 /* temp filename for the full flash content (actually only partial content |
| 40 * is available). But for flashrom -w to match flash size, we need to keep this |
| 41 * file from flashromRead() to writeFlashrom(). */ |
| 42 static uint8_t tmp_full_file[] = "/tmp/vpd.flashrom.XXXXXX"; |
| 38 | 43 |
| 39 /* 2 containers: | 44 /* 2 containers: |
| 40 * file: stores decoded pairs from file. | 45 * file: stores decoded pairs from file. |
| 41 * argument: stores parsed pairs from command arguments. | 46 * argument: stores parsed pairs from command arguments. |
| 42 */ | 47 */ |
| 43 struct PairContainer file; | 48 struct PairContainer file; |
| 44 struct PairContainer argument; | 49 struct PairContainer argument; |
| 45 | 50 |
| 46 /* The current padding length value. | 51 /* The current padding length value. |
| 47 * Default: VPD_AS_LONG_AS | 52 * Default: VPD_AS_LONG_AS |
| 48 */ | 53 */ |
| 49 int pad_value_len = VPD_AS_LONG_AS; | 54 int pad_value_len = VPD_AS_LONG_AS; |
| 50 | 55 |
| 51 /* The output buffer */ | 56 /* The output buffer */ |
| 52 unsigned char buf[BUF_LEN]; | 57 unsigned char buf[BUF_LEN]; |
| 53 int buf_len = 0; | 58 int buf_len = 0; |
| 54 int max_buf_len = sizeof(buf); | 59 int max_buf_len = sizeof(buf); |
| 55 | 60 |
| 56 /* The EPS base address used to fill the EPS table entry. | 61 /* The EPS base address used to fill the EPS table entry. |
| 57 * If the VPD partition can be found in fmap, this points to the starting | 62 * If the VPD partition can be found in fmap, this points to the starting |
| 58 * offset of VPD partition. If not found, this is used to be the base address | 63 * offset of VPD partition. If not found, this is used to be the base address |
| 59 * to increase SPD and VPD 2.0 offset fields. | 64 * to increase SPD and VPD 2.0 offset fields. |
| 60 * | 65 * |
| 61 * User can overwrite this by -E argument. | 66 * User can overwrite this by -E argument. |
| 62 */ | 67 */ |
| 63 uint32_t eps_base = GOOGLE_EPS_BASE; | 68 uint32_t eps_base = GOOGLE_EPS_BASE; |
| 69 int eps_base_force_specified = 0; /* a bool value to indicate if -E argument |
| 70 * is given. */ |
| 64 | 71 |
| 65 /* the fmap name of VPD. */ | 72 /* the fmap name of VPD. */ |
| 66 uint8_t fmap_vpd_area_name[FMAP_STRLEN] = "RO VPD"; | 73 uint8_t fmap_vpd_area_name[FMAP_STRLEN] = "RO_VPD"; |
| 67 | 74 |
| 68 /* If found_vpd, replace the VPD partition when saveFile(). | 75 /* If found_vpd, replace the VPD partition when saveFile(). |
| 69 * If not found, always create new file when saveFlie(). */ | 76 * If not found, always create new file when saveFlie(). */ |
| 70 int found_vpd = 0; | 77 int found_vpd = 0; |
| 71 | 78 |
| 72 /* The VPD partition offset and size in buf[]. The whole partition includes: | 79 /* The VPD partition offset and size in buf[]. The whole partition includes: |
| 73 * | 80 * |
| 74 * SMBIOS EPS | 81 * SMBIOS EPS |
| 75 * SMBIOS tables[] | 82 * SMBIOS tables[] |
| 76 * SPD | 83 * SPD |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 struct vpd_entry *eps; | 226 struct vpd_entry *eps; |
| 220 struct vpd_header *header; | 227 struct vpd_header *header; |
| 221 struct vpd_table_binary_blob_pointer *data; | 228 struct vpd_table_binary_blob_pointer *data; |
| 222 uint8_t spd_uuid[16], vpd_2_0_uuid[16]; | 229 uint8_t spd_uuid[16], vpd_2_0_uuid[16]; |
| 223 int expected_handle = 0; | 230 int expected_handle = 0; |
| 224 int table_len; | 231 int table_len; |
| 225 int index; | 232 int index; |
| 226 int retval = 0; | 233 int retval = 0; |
| 227 | 234 |
| 228 if (!(fp = fopen(filename, "r"))) { | 235 if (!(fp = fopen(filename, "r"))) { |
| 229 fprintf(stderr, "[WARN] File [%s] cannot be opened for read. Ignored.\n", | 236 fprintf(stderr, "[WARN] File [%s] cannot be opened for read. It's fine.\n", |
| 230 filename); | 237 filename); |
| 231 return 0; | 238 return 0; |
| 232 } | 239 } |
| 233 /* get file size */ | 240 /* get file size */ |
| 234 fseek(fp, 0, SEEK_END); | 241 fseek(fp, 0, SEEK_END); |
| 235 file_size = ftell(fp); | 242 file_size = ftell(fp); |
| 236 | 243 |
| 237 /* read file content */ | 244 /* read file content */ |
| 238 fseek(fp, 0, SEEK_SET); | 245 fseek(fp, 0, SEEK_SET); |
| 239 read_buf = malloc(file_size); | 246 read_buf = malloc(file_size); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 251 /* FMAP signature is not found, assume it is pure VPD partition. */ | 258 /* FMAP signature is not found, assume it is pure VPD partition. */ |
| 252 vpd_buf = read_buf; | 259 vpd_buf = read_buf; |
| 253 eps = (struct vpd_entry *)vpd_buf; | 260 eps = (struct vpd_entry *)vpd_buf; |
| 254 | 261 |
| 255 /* In overwrite mode, ignore all existing data. */ | 262 /* In overwrite mode, ignore all existing data. */ |
| 256 if (overwrite_it) { | 263 if (overwrite_it) { |
| 257 retval = 0; | 264 retval = 0; |
| 258 goto teardown; | 265 goto teardown; |
| 259 } | 266 } |
| 260 } else { | 267 } else { |
| 268 /* FMAP signature is found, try to search the partition name in table. */ |
| 261 int i; | 269 int i; |
| 262 | 270 |
| 263 fmap = (struct fmap *)&read_buf[sig_offset]; | 271 fmap = (struct fmap *)&read_buf[sig_offset]; |
| 264 for(i = 0; i < fmap->nareas; i++) { | 272 for(i = 0; i < fmap->nareas; i++) { |
| 265 fmapNormalizeAreaName(fmap->areas[i].name); | 273 fmapNormalizeAreaName(fmap->areas[i].name); |
| 266 } | 274 } |
| 267 | 275 |
| 268 if (FMAP_OK == fmapGetArea(fmap_vpd_area_name, fmap, | 276 if (FMAP_OK == fmapGetArea(fmap_vpd_area_name, fmap, |
| 269 &vpd_offset, &vpd_size)) { | 277 &vpd_offset, &vpd_size)) { |
| 270 found_vpd = 1; /* Mark found here then saveFile() knows where to | 278 found_vpd = 1; /* Mark found here then saveFile() knows where to |
| (...skipping 11 matching lines...) Expand all Loading... |
| 282 fprintf(stderr, "The VPD partition [%s] is not found.\n", | 290 fprintf(stderr, "The VPD partition [%s] is not found.\n", |
| 283 fmap_vpd_area_name); | 291 fmap_vpd_area_name); |
| 284 retval = 1; | 292 retval = 1; |
| 285 goto teardown; | 293 goto teardown; |
| 286 } | 294 } |
| 287 } | 295 } |
| 288 /* Now, vpd_buf points to the VPD partition in buffer. | 296 /* Now, vpd_buf points to the VPD partition in buffer. |
| 289 * eps points to the EPS structure, which is usually equal to vpd_buf. */ | 297 * eps points to the EPS structure, which is usually equal to vpd_buf. */ |
| 290 eps_offset = (uint8_t*)eps - vpd_buf; | 298 eps_offset = (uint8_t*)eps - vpd_buf; |
| 291 | 299 |
| 300 /* check if ups_base variable needs to be updated. */ |
| 301 if (!eps_base_force_specified) { |
| 302 if (eps->table_address > file_size) { |
| 303 /* If the table address field of EPS indicates the position exceeding |
| 304 * the file size, that means some how this field needs to be shifted. |
| 305 * A special case is 0xFFFFFFFF, which means unkowns address. But this |
| 306 * is okay because the later offset of structure table are counted |
| 307 * related to this value. */ |
| 308 eps_base = eps->table_address - sizeof(*eps); |
| 309 fprintf(stderr, "[INFO] we guess eps_base is 0x%x.\n", eps_base); |
| 310 } |
| 311 } |
| 312 |
| 292 /* jump if the VPD partition is not recognized. */ | 313 /* jump if the VPD partition is not recognized. */ |
| 293 if (memcmp(VPD_ENTRY_MAGIC, eps, sizeof(VPD_ENTRY_MAGIC) - 1)) { | 314 if (memcmp(VPD_ENTRY_MAGIC, eps, sizeof(VPD_ENTRY_MAGIC) - 1)) { |
| 294 /* But OKAY if the VPD partition is all-FF, which is un-used. */ | 315 /* But OKAY if the VPD partition is all-FF, which is un-used. */ |
| 295 if (memcmp("\xff\xff\xff\xff", eps, sizeof(VPD_ENTRY_MAGIC) - 1)) { | 316 if (!memcmp("\xff\xff\xff\xff", eps, sizeof(VPD_ENTRY_MAGIC) - 1)) { |
| 317 fprintf(stderr, "[WARN] VPD partition not formatted. It's fine.\n"); |
| 318 retval = 0; |
| 319 goto teardown; |
| 320 } else { |
| 296 fprintf(stderr, "SMBIOS signature is not matched.\n"); | 321 fprintf(stderr, "SMBIOS signature is not matched.\n"); |
| 297 fprintf(stderr, "You may use -O to overwrite the data.\n"); | 322 fprintf(stderr, "You may use -O to overwrite the data.\n"); |
| 298 retval = 1; | 323 retval = 1; |
| 299 goto teardown; | 324 goto teardown; |
| 300 } | 325 } |
| 301 /* TODO(yjlou): need more EPS sanity checks here. */ | 326 /* TODO(yjlou): need more EPS sanity checks here. */ |
| 302 } | 327 } |
| 303 /* EPS is done above. Parse structure tables below. */ | 328 /* EPS is done above. Parse structure tables below. */ |
| 304 /* Get the first type 241 blob, at the tail of EPS. */ | 329 /* Get the first type 241 blob, at the tail of EPS. */ |
| 305 header = (struct vpd_header*)(((uint8_t*)eps) + eps->entry_length); | 330 header = (struct vpd_header*)(((uint8_t*)eps) + eps->entry_length); |
| 306 data = (struct vpd_table_binary_blob_pointer *) | 331 data = (struct vpd_table_binary_blob_pointer *) |
| 307 ((uint8_t *)header + sizeof(*header)); | 332 ((uint8_t *)header + sizeof(*header)); |
| 308 | 333 |
| 309 /* TODO(yjlou): Re-factor the parsing code to support more SMBIOS entries. | 334 /* TODO(yjlou): Re-factor the parsing code to support more SMBIOS entries. |
| 310 * The current code only supports 2 combinations: | 335 * The current code only supports 2 combinations: |
| 311 * 1. Type 241 (SPD) + Type 241 (VPD 2.0) + Type 127 | 336 * 1. Type 241 (SPD) + Type 241 (VPD 2.0) + Type 127 |
| 312 * 2. Type 241 (VPD 2.0) + Type 127 | 337 * 2. Type 241 (VPD 2.0) + Type 127 |
| 313 */ | 338 */ |
| 314 | 339 |
| 315 /* Now header points to the first SMBIOS entry, and data points to the | 340 /* Now header points to the first SMBIOS entry, and data points to the |
| 316 * first BBP entry. The first entry could be SPD data. We don't care. */ | 341 * first BBP entry. The first entry could be SPD data. We don't care. */ |
| 317 if (header->handle != expected_handle) { | 342 if (header->handle != expected_handle) { |
| 318 fprintf(stderr, "The first handle value must be 0, but is %d.\n", | 343 fprintf(stderr, "[ERROR] The first handle value must be 0, but is %d.\n" |
| 344 " Use -O option to re-format.\n", |
| 319 header->handle); | 345 header->handle); |
| 320 retval = 1; | 346 retval = 1; |
| 321 goto teardown; | 347 goto teardown; |
| 322 } | 348 } |
| 323 if (header->type != VPD_TYPE_BINARY_BLOB_POINTER) { | 349 if (header->type != VPD_TYPE_BINARY_BLOB_POINTER) { |
| 324 fprintf(stderr, "Expect first entry is type Binary Blob Pointer (241)," | 350 fprintf(stderr, "Expect first entry is type Binary Blob Pointer (241)," |
| 325 " but actually is %d\n", header->type); | 351 " but actually is %d\n", header->type); |
| 326 fprintf(stderr, "You may use -O to overwrite the data.\n"); | 352 fprintf(stderr, "You may use -O to overwrite the data.\n"); |
| 327 retval = 1; | 353 retval = 1; |
| 328 goto teardown; | 354 goto teardown; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 355 retval = 1; | 381 retval = 1; |
| 356 goto teardown; | 382 goto teardown; |
| 357 } | 383 } |
| 358 header = (struct vpd_header*)((uint8_t*)header + table_len); | 384 header = (struct vpd_header*)((uint8_t*)header + table_len); |
| 359 data = (struct vpd_table_binary_blob_pointer *) | 385 data = (struct vpd_table_binary_blob_pointer *) |
| 360 ((uint8_t *)header + sizeof(*header)); | 386 ((uint8_t *)header + sizeof(*header)); |
| 361 } | 387 } |
| 362 | 388 |
| 363 /* The 2nd could be VPD 2.0 data or End Of Table. */ | 389 /* The 2nd could be VPD 2.0 data or End Of Table. */ |
| 364 if (header->handle != expected_handle) { | 390 if (header->handle != expected_handle) { |
| 365 fprintf(stderr, "The second handle value must be 1, but is %d.\n", | 391 fprintf(stderr, "[ERROR] The second handle value must be 1, but is %d.\n" |
| 392 " Use -O option to re-format.\n", |
| 366 header->handle); | 393 header->handle); |
| 367 retval = 1; | 394 retval = 1; |
| 368 goto teardown; | 395 goto teardown; |
| 369 } | 396 } |
| 370 uuid_parse(GOOGLE_VPD_2_0_UUID, vpd_2_0_uuid); | 397 uuid_parse(GOOGLE_VPD_2_0_UUID, vpd_2_0_uuid); |
| 371 if (header->type == VPD_TYPE_BINARY_BLOB_POINTER && | 398 if (header->type == VPD_TYPE_BINARY_BLOB_POINTER && |
| 372 !memcmp(data->uuid, vpd_2_0_uuid, sizeof(data->uuid))) { | 399 !memcmp(data->uuid, vpd_2_0_uuid, sizeof(data->uuid))) { |
| 373 ++expected_handle; | 400 ++expected_handle; |
| 374 | 401 |
| 375 /* iterate all pairs */ | 402 /* iterate all pairs */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 392 header = (struct vpd_header*)((uint8_t*)header + table_len); | 419 header = (struct vpd_header*)((uint8_t*)header + table_len); |
| 393 data = (struct vpd_table_binary_blob_pointer *) | 420 data = (struct vpd_table_binary_blob_pointer *) |
| 394 ((uint8_t *)header + sizeof(*header)); | 421 ((uint8_t *)header + sizeof(*header)); |
| 395 } else { | 422 } else { |
| 396 fprintf(stderr, "[WARN] no VPD 2.0 BBP is found, ignored.\n"); | 423 fprintf(stderr, "[WARN] no VPD 2.0 BBP is found, ignored.\n"); |
| 397 retval = 0; | 424 retval = 0; |
| 398 goto teardown; | 425 goto teardown; |
| 399 } | 426 } |
| 400 | 427 |
| 401 if (header->type != VPD_TYPE_END) { | 428 if (header->type != VPD_TYPE_END) { |
| 402 fprintf(stderr, "[WARN] we expect the last one is type 127. Ignored.\n"); | 429 fprintf(stderr, "[WARN] we expect the last one is type 127. It's fine.\n"); |
| 403 } | 430 } |
| 404 | 431 |
| 405 teardown: | 432 teardown: |
| 406 free(read_buf); | 433 free(read_buf); |
| 407 | 434 |
| 408 return retval; | 435 return retval; |
| 409 } | 436 } |
| 410 | 437 |
| 411 | 438 |
| 412 int saveFile(const struct PairContainer *container, const char *filename) { | 439 int saveFile(const struct PairContainer *container, const char *filename) { |
| 413 FILE *fp; | 440 FILE *fp; |
| 414 unsigned char eps[1024]; | 441 unsigned char eps[1024]; |
| 415 int eps_len = 0; | 442 int eps_len = 0; |
| 416 int retval = 0; | 443 int retval = 0; |
| 417 | 444 |
| 418 memset(eps, 0, sizeof(eps)); | 445 memset(eps, 0xff, sizeof(eps)); |
| 419 | 446 |
| 420 /* encode into buffer */ | 447 /* encode into buffer */ |
| 421 if (VPD_OK != encodeContainer(&file, max_buf_len, buf, &buf_len)) { | 448 if (VPD_OK != encodeContainer(&file, max_buf_len, buf, &buf_len)) { |
| 422 fprintf(stderr, "encodeContainer() error.\n"); | 449 fprintf(stderr, "encodeContainer() error.\n"); |
| 423 retval = 1; | 450 retval = 1; |
| 424 goto teardown; | 451 goto teardown; |
| 425 } | 452 } |
| 426 if (VPD_OK != encodeVpdTerminator(max_buf_len, buf, &buf_len)) { | 453 if (VPD_OK != encodeVpdTerminator(max_buf_len, buf, &buf_len)) { |
| 427 fprintf(stderr, "Out of space for terminator.\n"); | 454 fprintf(stderr, "Out of space for terminator.\n"); |
| 428 retval = 1; | 455 retval = 1; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 fprintf(stderr, "fwrite(VPD 2.0) error (%s)\n", strerror(errno)); | 510 fprintf(stderr, "fwrite(VPD 2.0) error (%s)\n", strerror(errno)); |
| 484 retval = 1; | 511 retval = 1; |
| 485 goto teardown; | 512 goto teardown; |
| 486 } | 513 } |
| 487 fclose(fp); | 514 fclose(fp); |
| 488 | 515 |
| 489 teardown: | 516 teardown: |
| 490 return retval; | 517 return retval; |
| 491 } | 518 } |
| 492 | 519 |
| 520 int myMkTemp(uint8_t *tmp_file) { |
| 521 int fd; |
| 522 fd = mkstemp(tmp_file); |
| 523 if (fd < 0) { |
| 524 fprintf(stderr, "mkstemp(%s) failed\n", tmp_file); |
| 525 } |
| 526 return fd; |
| 527 } |
| 528 |
| 529 int generateTempFilenames(void) { |
| 530 if (myMkTemp(tmp_part_file) < 0) return -1; |
| 531 if (myMkTemp(tmp_full_file) < 0) return -1; |
| 532 return 0; |
| 533 } |
| 493 | 534 |
| 494 static void usage(const char *progname) { | 535 static void usage(const char *progname) { |
| 495 printf("Chrome OS VPD 2.0 utility --\n"); | 536 printf("Chrome OS VPD 2.0 utility --\n"); |
| 496 #ifdef VPD_VERSION | 537 #ifdef VPD_VERSION |
| 497 printf("%s\n", VPD_VERSION); | 538 printf("%s\n", VPD_VERSION); |
| 498 #endif | 539 #endif |
| 499 printf("\n"); | 540 printf("\n"); |
| 500 printf("Usage: %s [OPTION] ...\n", progname); | 541 printf("Usage: %s [OPTION] ...\n", progname); |
| 501 printf(" OPTIONs include:\n"); | 542 printf(" OPTIONs include:\n"); |
| 502 printf(" -h This help page and version.\n"); | 543 printf(" -h This help page and version.\n"); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 goto teardown; | 585 goto teardown; |
| 545 break; | 586 break; |
| 546 | 587 |
| 547 case 'f': | 588 case 'f': |
| 548 filename = strdup(optarg); | 589 filename = strdup(optarg); |
| 549 break; | 590 break; |
| 550 | 591 |
| 551 case 'E': | 592 case 'E': |
| 552 errno = 0; | 593 errno = 0; |
| 553 eps_base = strtoul(optarg, (char **) NULL, 0); | 594 eps_base = strtoul(optarg, (char **) NULL, 0); |
| 595 eps_base_force_specified = 1; |
| 554 | 596 |
| 555 /* FIXME: this is not a stable way to detect error because | 597 /* FIXME: this is not a stable way to detect error because |
| 556 * implementation may (or may not) assign errno. */ | 598 * implementation may (or may not) assign errno. */ |
| 557 if (!eps_base && errno == EINVAL) { | 599 if (!eps_base && errno == EINVAL) { |
| 558 fprintf(stderr, "Not a number for EPS base address: %s\n", optarg); | 600 fprintf(stderr, "Not a number for EPS base address: %s\n", optarg); |
| 559 retval = 1; | 601 retval = 1; |
| 560 goto teardown; | 602 goto teardown; |
| 561 } | 603 } |
| 562 break; | 604 break; |
| 563 | 605 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 break; | 640 break; |
| 599 | 641 |
| 600 default: | 642 default: |
| 601 fprintf(stderr, "Invalid option, use --help for usage.\n"); | 643 fprintf(stderr, "Invalid option, use --help for usage.\n"); |
| 602 retval = 1; | 644 retval = 1; |
| 603 goto teardown; | 645 goto teardown; |
| 604 break; | 646 break; |
| 605 } | 647 } |
| 606 } | 648 } |
| 607 | 649 |
| 608 fd = mkstemp(flashrom_tmp_file); | 650 if (optind < argc) { |
| 609 if (fd < 0) { | 651 fprintf(stderr, "[ERROR] unexpected argument: %s\n\n", argv[optind]); |
| 610 fprintf(stderr, "mkstemp(%s) failed\n", flashrom_tmp_file); | 652 usage(argv[0]); |
| 611 retval = 1; | 653 retval = 1; |
| 612 goto teardown; | 654 goto teardown; |
| 613 } | 655 } |
| 656 |
| 657 if (generateTempFilenames() < 0) { |
| 658 retval = 1; |
| 659 goto teardown; |
| 660 } |
| 614 | 661 |
| 615 /* to avoid malicious attack, we replace suspicious chars. */ | 662 /* to avoid malicious attack, we replace suspicious chars. */ |
| 616 fmapNormalizeAreaName(fmap_vpd_area_name); | 663 fmapNormalizeAreaName(fmap_vpd_area_name); |
| 617 | 664 |
| 618 /* if no filename is specified, call flashrom to read from flash. */ | 665 /* if no filename is specified, call flashrom to read from flash. */ |
| 619 if (!filename) { | 666 if (!filename) { |
| 620 if (FLASHROM_OK != flashromRead(flashrom_tmp_file)) { | 667 if (FLASHROM_OK != flashromRead(tmp_part_file, tmp_full_file, |
| 668 fmap_vpd_area_name)) { |
| 621 fprintf(stderr, "flashromRead() error!\n"); | 669 fprintf(stderr, "flashromRead() error!\n"); |
| 622 retval = 1; | 670 retval = 1; |
| 623 goto teardown; | 671 goto teardown; |
| 624 } | 672 } |
| 625 write_back_to_flash = 1; | 673 write_back_to_flash = 1; |
| 626 filename = strdup(flashrom_tmp_file); | 674 filename = strdup(tmp_part_file); |
| 627 } | 675 } |
| 628 | 676 |
| 629 if (retval = loadFile(filename, &file, overwrite_it)) { | 677 if (retval = loadFile(filename, &file, overwrite_it)) { |
| 630 fprintf(stderr, "loadFile('%s') error.\n", filename); | 678 fprintf(stderr, "loadFile('%s') error.\n", filename); |
| 631 goto teardown; | 679 goto teardown; |
| 632 } | 680 } |
| 633 | 681 |
| 634 mergeContainer(&file, &argument); | 682 mergeContainer(&file, &argument); |
| 635 | 683 |
| 636 if (list_it) { | 684 if (list_it) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 648 printf("%s", list_buf); | 696 printf("%s", list_buf); |
| 649 } | 697 } |
| 650 | 698 |
| 651 if (modified) { | 699 if (modified) { |
| 652 if (retval = saveFile(&file, filename)) { | 700 if (retval = saveFile(&file, filename)) { |
| 653 fprintf(stderr, "saveFile('%s') error.\n", filename); | 701 fprintf(stderr, "saveFile('%s') error.\n", filename); |
| 654 goto teardown; | 702 goto teardown; |
| 655 } | 703 } |
| 656 | 704 |
| 657 if (write_back_to_flash) { | 705 if (write_back_to_flash) { |
| 658 if (FLASHROM_OK != flashromPartialWrite(filename, vpd_offset, vpd_size)) { | 706 if (FLASHROM_OK != flashromPartialWrite(filename, tmp_full_file, |
| 707 fmap_vpd_area_name)) { |
| 659 fprintf(stderr, "flashromPartialWrite() error.\n"); | 708 fprintf(stderr, "flashromPartialWrite() error.\n"); |
| 660 retval = 1; | 709 retval = 1; |
| 661 goto teardown; | 710 goto teardown; |
| 662 } | 711 } |
| 663 } | 712 } |
| 664 } | 713 } |
| 665 | 714 |
| 666 teardown: | 715 teardown: |
| 667 if (spd_data) free(spd_data); | 716 if (spd_data) free(spd_data); |
| 668 if (filename) free(filename); | 717 if (filename) free(filename); |
| 669 destroyContainer(&file); | 718 destroyContainer(&file); |
| 670 destroyContainer(&argument); | 719 destroyContainer(&argument); |
| 671 | 720 |
| 672 return retval; | 721 return retval; |
| 673 } | 722 } |
| OLD | NEW |