Esempio n. 1
0
/*
 * Parses one line from utab file
 */
static int mnt_parse_utab_line(struct libmnt_fs *fs, const char *s)
{
	const char *p = s;

	assert(fs);
	assert(s);
	assert(!fs->source);
	assert(!fs->target);

	while (p && *p) {
		char *end = NULL;

		while (*p == ' ') p++;
		if (!*p)
			break;

		if (!fs->source && !strncmp(p, "SRC=", 4)) {
			char *v = unmangle(p + 4, &end);
			if (!v)
				goto enomem;
			__mnt_fs_set_source_ptr(fs, v);

		} else if (!fs->target && !strncmp(p, "TARGET=", 7)) {
			fs->target = unmangle(p + 7, &end);
			if (!fs->target)
				goto enomem;

		} else if (!fs->root && !strncmp(p, "ROOT=", 5)) {
			fs->root = unmangle(p + 5, &end);
			if (!fs->root)
				goto enomem;

		} else if (!fs->bindsrc && !strncmp(p, "BINDSRC=", 8)) {
			fs->bindsrc = unmangle(p + 8, &end);
			if (!fs->bindsrc)
				goto enomem;

		} else if (!fs->user_optstr && !strncmp(p, "OPTS=", 5)) {
			fs->user_optstr = unmangle(p + 5, &end);
			if (!fs->user_optstr)
				goto enomem;

		} else if (!fs->attrs && !strncmp(p, "ATTRS=", 6)) {
			fs->attrs = unmangle(p + 6, &end);
			if (!fs->attrs)
				goto enomem;

		} else {
			/* unknown variable */
			while (*p && *p != ' ') p++;
		}
		if (end)
			p = end;
	}

	return 0;
enomem:
	DBG(TAB, mnt_debug("utab parse error: ENOMEM"));
	return -ENOMEM;
}
Esempio n. 2
0
/*
 * Parses one line from {fs,m}tab
 */
static int mnt_parse_table_line(struct libmnt_fs *fs, char *s)
{
	int rc, n = 0;
	char *src, *fstype, *optstr;

	rc = sscanf(s,	UL_SCNsA" "	/* (1) source */
			UL_SCNsA" "	/* (2) target */
			UL_SCNsA" "	/* (3) FS type */
			UL_SCNsA" "	/* (4) options */
			"%n",		/* byte count */

			&src,
			&fs->target,
			&fstype,
			&optstr,
			&n);

	if (rc == 4) {
		unmangle_string(src);
		unmangle_string(fs->target);
		unmangle_string(fstype);
		unmangle_string(optstr);

		rc = __mnt_fs_set_source_ptr(fs, src);
		if (!rc)
			rc = __mnt_fs_set_fstype_ptr(fs, fstype);
		if (!rc)
			rc = mnt_fs_set_options(fs, optstr);
		free(optstr);
	} else {
		DBG(TAB, mnt_debug("tab parse error: [sscanf rc=%d]: '%s'", rc, s));
		rc = -EINVAL;
	}

	if (rc)
		return rc;	/* error */

	fs->passno = fs->freq = 0;
	s = skip_spaces(s + n);
	if (*s) {
		if (next_number(&s, &fs->freq) != 0) {
			if (*s) {
				DBG(TAB, mnt_debug("tab parse error: [freq]"));
				rc = -EINVAL;
			}
		} else if (next_number(&s, &fs->passno) != 0 && *s) {
			DBG(TAB, mnt_debug("tab parse error: [passno]"));
			rc = -EINVAL;
		}
	}

	return rc;
}
Esempio n. 3
0
static int kernel_fs_postparse(struct libmnt_table *tb,
			       struct libmnt_fs *fs, pid_t *tid,
			       const char *filename)
{
	int rc = 0;
	const char *src = mnt_fs_get_srcpath(fs);

	/* This is a filesystem description from /proc, so we're in some process
	 * namespace. Let's remember the process PID.
	 */
	if (filename && *tid == -1)
		*tid = path_to_tid(filename);

	fs->tid = *tid;

	/*
	 * Convert obscure /dev/root to something more usable
	 */
	if (src && strcmp(src, "/dev/root") == 0) {
		char *real = NULL;

		rc = mnt_guess_system_root(fs->devno, tb->cache, &real);
		if (rc < 0)
			return rc;

		if (rc == 0 && real) {
			DBG(TAB, ul_debugobj(tb, "canonical root FS: %s", real));
			rc = __mnt_fs_set_source_ptr(fs, real);

		} else if (rc == 1) {
			/* mnt_guess_system_root() returns 1 if not able to conver to
			 * the real devname; ignore this problem */
			rc = 0;
		}
	}

	return rc;
}
Esempio n. 4
0
/*
 * Parses one line from {fs,m}tab
 */
