예제 #1
0
/*
 * Parse a single line of data, and return a newly allocated dev struct.
 * Add the new device to the cache struct, if one was read.
 *
 * Lines are of the form <device [TAG="value" ...]>/dev/foo</device>
 *
 * Returns -ve value on error.
 * Returns 0 otherwise.
 * If a valid device was read, *dev_p is non-NULL, otherwise it is NULL
 * (e.g. comment lines, unknown XML content, etc).
 */
static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp)
{
	blkid_dev dev;
	int ret;

	if (!cache || !dev_p)
		return -BLKID_ERR_PARAM;

	*dev_p = NULL;

	DBG(READ, ul_debug("line: %s", cp));

	if ((ret = parse_dev(cache, dev_p, &cp)) <= 0)
		return ret;

	dev = *dev_p;

	while ((ret = parse_tag(cache, dev, &cp)) > 0) {
		;
	}

	if (dev->bid_type == NULL) {
		DBG(READ, ul_debug("blkid: device %s has no TYPE",dev->bid_name));
		blkid_free_dev(dev);
		goto done;
	}

done:
	return ret;
}
예제 #2
0
파일: evaluate.c 프로젝트: 0xAX/util-linux
/**
 * blkid_send_uevent:
 * @devname: absolute path to the device
 * @action: event string
 *
 * Returns: -1 in case of failure, or 0 on success.
 */
int blkid_send_uevent(const char *devname, const char *action)
{
	char uevent[PATH_MAX];
	struct stat st;
	FILE *f;
	int rc = -1;

	DBG(EVALUATE, ul_debug("%s: uevent '%s' requested", devname, action));

	if (!devname || !action)
		return -1;
	if (stat(devname, &st) || !S_ISBLK(st.st_mode))
		return -1;

	snprintf(uevent, sizeof(uevent), "/sys/dev/block/%d:%d/uevent",
			major(st.st_rdev), minor(st.st_rdev));

	f = fopen(uevent, "w" UL_CLOEXECSTR);
	if (f) {
		rc = 0;
		if (fputs(action, f) >= 0)
			rc = 0;
		if (close_stream(f) != 0)
			DBG(EVALUATE, ul_debug("write failed: %s", uevent));
	}
	DBG(EVALUATE, ul_debug("%s: send uevent %s",
			uevent, rc == 0 ? "SUCCESS" : "FAILED"));
	return rc;
}
예제 #3
0
파일: init.c 프로젝트: ArakniD/util-linux
/**
 * mnt_init_debug:
 * @mask: debug mask (0xffff to enable full debugging)
 *
 * If the @mask is not specified, then this function reads
 * the LIBMOUNT_DEBUG environment variable to get the mask.
 *
 * Already initialized debugging stuff cannot be changed. Calling
 * this function twice has no effect.
 */
void mnt_init_debug(int mask)
{
	if (libmount_debug_mask)
		return;

	__UL_INIT_DEBUG(libmount, MNT_DEBUG_, mask, LIBMOUNT_DEBUG);

	if (libmount_debug_mask != MNT_DEBUG_INIT
	    && libmount_debug_mask != (MNT_DEBUG_HELP|MNT_DEBUG_INIT)) {
		const char *ver = NULL;
		const char **features = NULL, **p;

		mnt_get_library_version(&ver);
		mnt_get_library_features(&features);

		DBG(INIT, ul_debug("library debug mask: 0x%04x", libmount_debug_mask));
		DBG(INIT, ul_debug("library version: %s", ver));
		p = features;
		while (p && *p)
			DBG(INIT, ul_debug("    feature: %s", *p++));
	}

	ON_DBG(HELP, ul_debug_print_masks("LIBMOUNT_DEBUG",
				UL_DEBUG_MASKNAMES(libmount)));
}
예제 #4
0
/*
 * Note that the @target has to be an absolute path (so at least "/").  The
 * @filename returns an allocated buffer with the last path component, for example:
 *
 * mnt_chdir_to_parent("/mnt/test", &buf) ==> chdir("/mnt"), buf="test"
 */
