示例#1
0
/*
 * Given a null-terminated pathname pattern @pat that has been read from line
 * @line_no of the file @path, validate and canonicalize the pattern.
 *
 * On success, returns 0.
 * On failure, returns WIMLIB_ERR_INVALID_CAPTURE_CONFIG.
 * In either case, @pat may have been modified in-place (and possibly
 * shortened).
 */
int
mangle_pat(tchar *pat, const tchar *path, unsigned long line_no)
{
	if (!is_any_path_separator(pat[0]) &&
	    pat[0] != T('\0') && pat[1] == T(':'))
	{
		/* Pattern begins with drive letter.  */

		if (!is_any_path_separator(pat[2])) {
			/* Something like c:file, which is actually a path
			 * relative to the current working directory on the c:
			 * drive.  We require paths with drive letters to be
			 * absolute.  */
			ERROR("%"TS":%lu: Invalid pattern \"%"TS"\":\n"
			      "        Patterns including drive letters must be absolute!\n"
			      "        Maybe try \"%"TC":%"TC"%"TS"\"?\n",
			      path, line_no, pat,
			      pat[0], OS_PREFERRED_PATH_SEPARATOR, &pat[2]);
			return WIMLIB_ERR_INVALID_CAPTURE_CONFIG;
		}

		WARNING("%"TS":%lu: Pattern \"%"TS"\" starts with a drive "
			"letter, which is being removed.",
			path, line_no, pat);

		/* Strip the drive letter.  */
		tmemmove(pat, pat + 2, tstrlen(pat + 2) + 1);
	}

	/* Collapse consecutive path separators, and translate both / and \ into
	 * / (UNIX) or \ (Windows).
	 *
	 * Note: we expect that this function produces patterns that can be used
	 * for both filesystem paths and WIM paths, so the desired path
	 * separators must be the same.  */
	BUILD_BUG_ON(OS_PREFERRED_PATH_SEPARATOR != WIM_PATH_SEPARATOR);
	do_canonicalize_path(pat, pat);

	/* Relative patterns can only match file names, so they must be
	 * single-component only.  */
	if (pat[0] != OS_PREFERRED_PATH_SEPARATOR &&
	    tstrchr(pat, OS_PREFERRED_PATH_SEPARATOR))
	{
		ERROR("%"TS":%lu: Invalid pattern \"%"TS"\":\n"
		      "        Relative patterns can only include one path component!\n"
		      "        Maybe try \"%"TC"%"TS"\"?",
		      path, line_no, pat, OS_PREFERRED_PATH_SEPARATOR, pat);
		return WIMLIB_ERR_INVALID_CAPTURE_CONFIG;
	}

	return 0;
}
示例#2
0
/*
 * canonicalize_wim_path() - Given a user-provided path to a file within a WIM
 * image, translate it into a "canonical" path.
 *
 * - Translate both types of slash into a consistent type (WIM_PATH_SEPARATOR).
 * - Collapse path separators.
 * - Add leading slash if missing.
 * - Strip trailing slashes.
 *
 * Examples (with WIM_PATH_SEPARATOR == '/'):
 *
 *		=> /		[ either NULL or empty string ]
 * /		=> /
 * \		=> /
 * hello	=> /hello
 * \hello	=> /hello
 * \hello	=> /hello
 * /hello/	=> /hello
 * \hello/	=> /hello
 * /hello//1	=> /hello/1
 * \\hello\\1\\	=> /hello/1
 */
tchar *
canonicalize_wim_path(const tchar *wim_path)
{
	const tchar *in;
	tchar *out;
	tchar *result;

	in = wim_path;
	if (!in)
		in = T("");

	result = MALLOC((1 + tstrlen(in) + 1) * sizeof(result[0]));
	if (!result)
		return NULL;

	out = result;

	/* Add leading slash if missing  */
	if (!is_any_path_separator(*in))
		*out++ = WIM_PATH_SEPARATOR;

	do_canonicalize_path(in, out);

	return result;
}
示例#3
0
/* Collapse and translate path separators, and strip trailing slashes.  Doesn't
 * add or delete a leading slash.
 *
 * @in may alias @out.
 */
void
do_canonicalize_path(const tchar *in, tchar *out)
{
	tchar *orig_out = out;

	while (*in) {
		if (is_any_path_separator(*in)) {
			/* Collapse multiple path separators into one  */
			*out++ = WIM_PATH_SEPARATOR;
			do {
				in++;
			} while (is_any_path_separator(*in));
		} else {
			/* Copy non-path-separator character  */
			*out++ = *in++;
		}
	}

	/* Remove trailing slash if existent  */
	if (out - orig_out > 1 && *(out - 1) == WIM_PATH_SEPARATOR)
		--out;

	*out = T('\0');
}