コード例 #1
0
ファイル: grouped.c プロジェクト: TI8XEmulator/graph89
/**
 * tifiles_ungroup_file:
 * @src_filename: full path of file to ungroup.
 * @dst_filenames: NULL or the address of a pointer where to store a NULL-terminated 
 * array of strings which contain the list of ungrouped files.
 *
 * Ungroup a TI 'group' file into several files. Resulting files have the
 * same name as the variable stored within group file.
 * Beware: there is no existence check; files may be overwritten !
 *
 * %dst_filenames must be freed when no longer used.
 *
 * Return value: an error code if unsuccessful, 0 otherwise.
 **/
TIEXPORT2 int TICALL tifiles_ungroup_file(const char *src_filename, char ***dst_filenames)
{
	FileContent *src = NULL;
	FileContent **ptr, **dst = NULL;
	char *real_name, **p;
	int i, n;
	int ret;

	if (src_filename == NULL)
	{
		tifiles_critical("%s: an argument is NULL", __FUNCTION__);
		return ERR_INVALID_FILE;
	}

	if(tifiles_file_get_model(src_filename) == CALC_NSPIRE)
		return ERR_BAD_CALC;

	// read group file
	src = tifiles_content_create_regular(CALC_NONE);
	ret = tifiles_file_read_regular(src_filename, src);
	if(ret) goto tuf;

	// ungroup structure
	ret = tifiles_ungroup_content(src, &dst);
	if(ret) goto tuf;

	// count number of structures and allocates array of strings
	for(ptr = dst, n = 0; *ptr != NULL; ptr++, n++);
	if(dst_filenames != NULL)
		*dst_filenames = (char **)g_malloc((n + 1) * sizeof(char *));

	// store each structure content to file
	for (ptr = dst, i = 0; *ptr != NULL; ptr++, i++)
	{
		ret = tifiles_file_write_regular(NULL, *ptr, &real_name);
		if(ret) goto tuf;

		if(dst_filenames != NULL)
			*dst_filenames[i] = real_name;
		else
			g_free(real_name);
	}

	// release allocated memory
	tifiles_content_delete_regular(src);
	tifiles_content_delete_group(dst);

	return 0;

tuf:
	if(dst_filenames != NULL)
	{
		for(p = *dst_filenames; *p; p++)
			g_free(*p);
		g_free(p);
	}
	tifiles_content_delete_regular(src);
	tifiles_content_delete_group(dst);
	return ret;
}
コード例 #2
0
ファイル: grouped.c プロジェクト: TI8XEmulator/graph89
/**
 * tifiles_group_del_file:
 * @src_filename: the file to remove from group file
 * @dst_filename: the group file
 *
 * Search for entry and remove it from file.
 *
 * Return value: 0 if successful, an error code otherwise.
 **/