int mnt_chdir_to_parent(const char *target, char **filename)
{
	char *buf, *parent, *last = NULL;
	char cwd[PATH_MAX];
	int rc = -EINVAL;

	if (!target || *target != '/')
		return -EINVAL;

	DBG(UTILS, ul_debug("moving to %s parent", target));

	buf = strdup(target);
	if (!buf)
		return -ENOMEM;

	if (*(buf + 1) != '\0') {
		last = stripoff_last_component(buf);
		if (!last)
			goto err;
	}

	parent = buf && *buf ? buf : "/";

	if (chdir(parent) == -1) {
		DBG(UTILS, ul_debug("failed to chdir to %s: %m", parent));
		rc = -errno;
		goto err;
	}
	if (!getcwd(cwd, sizeof(cwd))) {
		DBG(UTILS, ul_debug("failed to obtain current directory: %m"));
		rc = -errno;
		goto err;
	}
	if (strcmp(cwd, parent) != 0) {
		DBG(UTILS, ul_debug(
		    "unexpected chdir (expected=%s, cwd=%s)", parent, cwd));
		goto err;
	}

	DBG(CXT, ul_debug(
		"current directory moved to %s [last_component='%s']",
		parent, last));

	if (filename) {
		*filename = buf;

		if (!last || !*last)
			memcpy(*filename, ".", 2);
		else
			memmove(*filename, last, strlen(last) + 1);
	} else
		free(buf);
	return 0;
err:
	free(buf);
	return rc;
}
예제 #5
0
static int write_output(char *obuf, ssize_t bytes)
{
	DBG(PTY, ul_debug(" writing output"));

	if (write_all(STDOUT_FILENO, obuf, bytes)) {
		DBG(PTY, ul_debug("  writing output *failed*"));
		warn(_("write failed"));
		return -errno;
	}

	return 0;
}
예제 #6
0
파일: evaluate.c 프로젝트: 0xAX/util-linux
static char *evaluate_by_udev(const char *token, const char *value, int uevent)
{
	char dev[PATH_MAX];
	char *path = NULL;
	size_t len;
	struct stat st;

	DBG(EVALUATE, ul_debug("evaluating by udev %s=%s", token, value));

	if (!strcmp(token, "UUID"))
		strcpy(dev, _PATH_DEV_BYUUID "/");
	else if (!strcmp(token, "LABEL"))
		strcpy(dev, _PATH_DEV_BYLABEL "/");
	else if (!strcmp(token, "PARTLABEL"))
		strcpy(dev, _PATH_DEV_BYPARTLABEL "/");
	else if (!strcmp(token, "PARTUUID"))
		strcpy(dev, _PATH_DEV_BYPARTUUID "/");
	else {
		DBG(EVALUATE, ul_debug("unsupported token %s", token));
		return NULL;	/* unsupported tag */
	}

	len = strlen(dev);
	if (blkid_encode_string(value, &dev[len], sizeof(dev) - len) != 0)
		return NULL;

	DBG(EVALUATE, ul_debug("expected udev link: %s", dev));

	if (stat(dev, &st))
		goto failed;	/* link or device does not exist */

	if (!S_ISBLK(st.st_mode))
		return NULL;

	path = canonicalize_path(dev);
	if (!path)
		return NULL;

#ifdef CONFIG_BLKID_VERIFY_UDEV
	if (verify_tag(path, token, value))
		goto failed;
#endif
	return path;

failed:
	DBG(EVALUATE, ul_debug("failed to evaluate by udev"));

	if (uevent && path)
		blkid_send_uevent(path, "change");
	free(path);
	return NULL;
}
예제 #7
0
파일: vfat.c 프로젝트: Artox/fstools
/*
 * Look for LABEL (name) in the FAT root directory.
 */
