int ty_firmware_new(const char *filename, ty_firmware **rfw) { assert(filename); assert(rfw); ty_firmware *fw; int r; fw = calloc(1, sizeof(ty_firmware)); if (!fw) { r = ty_error(TY_ERROR_MEMORY, NULL); goto error; } fw->refcount = 1; fw->filename = strdup(filename); if (!fw->filename) { r = ty_error(TY_ERROR_MEMORY, NULL); goto error; } if (!fw->name) { fw->name = strdup(get_basename(filename)); if (!fw->name) { r = ty_error(TY_ERROR_MEMORY, NULL); goto error; } } *rfw = fw; return 0; error: ty_firmware_unref(fw); return r; }
int ty_firmware_load(const char *filename, const char *format_name, ty_firmware **rfw) { assert(filename); assert(rfw); const ty_firmware_format *format; ty_firmware *fw = NULL; int r; if (format_name) { for (format = ty_firmware_formats; format->name; format++) { if (strcasecmp(format->name, format_name) == 0) break; } if (!format->name) { r = ty_error(TY_ERROR_UNSUPPORTED, "Firmware file format '%s' unknown", format_name); goto error; } } else { const char *ext = strrchr(filename, '.'); if (!ext) { r = ty_error(TY_ERROR_UNSUPPORTED, "Firmware '%s' has no file extension", filename); goto error; } for (format = ty_firmware_formats; format->name; format++) { if (strcmp(format->ext, ext) == 0) break; } if (!format->name) { r = ty_error(TY_ERROR_UNSUPPORTED, "Firmware '%s' uses unrecognized file format", filename); goto error; } } fw = malloc(sizeof(ty_firmware) + strlen(filename) + 1); if (!fw) { r = ty_error(TY_ERROR_MEMORY, NULL); goto error; } memset(fw, 0, sizeof(*fw)); fw->refcount = 1; strcpy(fw->filename, filename); r = (*format->load)(fw); if (r < 0) goto error; if (!fw->name) { fw->name = strdup(get_basename(filename)); if (!fw->name) { r = ty_error(TY_ERROR_MEMORY, NULL); goto error; } } *rfw = fw; return 0; error: ty_firmware_unref(fw); return r; }