TIEXPORT2 int TICALL tifiles_group_del_file(VarEntry *entry, const char *dst_filename)
{
	CalcModel dst_model;
	FileContent* dst_content = NULL;
	int ret = 0;

	if (entry == NULL || dst_filename == NULL)
	{
		tifiles_critical("%s: an argument is NULL", __FUNCTION__);
		return ERR_INVALID_FILE;
	}

	// src can be single/group file and dst must be group file
	if(!tifiles_file_is_group(dst_filename))
		return -1;

	dst_model = tifiles_file_get_model(dst_filename);
	dst_content = tifiles_content_create_regular(dst_model);
	ret = tifiles_file_read_regular(dst_filename, dst_content);
	if(ret) goto tgdf;

	tifiles_content_del_entry(dst_content, entry);
	tifiles_file_display_regular(dst_content);

	ret = tifiles_file_write_regular(dst_filename, dst_content, NULL);
	if(ret) goto tgdf;

tgdf:
	tifiles_content_delete_regular(dst_content);
	return ret;
}
コード例 #3
0
ファイル: filesnsp.c プロジェクト: TC01/tilibs
/**
 * 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;
}
コード例 #4
0
ファイル: tilp_slct.c プロジェクト: debrouxl/tilp_and_gfm
void tilp_local_contents_unload(void)
{
	GList *ptr;

	if (local.selection1 != NULL)
	{
		for(ptr = local.selection1; ptr; ptr = ptr->next)
		{
			FileEntry *fe = ptr->data;

			if(fe->content1)
				tifiles_content_delete_regular(fe->content1);
		}
	}

	if (local.selection3 != NULL)
	{
		for(ptr = local.selection3; ptr; ptr = ptr->next)
		{
			FileEntry *fe = ptr->data;

			if(fe->content2)
				tifiles_content_delete_flash(fe->content2);
		}
	}
}
コード例 #5
0
ファイル: test_tifiles_2.c プロジェクト: TC01/tilibs
static int test_tixx_regular_support_group(const char * message,
                                            CalcModel calculator,
                                            const char * input_group,
                                            const char * output_group)
{
	FileContent *content;
	char *unused = NULL;
	int ret = -1;

	printf("%s", message);
	tifiles_file_display(PATH(input_group));

	content = tifiles_content_create_regular(calculator);
	if (content != NULL)
	{
		ret = tifiles_file_read_regular(PATH(input_group), content);
		if (!ret)
		{
			ret = tifiles_file_write_regular(PATH(output_group), content, &unused);
			if (!ret)
			{
				compare_files(PATH(input_group), PATH2(output_group));
			}
			tifiles_filename_free(unused);
			tifiles_content_delete_regular(content);
		}
	}

	return ret;
}
コード例 #6
0
ファイル: filesnsp.c プロジェクト: TI8XEmulator/graph89
/**
 * 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;
}
コード例 #7
0
void fs_send_file_and_debug_info(const gchar *filename)
{
    const gchar *ext;
    FileContent *metadata;

    fs_send_file(filename);

    ext = strrchr(filename, '.');
    if (ext)
    {
        gchar *temp;
        *(char *)ext = 0;
        temp = g_strconcat(filename, ".dbg", NULL);
#ifdef WIN32
        symfile = g_locale_from_utf8(temp,-1,NULL,NULL,NULL);
        g_free(temp);
#else
        symfile = temp;
#endif
        *(char *)ext = '.';
    }

    metadata = tifiles_content_create_regular(CALC_TI89);
    if (!tifiles_file_read_regular(filename, metadata))
    {
        if (metadata->num_entries > 0)
        {
            int handle = sym_find_handle (metadata->entries[0]->folder, metadata->entries[0]->name);
            if (handle)
                ti68k_bkpt_add_pgmentry (handle);
        }
    }
    tifiles_content_delete_regular(metadata);
}
コード例 #8
0
ファイル: filesnsp.c プロジェクト: debrouxl/tilp-libtifiles
/**
 * 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;
}
コード例 #9
0
ファイル: gui.c プロジェクト: uyjulian/tilp_and_gfm
GLADE_CB void
on_add_clicked                         (GtkToolButton   *toolbutton,
                                        gpointer         user_data)
{
	char **array, **ptr;
	CalcModel model;
	FileContent *content;
	int ret;
	unsigned int i;

	array = create_fsels(inst_paths.home_dir, "", "*.*");
	if(array == NULL)
		return;

	for(ptr = array; *ptr; ptr++)
	{
		char *fn = *ptr;

		if(tifiles_file_is_tigroup(fn))
		{
			msgbox_one(MSGBOX_ERROR, _("Importing of TiGroup files is not allowed."));
			return;
		}

		model = tifiles_file_get_model(fn);
		if(!tifiles_calc_are_compat(GFMFile.model, model))
		{
			msgbox_one(MSGBOX_ERROR, _("File is not compatible with current target."));
			return;
		}

		content = tifiles_content_create_regular(model);
		ret = tifiles_file_read_regular(fn, content);

		for(i = 0; i < content->num_entries; i++)
		{
			VarEntry *ve = content->entries[i];

			if(ticalcs_dirlist_ve_exist(GFMFile.trees.vars, ve))
			{
				msgbox_one(MSGBOX_ERROR, _("The entry already exists. Skipped!"));
				continue;
			}

			ticalcs_dirlist_ve_add(GFMFile.trees.vars, ve);
		}

		ret = tifiles_content_delete_regular(content);
	}

	enable_save(TRUE);
	enable_tree(TRUE);

	ctree_refresh();
	labels_refresh();
}
コード例 #10
0
ファイル: grouped.c プロジェクト: TI8XEmulator/graph89
/**
 * tifiles_group_add_file:
 * @src_filename: the file to add to group file
 * @dst_filename: the group file
 *
 * Add src_filename content to dst_filename content and write to dst_filename.
 *
 * Return value: 0 if successful, an error code otherwise.
 **/
TIEXPORT2 int TICALL tifiles_group_add_file(const char *src_filename, const char *dst_filename)
{
	CalcModel src_model;
	CalcModel dst_model;
	FileContent* src_content = NULL;
	FileContent* dst_content = NULL;
	int i;
	int ret = 0;

	if (src_filename == NULL || dst_filename == NULL)
	{
		tifiles_critical("%s: an argument is NULL", __FUNCTION__);
		return ERR_INVALID_FILE;
	}

	// src can be single/group file and dst must be group file
	if(!tifiles_file_is_group(dst_filename))
		return -1;

	src_model = tifiles_file_get_model(src_filename);
	dst_model = tifiles_file_get_model(dst_filename);

	src_content = tifiles_content_create_regular(src_model);
	dst_content = tifiles_content_create_regular(dst_model);

	ret = tifiles_file_read_regular(src_filename, src_content);
	if(ret) goto tgaf;
	ret = tifiles_file_read_regular(dst_filename, dst_content);
	if(ret) goto tgaf;

	for(i = 0; i < src_content->num_entries; i++)
		tifiles_content_add_entry(dst_content, tifiles_ve_dup(src_content->entries[i]));

	ret = tifiles_file_write_regular(dst_filename, dst_content, NULL);
	if(ret) goto tgaf;

tgaf:
	tifiles_content_delete_regular(src_content);
	tifiles_content_delete_regular(dst_content);

	return ret;
}
コード例 #11
0
ファイル: grouped.c プロジェクト: TI8XEmulator/graph89
/**
 * tifiles_group_files:
 * @src_filenames: a NULL-terminated array of strings (list of files to group).
 * @dst_filename: the filename where to store the group.
 *
 * Group several TI files into a single one (group file).
 *
 * Return value: an error code if unsuccessful, 0 otherwise.
 **/