static unsigned char *search_fat_label(blkid_probe pr,
				uint64_t offset, uint32_t entries)
{
	struct vfat_dir_entry *ent, *dir = NULL;
	uint32_t i;

	DBG(LOWPROBE, ul_debug("\tlook for label in root-dir "
			"(entries: %d, offset: %jd)", entries, offset));

	if (!blkid_probe_is_tiny(pr)) {
		/* large disk, read whole root directory */
		dir = (struct vfat_dir_entry *)
			blkid_probe_get_buffer(pr,
					offset,
					(blkid_loff_t) entries *
						sizeof(struct vfat_dir_entry));
		if (!dir)
			return NULL;
	}

	for (i = 0; i < entries; i++) {
		/*
		 * The root directory could be relatively large (4-16kB).
		 * Fortunately, the LABEL is usually the first entry in the
		 * directory. On tiny disks we call read() per entry.
		 */
		if (!dir)
			ent = (struct vfat_dir_entry *)
				blkid_probe_get_buffer(pr,
					(blkid_loff_t) offset + (i *
						sizeof(struct vfat_dir_entry)),
					sizeof(struct vfat_dir_entry));
		else
			ent = &dir[i];

		if (!ent || ent->name[0] == 0x00)
			break;

		if ((ent->name[0] == FAT_ENTRY_FREE) ||
		    (ent->cluster_high != 0 || ent->cluster_low != 0) ||
		    ((ent->attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME))
			continue;

		if ((ent->attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) ==
		    FAT_ATTR_VOLUME_ID) {
			DBG(LOWPROBE, ul_debug("\tfound fs LABEL at entry %d", i));
			return ent->name;
		}
	}
	return NULL;
}
예제 #8
0
/*
 * Allocate a new device struct with device name filled in.  Will handle
 * finding the device on lines of the form:
 * <device foo=bar>devname</device>
 * <device>devname<foo>bar</foo></device>
 */
static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp)
{
	char *start, *tmp, *end, *name;
	int ret;

	if ((ret = parse_start(cp)) <= 0)
		return ret;

	start = tmp = strchr(*cp, '>');
	if (!start) {
		DBG(READ, ul_debug("blkid: short line parsing dev: %s", *cp));
		return -BLKID_ERR_CACHE;
	}
	start = skip_over_blank(start + 1);
	end = skip_over_word(start);

	DBG(READ, ul_debug("device should be %*s",
			       (int)(end - start), start));

	if (**cp == '>')
		*cp = end;
	else
		(*cp)++;

	*tmp = '\0';

	if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0) {
		DBG(READ, ul_debug("blkid: missing </device> ending: %s", end));
	} else if (tmp)
		*tmp = '\0';

	if (end - start <= 1) {
		DBG(READ, ul_debug("blkid: empty device name: %s", *cp));
		return -BLKID_ERR_CACHE;
	}

	name = strndup(start, end - start);
	if (name == NULL)
		return -BLKID_ERR_MEM;

	DBG(READ, ul_debug("found dev %s", name));

	if (!(*dev = blkid_get_dev(cache, name, BLKID_DEV_CREATE))) {
		free(name);
		return -BLKID_ERR_MEM;
	}

	free(name);
	return 1;
}
예제 #9
0
파일: bsd.c 프로젝트: Berrrry/util-linux
/*
 * Read a bsd_disklabel from sector 0 or from the starting sector of p.
 * If it has the right magic, return 0.
 */