static int mnt_parse_table_line(struct libmnt_fs *fs, char *s)
{
	int rc, n = 0, xrc;
	char *src = NULL, *fstype = NULL, *optstr = NULL;

	rc = sscanf(s,	UL_SCNsA" "	/* (1) source */
			UL_SCNsA" "	/* (2) target */
			UL_SCNsA" "	/* (3) FS type */
			UL_SCNsA" "	/* (4) options */
			"%n",		/* byte count */

			&src,
			&fs->target,
			&fstype,
			&optstr,
			&n);
	xrc = rc;

	if (rc == 3 || rc == 4) {			/* options are optional */
		unmangle_string(src);
		unmangle_string(fs->target);
		unmangle_string(fstype);

		if (optstr && *optstr)
			unmangle_string(optstr);

		/* note that __foo functions does not reallocate the string
		 */
		rc = __mnt_fs_set_source_ptr(fs, src);
		if (!rc) {
			src = NULL;
			rc = __mnt_fs_set_fstype_ptr(fs, fstype);
			if (!rc)
				fstype = NULL;
		}
		if (!rc && optstr)
			rc = mnt_fs_set_options(fs, optstr);
		free(optstr);
		optstr = NULL;
	} else {
		DBG(TAB, mnt_debug("tab parse error: [sscanf rc=%d]: '%s'", rc, s));
		rc = -EINVAL;
	}

	if (rc) {
		free(src);
		free(fstype);
		free(optstr);
		DBG(TAB, mnt_debug("tab parse error: [set vars, rc=%d]\n", rc));
		return rc;	/* error */
	}

	fs->passno = fs->freq = 0;

	if (xrc == 4 && n)
		s = skip_spaces(s + n);
	if (xrc == 4 && *s) {
		if (next_number(&s, &fs->freq) != 0) {
			if (*s) {
				DBG(TAB, mnt_debug("tab parse error: [freq]"));
				rc = -EINVAL;
			}
		} else if (next_number(&s, &fs->passno) != 0 && *s) {
			DBG(TAB, mnt_debug("tab parse error: [passno]"));
			rc = -EINVAL;
		}
	}

	return rc;
}
Esempio n. 5
0
/*
 * Parses one line from mountinfo file
 */
static int mnt_parse_mountinfo_line(struct libmnt_fs *fs, char *s)
{
	int rc, end = 0;
	unsigned int maj, min;
	char *fstype = NULL, *src = NULL, *p;

	rc = sscanf(s,	"%u "		/* (1) id */
			"%u "		/* (2) parent */
			"%u:%u "	/* (3) maj:min */
			UL_SCNsA" "	/* (4) mountroot */
			UL_SCNsA" "	/* (5) target */
			UL_SCNsA	/* (6) vfs options (fs-independent) */
			"%n",		/* number of read bytes */

			&fs->id,
			&fs->parent,
			&maj, &min,
			&fs->root,
			&fs->target,
			&fs->vfs_optstr,
			&end);

	if (rc >= 7 && end > 0)
		s += end;

	/* (7) optional fields, terminated by " - " */
	p = strstr(s, " - ");
	if (!p) {
		DBG(TAB, mnt_debug("mountinfo parse error: not found separator"));
		return -EINVAL;
	}
	s = p + 3;

	rc += sscanf(s,	UL_SCNsA" "	/* (8) FS type */
			UL_SCNsA" "	/* (9) source */
			UL_SCNsA,	/* (10) fs options (fs specific) */

			&fstype,
			&src,
			&fs->fs_optstr);

	if (rc >= 10) {
		fs->flags |= MNT_FS_KERNEL;
		fs->devno = makedev(maj, min);

		unmangle_string(fs->root);
		unmangle_string(fs->target);
		unmangle_string(fs->vfs_optstr);
		unmangle_string(fstype);
		unmangle_string(src);
		unmangle_string(fs->fs_optstr);

		rc = __mnt_fs_set_fstype_ptr(fs, fstype);
		if (!rc) {
			fstype = NULL;
			rc = __mnt_fs_set_source_ptr(fs, src);
			if (!rc)
				src = NULL;
		}

		/* merge VFS and FS options to the one string */
		fs->optstr = mnt_fs_strdup_options(fs);
		if (!fs->optstr)
			rc = -ENOMEM;
	} else {
		free(fstype);
		free(src);
		DBG(TAB, mnt_debug(
			"mountinfo parse error [sscanf rc=%d]: '%s'", rc, s));
		rc = -EINVAL;
	}
	return rc;
}
Esempio n. 6
0
/*
 * Parses one line from a mountinfo file
 */