TIEXPORT2 int TICALL tifiles_group_files(char **src_filenames, const char *dst_filename)
{
	int i, n;
	FileContent **src = NULL;
	FileContent *dst = NULL;
	int ret = 0;

	if (src_filenames == NULL || dst_filename == NULL)
	{
		tifiles_critical("%s: an argument is NULL", __FUNCTION__);
		return ERR_INVALID_FILE;
	}

	if(tifiles_file_get_model(src_filenames[0]) == CALC_NSPIRE)
		return ERR_BAD_CALC;

	// counter number of files to group
	for (n = 0; src_filenames[n] != NULL; n++);

	// allocate space for that
	src = (FileContent **)g_malloc0((n + 1) * sizeof(FileContent *));
	if (src == NULL)
		return ERR_MALLOC;

	// allocate each structure and load file content
	for (i = 0; i < n; i++)
	{
		src[i] = (FileContent *)g_malloc0(sizeof(FileContent));
		if (src[i] == NULL)
			return ERR_MALLOC;

		ret = tifiles_file_read_regular(src_filenames[i], src[i]);
		if(ret) goto tgf;
	}
	src[i] = NULL;

	// group the array of structures
	ret = tifiles_group_contents(src, &dst);
	if(ret) goto tgf;

	// write grouped file
	ret = tifiles_file_write_regular(dst_filename, dst, NULL);
	if(ret) goto tgf;

	// release allocated memory
tgf:
	tifiles_content_delete_group(src);
	tifiles_content_delete_regular(dst);

	return 0;
}
コード例 #12
0
ファイル: files9x.c プロジェクト: TC01/tilibs
/**
 * 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;
}
コード例 #13
0
ファイル: grouped.c プロジェクト: TI8XEmulator/graph89
/**
 * tifiles_content_delete_group:
 *
 * Convenient function which free a NULL-terminated array of #FileContent 
 * structures (typically used to store a group file) and the array itself.
 *
 * Return value: always 0.
 **/