static int bsd_readlabel(struct fdisk_context *cxt)
{
    struct fdisk_bsd_label *l;
    struct bsd_disklabel *d;
    int t;
    off_t offset = 0;

    l = self_label(cxt);
    d = self_disklabel(cxt);

    if (l->dos_part)
        /* BSD is nested within DOS partition, get the begin of the
         * partition. Note that DOS uses native sector size. */
        offset = dos_partition_get_start(l->dos_part) * cxt->sector_size;

    if (lseek(cxt->dev_fd, offset, SEEK_SET) == -1)
        return -1;
    if (read_all(cxt->dev_fd, l->bsdbuffer, sizeof(l->bsdbuffer)) < 0)
        return errno ? -errno : -1;

    /* The offset to begin of the disk label. Note that BSD uses
     * 512-byte (default) sectors. */
    memmove(d, &l->bsdbuffer[BSD_LABELSECTOR * DEFAULT_SECTOR_SIZE
                             + BSD_LABELOFFSET], sizeof(*d));

    if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC) {
        DBG(LABEL, ul_debug("not found magic"));
        return -1;
    }

    for (t = d->d_npartitions; t < BSD_MAXPARTITIONS; t++) {
        d->d_partitions[t].p_size   = 0;
        d->d_partitions[t].p_offset = 0;
        d->d_partitions[t].p_fstype = BSD_FS_UNUSED;
    }

    if (d->d_npartitions > BSD_MAXPARTITIONS)
        fdisk_warnx(cxt, ("Too many partitions (%d, maximum is %d)."),
                    d->d_npartitions, BSD_MAXPARTITIONS);

    /* let's follow in-PT geometry */
    cxt->geom.sectors = d->d_nsectors;
    cxt->geom.heads = d->d_ntracks;
    cxt->geom.cylinders = d->d_ncylinders;

    cxt->label->nparts_cur = d->d_npartitions;
    cxt->label->nparts_max = BSD_MAXPARTITIONS;
    DBG(LABEL, ul_debug("read BSD label"));
    return 0;
}
예제 #10
0
/*
 * Don't export this to libmount API -- utab is private library stuff.
 *
 * If the file does not exist and @writable argument is not NULL, then it will
 * try to create the directory (e.g. /run/mount) and the file.
 *
 * Returns: 1 if utab is a regular file, and 0 in case of
 *          error (check errno for more details).
 */
int mnt_has_regular_utab(const char **utab, int *writable)
{
	struct stat st;
	int rc;
	const char *filename = utab && *utab ? *utab : mnt_get_utab_path();

	if (writable)
		*writable = 0;
	if (utab && !*utab)
		*utab = filename;

	DBG(UTILS, ul_debug("utab: %s", filename));

	rc = lstat(filename, &st);

	if (rc == 0) {
		/* file exists */
		if (S_ISREG(st.st_mode)) {
			if (writable)
				*writable = !try_write(filename);
			return 1;
		}
		goto done;	/* it's not a regular file */
	}

	if (writable) {
		char *dirname = strdup(filename);

		if (!dirname)
			goto done;

		stripoff_last_component(dirname);	/* remove filename */

		rc = mkdir(dirname, S_IWUSR|
				    S_IRUSR|S_IRGRP|S_IROTH|
				    S_IXUSR|S_IXGRP|S_IXOTH);
		free(dirname);
		if (rc && errno != EEXIST)
			goto done;			/* probably EACCES */

		*writable = !try_write(filename);
		if (*writable)
			return 1;
	}
done:
	DBG(UTILS, ul_debug("%s: irregular/non-writable file", filename));
	return 0;
}
예제 #11
0
파일: evaluate.c 프로젝트: 0xAX/util-linux
/**
 * blkid_evaluate_tag:
 * @token: token name (e.g "LABEL" or "UUID") or unparsed tag (e.g. "LABEL=foo")
 * @value: token data (e.g. "foo")
 * @cache: pointer to cache (or NULL when you don't want to re-use the cache)
 *
 * Returns: allocated string with a device name.
 */
