예제 #1
0
/* allocate and fill the file_search_data */
file_search_data* create_file_search_data(rsh_tchar** paths, size_t count, int max_depth)
{
	size_t i;

	file_search_data* data = (file_search_data*)rsh_malloc(sizeof(file_search_data));
	memset(data, 0, sizeof(file_search_data));
	rsh_blocks_vector_init(&data->root_files);
	data->max_depth = max_depth;

#ifdef _WIN32
	/* expand wildcards and fill the root_files */
	for (i = 0; i < count; i++)
	{
		int added = 0;
		size_t length, index;
		wchar_t* path = paths[i];
		wchar_t* p = wcschr(path, L'\0') - 1;

		/* strip trailing '\','/' symbols (if not preceded by ':') */
		for (; p > path && IS_PATH_SEPARATOR_W(*p) && p[-1] != L':'; p--) *p = 0;

		/* Expand a wildcard in the current file path and store results into data->root_files.
		 * If a wildcard is not found then just the file path is stored.
		 * NB, only wildcards in the last filename of the path are expanded. */

		length = p - path + 1;
		index = wcscspn(path, L"*?");

		if (index < length && wcscspn(path + index, L"/\\") >= (length - index))
		{
			/* a wildcard is found without a directory separator after it */
			wchar_t* parent;
			WIN32_FIND_DATAW d;
			HANDLE handle;

			/* find a directory separator before the file name */
			for (; index > 0 && !IS_PATH_SEPARATOR(path[index]); index--);
			parent = (IS_PATH_SEPARATOR(path[index]) ? path : 0);

			handle = FindFirstFileW(path, &d);
			if (INVALID_HANDLE_VALUE != handle)
			{
				do {
					file_t file;
					int failed;
					if (IS_CURRENT_OR_PARENT_DIRW(d.cFileName)) continue;

					memset(&file, 0, sizeof(file));
					file.wpath = make_pathw(parent, index + 1, d.cFileName);
					if (!file.wpath) continue;

					/* skip directories if not in recursive mode */
					if (data->max_depth == 0 && (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) continue;

					/* convert file name */
					file.path = wchar_to_cstr(file.wpath, WIN_DEFAULT_ENCODING, &failed);
					if (!failed) {
						failed = (file_statw(&file) < 0);
					}

					/* quietly skip unconvertible file names */
					if (!file.path || failed) {
						if (failed) {
							data->errors_count++;
						}
						free(file.path);
						free(file.wpath);
						continue;
					}

					/* fill the file information */
					file.mode |= FILE_IFROOT;
					add_root_file(data, &file);
					added++;
				} while (FindNextFileW(handle, &d));
				FindClose(handle);
			} else {
				/* report error on the specified wildcard */
				char * cpath = wchar_to_cstr(path, WIN_DEFAULT_ENCODING, NULL);
				set_errno_from_last_file_error();
				log_file_error(cpath);
				free(cpath);
				data->errors_count++;
			}
		}
		else
		{
			int failed;
			file_t file;
			memset(&file, 0, sizeof(file));

			/* if filepath is a dash string "-" */
			if ((path[0] == L'-' && path[1] == L'\0'))
			{
				file.mode = FILE_IFSTDIN;
				file.path = rsh_strdup("(stdin)");
			} else {
				file.path = wchar_to_cstr(path, WIN_DEFAULT_ENCODING, &failed);
				if (failed) {
					log_error(_("Can't convert the path to local encoding: %s\n"), file.path);
					free(file.path);
					data->errors_count++;
					continue;
				}
				file.wpath = path;
				if (file_statw(&file) < 0) {
					log_file_error(file.path);
					free(file.path);
					data->errors_count++;
					continue;
				}
			}

			/* mark the file as obtained from the command line */
			file.mode |= FILE_IFROOT;
			file.wpath = rsh_wcsdup(path);
			add_root_file(data, &file);
		}
	} /* for */
#else
	/* copy file paths */
	for (i = 0; i < count; i++)
	{
		file_t file;
		file_init(&file, paths[i], 0);

		if (IS_DASH_STR(file.path))
		{
			file.mode = FILE_IFSTDIN;
		}
		else if (file_stat2(&file, USE_LSTAT) < 0) {
			log_file_error(file.path);
			file_cleanup(&file);
			data->errors_count++;
			continue;
		}

		file.mode |= FILE_IFROOT;
		add_root_file(data, &file);
	}
#endif
	return data;
}
예제 #2
0
/**
 * Parse command line options.
 *
 * @param argv program arguments
 */
void read_options(int argc, char *argv[])
{
	struct parsed_cmd_line_t cmd_line;
#ifdef _WIN32
	int i;
	vector_t *expanded_cnames;
#endif

	memset(&opt, 0, sizeof(opt));
	opt.mem = rsh_vector_new_simple();
	opt.find_max_depth = -1;

	/* initialize cmd_line */
	memset(&cmd_line, 0, sizeof(cmd_line));
	rsh_blocks_vector_init(&cmd_line.options);
	cmd_line.argv = argv;
	cmd_line.argc = argc;

	/* parse command line and apply encoding options */
	parse_cmdline_options(&cmd_line);
	read_config();
	
#ifdef _WIN32
	/* set default encoding if no encoding options were specified, */
	/* this should be done here, even if config file was not found. */
	if( (opt.flags & OPT_ENCODING) == 0 ) opt.flags |= OPT_UTF8;
#endif

	/* note: encoding and -o/-l options are already applied */
	IF_WINDOWS(setup_console());
	setup_output(); /* setup program output */

	apply_cmdline_options(&cmd_line); /* process the rest of command options */

	/* options were processed, so we don't need them anymore */
	rsh_blocks_vector_destroy(&cmd_line.options);
	
#ifdef _WIN32
	expanded_cnames = rsh_vector_new_simple();

	/* convert paths to internal encoding and expand wildcards. */
	for(i = 0; i < cmd_line.n_files; i++) {
		wchar_t* path = cmd_line.files[i];
		wchar_t* p = wcschr(path, L'\0') - 1;

		/* strip trailing '\','/' symbols (if not preceded by ':') */
		for(; p > path && IS_PATH_SEPARATOR_W(*p) && p[-1] != L':'; p--) *p = 0;
		expand_wildcards(expanded_cnames, path);
	}

	opt.cmd_vec = expanded_cnames;
	opt.files = (char**)expanded_cnames->array;
	opt.n_files = (int)expanded_cnames->size;
	free(cmd_line.files);
	LocalFree(cmd_line.warg);
#else
	opt.files = cmd_line.files;
	opt.n_files = cmd_line.n_files;
	rsh_vector_add_ptr(opt.mem, opt.files);
#endif

	make_final_options_checks();

	set_default_sums_flags(argv[0]); /* detect default hashes from program name */
}