TIEXPORT2 int TICALL tifiles_content_delete_group(FileContent **array)
{
	int i, n;

	if (array != NULL)
	{
		// counter number of files to group
		for (n = 0; array[n] != NULL; n++);

		// release allocated memory in structures
		for (i = 0; i < n; i++)
		{
			tifiles_content_delete_regular(array[i]);
		}
		g_free(array);
	}
	else
	{
		tifiles_critical("%s(NULL)", __FUNCTION__);
	}

	return 0;
}
コード例 #14
0
ファイル: backup.c プロジェクト: debrouxl/tilibs
int tixx_recv_all_vars_backup(CalcHandle* handle, FileContent* content)
{
	int i, j, k;
	int i_max;
	GNode *vars, *apps;
	int nvars, ivars = 0;
	int b = 0;
	FileContent **group;
	FileContent *single;
	int ret;

	VALIDATE_HANDLE(handle);
	if (content == NULL)
	{
		ticalcs_critical("tixx_recv_backup: content is NULL");
		return -1;
	}
	VALIDATE_CALCFNCTS(handle->calc);

	// Do a directory list and check for something to backup
	ret = handle->calc->get_dirlist(handle, &vars, &apps);
	if (ret)
	{
		return ret;
	}
	nvars = ticalcs_dirlist_ve_count(vars);
	if (!nvars)
	{
		return ERR_NO_VARS;
	}

	handle->updat->cnt2 = handle->updat->cnt3 = 0;
	handle->updat->max2 = handle->updat->max3 = nvars;
	ticalcs_update_pbar(handle);

	// Check whether the last folder is empty
	b = g_node_n_children(g_node_nth_child(vars, g_node_n_children(vars) - 1));
	PAUSE(100); // needed by TI84+/USB

	// Create a group file
	k = 0;
	group = tifiles_content_create_group(nvars);

	// Receive all vars except for FLASH apps
	i_max = g_node_n_children(vars);
	for (i = 0; i < i_max; i++)
	{
		GNode *parent = g_node_nth_child(vars, i);

		int j_max = g_node_n_children(parent);
		for (j = 0; j < j_max; j++)
		{
			GNode *node = g_node_nth_child(parent, j);
			VarEntry *ve = (VarEntry *) (node->data);

			handle->updat->cnt2 = handle->updat->cnt3 = ++ivars;
			ticalcs_update_pbar(handle);

			// we need to group files !
			ret = handle->calc->is_ready(handle);
			if (ret)
			{
				goto end;
			}
			group[k] = tifiles_content_create_regular(handle->model);
			ret = handle->calc->recv_var(handle, 0, group[k++], ve);
			if (ret)
			{
				goto end;
			}
		}
	}

end:
	ticalcs_dirlist_destroy(&vars);
	ticalcs_dirlist_destroy(&apps);

	if (!ret)
	{
		FileContent * cnt;
		ret = tifiles_group_contents(group, &cnt);
		if (!ret)
		{
			cnt->model = content->model;

			// Steal contents of cnt, then clean up.
			memcpy(content, cnt, sizeof(*content));
			cnt->num_entries = 0;
			cnt->entries = NULL;
			tifiles_content_delete_regular(cnt);

			ticalcs_strlcpy(content->comment, tifiles_comment_set_group(), sizeof(content->comment));
		}
	}

	tifiles_content_delete_group(group);

	return ret;
}
コード例 #15
0
ファイル: files9x.c プロジェクト: TC01/tilibs
/**
 * 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;
	char default_folder[FLDNAME_MAX];
	char current_folder[FLDNAME_MAX];
	uint32_t curr_offset = 0;
	uint32_t next_offset = 0;
	uint32_t file_size;
	uint16_t tmp;
	unsigned int i, j;
	char signature[9];
	char varname[VARNAME_MAX];
	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) 
	{
		ret = ERR_FILE_OPEN;
		goto tfrr2;
	}

	// Get file size, then rewind.
	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 TI-68k series' members have at best 4 MB of Flash (TODO: modify this code if this no longer holds).
	// Regular / group 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 tfrr;
	}
	file_size = (uint32_t)cur_pos;

	if (fread_8_chars(f, signature) < 0) goto tfrr; // Offset 0
	content->model = tifiles_signature2calctype(signature);
	if (content->model == CALC_NONE)
	{
		ret = ERR_INVALID_FILE;
		goto tfrr;
	}
	if (content->model_dst == CALC_NONE)
	{
		content->model_dst = content->model;
	}

	if (fread_word(f, NULL) < 0) goto tfrr; // Offset 0x8
	if (fread_8_chars(f, default_folder) < 0) goto tfrr; // Offset 0xA
	ticonv_varname_from_tifile_sn(content->model_dst, default_folder, content->default_folder, sizeof(content->default_folder), -1);
	strncpy(current_folder, content->default_folder, sizeof(current_folder) - 1);
	current_folder[sizeof(current_folder) - 1] = 0;
	if (fread_n_chars(f, 40, content->comment) < 0) goto tfrr; // Offset 0x12
	if (fread_word(f, &tmp) < 0) goto tfrr; // Offset 0x3A
	content->num_entries = tmp;

	content->entries = g_malloc0((content->num_entries + 1) * sizeof(VarEntry*));
	if (content->entries == NULL) 
	{
		ret = ERR_MALLOC;
		goto tfrr;
	}

	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 tfrr; // Offset N, 0x3C for the first entry
		if (curr_offset > file_size)
		{
			ret = ERR_INVALID_FILE;
			goto tfrr;
		}
		if (fread_8_chars(f, varname) < 0)  goto tfrr; // Offset N+4, 0x40 for the first entry
		ticonv_varname_from_tifile_sn(content->model_dst, varname, entry->name, sizeof(entry->name), entry->type);
		if (fread_byte(f, &(entry->type)) < 0) goto tfrr; // Offset N+12, 0x48 for the first entry
		if (fread_byte(f, &(entry->attr)) < 0) goto tfrr; // Offset N+13, 0x49 for the first entry
		entry->attr = (entry->attr == 2 || entry->attr == 3) ? ATTRB_ARCHIVED : entry->attr;
		if (fread_word(f, NULL) < 0) goto tfrr; // Offset N+14, 0x4A for the first entry

		if (entry->type == TI92_DIR) // same as TI89_DIR, TI89t_DIR, ...
		{
			strncpy(current_folder, entry->name,sizeof(current_folder) - 1);
			current_folder[sizeof(current_folder) - 1] = 0;
			g_free(entry);
			continue;			// folder: skip entry
		}
		else 
		{
			uint16_t checksum, sum = 0;

			j++;
			strncpy(entry->folder, current_folder, sizeof(entry->folder) - 1);
			current_folder[sizeof(entry->folder) - 1] = 0;
			cur_pos = ftell(f);
			if (cur_pos < 0) goto tfrr;
			if (fread_long(f, &next_offset) < 0) goto tfrr; // Offset N+16, 0x4C for the first entry
			if (next_offset > file_size)
			{
				ret = ERR_INVALID_FILE;
				goto tfrr;
			}
			entry->size = next_offset - curr_offset - 4 - 2;
			if (entry->size > file_size)
			{
				ret = ERR_INVALID_FILE;
				goto tfrr;
			}
			entry->data = (uint8_t *)g_malloc0(entry->size);
			if (entry->data == NULL) 
			{
				ret = ERR_MALLOC;
				goto tfrr;
			}

			if (fseek(f, curr_offset, SEEK_SET)) goto tfrr;
			if (fread_long(f, NULL) < 0) goto tfrr;	// Normally: offset N+22, 0x52 for the first entry
			if (fread(entry->data, 1, entry->size, f) < entry->size) goto tfrr; // Normally: offset N+26, 0x56 for the first entry

			if (fread_word(f, &checksum) < 0) goto tfrr;
			if (fseek(f, cur_pos, SEEK_SET)) goto tfrr;

			sum = tifiles_checksum(entry->data, entry->size);
			if (sum != checksum)
			{
				ret = ERR_FILE_CHECKSUM;
				goto tfrr;
			}
			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;

tfrr:	// release on exit
	tifiles_critical("%s: error reading / understanding file %s", __FUNCTION__, filename);
	fclose(f);
tfrr2:
	tifiles_content_delete_regular(content);
	return ret;
}
コード例 #16
0
ファイル: filesnsp.c プロジェクト: TC01/tilibs
/**
 * 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;
}
コード例 #17
0
ファイル: tilp_slct.c プロジェクト: debrouxl/tilp_and_gfm
/* Preload TI variables belonging with the selection */
void tilp_local_contents_load(void)
{
	GList *ptr;
	int err;

	// TIGroups
	if (local.selection5 != NULL)
	{
		for(ptr = local.selection5; ptr; ptr = ptr->next)
		{
			FileEntry *fe5 = ptr->data;

			if(tifiles_file_is_tigroup(fe5->name))
			{
				TigContent *content = NULL;
				FileContent **p, **contents1 = NULL;
				FlashContent **q, **contents2 = NULL;
				
				content = tifiles_content_create_tigroup(options.calc_model, 0);
				err = tifiles_file_read_tigroup(fe5->name, content);
				if(err)
				{
					tilp_err(err);
					continue;
				}
				err = tifiles_untigroup_content(content, &contents1, &contents2);
				if(err)
				{
					tilp_err(err);
					tifiles_content_delete_tigroup(content);
					continue;
				}
				tifiles_content_delete_tigroup(content);
				
				for(p = contents1; *p; p++)
				{
					FileEntry *fe1 = g_memdup(ptr->data, sizeof(FileEntry));
					fe1->name = g_memdup(fe1->name, strlen(fe1->name)+1);

					fe1->content1 = *p;
					//g_free(fe1->name);
					//fe1->name = tifiles_build_filename(options.calc_model, (*p)->entries[0]);
				
					local.selection1 = g_list_append(local.selection1, fe1);
				}
				
				for(q = contents2; *q; q++)
				{
					FileEntry *fe3 = g_memdup(ptr->data, sizeof(FileEntry));
					fe3->name = g_memdup(fe3->name, strlen(fe3->name)+1);

					fe3->content2 = *q;
					/*
					{
						VarEntry ve;
						g_free(fe3->name);
						strcpy(ve.name, (*q)->name);
						ve.type = (*q)->data_type;
						fe3->name = tifiles_build_filename(options.calc_model, &ve);
					}*/
				
					local.selection3 = g_list_append(local.selection3, fe3);
				}
			}
		}
	}

	// Variables
	if (local.selection0 != NULL)
	{
		for(ptr = local.selection0; ptr; ptr = ptr->next)
		{
			FileEntry *fe0 = ptr->data;

			if(!g_ascii_strcasecmp(tifiles_fext_get(fe0->name), "8xidl"))
				continue;	// doesn't send this pseudo-variable

			if(tifiles_file_is_single(fe0->name))
			{
				FileEntry *fe1 = g_memdup(ptr->data, sizeof(FileEntry));

				fe1->content1 = tifiles_content_create_regular(options.calc_model);
				err = tifiles_file_read_regular(fe1->name, fe1->content1);
				if(err)
				{
					// The content is already deleted by the subroutines of tifiles_file_read_regular.
					//tifiles_content_delete_regular(fe1->content1);
					g_free(fe1);
					continue;
				}

				local.selection1 = g_list_append(local.selection1, fe1);
			}
			else if(tifiles_file_is_group(fe0->name))
			{
				// explode group files so that we have 1 VarEntry per item (skip/retry/cancel)
				FileContent **p, **dst = NULL;
				FileContent *src = NULL;

				src = tifiles_content_create_regular(options.calc_model);
				err = tifiles_file_read_regular(fe0->name, src);
				if(err)
				{
					// The content is already deleted by the subroutines of tifiles_file_read_regular.
					//tifiles_content_delete_regular(src);
					continue;
				}
				
				err = tifiles_ungroup_content(src, &dst);
				if(err)
				{
					tifiles_content_delete_regular(src);
					continue;
				}

				for(p = dst; *p; p++)
				{
					FileEntry *fe = g_memdup(ptr->data, sizeof(FileEntry));

					fe->content1 = *p;
				
					local.selection1 = g_list_append(local.selection1, fe);
				}

				tifiles_content_delete_regular(src);
			}
		}
	}

	// Applications
	if(local.selection2 != NULL)
	{
		for(ptr = local.selection2; ptr; ptr = ptr->next)
		{
			FileEntry *fe2 = ptr->data;

			if(tifiles_file_is_app(fe2->name) || tifiles_file_test(fe2->name, TIFILE_OS, options.calc_model))
			{
				FileEntry *fe3 = g_memdup(ptr->data, sizeof(FileEntry));

				fe3->content2 = tifiles_content_create_flash(options.calc_model);
				err = tifiles_file_read_flash(fe2->name, fe3->content2);
				if(err)
				{
					tifiles_content_delete_flash(fe3->content2);
					g_free(fe3);
					continue;
				}

				local.selection3 = g_list_append(local.selection3, fe3);
			}
		}
	}

	// Reparse variables and change target folder
	if (local.selection1)
	{
		// replaced "" folder by "main"
		if(!tifiles_has_folder(options.calc_model))
			return;

		for(ptr = local.selection1; ptr; ptr = ptr->next)
		{
			FileEntry *fe = ptr->data;
			FileContent *fc = fe->content1;
			unsigned int i;

			if(fc == NULL)
				continue;

			for(i = 0; i < fc->num_entries; i++)
			{
				VarEntry *ve = (fc->entries)[i];

				if(!strcmp(ve->folder , ""))
					strcpy(ve->folder, "main");
			}
		}
	}
}
コード例 #18
0
ファイル: torture_tifiles.c プロジェクト: TC01/tilibs
int main(int argc, char **argv)
{
    void * ptr;

    tifiles_library_init();

    PRINTF(tifiles_error_get, INT, -1, NULL);
    PRINTF(tifiles_error_free, INT, NULL);
    PRINTF(tifiles_model_to_string, STR, -1);
    PRINTF(tifiles_string_to_model, INT, NULL);
    PRINTF(tifiles_attribute_to_string, STR, -1);
    PRINTF(tifiles_string_to_attribute, INT, NULL);
    PRINTF(tifiles_class_to_string, STR, -1);
    PRINTF(tifiles_string_to_class, INT, NULL);
    PRINTF(tifiles_fext_of_group, STR, -1);
    PRINTF(tifiles_fext_of_backup, STR, -1);

    PRINTF(tifiles_fext_of_flash_app, STR, -1);
    PRINTF(tifiles_fext_of_flash_os, STR, -1);
    PRINTF(tifiles_fext_of_certif, STR, -1);
    PRINTF(tifiles_fext_get, STR, NULL);
    ptr = tifiles_fext_dup(NULL);
    PRINTF(, PTR, ptr);
    tifiles_fext_free(ptr);
    PRINTFVOID(tifiles_fext_free, NULL);
    PRINTF(tifiles_file_is_ti, INT, NULL);
    PRINTF(tifiles_file_is_single, INT, NULL);
    PRINTF(tifiles_file_is_group, INT, NULL);
    PRINTF(tifiles_file_is_regular, INT, NULL);

    PRINTF(tifiles_file_is_backup, INT, NULL);
    PRINTF(tifiles_file_is_os, INT, NULL);
    PRINTF(tifiles_file_is_app, INT, NULL);
    PRINTF(tifiles_file_is_tib, INT, NULL);
    PRINTF(tifiles_file_is_flash, INT, NULL);
    PRINTF(tifiles_file_is_tigroup, INT, NULL);
    PRINTF(tifiles_file_is_tno, INT, NULL);
    PRINTF(tifiles_file_has_ti_header, INT, NULL);
    PRINTF(tifiles_file_has_tib_header, INT, NULL);
    PRINTF(tifiles_file_has_tig_header, INT, NULL);

    PRINTF(tifiles_file_has_tifl_header, INT, NULL, (void *)0x12345678, (void *)0x12345678);
    PRINTF(tifiles_file_has_tno_header, INT, NULL);
    PRINTF(tifiles_model_to_dev_type, INT, -1);
    PRINTF(tifiles_file_test, INT, NULL, -1, -1);
    PRINTF(tifiles_file_get_model, INT, NULL);
    PRINTF(tifiles_file_get_class, INT, NULL);
    PRINTF(tifiles_file_get_type, STR, NULL);
    PRINTF(tifiles_file_get_icon, STR, NULL);
    PRINTF(tifiles_vartype2string, STR, -1, -1);
    PRINTF(tifiles_string2vartype, INT, -1, NULL);

    PRINTF(tifiles_vartype2fext, STR, -1, -1);
    PRINTF(tifiles_fext2vartype, INT, -1, NULL);
    PRINTF(tifiles_vartype2type, STR, -1, -1);
    PRINTF(tifiles_vartype2icon, STR, -1, -1);
    PRINTF(tifiles_calctype2signature, STR, -1);
    PRINTF(tifiles_signature2calctype, INT, NULL);
    PRINTF(tifiles_folder_type, INT, -1);
    PRINTF(tifiles_flash_type, INT, -1);
    PRINTF(tifiles_idlist_type, INT, -1);
    PRINTF(tifiles_calc_is_ti8x, INT, -1);

    PRINTF(tifiles_calc_is_ti9x, INT, -1);
    PRINTF(tifiles_calc_are_compat, INT, -1, -1);
    PRINTF(tifiles_has_folder, INT, -1);
    PRINTF(tifiles_is_flash, INT, -1);
    PRINTF(tifiles_has_backup, INT, -1);
    PRINTF(tifiles_checksum, INT, NULL, 1234567891);
    PRINTF(tifiles_hexdump, INT, NULL, 1);
    PRINTF(tifiles_get_varname, STR, NULL);
    PRINTF(tifiles_get_fldname, STR, NULL);
    PRINTF(tifiles_build_fullname, STR, -1, NULL, NULL, (void *)0x12345678);

    PRINTF(tifiles_build_fullname, STR, -1, (void *)0x12345678, NULL, NULL);
    PRINTF(tifiles_build_fullname, STR, -1, NULL, (void *)0x12345678, NULL);
    PRINTF(tifiles_build_filename, STR, -1, NULL);
    PRINTFVOID(tifiles_filename_free, NULL);
    ptr = tifiles_content_create_regular(-1);
    PRINTF(, PTR, ptr);
    tifiles_content_delete_regular(ptr);
    PRINTF(tifiles_content_delete_regular, INT, NULL);
    PRINTF(tifiles_file_read_regular, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_file_read_regular, INT, (void *)0x12345678, NULL);
    PRINTF(tifiles_file_write_regular, INT, NULL, NULL, (void *)0x12345678);
    PRINTF(tifiles_file_write_regular, INT, NULL, (void *)0x12345678, NULL);

    PRINTF(tifiles_file_write_regular, INT, (void *)0x12345678, NULL, NULL);
    PRINTF(tifiles_file_display_regular, INT, NULL);
    ptr = tifiles_content_create_backup(-1);
    PRINTF(, PTR, ptr);
    tifiles_content_delete_backup(ptr);
    PRINTF(tifiles_content_delete_backup, INT, NULL);
    PRINTF(tifiles_file_read_backup, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_file_read_backup, INT, (void *)0x12345678, NULL);
    PRINTF(tifiles_file_write_backup, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_file_write_backup, INT, (void *)0x12345678, NULL);
    PRINTF(tifiles_file_display_backup, INT, NULL);
    ptr = tifiles_content_create_flash(-1);
    PRINTF(, PTR, ptr);
    tifiles_content_delete_flash(ptr);

    PRINTF(tifiles_file_read_flash, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_content_delete_flash, INT, NULL);
    PRINTF(tifiles_file_read_flash, INT, (void *)0x12345678, NULL);
    PRINTF(tifiles_file_write_flash, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_file_write_flash, INT, (void *)0x12345678, NULL);
    PRINTF(tifiles_file_write_flash2, INT, NULL, (void *)0x12345678, NULL);
    PRINTF(tifiles_file_write_flash2, INT, (void *)0x12345678, NULL, NULL);
    PRINTF(tifiles_file_display_flash, INT, NULL);
    PRINTF(tifiles_content_dup_regular, PTR, NULL);
    PRINTF(tifiles_content_dup_flash, PTR, NULL);

    PRINTF(tifiles_file_display, INT, NULL);
    ptr = tifiles_content_create_group(0);
    PRINTF(, PTR, ptr);
    tifiles_content_delete_group(ptr);
    PRINTF(tifiles_content_delete_group, INT, NULL);
    PRINTF(tifiles_group_contents, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_group_contents, INT, (void *)0x12345678, NULL);
    PRINTF(tifiles_ungroup_content, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_ungroup_content, INT, (void *)0x12345678, NULL);
    PRINTF(tifiles_group_files, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_group_files, INT, (void *)0x12345678, NULL);
    PRINTF(tifiles_ungroup_file, INT, NULL, (void *)0x12345678);

    PRINTF(tifiles_content_add_entry, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_content_del_entry, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_group_add_file, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_group_add_file, INT, (void *)0x12345678, NULL);
    PRINTF(tifiles_group_del_file, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_group_del_file, INT, (void *)0x12345678, NULL);
    ptr = tifiles_content_create_tigroup(-1, -1);
    PRINTF(, PTR, ptr);
    tifiles_content_delete_tigroup(ptr);
    PRINTF(tifiles_content_delete_tigroup, INT, NULL);
    PRINTF(tifiles_file_read_tigroup, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_file_read_tigroup, INT, (void *)0x12345678, NULL);

    PRINTF(tifiles_file_write_tigroup, INT, NULL, (void *)0x12345678);
    PRINTF(tifiles_file_write_tigroup, INT, (void *)0x12345678, NULL);
    PRINTF(tifiles_file_display_tigroup, INT, NULL);
    PRINTF(tifiles_tigroup_contents, INT, NULL, (void *)0x12345678, NULL);
    PRINTF(tifiles_tigroup_contents, INT, (void *)0x12345678, NULL, NULL);
    PRINTF(tifiles_tigroup_contents, INT, NULL, NULL, NULL);
    PRINTF(tifiles_untigroup_content, INT, NULL, NULL, NULL);
    PRINTF(tifiles_untigroup_content, INT, NULL, NULL, NULL);
    PRINTF(tifiles_untigroup_content, INT, NULL, NULL, NULL);
    PRINTF(tifiles_tigroup_files, INT, NULL, NULL);

    PRINTF(tifiles_tigroup_files, INT, NULL, NULL);
    PRINTF(tifiles_untigroup_file, INT, NULL, NULL);
    PRINTF(tifiles_untigroup_file, INT, NULL, NULL);
    PRINTF(tifiles_content_add_te, INT, NULL, NULL);
    PRINTF(tifiles_content_add_te, INT, NULL, NULL);
    PRINTF(tifiles_content_del_te, INT, NULL, NULL);
    PRINTF(tifiles_content_del_te, INT, NULL, NULL);
    PRINTF(tifiles_tigroup_add_file, INT, NULL, NULL);
    PRINTF(tifiles_tigroup_add_file, INT, NULL, NULL);
    PRINTF(tifiles_tigroup_del_file, INT, NULL, NULL);

    PRINTF(tifiles_tigroup_del_file, INT, NULL, NULL);
    PRINTF(tifiles_te_create, PTR, NULL, -1, -1);
    PRINTF(tifiles_te_delete, INT, NULL);
    ptr = tifiles_te_create_array(0);
    PRINTF(, PTR, ptr);
    tifiles_te_delete_array(ptr);
    ptr = tifiles_te_resize_array(NULL, 0);
    PRINTF(, PTR, ptr);
    tifiles_te_delete_array(ptr);
    PRINTFVOID(tifiles_te_delete_array, NULL);
    PRINTF(tifiles_te_sizeof_array, INT, NULL);
    PRINTF(tifiles_comment_set_single, STR);
    PRINTF(tifiles_comment_set_group, STR);
    PRINTF(tifiles_comment_set_backup, STR);

    PRINTF(tifiles_comment_set_tigroup, STR);
    ptr = tifiles_ve_create();
    PRINTF(, PTR, ptr);
    tifiles_ve_delete(ptr);
    ptr = tifiles_ve_create_alloc_data(0);
    PRINTF(, PTR, ptr);
    tifiles_ve_delete(ptr);
    ptr = tifiles_ve_create_with_data(0);
    PRINTF(, PTR, ptr);
    tifiles_ve_delete(ptr);
    ptr = tifiles_ve_create_with_data2(0, NULL);
    PRINTF(, PTR, ptr);
    tifiles_ve_delete(ptr);
    PRINTFVOID(tifiles_ve_delete, NULL);
    ptr = tifiles_ve_alloc_data(0);
    PRINTF(, PTR, ptr);
    tifiles_ve_free_data(ptr);
    ptr = tifiles_ve_realloc_data(NULL, 1);
    PRINTF(, PTR, ptr);
    tifiles_ve_free_data(ptr);
    PRINTFVOID(tifiles_ve_free_data, NULL);
    PRINTF(tifiles_ve_copy, PTR, NULL, NULL);

    PRINTF(tifiles_ve_dup, PTR, NULL);
    ptr = tifiles_ve_create_array(0);
    PRINTF(, PTR, ptr);
    tifiles_ve_delete_array(ptr);
    ptr = tifiles_ve_resize_array(NULL, 0);
    PRINTF(, PTR, ptr);
    tifiles_ve_delete_array(ptr);
    PRINTFVOID(tifiles_ve_delete_array, NULL);
    ptr = tifiles_fp_create();
    PRINTF(, PTR, ptr);
    tifiles_fp_delete(ptr);
    ptr = tifiles_fp_create_alloc_data(0);
    PRINTF(, PTR, ptr);
    tifiles_fp_delete(ptr);
    ptr = tifiles_fp_create_with_data(0);
    PRINTF(, PTR, ptr);
    tifiles_fp_delete(ptr);
    ptr = tifiles_fp_create_with_data2(0, NULL);
    PRINTF(, PTR, ptr);
    tifiles_fp_delete(ptr);
    PRINTFVOID(tifiles_fp_delete, NULL);
    ptr = tifiles_fp_alloc_data(0);
    PRINTF(, PTR, ptr);
    tifiles_fp_free_data(ptr);

    ptr = tifiles_fp_realloc_data(NULL, 1);
    PRINTF(, PTR, ptr);
    tifiles_fp_free_data(ptr);
    PRINTFVOID(tifiles_fp_free_data, NULL);
    ptr = tifiles_fp_create_array(0);
    PRINTF(, PTR, ptr);
    tifiles_fp_delete_array(ptr);
    ptr = tifiles_fp_resize_array(NULL, 0);
    PRINTF(, PTR, ptr);
    tifiles_fp_delete_array(ptr);
    PRINTFVOID(tifiles_fp_delete_array, NULL);
    ptr = tifiles_create_table_of_entries(NULL, NULL);
    PRINTF(, PTR, ptr);
    tifiles_free_table_of_entries(ptr);
    PRINTFVOID(tifiles_free_table_of_entries, NULL);

    cert_functions_unit_test();

    tifiles_library_exit();

    return 0;
}
コード例 #19
0
ファイル: files9x.c プロジェクト: debrouxl/tilp-libtifiles
/**
 * 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;
}