char *blkid_evaluate_tag(const char *token, const char *value, blkid_cache *cache)
{
	struct blkid_config *conf = NULL;
	char *t = NULL, *v = NULL;
	char *ret = NULL;
	int i;

	if (!token)
		return NULL;

	if (!cache || !*cache)
		blkid_init_debug(0);

	DBG(EVALUATE, ul_debug("evaluating  %s%s%s", token, value ? "=" : "",
		   value ? value : ""));

	if (!value) {
		if (!strchr(token, '=')) {
			ret = strdup(token);
			goto out;
		}
		blkid_parse_tag_string(token, &t, &v);
		if (!t || !v)
			goto out;
		token = t;
		value = v;
	}

	conf = blkid_read_config(NULL);
	if (!conf)
		goto out;

	for (i = 0; i < conf->nevals; i++) {
		if (conf->eval[i] == BLKID_EVAL_UDEV)
			ret = evaluate_by_udev(token, value, conf->uevent);
		else if (conf->eval[i] == BLKID_EVAL_SCAN)
			ret = evaluate_by_scan(token, value, cache, conf);
		if (ret)
			break;
	}

	DBG(EVALUATE, ul_debug("%s=%s evaluated as %s", token, value, ret));
out:
	blkid_free_config(conf);
	free(t);
	free(v);
	return ret;
}
예제 #12
0
int mnt_get_gid(const char *groupname, gid_t *gid)
{
	int rc = -1;
        struct group grp;
	struct group *gr;
	size_t sz = get_pw_record_size();
	char *buf;

	if (!groupname || !gid)
		return -EINVAL;

	buf = malloc(sz);
	if (!buf)
		return -ENOMEM;

	if (!getgrnam_r(groupname, &grp, buf, sz, &gr) && gr) {
		*gid= gr->gr_gid;
		rc = 0;
	} else {
		DBG(UTILS, ul_debug(
			"cannot convert '%s' groupname to GID", groupname));
		rc = errno ? -errno : -EINVAL;
	}

	free(buf);
	return rc;
}
예제 #13
0
파일: optstr.c 프로젝트: JohnLih/util-linux
/**
 * mnt_optstr_prepend_option:
 * @optstr: option string or NULL, returns a reallocated string
 * @name: value name
 * @value: value
 *
 * Returns: 0 on success or <0 in case of error. After an error the @optstr should
 *          be unmodified.
 */
int mnt_optstr_prepend_option(char **optstr, const char *name, const char *value)
{
	int rc = 0;
	char *tmp;

	if (!optstr)
		return -EINVAL;
	if (!name || !*name)
		return 0;

	tmp = *optstr;
	*optstr = NULL;

	rc = mnt_optstr_append_option(optstr, name, value);
	if (!rc && tmp && *tmp)
		rc = mnt_optstr_append_option(optstr, tmp, NULL);
	if (!rc) {
		free(tmp);
		return 0;
	}

	free(*optstr);
	*optstr = tmp;

	DBG(OPTIONS, ul_debug("failed to prepend '%s[=%s]' to '%s'",
				name, value, *optstr));
	return rc;
}
예제 #14
0
static pid_t path_to_tid(const char *filename)
{
	char *path = mnt_resolve_path(filename, NULL);
	char *p, *end = NULL;
	pid_t tid = 0;

	if (!path)
		goto done;
	p = strrchr(path, '/');
	if (!p)
		goto done;
	*p = '\0';
	p = strrchr(path, '/');
	if (!p)
		goto done;
	p++;

	errno = 0;
	tid = strtol(p, &end, 10);
	if (errno || p == end || (end && *end)) {
		tid = 0;
		goto done;
	}
	DBG(TAB, ul_debug("TID for %s is %d", filename, tid));
done:
	free(path);
	return tid;
}
예제 #15
0
파일: evaluate.c 프로젝트: 0xAX/util-linux
static char *evaluate_by_scan(const char *token, const char *value,
		blkid_cache *cache, struct blkid_config *conf)
{
	blkid_cache c = cache ? *cache : NULL;
	char *res;

	DBG(EVALUATE, ul_debug("evaluating by blkid scan %s=%s", token, value));

	if (!c) {
		char *cachefile = blkid_get_cache_filename(conf);
		blkid_get_cache(&c, cachefile);
		free(cachefile);
	}
	if (!c)
		return NULL;

	res = blkid_get_devname(c, token, value);

	if (cache)
		*cache = c;
	else
		blkid_put_cache(c);

	return res;
}
예제 #16
0
static int get_user_reply(const char *prompt, char *buf, size_t bufsz)
{
	char *p;
	size_t sz;

#ifdef HAVE_LIBREADLINE
	if (isatty(STDIN_FILENO)) {
		p = readline(prompt);
		if (!p)
			return 1;
		memcpy(buf, p, bufsz);
		free(p);
	} else
#endif
	{
		fputs(prompt, stdout);
		fflush(stdout);

		if (!fgets(buf, bufsz, stdin))
			return 1;
	}

	for (p = buf; *p && !isgraph(*p); p++);	/* get first non-blank */

	if (p > buf)
		memmove(buf, p, p - buf);	/* remove blank space */
	sz = strlen(buf);
	if (sz && *(buf + sz - 1) == '\n')
		*(buf + sz - 1) = '\0';

	DBG(ASK, ul_debug("user's reply: >>>%s<<<", buf));
	return 0;
}
예제 #17
0
static int get_filesystems(const char *filename, char ***filesystems, const char *pattern)
{
	int rc = 0;
	FILE *f;
	char line[129];

	f = fopen(filename, "r" UL_CLOEXECSTR);
	if (!f)
		return 1;

	DBG(UTILS, ul_debug("reading filesystems list from: %s", filename));

	while (fgets(line, sizeof(line), f)) {
		char name[sizeof(line)];

		if (*line == '#' || strncmp(line, "nodev", 5) == 0)
			continue;
		if (sscanf(line, " %128[^\n ]\n", name) != 1)
			continue;
		if (strcmp(name, "*") == 0) {
			rc = 1;
			break;		/* end of the /etc/filesystems */
		}
		if (pattern && !mnt_match_fstype(name, pattern))
			continue;
		rc = add_filesystem(filesystems, name);
		if (rc)
			break;
	}

	fclose(f);
	return rc;
}
예제 #18
0
/*
 * Extract a tag from the line.
 *
 * Return 1 if a valid tag was found.
 * Return 0 if no tag found.
 * Return -ve error code.
 */
