in common/recipes-core/fruid/files/fruid-util.c [803:1053]
int do_action(int argc, char * argv[], unsigned char action_flag) {
int ret;
int fd_tmpbin;
int fd_newbin;
int fru_size;
char path[64] = {0};
char name[64] = {0};
char eeprom_path[64] = {0};
char command[128] = {0};
char *file_path;
uint8_t status;
uint8_t fru;
uint8_t num_devs = 0;
uint8_t dev_id = DEV_NONE;
fruid_info_t fruid;
FILE *fp;
ret = pal_get_fru_id(argv[optind], &fru);
if (ret < 0) {
print_usage();
}
if (fru == FRU_ALL) {
print_usage();
return -1;
}
ret = pal_get_fruid_name(fru, name);
if (ret < 0) {
printf("pal_get_fruid_name failed for fru: %d\n", fru);
return ret;
}
ret = pal_is_fru_prsnt(fru, &status);
if (ret < 0) {
printf("pal_is_fru_prsnt failed for fru: %d\n", fru);
return ret;
}
if (status == 0) {
printf("%s is not present!\n\n", name);
return ret;
}
ret = pal_is_fru_ready(fru, &status);
if ((ret < 0) || (status == 0)) {
printf("%s is unavailable!\n\n", name);
return ret;
}
if (argc == 5 || argc == 7) {
pal_get_num_devs(fru, &num_devs);
if (num_devs == 0) {
print_usage();
}
ret = pal_get_dev_id(argv[optind+1], &dev_id);
if (ret < 0) {
print_usage();
}
if ( dev_id == DEV_NONE || dev_id == DEV_ALL ) {
print_usage();
}
pal_get_dev_fruid_name(fru, dev_id,name);
ret = pal_get_dev_fruid_path(fru, dev_id, path);
} else {
ret = pal_get_fruid_path(fru, path);
}
if (ret < 0) {
return ret;
}
switch(action_flag) {
case FLAG_DUMP:
file_path = argv[optind-1];
fd_tmpbin = open(path, O_RDONLY);
if (fd_tmpbin == -1) {
syslog(LOG_ERR, "Unable to open the %s file: %s", path, strerror(errno));
return errno;
}
fd_newbin = open(file_path, O_WRONLY | O_CREAT, 0644);
if (fd_newbin == -1) {
syslog(LOG_ERR, "Unable to create %s file: %s", file_path, strerror(errno));
return errno;
}
ret = copy_file(fd_newbin, fd_tmpbin, FRUID_SIZE);
if (ret < 0) {
syslog(LOG_ERR, "copy: write to %s file failed: %s",
file_path, strerror(errno));
}
close(fd_newbin);
close(fd_tmpbin);
return ret;
case FLAG_WRITE:
file_path = argv[optind-1];
// Check if the new eeprom binary file exits.
// TODO: Add file size check before adding to the eeprom
if (access(file_path, F_OK) == -1) {
print_usage();
syslog(LOG_ERR, "Unable to access the %s file: %s", file_path, strerror(errno));
return -1;
}
// Verify the checksum of the new binary
ret = fruid_parse(file_path, &fruid);
if(ret != 0) {
printf("New FRU data checksum is invalid\n");
syslog(LOG_CRIT, "New FRU data checksum is invalid");
return -1;
}
fd_tmpbin = open(path, O_WRONLY | O_CREAT, 0666);
if (fd_tmpbin == -1) {
printf("Unable to open the %s file: %s\n", path, strerror(errno));
syslog(LOG_ERR, "Unable to open the %s file: %s", path, strerror(errno));
return errno;
}
fd_newbin = open(file_path, O_RDONLY);
if (fd_newbin == -1) {
printf("Unable to open the %s file: %s\n", file_path, strerror(errno));
syslog(LOG_ERR, "Unable to open the %s file: %s", file_path, strerror(errno));
return errno;
}
fp = fopen(file_path, "rb");
if ( NULL == fp ) {
printf("Unable to get the %s fp %s\n", file_path, strerror(errno));
syslog(LOG_ERR, "Unable to get the %s fp %s", file_path, strerror(errno));
return errno;
}
//get the size of the new binary
fseek(fp, 0L, SEEK_END);
fru_size = ftell(fp);
rewind(fp);
fclose(fp);
//check the size overflow or not
fru_size = (fru_size > FRUID_SIZE)?FRUID_SIZE:fru_size;
ret = pal_get_fruid_eeprom_path(fru, eeprom_path);
if ((dev_id != DEV_NONE) && (ret < 0)) {
ret = pal_get_dev_fruid_eeprom_path(fru, dev_id, eeprom_path, sizeof(eeprom_path));
}
if (ret < 0) {
//Can not handle in common, so call pal libray for update
if (num_devs) {
if (dev_id == DEV_ALL)
ret = -1;
else if (dev_id == DEV_NONE)
ret = pal_fruid_write(fru, file_path);
else
ret = pal_dev_fruid_write(fru, dev_id, file_path);
} else {
ret = pal_fruid_write(fru, file_path);
}
if (ret < 0) {
printf("FRU:%d Write failed!\n", fru);
syslog(LOG_WARNING, "[%s] Please check the fruid: %d dev_id: %d file_path: %s", __func__, fru, dev_id, file_path);
close(fd_newbin);
close(fd_tmpbin);
return -1;
}
} else {
if (access(eeprom_path, F_OK) == -1) {
printf("Fail to access eeprom file file : %s for fru %d\n", eeprom_path, fru);
syslog(LOG_ERR, "cannot access the eeprom file : %s for fru %d",
eeprom_path, fru);
close(fd_newbin);
close(fd_tmpbin);
return -1;
}
sprintf(command, "dd if=%s of=%s bs=%d count=1", file_path, eeprom_path, fru_size);
if (system(command) != 0) {
printf("Copy of %s to %s failed!\n", file_path, eeprom_path);
syslog(LOG_ERR, "Copy of %s to %s failed!\n", file_path, eeprom_path);
return -1;
}
ret = pal_compare_fru_data(eeprom_path, file_path, fru_size);
if (ret < 0) {
printf("Compare %s with %s failed!\n", file_path, eeprom_path);
syslog(LOG_ERR, "[%s] FRU:%d Write Fail", __func__, fru);
close(fd_newbin);
close(fd_tmpbin);
return -1;
}
}
ret = copy_file(fd_tmpbin, fd_newbin, fru_size);
if (ret < 0) {
printf("Write to %s file failed: %s\n", path, strerror(errno));
syslog(LOG_ERR, "copy: write to %s file failed: %s", path, strerror(errno));
}
close(fd_newbin);
close(fd_tmpbin);
return ret;
case FLAG_MODIFY:
file_path = argv[argc-1];
if (optind != 4) { //fail to get field "--XXX"
printf("Parameter \"%s\" is invalid!\n", argv[argc-3]);
printf("Fail to modify %s FRU\n", name);
return -1;
}
if(access(file_path, F_OK) == -1) { //copy current FRU bin file to specified bin file
fd_tmpbin = open(path, O_RDONLY);
if (fd_tmpbin == -1) {
syslog(LOG_ERR, "Unable to open the %s file: %s", path, strerror(errno));
return errno;
}
fd_newbin = open(file_path, O_WRONLY | O_CREAT, 0644);
if (fd_newbin == -1) {
syslog(LOG_ERR, "Unable to create %s file: %s", file_path, strerror(errno));
return errno;
}
ret = copy_file(fd_newbin, fd_tmpbin, FRUID_SIZE);
if (ret < 0) {
syslog(LOG_ERR, "copy: write to %s file failed: %s",
file_path, strerror(errno));
return ret;
}
close(fd_newbin);
close(fd_tmpbin);
} else {
memset(path, 0, sizeof(path));
sprintf(path, "%s", file_path);
}
ret = fruid_modify(path, file_path, argv[optind-2], argv[optind-1]);
if(ret < 0){
printf("Fail to modify %s FRU\n", name);
return ret;
}
ret = get_fruid_info(fru, file_path, name, DEFAULT_FORMAT,NULL);
return ret;
default:
return -1;
}
return 0;
}