static int mnt_parse_mountinfo_line(struct libmnt_fs *fs, char *s)
{
	int rc, end = 0;
	unsigned int maj, min;
	char *fstype = NULL, *src = NULL, *p;

#ifndef HAVE_SCANF_MS_MODIFIER
	size_t len = strlen(s) + 1;
	fs->root = malloc(len);
	fs->target = malloc(len);
	fs->vfs_optstr = malloc(len);
	fs->fs_optstr = malloc(len);
	fstype = malloc(len);
	src = malloc(len);
#endif

	rc = sscanf(s,	"%d "		/* (1) id */
			"%d "		/* (2) parent */
			"%u:%u "	/* (3) maj:min */
			UL_SCNsA" "	/* (4) mountroot */
			UL_SCNsA" "	/* (5) target */
			UL_SCNsA	/* (6) vfs options (fs-independent) */
			"%n",		/* number of read bytes */

			&fs->id,
			&fs->parent,
			&maj, &min,
#ifdef HAVE_SCANF_MS_MODIFIER
			&fs->root,
			&fs->target,
			&fs->vfs_optstr,
#else
			fs->root,
			fs->target,
			fs->vfs_optstr,
#endif
			&end);

	if (rc >= 7 && end > 0)
		s += end;

	/* (7) optional fields, terminated by " - " */
	p = strstr(s, " - ");
	if (!p) {
		DBG(TAB, ul_debug("mountinfo parse error: separator not found"));
		return -EINVAL;
	}
	if (p > s + 1)
		fs->opt_fields = strndup(s + 1, p - s - 1);
	s = p + 3;

	rc += sscanf(s,	UL_SCNsA" "	/* (8) FS type */
			UL_SCNsA" "	/* (9) source */
			UL_SCNsA,	/* (10) fs options (fs specific) */

#ifdef HAVE_SCANF_MS_MODIFIER
			&fstype,
			&src,
			&fs->fs_optstr);
#else
			fstype,
			src,
			fs->fs_optstr);
#endif

	if (rc >= 10) {
		size_t sz;

		fs->flags |= MNT_FS_KERNEL;
		fs->devno = makedev(maj, min);

		/* remove "(deleted)" suffix */
		sz = strlen(fs->target);
		if (sz > PATH_DELETED_SUFFIX_SZ) {
			char *p = fs->target + (sz - PATH_DELETED_SUFFIX_SZ);

			if (strcmp(p, PATH_DELETED_SUFFIX) == 0)
				*p = '\0';
		}

		unmangle_string(fs->root);
		unmangle_string(fs->target);
		unmangle_string(fs->vfs_optstr);
		unmangle_string(fstype);
		unmangle_string(src);
		unmangle_string(fs->fs_optstr);

		rc = __mnt_fs_set_fstype_ptr(fs, fstype);
		if (!rc) {
			fstype = NULL;
			rc = __mnt_fs_set_source_ptr(fs, src);
			if (!rc)
				src = NULL;
		}

		/* merge VFS and FS options to one string */
		fs->optstr = mnt_fs_strdup_options(fs);
		if (!fs->optstr)
			rc = -ENOMEM;
	} else {
		free(fstype);
		free(src);
		DBG(TAB, ul_debug(
			"mountinfo parse error [sscanf rc=%d]: '%s'", rc, s));
		rc = -EINVAL;
	}
	return rc;
}