static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp)
{
	char *name = NULL;
	char *value = NULL;
	int ret;

	if (!cache || !dev)
		return -BLKID_ERR_PARAM;

	if ((ret = parse_token(&name, &value, cp)) <= 0 /* &&
	    (ret = parse_xml(&name, &value, cp)) <= 0 */)
		return ret;

	DBG(READ, ul_debug("tag: %s=\"%s\"", name, value));

	/* Some tags are stored directly in the device struct */
	if (!strcmp(name, "DEVNO"))
		dev->bid_devno = strtoull(value, NULL, 0);
	else if (!strcmp(name, "PRI"))
		dev->bid_pri = strtol(value, NULL, 0);
	else if (!strcmp(name, "TIME")) {
		char *end = NULL;
		dev->bid_time = strtoull(value, &end, 0);
		if (end && *end == '.')
			dev->bid_utime = strtoull(end + 1, NULL, 0);
	} else
		ret = blkid_set_tag(dev, name, value, strlen(value));

	return ret < 0 ? ret : 1;
}
예제 #19
0
/*
 * Start parsing a new line from the cache.
 *
 * line starts with "<device" return 1 -> continue parsing line
 * line starts with "<foo", empty, or # return 0 -> skip line
 * line starts with other, return -BLKID_ERR_CACHE -> error
 */
