/** * tnsp_content_display_flash: * @content: a FlashContent structure. * * Display fields of a FlashContent structure. * * Return value: an error code, 0 otherwise. **/ int tnsp_content_display_flash(FlashContent *content) { FlashContent *ptr = content; if (content == NULL) { tifiles_critical("%s(NULL)", __FUNCTION__); return ERR_INVALID_FILE; } tifiles_info("Signature: %s", tifiles_calctype2signature(ptr->model)); tifiles_info("Revision: %i.%i", ptr->revision_major, ptr->revision_minor); tifiles_info("Flags: %02X", ptr->flags); tifiles_info("Object type: %02X", ptr->object_type); tifiles_info("Date: %02X/%02X/%02X%02X", ptr->revision_day, ptr->revision_month, ptr->revision_year & 0xff, (ptr->revision_year & 0xff00) >> 8); tifiles_info("Name: %s", ptr->name); tifiles_info("Device type: %s", ptr->device_type == DEVICE_TYPE_89 ? "ti89" : "ti92+"); tifiles_info("Data type: OS data"); tifiles_info("Length: %08X (%i)", ptr->data_length, ptr->data_length); tifiles_info(""); return 0; }
/** * tnsp_file_read_regular: * @filename: name of file to open. * @content: where to store the file content. * * Load the file into a FileContent structure. * * Structure content must be freed with #tifiles_content_delete_regular when * no longer used. If error occurs, the structure content is released for you. * * Return value: an error code, 0 otherwise. **/ int tnsp_file_read_regular(const char *filename, FileContent *content) { FILE *f; if (!tifiles_file_is_regular(filename)) { return ERR_INVALID_FILE; } if (content == NULL) { tifiles_critical("%s: an argument is NULL", __FUNCTION__); return ERR_INVALID_FILE; } f = g_fopen(filename, "rb"); if (f == NULL) { tifiles_info( "Unable to open this file: %s", filename); return ERR_FILE_OPEN; } content->model = CALC_NSPIRE; content->model_dst = content->model; content->entries = g_malloc0((content->num_entries + 1) * sizeof(VarEntry*)); { VarEntry *entry = content->entries[0] = g_malloc0(sizeof(VarEntry)); gchar *basename = g_path_get_basename(filename); gchar *ext = tifiles_fext_get(basename); entry->type = tifiles_fext2vartype(content->model, ext); if(ext) *(ext-1) = '\0'; strcpy(entry->folder, ""); strcpy(entry->name, basename); g_free(basename); entry->attr = ATTRB_NONE; fseek(f, 0, SEEK_END); entry->size = (uint32_t)ftell(f); fseek(f, 0, SEEK_SET); entry->data = (uint8_t *)g_malloc0(entry->size); if(fread(entry->data, 1, entry->size, f) < entry->size) goto tffr; } content->num_entries++; fclose(f); return 0; tffr: // release on exit tifiles_critical("%s: error reading / understanding file %s", __FUNCTION__, filename); fclose(f); tifiles_content_delete_regular(content); return ERR_FILE_IO; }
/** * tnsp_file_display: * @filename: a TI file. * * Determine file class and display internal content. * * Return value: an error code, 0 otherwise. **/ int tnsp_file_display(const char *filename) { FileContent *content1; FlashContent *content3; // the testing order is important: regular before backup (due to TI89/92+) if (tifiles_file_is_os(filename)) { content3 = tifiles_content_create_flash(CALC_NSPIRE); tnsp_file_read_flash(filename, content3); tnsp_content_display_flash(content3); tifiles_content_delete_flash(content3); } else if (tifiles_file_is_regular(filename)) { content1 = tifiles_content_create_regular(CALC_TI92); tnsp_file_read_regular(filename, content1); tnsp_content_display_regular(content1); tifiles_content_delete_regular(content1); } else { tifiles_info("Unknown file type !"); return ERR_BAD_FILE; } return 0; }
/** * tifiles_hexdump: * @ptr: a pointer on some data to dump * @len: the number of bytes to dump * * Dump the content of a buffer into hexadecimal format. * Return value: always 0 **/ TIEXPORT2 int TICALL tifiles_hexdump(const uint8_t * ptr, unsigned int len) { char *str; if (ptr != NULL) { unsigned int i; unsigned int alloc_len = (len < 1024) ? len : 1024; str = (char *)g_malloc(3 * alloc_len + 14); for (i = 0; i < alloc_len; i++) { sprintf(&str[3 * i], "%02X ", ptr[i]); } if (alloc_len < len) { sprintf(&str[3 * alloc_len], "[...] (%u)", len); } else { sprintf(&str[3 * alloc_len], "(%u)", len); } tifiles_info("%s", str); g_free(str); } return 0; }
/** * tnsp_file_display: * @filename: a TI file. * * Determine file class and display internal content. * * Return value: an error code, 0 otherwise. **/ int tnsp_file_display(const char *filename) { FileContent *content1; FlashContent *content3; int ret; if (tifiles_file_is_os(filename)) { content3 = tifiles_content_create_flash(CALC_NSPIRE); ret = tnsp_file_read_flash(filename, content3); if (!ret) { tnsp_content_display_flash(content3); tifiles_content_delete_flash(content3); } } else if (tifiles_file_is_regular(filename)) { content1 = tifiles_content_create_regular(CALC_NSPIRE); ret = tnsp_file_read_regular(filename, content1); if (!ret) { tifiles_file_display_regular(content1); tifiles_content_delete_regular(content1); } } else { tifiles_info("Unknown file type !"); return ERR_BAD_FILE; } return ret; }
/** * tnsp_file_read_flash: * @filename: name of flash file to open. * @content: where to store the file content. * * Load the flash file into a #FlashContent structure. * * Structure content must be freed with #tifiles_content_delete_flash when * no longer used. If error occurs, the structure content is released for you. * * Return value: an error code, 0 otherwise. **/ int tnsp_file_read_flash(const char *filename, FlashContent *content) { FILE *f; int c; if (!tifiles_file_is_tno(filename)) return ERR_INVALID_FILE; if (content == NULL) { tifiles_critical("%s: an argument is NULL", __FUNCTION__); return ERR_INVALID_FILE; } f = g_fopen(filename, "rb"); if (f == NULL) { tifiles_info("Unable to open this file: %s\n", filename); return ERR_FILE_OPEN; } content->model = CALC_NSPIRE; for(c = 0; c != ' '; c=fgetc(f)); content->revision_major = fgetc(f); fgetc(f); content->revision_minor = fgetc(f); fgetc(f); for(c = 0; c != ' '; c=fgetc(f)); if (fscanf(f, "%i", &(content->data_length)) < 1) { goto tfrf; } rewind(f); content->data_part = (uint8_t *)g_malloc0(content->data_length); if (content->data_part == NULL) { fclose(f); tifiles_content_delete_flash(content); return ERR_MALLOC; } content->next = NULL; if(fread(content->data_part, 1, content->data_length, f) < content->data_length) goto tfrf; fclose(f); return 0; tfrf: // release on exit tifiles_critical("%s: error reading / understanding file %s", __FUNCTION__, filename); fclose(f); tifiles_content_delete_flash(content); return ERR_FILE_IO; }
/** * tifiles_library_init: * * This function must be the first one to call. It inits library internals. * * Return value: the handle count. **/ TIEXPORT2 int TICALL tifiles_library_init() { char locale_dir[65536]; #ifdef __WIN32__ HANDLE hDll; int i; hDll = GetModuleHandle("libtifiles2-9.dll"); GetModuleFileName(hDll, locale_dir, 65535); for (i = strlen(locale_dir); i >= 0; i--) { if (locale_dir[i] == '\\') { break; } } locale_dir[i] = '\0'; #ifdef __MINGW32__ strcat(locale_dir, "\\..\\share\\locale"); #else strcat(locale_dir, "\\locale"); #endif #else strcpy(locale_dir, LOCALEDIR); #endif if (tifiles_instance) return (++tifiles_instance); tifiles_info( _("tifiles library version %s"), LIBFILES_VERSION); #if defined(ENABLE_NLS) tifiles_info("setlocale: %s", setlocale(LC_ALL, "")); tifiles_info("bindtextdomain: %s", bindtextdomain(PACKAGE, locale_dir)); bind_textdomain_codeset(PACKAGE, "UTF-8"/*"ISO-8859-15"*/); tifiles_info("textdomain: %s", textdomain(NULL)); #endif return (++tifiles_instance); }
/** * tnsp_file_write_regular: * @filename: name of file where to write or NULL. * @content: the file content to write. * @real_filename: pointer address or NULL. Must be freed if needed when no longer needed. * * Write one variable into a single file. If filename is set to NULL, * the function build a filename from varname and allocates resulting filename in %real_fname. * %filename and %real_filename can be NULL but not both ! * * %real_filename must be freed when no longer used. * * Return value: an error code, 0 otherwise. **/ int tnsp_file_write_regular(const char *fname, FileContent *content, char **real_fname) { FILE *f; char *filename = NULL; VarEntry *entry; if (content->entries == NULL || content->entries[0] == NULL) { tifiles_warning("%s: skipping content with NULL content->entries or content->entries[0]", __FUNCTION__); return ERR_FILE_IO; } if (fname != NULL) { filename = g_strdup(fname); if (filename == NULL) { return ERR_MALLOC; } } else { filename = tifiles_build_filename(content->model_dst, content->entries[0]); if (real_fname != NULL) { *real_fname = g_strdup(filename); } } f = g_fopen(filename, "wb"); if (f == NULL) { tifiles_info( "Unable to open this file: %s", filename); g_free(filename); return ERR_FILE_OPEN; } entry = content->entries[0]; if(fwrite(entry->data, 1, entry->size, f) < entry->size) { goto tfwr; } g_free(filename); fclose(f); return 0; tfwr: // release on exit tifiles_critical("%s: error writing file %s", __FUNCTION__, filename); g_free(filename); fclose(f); return ERR_FILE_IO; }
/* Dump into hexadecimal format the content of a buffer - ptr [in]: a pointer on some data to dump - len [in]: the number of bytes to dump - [out]: always 0 */ int hexdump(uint8_t * ptr, int len) { char *str = (char *)g_malloc(3*len + 8); int i; for (i = 0; i < len; i++) sprintf(&str[3*i], "%02X ", ptr[i]); sprintf(&str[3*i], "(%i)", len); tifiles_info(str); g_free(str); return 0; }
/** * ti9x_content_display_backup: * @content: a Ti9xBackup structure. * * Display fields of a Ti9xBackup structure. * * Return value: an error code, 0 otherwise. **/ int ti9x_content_display_backup(Ti9xBackup *content) { if (content == NULL) { tifiles_critical("%s(NULL)", __FUNCTION__); return ERR_INVALID_FILE; } tifiles_info("BackupContent for TI-9x: %p", content); tifiles_info("Model: %02X (%u)", content->model, content->model); tifiles_info("Signature: %s", tifiles_calctype2signature(content->model)); tifiles_info("Comment: %s", content->comment); tifiles_info("ROM version: %s", content->rom_version); tifiles_info("Type: %02X (%s)", content->type, tifiles_vartype2string(content->model, content->type)); tifiles_info("data_length: %08X (%u)", content->data_length, content->data_length); tifiles_info("data_part: %p", content->data_part); tifiles_info("Checksum: %04X (%u)", content->checksum, content->checksum); return 0; }
/** * ti9x_file_display: * @filename: a TI file. * * Determine file class and display internal content. * * Return value: an error code, 0 otherwise. **/ int ti9x_file_display(const char *filename) { Ti9xRegular *content1; Ti9xBackup *content2; Ti9xFlash *content3; int ret; // the testing order is important: regular before backup (due to TI89/92+) if (tifiles_file_is_flash(filename) || tifiles_file_is_tib(filename)) { content3 = tifiles_content_create_flash(CALC_TI92); ret = ti9x_file_read_flash(filename, content3); if (!ret) { ti9x_content_display_flash(content3); tifiles_content_delete_flash(content3); } } else if (tifiles_file_is_regular(filename)) { content1 = tifiles_content_create_regular(CALC_TI92); ret = ti9x_file_read_regular(filename, content1); if (!ret) { tifiles_file_display_regular(content1); tifiles_content_delete_regular(content1); } } else if (tifiles_file_is_backup(filename)) { content2 = tifiles_content_create_backup(CALC_TI92); ret = ti9x_file_read_backup(filename, content2); if (!ret) { ti9x_content_display_backup(content2); tifiles_content_delete_backup(content2); } } else { tifiles_info("Unknown file type !"); return ERR_BAD_FILE; } return ret; }
/* Dump into hexadecimal format the content of a buffer - ptr [in]: a pointer on some data to dump - len [in]: the number of bytes to dump - [out]: always 0 */ int hexdump(uint8_t * ptr, int len) { char *str; if (ptr != NULL) { int i; str = (char *)g_malloc(3*len + 8); for (i = 0; i < len; i++) { sprintf(&str[3*i], "%02X ", ptr[i]); } sprintf(&str[3*i], "(%i)", len); tifiles_info(str); g_free(str); } return 0; }
/** * ti9x_file_write_backup: * @filename: name of backup file where to write. * @content: the file content to write. * * Write content to a backup file. * * Return value: an error code, 0 otherwise. **/ int ti9x_file_write_backup(const char *filename, Ti9xBackup *content) { FILE *f; if (filename == NULL || content == NULL) { tifiles_critical("%s: an argument is NULL", __FUNCTION__); return ERR_INVALID_FILE; } f = g_fopen(filename, "wb"); if (f == NULL) { tifiles_info("Unable to open this file: %s", filename); return ERR_FILE_OPEN; } if (fwrite_8_chars(f, tifiles_calctype2signature(content->model)) < 0) goto tfwb; if (fwrite(fsignature, 1, 2, f) < 2) goto tfwb; if (fwrite_8_chars(f, "") < 0) goto tfwb; if (fwrite_n_bytes(f, 40, (uint8_t *)content->comment) < 0) goto tfwb; if (fwrite_word(f, 1) < 0) goto tfwb; if (fwrite_long(f, 0x52) < 0) goto tfwb; if (fwrite_8_chars(f, content->rom_version) < 0) goto tfwb; if (fwrite_word(f, content->type) < 0) goto tfwb; if (fwrite_word(f, 0) < 0) goto tfwb; if (fwrite_long(f, content->data_length + 0x52 + 2) < 0) goto tfwb; if (fwrite_word(f, 0x5aa5) < 0) goto tfwb; if (fwrite(content->data_part, 1, content->data_length, f) < content->data_length) goto tfwb; content->checksum = tifiles_checksum(content->data_part, content->data_length); if (fwrite_word(f, content->checksum) < 0) goto tfwb; fclose(f); return 0; tfwb: // release on exit tifiles_critical("%s: error writing file %s", __FUNCTION__, filename); fclose(f); return ERR_FILE_IO; }
/** * ti9x_content_display_flash: * @content: a Ti9xFlash structure. * * Display fields of a Ti9xFlash structure. * * Return value: an error code, 0 otherwise. **/ int ti9x_content_display_flash(Ti9xFlash *content) { Ti9xFlash *ptr; for (ptr = content; ptr != NULL; ptr = ptr->next) { tifiles_info("FlashContent for TI-9x: %p", ptr); tifiles_info("Model: %02X (%u)", ptr->model, ptr->model); tifiles_info("Signature: %s", tifiles_calctype2signature(ptr->model)); tifiles_info("model_dst: %02X (%u)", ptr->model_dst, ptr->model_dst); tifiles_info("Revision: %u.%u", ptr->revision_major, ptr->revision_minor); tifiles_info("Flags: %02X", ptr->flags); tifiles_info("Object type: %02X", ptr->object_type); tifiles_info("Date: %02X/%02X/%02X%02X", ptr->revision_day, ptr->revision_month, ptr->revision_year & 0xff, (ptr->revision_year & 0xff00) >> 8); tifiles_info("Name: %s", ptr->name); tifiles_info("Device type: %s", ptr->device_type == DEVICE_TYPE_89 ? "ti89" : "ti92+"); switch (ptr->data_type) { case 0x23: tifiles_info("Data type: OS data"); break; case 0x24: tifiles_info("Data type: APP data"); break; case 0x20: case 0x25: tifiles_info("Data type: certificate"); break; case 0x3E: tifiles_info("Data type: license"); break; default: tifiles_info("Data type: Unknown (send mail to [email protected])"); break; } tifiles_info("Hardware ID: %02X (%u)", ptr->hw_id, ptr->hw_id); tifiles_info("Length: %08X (%u)", ptr->data_length, ptr->data_length); tifiles_info("Data part: %p", ptr->data_part); tifiles_info("Next: %p", ptr->next); } return 0; }
/** * ti9x_file_write_flash: * @filename: name of flash file where to write. * @content: the file content to write. * * Write content to a flash file (os or app). * * Return value: an error code, 0 otherwise. **/ int ti9x_file_write_flash(const char *fname, Ti9xFlash *head, char **real_fname) { FILE *f; Ti9xFlash *content = head; char *filename; if (head == NULL) { tifiles_critical("%s: head is NULL", __FUNCTION__); return ERR_INVALID_FILE; } if (fname) { filename = g_strdup(fname); if (filename == NULL) { return ERR_MALLOC; } } else { VarEntry ve; for (content = head; content != NULL; content = content->next) { if (content->data_type == TI89_AMS || content->data_type == TI89_APPL) { break; } } if (content == NULL) { tifiles_critical("%s: content is NULL", __FUNCTION__); return ERR_BAD_FILE; } strncpy(ve.name, content->name, sizeof(ve.name) - 1); ve.name[sizeof(ve.name) - 1] = 0; ve.type = content->data_type; filename = tifiles_build_filename(content->model, &ve); if (real_fname != NULL) { *real_fname = g_strdup(filename); } } f = g_fopen(filename, "wb"); if (f == NULL) { tifiles_info("Unable to open this file: %s", filename); g_free(filename); return ERR_FILE_OPEN; } for (content = head; content != NULL; content = content->next) { if (fwrite_8_chars(f, "**TIFL**") < 0) goto tfwf; if (fwrite_byte(f, content->revision_major) < 0) goto tfwf; if (fwrite_byte(f, content->revision_minor) < 0) goto tfwf; if (fwrite_byte(f, content->flags) < 0) goto tfwf; if (fwrite_byte(f, content->object_type) < 0) goto tfwf; if (fwrite_byte(f, content->revision_day) < 0) goto tfwf; if (fwrite_byte(f, content->revision_month) < 0) goto tfwf; if (fwrite_word(f, content->revision_year) < 0) goto tfwf; if (fwrite_byte(f, (uint8_t) strlen(content->name)) < 0) goto tfwf; if (fwrite_8_chars(f, content->name) < 0) goto tfwf; if (fwrite_n_chars(f, 23, "") < 0) goto tfwf; if (fwrite_byte(f, content->device_type) < 0) goto tfwf; if (fwrite_byte(f, content->data_type) < 0) goto tfwf; if (fwrite_n_chars(f, 23, "") < 0) goto tfwf; if (fwrite_byte(f, content->hw_id) < 0) goto tfwf; if (fwrite_long(f, content->data_length) < 0) goto tfwf; if (fwrite(content->data_part, 1, content->data_length, f) < content->data_length) goto tfwf; } g_free(filename); fclose(f); return 0; tfwf: // release on exit tifiles_critical("%s: error writing file %s", __FUNCTION__, filename); g_free(filename); fclose(f); return ERR_FILE_IO; }
/** * ti9x_file_write_regular: * @filename: name of single/group file where to write or NULL. * @content: the file content to write. * @real_filename: pointer address or NULL. Must be freed if needed when no longer needed. * * Write one (or several) variable(s) into a single (group) file. If filename is set to NULL, * the function build a filename from varname and allocates resulting filename in %real_fname. * %filename and %real_filename can be NULL but not both ! * * %real_filename must be freed when no longer used. * * Return value: an error code, 0 otherwise. **/ int ti9x_file_write_regular(const char *fname, Ti9xRegular *content, char **real_fname) { FILE *f; unsigned int i; char *filename = NULL; uint32_t offset = 0x52; int **table; unsigned int num_folders; char default_folder[FLDNAME_MAX]; char fldname[FLDNAME_MAX], varname[VARNAME_MAX]; if (content->entries == NULL) { tifiles_warning("%s: skipping content with NULL content->entries", __FUNCTION__); return 0; } if (fname != NULL) { filename = g_strdup(fname); if (filename == NULL) { return ERR_MALLOC; } } else { if (content->entries[0]) { filename = tifiles_build_filename(content->model_dst, content->entries[0]); } else { tifiles_warning("%s: asked to build a filename from null content->entries[0], bailing out", __FUNCTION__); if (real_fname != NULL) { *real_fname = NULL; } return 0; } if (real_fname != NULL) { *real_fname = g_strdup(filename); } } // build the table of folder & variable entries table = tifiles_create_table_of_entries((FileContent *)content, &num_folders); if (table == NULL) { g_free(filename); return ERR_MALLOC; } f = g_fopen(filename, "wb"); if (f == NULL) { tifiles_info( "Unable to open this file: %s", filename); tifiles_free_table_of_entries(table); g_free(filename); return ERR_FILE_OPEN; } // write header if (fwrite_8_chars(f, tifiles_calctype2signature(content->model)) < 0) goto tfwr; if (fwrite(fsignature, 1, 2, f) < 2) goto tfwr; if (content->num_entries == 1) // folder entry for single var is placed here { strncpy(content->default_folder, content->entries[0]->folder, sizeof(content->default_folder) - 1); content->default_folder[sizeof(content->default_folder) - 1] = 0; } ticonv_varname_to_tifile_sn(content->model, content->default_folder, default_folder, sizeof(default_folder), -1); if (fwrite_8_chars(f, default_folder) < 0) goto tfwr; if (fwrite_n_bytes(f, 40, (uint8_t *)content->comment) < 0) goto tfwr; if (content->num_entries > 1) { if (fwrite_word(f, (uint16_t) (content->num_entries + num_folders)) < 0) goto tfwr; offset += 16 * (content->num_entries + num_folders - 1); } else { if (fwrite_word(f, 1) < 0) goto tfwr; } // write table of entries for (i = 0; table[i] != NULL; i++) { VarEntry *fentry; int j, idx = table[i][0]; fentry = content->entries[idx]; if (fentry == NULL) { tifiles_warning("%s: skipping null content entry %d", __FUNCTION__, i); continue; } if (content->num_entries > 1) // single var does not have folder entry { if (fwrite_long(f, offset) < 0) goto tfwr; ticonv_varname_to_tifile_sn(content->model, fentry->folder, fldname, sizeof(fldname), -1); if (fwrite_8_chars(f, fldname) < 0) goto tfwr; if (fwrite_byte(f, (uint8_t)tifiles_folder_type(content->model)) < 0) goto tfwr; if (fwrite_byte(f, 0x00) < 0) goto tfwr; for (j = 0; table[i][j] != -1; j++); if (fwrite_word(f, (uint16_t) j) < 0) goto tfwr; } for (j = 0; table[i][j] != -1; j++) { int idx2 = table[i][j]; VarEntry *entry = content->entries[idx2]; uint8_t attr = ATTRB_NONE; if (fwrite_long(f, offset) < 0) goto tfwr; ticonv_varname_to_tifile_sn(content->model, entry->name, varname, sizeof(varname), entry->type); if (fwrite_8_chars(f, varname) < 0) goto tfwr; if (fwrite_byte(f, entry->type) < 0) goto tfwr; attr = (entry->attr == ATTRB_ARCHIVED) ? 3 : entry->attr; if (fwrite_byte(f, attr) < 0) goto tfwr; if (fwrite_word(f, 0) < 0) goto tfwr; offset += entry->size + 4 + 2; } } if (fwrite_long(f, offset) < 0) goto tfwr; if (fwrite_word(f, 0x5aa5) < 0) goto tfwr; // write data for (i = 0; table[i] != NULL; i++) { int j; for (j = 0; table[i][j] != -1; j++) { int idx = table[i][j]; VarEntry *entry = content->entries[idx]; uint16_t sum; if (fwrite_long(f, 0) < 0) goto tfwr; if (fwrite(entry->data, 1, entry->size, f) < entry->size) goto tfwr; sum = tifiles_checksum(entry->data, entry->size); if (fwrite_word(f, sum) < 0) goto tfwr; } } tifiles_free_table_of_entries(table); g_free(filename); fclose(f); return 0; tfwr: // release on exit tifiles_critical("%s: error writing file %s", __FUNCTION__, filename); tifiles_free_table_of_entries(table); g_free(filename); fclose(f); return ERR_FILE_IO; }
/** * ti9x_file_read_flash: * @filename: name of flash file to open. * @content: where to store the file content. * * Load the flash file into a #FlashContent structure. * * Structure content must be freed with #tifiles_content_delete_flash when * no longer used. If error occurs, the structure content is released for you. * * Return value: an error code, 0 otherwise. **/ int ti9x_file_read_flash(const char *filename, Ti9xFlash *head) { FILE *f; Ti9xFlash *content = head; long cur_pos = 0; int tib = 0; char signature[9]; int ret = ERR_FILE_IO; if (head == NULL) { tifiles_critical("%s: an argument is NULL", __FUNCTION__); return ERR_INVALID_FILE; } if (!tifiles_file_is_flash(filename) && !tifiles_file_is_tib(filename)) { ret = ERR_INVALID_FILE; goto tfrf2; } // detect file type (old or new format) tib = tifiles_file_is_tib(filename); f = g_fopen(filename, "rb"); if (f == NULL) { tifiles_info("Unable to open this file: %s", filename); ret = ERR_FILE_OPEN; goto tfrf2; } if (fseek(f, 0, SEEK_END)) goto tfrf; cur_pos = ftell(f); if (cur_pos < 0) goto tfrf; if (fseek(f, 0, SEEK_SET)) goto tfrf; // The TI-68k series' members have at best 4 MB of Flash. // TIB files larger than that size are insane. if (cur_pos >= (4L << 20)) { ret = ERR_INVALID_FILE; goto tfrf; } if (tib) { // tib is an old format but mainly used by developers memset(content, 0, sizeof(Ti9xFlash)); content->data_length = (uint32_t)cur_pos; strncpy(content->name, "basecode", sizeof(content->name) - 1); content->name[sizeof(content->name) - 1] = 0; content->data_type = 0x23; // FLASH os content->data_part = (uint8_t *)g_malloc0(content->data_length); if (content->data_part == NULL) { ret = ERR_MALLOC; goto tfrf; } if (fread(content->data_part, 1, content->data_length, f) < content->data_length) goto tfrf; switch(content->data_part[8]) { case 1: content->device_type = DEVICE_TYPE_92P; break; // TI92+ case 3: content->device_type = DEVICE_TYPE_89; break; // TI89 // value added by the TI community according to HWID parameter // doesn't have any 'legal' existence. case 8: content->device_type = DEVICE_TYPE_92P; break; // V200PLT case 9: content->device_type = DEVICE_TYPE_89; break; // Titanium } content->next = NULL; } else { for (content = head;; content = content->next) { if (fread_8_chars(f, signature) < 0) goto tfrf; content->model = tifiles_file_get_model(filename); if (fread_byte(f, &(content->revision_major)) < 0) goto tfrf; if (fread_byte(f, &(content->revision_minor)) < 0) goto tfrf; if (fread_byte(f, &(content->flags)) < 0) goto tfrf; if (fread_byte(f, &(content->object_type)) < 0) goto tfrf; if (fread_byte(f, &(content->revision_day)) < 0) goto tfrf; if (fread_byte(f, &(content->revision_month)) < 0) goto tfrf; if (fread_word(f, &(content->revision_year)) < 0) goto tfrf; if (fskip(f, 1) < 0) goto tfrf; if (fread_8_chars(f, content->name) < 0) goto tfrf; if (fskip(f, 23) < 0) goto tfrf; if (fread_byte(f, &(content->device_type)) < 0) goto tfrf; if (fread_byte(f, &(content->data_type)) < 0) goto tfrf; if (fskip(f, 23) < 0) goto tfrf; if (fread_byte(f, &(content->hw_id)) < 0) goto tfrf; if (fread_long(f, &(content->data_length)) < 0) goto tfrf; if (content->data_type != TI89_LICENSE && !check_device_type(content->device_type)) { ret = ERR_INVALID_FILE; goto tfrf; } if (!check_data_type(content->data_type)) { ret = ERR_INVALID_FILE; goto tfrf; } // TODO: modify this code if TI ever makes a TI-eZ80 model with more than 4 MB of Flash memory... if (content->data_length > 4U * 1024 * 1024 - 65536U) { // Data length larger than Flash memory size - boot code sector size doesn't look right. ret = ERR_INVALID_FILE; goto tfrf; } content->data_part = (uint8_t *)g_malloc0(content->data_length); if (content->data_part == NULL) { ret = ERR_MALLOC; goto tfrf; } if (fread(content->data_part, 1, content->data_length, f) < content->data_length) goto tfrf; if ( (content->data_type == TI83p_AMS && content->data_part[0] != 0x80) || (content->data_type == TI83p_APPL && content->data_part[0] != 0x81)) { ret = ERR_INVALID_FILE; goto tfrf; } content->next = NULL; // check for end of file if (fread_8_chars(f, signature) < 0) { break; } if (strcmp(signature, "**TIFL**") || feof(f)) { break; } if (fseek(f, -8, SEEK_CUR)) goto tfrf; content->next = (Ti9xFlash *)g_malloc0(sizeof(Ti9xFlash)); if (content->next == NULL) { ret = ERR_MALLOC; goto tfrf; } } } fclose(f); return 0; tfrf: // release on exit tifiles_critical("%s: error reading / understanding file %s", __FUNCTION__, filename); fclose(f); tfrf2: tifiles_content_delete_flash(content); return ret; }
/** * ti9x_file_read_backup: * @filename: name of backup file to open. * @content: where to store the file content. * * Load the backup file into a Ti9xBackup structure. * * Structure content must be freed with #tifiles_content_delete_backup when * no longer used. If error occurs, the structure content is released for you. * * Return value: an error code, 0 otherwise. **/ int ti9x_file_read_backup(const char *filename, Ti9xBackup *content) { FILE *f; long cur_pos = 0; uint32_t file_size; char signature[9]; uint16_t sum; int ret = ERR_FILE_IO; if (content == NULL) { tifiles_critical("%s: an argument is NULL", __FUNCTION__); return ERR_INVALID_FILE; } if (!tifiles_file_is_backup(filename)) { ret = ERR_INVALID_FILE; goto tfrb2; } f = g_fopen(filename, "rb"); if (f == NULL) { tifiles_info( "Unable to open this file: %s", filename); ret = ERR_FILE_OPEN; goto tfrb2; } // Get file size, then rewind. if (fseek(f, 0, SEEK_END) < 0) goto tfrb; cur_pos = ftell(f); if (cur_pos < 0) goto tfrb; if (fseek(f, 0, SEEK_SET) < 0) goto tfrb; // The TI-68k series' members have at best 4 MB of Flash (TODO: modify this code if this no longer holds). // Backup files larger than that size are highly dubious, files larger than twice that size are insane. if (cur_pos >= (8L << 20)) { ret = ERR_INVALID_FILE; goto tfrb; } if (fread_8_chars(f, signature) < 0) goto tfrb; content->model = tifiles_signature2calctype(signature); if (content->model == CALC_NONE) { ret = ERR_INVALID_FILE; } if (fread_word(f, NULL) < 0) goto tfrb; if (fread_8_chars(f, NULL) < 0) goto tfrb; if (fread_n_chars(f, 40, content->comment) < 0) goto tfrb; if (fread_word(f, NULL) < 0) goto tfrb; if (fread_long(f, NULL) < 0) goto tfrb; if (fread_8_chars(f, content->rom_version) < 0) goto tfrb; if (fread_byte(f, &(content->type)) < 0) goto tfrb; if (fread_byte(f, NULL) < 0) goto tfrb; if (fread_word(f, NULL) < 0) goto tfrb; if (fread_long(f, &file_size) < 0) goto tfrb; if (file_size > (uint32_t)cur_pos) { ret = ERR_INVALID_FILE; goto tfrb; } content->data_length = file_size - 0x52 - 2; if (fread_word(f, NULL) < 0) goto tfrb; content->data_part = (uint8_t *)g_malloc0(content->data_length); if (content->data_part == NULL) { ret = ERR_MALLOC; goto tfrb; } if (fread(content->data_part, 1, content->data_length, f) < content->data_length) goto tfrb; if (fread_word(f, &(content->checksum)) < 0) goto tfrb; sum = tifiles_checksum(content->data_part, content->data_length); #if defined(CHECKSUM_ENABLED) if (sum != content->checksum) { ret = ERR_FILE_CHECKSUM; goto tfrb; } #endif fclose(f); return 0; tfrb: // release on exit tifiles_critical("%s: error reading / understanding file %s", __FUNCTION__, filename); fclose(f); tfrb2: tifiles_content_delete_backup(content); return ret; }
/** * ti9x_file_read_backup: * @filename: name of backup file to open. * @content: where to store the file content. * * Load the backup file into a Ti9xBackup structure. * * Structure content must be freed with #tifiles_content_delete_backup when * no longer used. If error occurs, the structure content is released for you. * * Return value: an error code, 0 otherwise. **/ int ti9x_file_read_backup(const char *filename, Ti9xBackup *content) { FILE *f; uint32_t file_size; char signature[9]; uint16_t sum; if (!tifiles_file_is_backup(filename)) { return ERR_INVALID_FILE; } f = g_fopen(filename, "rb"); if (f == NULL) { tifiles_info( "Unable to open this file: %s", filename); return ERR_FILE_OPEN; } if (content == NULL) { tifiles_critical("%s: an argument is NULL", __FUNCTION__); return ERR_INVALID_FILE; } if(fread_8_chars(f, signature) < 0) goto tfrb; content->model = tifiles_signature2calctype(signature); if (content->model == CALC_NONE) { return ERR_INVALID_FILE; } if(fread_word(f, NULL) < 0) goto tfrb; if(fread_8_chars(f, NULL) < 0) goto tfrb; if(fread_n_chars(f, 40, content->comment) < 0) goto tfrb; if(fread_word(f, NULL) < 0) goto tfrb; if(fread_long(f, NULL) < 0) goto tfrb; if(fread_8_chars(f, content->rom_version) < 0) goto tfrb; if(fread_byte(f, &(content->type)) < 0) goto tfrb; if(fread_byte(f, NULL) < 0) goto tfrb; if(fread_word(f, NULL) < 0) goto tfrb; if(fread_long(f, &file_size) < 0) goto tfrb; content->data_length = file_size - 0x52 - 2; if(fread_word(f, NULL) < 0) goto tfrb; content->data_part = (uint8_t *)g_malloc0(content->data_length); if (content->data_part == NULL) { fclose(f); tifiles_content_delete_backup(content); return ERR_MALLOC; } if(fread(content->data_part, 1, content->data_length, f) < content->data_length) goto tfrb; if(fread_word(f, &(content->checksum)) < 0) goto tfrb; sum = tifiles_checksum(content->data_part, content->data_length); #if defined(CHECKSUM_ENABLED) if(sum != content->checksum) { fclose(f); tifiles_content_delete_backup(content); return ERR_FILE_CHECKSUM; } #endif fclose(f); return 0; tfrb: // release on exit tifiles_critical("%s: error reading / understanding file %s", __FUNCTION__, filename); fclose(f); tifiles_content_delete_backup(content); return ERR_FILE_IO; }
/** * tnsp_file_read_regular: * @filename: name of file to open. * @content: where to store the file content. * * Load the file into a FileContent structure. * * Structure content must be freed with #tifiles_content_delete_regular when * no longer used. If error occurs, the structure content is released for you. * * Return value: an error code, 0 otherwise. **/ int tnsp_file_read_regular(const char *filename, FileContent *content) { FILE *f; int ret = ERR_FILE_IO; if (content == NULL) { tifiles_critical("%s: an argument is NULL", __FUNCTION__); return ERR_INVALID_FILE; } if (!tifiles_file_is_regular(filename)) { ret = ERR_INVALID_FILE; goto tfrr2; } f = g_fopen(filename, "rb"); if (f == NULL) { tifiles_info( "Unable to open this file: %s", filename); ret = ERR_FILE_OPEN; goto tfrr2; } content->model = CALC_NSPIRE; content->model_dst = content->model; content->entries = g_malloc0((content->num_entries + 1) * sizeof(VarEntry*)); { long cur_pos; VarEntry *entry = content->entries[0] = g_malloc0(sizeof(VarEntry)); gchar *basename = g_path_get_basename(filename); gchar *ext = tifiles_fext_get(basename); entry->type = tifiles_fext2vartype(content->model, ext); if (ext && ext[0]) *(ext-1) = '\0'; entry->folder[0] = 0; strncpy(entry->name, basename, sizeof(entry->name) - 1); entry->name[sizeof(entry->name) - 1] = 0; g_free(basename); entry->attr = ATTRB_NONE; if (fseek(f, 0, SEEK_END) < 0) goto tfrr; cur_pos = ftell(f); if (cur_pos < 0) goto tfrr; if (fseek(f, 0, SEEK_SET) < 0) goto tfrr; // The Nspire series' members have at best 128 MB of Flash (TODO: modify this code if this no longer holds). // Regular files larger than that size are insane. if (cur_pos >= (128L << 20)) { ret = ERR_INVALID_FILE; goto tfrr; } entry->size = (uint32_t)cur_pos; entry->data = (uint8_t *)g_malloc0(entry->size); if(fread(entry->data, 1, entry->size, f) < entry->size) goto tfrr; } content->num_entries++; fclose(f); return 0; tfrr: // release on exit tifiles_critical("%s: error reading / understanding file %s", __FUNCTION__, filename); fclose(f); tfrr2: tifiles_content_delete_regular(content); return ret; }
/** * tnsp_content_display_flash: * @content: a FlashContent structure. * * Display fields of a FlashContent structure. * * Return value: an error code, 0 otherwise. **/ int tnsp_content_display_flash(FlashContent *content) { FlashContent *ptr = content; if (content == NULL) { tifiles_critical("%s(NULL)", __FUNCTION__); return ERR_INVALID_FILE; } for (ptr = content; ptr != NULL; ptr = ptr->next) { tifiles_info("FlashContent for TI-Nspire: %p", ptr); tifiles_info("Model: %02X (%u)", ptr->model, ptr->model); tifiles_info("Signature: %s", tifiles_calctype2signature(ptr->model)); tifiles_info("model_dst: %02X (%u)", ptr->model_dst, ptr->model_dst); tifiles_info("Revision: %u.%u", ptr->revision_major, ptr->revision_minor); tifiles_info("Flags: %02X", ptr->flags); tifiles_info("Object type: %02X", ptr->object_type); tifiles_info("Date: %02X/%02X/%02X%02X", ptr->revision_day, ptr->revision_month, ptr->revision_year & 0xff, (ptr->revision_year & 0xff00) >> 8); tifiles_info("Name: %s", ptr->name); tifiles_info("Data type: OS data"); tifiles_info("Length: %08X (%i)", ptr->data_length, ptr->data_length); tifiles_info("Data part: %p", ptr->data_part); tifiles_info("Next: %p", ptr->next); } return 0; }
/** * ti9x_file_read_flash: * @filename: name of flash file to open. * @content: where to store the file content. * * Load the flash file into a #FlashContent structure. * * Structure content must be freed with #tifiles_content_delete_flash when * no longer used. If error occurs, the structure content is released for you. * * Return value: an error code, 0 otherwise. **/ int ti9x_file_read_flash(const char *filename, Ti9xFlash *head) { FILE *f; Ti9xFlash *content = head; int tib = 0; char signature[9]; if (!tifiles_file_is_flash(filename) && !tifiles_file_is_tib(filename)) { return ERR_INVALID_FILE; } if (head == NULL) { tifiles_critical("%s: an argument is NULL", __FUNCTION__); return ERR_INVALID_FILE; } // detect file type (old or new format) tib = tifiles_file_is_tib(filename); f = g_fopen(filename, "rb"); if (f == NULL) { tifiles_info("Unable to open this file: %s\n", filename); return ERR_FILE_OPEN; } if (tib) { // tib is an old format but mainly used by developers memset(content, 0, sizeof(Ti9xFlash)); if(fseek(f, 0, SEEK_END)) goto tfrf; content->data_length = (uint32_t) ftell(f); if(fseek(f, 0, SEEK_SET)) goto tfrf; strcpy(content->name, "basecode"); content->data_type = 0x23; // FLASH os content->data_part = (uint8_t *)g_malloc0(content->data_length); if (content->data_part == NULL) { fclose(f); return ERR_MALLOC; } if(fread(content->data_part, 1, content->data_length, f) < content->data_length) goto tfrf; switch(content->data_part[8]) { case 1: content->device_type = DEVICE_TYPE_92P; break; // TI92+ case 3: content->device_type = DEVICE_TYPE_89; break; // TI89 // value added by the TI community according to HWID parameter // doesn't have any 'legal' existence. case 8: content->device_type = DEVICE_TYPE_92P; break; // V200PLT case 9: content->device_type = DEVICE_TYPE_89; break; // Titanium } content->next = NULL; } else { for (content = head;; content = content->next) { if(fread_8_chars(f, signature) < 0) goto tfrf; content->model = tifiles_file_get_model(filename); if(fread_byte(f, &(content->revision_major)) < 0) goto tfrf; if(fread_byte(f, &(content->revision_minor)) < 0) goto tfrf; if(fread_byte(f, &(content->flags)) < 0) goto tfrf; if(fread_byte(f, &(content->object_type)) < 0) goto tfrf; if(fread_byte(f, &(content->revision_day)) < 0) goto tfrf; if(fread_byte(f, &(content->revision_month)) < 0) goto tfrf; if(fread_word(f, &(content->revision_year)) < 0) goto tfrf; if(fskip(f, 1) < 0) goto tfrf; if(fread_8_chars(f, content->name) < 0) goto tfrf; if(fskip(f, 23) < 0) goto tfrf; if(fread_byte(f, &(content->device_type)) < 0) goto tfrf; if(fread_byte(f, &(content->data_type)) < 0) goto tfrf; if(fskip(f, 23) < 0) goto tfrf; if(fread_byte(f, &(content->hw_id)) < 0) goto tfrf; if(fread_long(f, &(content->data_length)) < 0) goto tfrf; if(content->data_type != TI89_LICENSE && !check_device_type(content->device_type)) { return ERR_INVALID_FILE; } if(!check_data_type(content->data_type)) { return ERR_INVALID_FILE; } content->data_part = (uint8_t *)g_malloc0(content->data_length); if (content->data_part == NULL) { fclose(f); tifiles_content_delete_flash(content); return ERR_MALLOC; } if(fread(content->data_part, 1, content->data_length, f) < content->data_length) goto tfrf; content->next = NULL; // check for end of file if(fread_8_chars(f, signature) < 0) { break; } if(strcmp(signature, "**TIFL**") || feof(f)) { break; } if(fseek(f, -8, SEEK_CUR)) goto tfrf; content->next = (Ti9xFlash *)g_malloc0(sizeof(Ti9xFlash)); if (content->next == NULL) { fclose(f); tifiles_content_delete_flash(content); return ERR_MALLOC; } } } fclose(f); return 0; tfrf: // release on exit tifiles_critical("%s: error reading / understanding file %s", __FUNCTION__, filename); fclose(f); tifiles_content_delete_flash(content); return ERR_FILE_IO; }
/** * tnsp_file_read_flash: * @filename: name of flash file to open. * @content: where to store the file content. * * Load the flash file into a #FlashContent structure. * * Structure content must be freed with #tifiles_content_delete_flash when * no longer used. If error occurs, the structure content is released for you. * * Return value: an error code, 0 otherwise. **/ int tnsp_file_read_flash(const char *filename, FlashContent *content) { FILE *f; int c; long cur_pos; uint32_t file_size; int ret = ERR_FILE_IO; if (content == NULL) { tifiles_critical("%s: an argument is NULL", __FUNCTION__); return ERR_INVALID_FILE; } if (!tifiles_file_is_tno(filename)) { ret = ERR_INVALID_FILE; goto tfrf2; } f = g_fopen(filename, "rb"); if (f == NULL) { tifiles_info("Unable to open this file: %s", filename); ret = ERR_FILE_OPEN; goto tfrf2; } if (fseek(f, 0, SEEK_END) < 0) goto tfrf; cur_pos = ftell(f); if (cur_pos < 0) goto tfrf; if (fseek(f, 0, SEEK_SET) < 0) goto tfrf; // The Nspire series' members have at best 128 MB of Flash (TODO: modify this code if this no longer holds). // Flash files larger than that size are insane. if (cur_pos >= (128L << 20)) { ret = ERR_INVALID_FILE; goto tfrf; } file_size = (uint32_t)cur_pos; content->model = CALC_NSPIRE; // Skip chars. c = 0; while (c != ' ') { c = fgetc(f); if (c == EOF) { goto tfrf; } } // Read revision major. c = fgetc(f); if (c == EOF) { goto tfrf; } content->revision_major = c; // Skip char. c = fgetc(f); if (c == EOF) { goto tfrf; } // Read revision minor. c = fgetc(f); if (c == EOF) { goto tfrf; } content->revision_minor = c; // Skip chars. c = fgetc(f); if (c == EOF) { goto tfrf; } c = 0; while (c != ' ') { c = fgetc(f); if (c == EOF) { goto tfrf; } } if (fscanf(f, "%i", &(content->data_length)) < 1) { goto tfrf; } if (content->data_length > file_size) { ret = ERR_INVALID_FILE; goto tfrf; } if (fseek(f, 0, SEEK_SET) < 0) goto tfrf; content->data_part = (uint8_t *)g_malloc0(content->data_length); if (content->data_part == NULL) { fclose(f); tifiles_content_delete_flash(content); return ERR_MALLOC; } content->next = NULL; if(fread(content->data_part, 1, content->data_length, f) < content->data_length) goto tfrf; fclose(f); return 0; tfrf: // release on exit tifiles_critical("%s: error reading / understanding file %s", __FUNCTION__, filename); fclose(f); tfrf2: tifiles_content_delete_flash(content); return ret; }
/** * ti9x_file_read_regular: * @filename: name of single/group file to open. * @content: where to store the file content. * * Load the single/group file into a Ti9xRegular structure. * * Structure content must be freed with #tifiles_content_delete_regular when * no longer used. If error occurs, the structure content is released for you. * * Return value: an error code, 0 otherwise. **/ int ti9x_file_read_regular(const char *filename, Ti9xRegular *content) { FILE *f; long cur_pos = 0; char default_folder[FLDNAME_MAX]; char current_folder[FLDNAME_MAX]; uint32_t curr_offset = 0; uint32_t next_offset = 0; uint16_t tmp; int i, j; char signature[9]; char varname[VARNAME_MAX]; if (!tifiles_file_is_regular(filename)) { return ERR_INVALID_FILE; } if (content == NULL) { tifiles_critical("%s: an argument is NULL", __FUNCTION__); return ERR_INVALID_FILE; } f = g_fopen(filename, "rb"); if (f == NULL) { tifiles_info( "Unable to open this file: %s", filename); return ERR_FILE_OPEN; } if(fread_8_chars(f, signature) < 0) goto tffr; content->model = tifiles_signature2calctype(signature); if (content->model == CALC_NONE) { return ERR_INVALID_FILE; } if(content->model_dst == CALC_NONE) { content->model_dst = content->model; } if(fread_word(f, NULL) < 0) goto tffr; if(fread_8_chars(f, default_folder) < 0) goto tffr; ticonv_varname_from_tifile_s(content->model_dst, default_folder, content->default_folder, -1); strcpy(current_folder, content->default_folder); if(fread_n_chars(f, 40, content->comment) < 0) goto tffr; if(fread_word(f, &tmp) < 0) goto tffr; content->num_entries = tmp; content->entries = g_malloc0((content->num_entries + 1) * sizeof(VarEntry*)); if (content->entries == NULL) { fclose(f); return ERR_MALLOC; } for (i = 0, j = 0; i < content->num_entries; i++) { VarEntry *entry = content->entries[j] = g_malloc0(sizeof(VarEntry)); if(fread_long(f, &curr_offset) < 0) goto tffr; if(fread_8_chars(f, varname) < 0) goto tffr; ticonv_varname_from_tifile_s(content->model_dst, varname, entry->name, entry->type); if(fread_byte(f, &(entry->type)) < 0) goto tffr; if(fread_byte(f, &(entry->attr)) < 0) goto tffr; entry->attr = (entry->attr == 2 || entry->attr == 3) ? ATTRB_ARCHIVED : entry->attr; if(fread_word(f, NULL) < 0) goto tffr; if (entry->type == TI92_DIR) // same as TI89_DIR, TI89t_DIR, ... { strcpy(current_folder, entry->name); g_free(entry); continue; // folder: skip entry } else { uint16_t checksum, sum = 0; j++; strcpy(entry->folder, current_folder); cur_pos = ftell(f); if(cur_pos == -1L) goto tffr; if(fread_long(f, &next_offset) < 0) goto tffr; entry->size = next_offset - curr_offset - 4 - 2; entry->data = (uint8_t *)g_malloc0(entry->size); if (entry->data == NULL) { fclose(f); tifiles_content_delete_regular(content); return ERR_MALLOC; } if(fseek(f, curr_offset, SEEK_SET)) goto tffr; if(fread_long(f, NULL) < 0) goto tffr; // 4 bytes (NULL) if(fread(entry->data, 1, entry->size, f) < entry->size) goto tffr; if(fread_word(f, &checksum) < 0) goto tffr; if(fseek(f, cur_pos, SEEK_SET)) goto tffr; sum = tifiles_checksum(entry->data, entry->size); if(sum != checksum) { fclose(f); tifiles_content_delete_regular(content); return ERR_FILE_CHECKSUM; } content->checksum += sum; // sum of all checksums but unused } } content->num_entries = j; content->entries = g_realloc(content->entries, content->num_entries * sizeof(VarEntry*)); //fread_long(f, &next_offset); //fseek(f, next_offset - 2, SEEK_SET); //fread_word(f, &(content->checksum)); fclose(f); return 0; tffr: // release on exit tifiles_critical("%s: error reading / understanding file %s", __FUNCTION__, filename); fclose(f); tifiles_content_delete_regular(content); return ERR_FILE_IO; }
/** * tnsp_content_display_regular: * @content: a FileContent structure. * * Display fields of a FileContent structure. * * Return value: an error code, 0 otherwise. **/ int tnsp_content_display_regular(FileContent *content) { int i; char trans[17]; if (content == NULL) { tifiles_critical("%s(NULL)", __FUNCTION__); return ERR_INVALID_FILE; } tifiles_info("Signature: %s", tifiles_calctype2signature(content->model)); tifiles_info("Comment: %s", content->comment); tifiles_info("Default folder: %s", content->default_folder); tifiles_info("Number of entries: %i", content->num_entries); for (i = 0; i < content->num_entries /*&& i<5 */ ; i++) { tifiles_info("Entry #%i", i); tifiles_info(" folder: %s", content->entries[i]->folder); tifiles_info(" name: %s", ticonv_varname_to_utf8_s(content->model, content->entries[i]->name, trans, content->entries[i]->type)); tifiles_info(" type: %02X (%s)", content->entries[i]->type, tifiles_vartype2string(content->model, content->entries[i]->type)); tifiles_info(" attr: %s", tifiles_attribute_to_string(content->entries[i]->attr)); tifiles_info(" length: %04X (%i)", content->entries[i]->size, content->entries[i]->size); } tifiles_info("Checksum: %04X (%i) ", content->checksum, content->checksum); return 0; }