static int parse_start(char **cp)
{
	char *p;

	p = strip_line(*cp);

	/* Skip comment or blank lines.  We can't just NUL the first '#' char,
	 * in case it is inside quotes, or escaped.
	 */
	if (*p == '\0' || *p == '#')
		return 0;

	if (!strncmp(p, "<device", 7)) {
		DBG(READ, ul_debug("found device header: %8s", p));
		p += 7;

		*cp = p;
		return 1;
	}

	if (*p == '<')
		return 0;

	return -BLKID_ERR_CACHE;
}
예제 #20
0
int mnt_get_uid(const char *username, uid_t *uid)
{
	int rc = -1;
        struct passwd pwd;
	struct passwd *pw;
	size_t sz = get_pw_record_size();
	char *buf;

	if (!username || !uid)
		return -EINVAL;

	buf = malloc(sz);
	if (!buf)
		return -ENOMEM;

	if (!getpwnam_r(username, &pwd, buf, sz, &pw) && pw) {
		*uid= pw->pw_uid;
		rc = 0;
	} else {
		DBG(UTILS, ul_debug(
			"cannot convert '%s' username to UID", username));
		rc = errno ? -errno : -EINVAL;
	}

	free(buf);
	return rc;
}
예제 #21
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, ul_debug("utab parse error: ENOMEM"));
	return -ENOMEM;
}
예제 #22
0
파일: fdisk.c 프로젝트: wavenger/util-linux
int get_user_reply(struct fdisk_context *cxt, const char *prompt,
			  char *buf, size_t bufsz)
{
	char *p;
	size_t sz;

	do {
	        fputs(prompt, stdout);
		fflush(stdout);

		if (!fgets(buf, bufsz, stdin)) {
			if (fdisk_label_is_changed(fdisk_get_label(cxt, NULL))) {
				fprintf(stderr, _("\nDo you really want to quit? "));

				if (fgets(buf, bufsz, stdin) && !rpmatch(buf))
					continue;
			}
			fdisk_free_context(cxt);
			exit(EXIT_FAILURE);
		} else
			break;
	} while (1);

	for (p = buf; *p && !isgraph(*p); p++);	/* get first non-blank */

	if (p > buf)
		memmove(buf, p, p - buf);		/* remove blank space */
	sz = strlen(buf);
	if (sz && *(buf + sz - 1) == '\n')
		*(buf + sz - 1) = '\0';

	DBG(ASK, ul_debug("user's reply: >>>%s<<<", buf));
	return 0;
}
예제 #23
0
static void init_tty(struct su_context *su)
{
	su->isterm = isatty(STDIN_FILENO) ? 1 : 0;
	DBG(TTY, ul_debug("initialize [is-term=%s]", su->isterm ? "true" : "false"));
	if (su->isterm)
		get_terminal_name(NULL, &su->tty_name, &su->tty_number);
}
예제 #24
0
static void __attribute__((__noreturn__)) done(struct script_control *ctl)
{
	DBG(MISC, ul_debug("done!"));

	if (ctl->isterm)
		tcsetattr(STDIN_FILENO, TCSADRAIN, &ctl->attrs);
	if (!ctl->quiet)
		printf(_("Script done, file is %s\n"), ctl->fname);
#ifdef HAVE_LIBUTEMPTER
	if (ctl->master >= 0)
		utempter_remove_record(ctl->master);
#endif
	kill(ctl->child, SIGTERM);	/* make sure we don't create orphans */

	if (ctl->timingfp)
		fclose(ctl->timingfp);
	fclose(ctl->typescriptfp);

	if (ctl->rc_wanted) {
		if (WIFSIGNALED(ctl->childstatus))
			exit(WTERMSIG(ctl->childstatus) + 0x80);
		else
			exit(WEXITSTATUS(ctl->childstatus));
	}
	exit(EXIT_SUCCESS);
}
예제 #25
0
/*
 * Returns 1 if the @major number is associated with @drvname.
 */
int blkid_driver_has_major(const char *drvname, int major)
{
	FILE *f;
	char buf[128];
	int match = 0;

	f = fopen(_PATH_PROC_DEVICES, "r" UL_CLOEXECSTR);
	if (!f)
		return 0;

	while (fgets(buf, sizeof(buf), f)) {	/* skip to block dev section */
		if (strncmp("Block devices:\n", buf, sizeof(buf)) == 0)
			break;
	}

	while (fgets(buf, sizeof(buf), f)) {
		int maj;
		char name[64 + 1];

		if (sscanf(buf, "%d %64[^\n ]", &maj, name) != 2)
			continue;

		if (maj == major && strcmp(name, drvname) == 0) {
			match = 1;
			break;
		}
	}

	fclose(f);

	DBG(DEVNO, ul_debug("major %d %s associated with '%s' driver",
			major, match ? "is" : "is NOT", drvname));
	return match;
}
예제 #26
0
static void findin(const char *dir, const char *pattern, int *count, char **wait)
{
	DIR *dirp;
	struct dirent *dp;

	dirp = opendir(dir);
	if (dirp == NULL)
		return;

	DBG(SEARCH, ul_debug("find '%s' in '%s'", pattern, dir));

	while ((dp = readdir(dirp)) != NULL) {
		if (!filename_equal(pattern, dp->d_name))
			continue;

		if (uflag && *count == 0)
			xasprintf(wait, "%s/%s", dir, dp->d_name);

		else if (uflag && *count == 1 && *wait) {
			printf("%s: %s %s/%s", pattern, *wait, dir,  dp->d_name);
			free(*wait);
			*wait = NULL;
		} else
			printf(" %s/%s", dir, dp->d_name);
		++(*count);
	}
	closedir(dirp);
	return;
}
예제 #27
0
static int filename_equal(const char *cp, const char *dp)
{
	int i = strlen(dp);

	DBG(SEARCH, ul_debug("compare '%s' and '%s'", cp, dp));

	if (dp[0] == 's' && dp[1] == '.' && filename_equal(cp, dp + 2))
		return 1;
	if (!strcmp(dp + i - 2, ".Z"))
		i -= 2;
	else if (!strcmp(dp + i - 3, ".gz"))
		i -= 3;
	else if (!strcmp(dp + i - 3, ".xz"))
		i -= 3;
	else if (!strcmp(dp + i - 4, ".bz2"))
		i -= 4;
	while (*cp && *dp && *cp == *dp)
		cp++, dp++, i--;
	if (*cp == 0 && *dp == 0)
		return 1;
	while (isdigit(*dp))
		dp++;
	if (*cp == 0 && *dp++ == '.') {
		--i;
		while (i > 0 && *dp)
			if (--i, *dp++ == '.')
				return (*dp++ == 'C' && *dp++ == 0);
		return 1;
	}
	return 0;
}
예제 #28
0
void blkid__scan_dir(char *dirname, dev_t devno, struct dir_list **list,
		     char **devname)
{
	DIR	*dir;
	struct dirent *dp;
	struct stat st;

	if ((dir = opendir(dirname)) == NULL)
		return;

	while ((dp = readdir(dir)) != NULL) {
#ifdef _DIRENT_HAVE_D_TYPE
		if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_BLK &&
		    dp->d_type != DT_LNK && dp->d_type != DT_DIR)
			continue;
#endif
		if (dp->d_name[0] == '.' &&
		    ((dp->d_name[1] == 0) ||
		     ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
			continue;

		if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 0))
			continue;

		if (S_ISBLK(st.st_mode) && st.st_rdev == devno) {
			*devname = blkid_strconcat(dirname, "/", dp->d_name);
			DBG(DEVNO, ul_debug("found 0x%llx at %s", (long long)devno,
				   *devname));
			break;
		}

		if (!list || !S_ISDIR(st.st_mode))
			continue;

		/* add subdirectory (but not symlink) to the list */
#ifdef _DIRENT_HAVE_D_TYPE
		if (dp->d_type == DT_LNK)
			continue;
		if (dp->d_type == DT_UNKNOWN)
#endif
		{
			if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 1) ||
			    !S_ISDIR(st.st_mode))
				continue;	/* symlink or lstat() failed */
		}

		if (*dp->d_name == '.' || (
#ifdef _DIRENT_HAVE_D_TYPE
		    dp->d_type == DT_DIR &&
#endif
		    strcmp(dp->d_name, "shm") == 0))
			/* ignore /dev/.{udev,mount,mdadm} and /dev/shm */
			continue;

		add_to_dirlist(dirname, dp->d_name, list);
	}
	closedir(dir);
	return;
}
예제 #29
0
void fdisk_label_set_disabled(struct fdisk_label *lb, int disabled)
{
	assert(lb);

	DBG(LABEL, ul_debug("%s label %s",
				lb->name,
				disabled ? "DISABLED" : "ENABLED"));
	lb->disabled = disabled ? 1 : 0;
}
예제 #30
0
static void pty_cleanup(struct su_context *su)
{
	if (su->pty_master == -1)
		return;

	DBG(PTY, ul_debug("cleanup"));
	if (su->isterm)
		tcsetattr(STDIN_FILENO, TCSADRAIN, &su->stdin_attrs);
}