Example #1
0
/**
 * mnt_table_parse_mtab:
 * @tb: table
 * @filename: overwrites default (/etc/mtab or $LIBMOUNT_MTAB) or NULL
 *
 * This function parses /etc/mtab or /proc/self/mountinfo +
 * /run/mount/utabs or /proc/mounts.
 *
 * See also mnt_table_set_parser_errcb().
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_parse_mtab(struct libmnt_table *tb, const char *filename)
{
	int rc;
	const char *utab = NULL;

	if (mnt_has_regular_mtab(&filename, NULL)) {

		DBG(TAB, mnt_debug_h(tb, "force %s usage", filename));

		rc = mnt_table_parse_file(tb, filename);
		if (!rc)
			return 0;
		filename = NULL;	/* failed */
	}

	/*
	 * useless /etc/mtab
	 * -- read kernel information from /proc/self/mountinfo
	 */
	tb->fmt = MNT_FMT_MOUNTINFO;
	rc = mnt_table_parse_file(tb, _PATH_PROC_MOUNTINFO);
	if (rc) {
		/* hmm, old kernel? ...try /proc/mounts */
		tb->fmt = MNT_FMT_MTAB;
		return mnt_table_parse_file(tb, _PATH_PROC_MOUNTS);
	}

	/*
	 * try to read user specific information from /run/mount/utabs
	 */
	utab = mnt_get_utab_path();
	if (utab) {
		struct libmnt_table *u_tb = mnt_new_table();
		if (u_tb) {
			u_tb->fmt = MNT_FMT_UTAB;
			mnt_table_set_parser_fltrcb(u_tb, tb->fltrcb, tb->fltrcb_data);

			if (mnt_table_parse_file(u_tb, utab) != 0) {
				mnt_free_table(u_tb);
				u_tb = NULL;
			}
		}

		if (u_tb) {
			struct libmnt_fs *u_fs;
			struct libmnt_iter itr;

			mnt_reset_iter(&itr, MNT_ITER_BACKWARD);

			/*  merge user options into mountinfo from kernel */
			while(mnt_table_next_fs(u_tb, &itr, &u_fs) == 0)
				mnt_table_merge_user_fs(tb, u_fs);

			mnt_free_table(u_tb);
		}
	}
	return 0;
}
Example #2
0
/* returns: error = -1, success = 0 , unknown = 1 */
static int is_vers4(struct libmnt_context *cxt)
{
    struct libmnt_fs *fs = mnt_context_get_fs(cxt);
    struct libmnt_table *tb = NULL;
    const char *src = mnt_context_get_source(cxt),
                *tgt = mnt_context_get_target(cxt);
    int rc = 1;

    if (!src || !tgt)
        return -1;

    if (!mnt_fs_is_kernel(fs)) {
        struct libmnt_table *tb = mnt_new_table_from_file("/proc/mounts");

        if (!tb)
            return -1;
        fs = mnt_table_find_pair(tb, src, tgt, MNT_ITER_BACKWARD);
    }

    if (fs) {
        const char *type = mnt_fs_get_fstype(fs);
        if (type && strcmp(type, "nfs4") == 0)
            rc = 0;
    }
    mnt_free_table(tb);
    return rc;
}
Example #3
0
static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *lc)
{
	struct libmnt_table *tb = NULL;
	int rc = 0;

	DBG(UPDATE, mnt_debug_h(upd, "%s: modify target", upd->filename));

	if (lc)
		rc = mnt_lock_file(lc);
	if (rc)
		return rc;

	tb = __mnt_new_table_from_file(upd->filename,
			upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
	if (tb) {
		struct libmnt_fs *cur = mnt_table_find_target(tb,
				mnt_fs_get_srcpath(upd->fs), MNT_ITER_BACKWARD);
		if (cur) {
			rc = mnt_fs_set_target(cur, mnt_fs_get_target(upd->fs));
			if (!rc)
				rc = update_table(upd, tb);
		}
	}

	if (lc)
		mnt_unlock_file(lc);

	mnt_free_table(tb);
	return rc;
}
Example #4
0
static int update_remove_entry(struct libmnt_update *upd, struct libmnt_lock *lc)
{
	struct libmnt_table *tb;
	int rc = 0;

	assert(upd);
	assert(upd->target);

	DBG(UPDATE, mnt_debug_h(upd, "%s: remove entry", upd->filename));

	if (lc)
		rc = mnt_lock_file(lc);
	if (rc)
		return rc;

	tb = __mnt_new_table_from_file(upd->filename,
			upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
	if (tb) {
		struct libmnt_fs *rem = mnt_table_find_target(tb, upd->target, MNT_ITER_BACKWARD);
		if (rem) {
			mnt_table_remove_fs(tb, rem);
			rc = update_table(upd, tb);
			mnt_free_fs(rem);
		}
	}

	if (lc)
		mnt_unlock_file(lc);

	mnt_free_table(tb);
	return rc;
}
Example #5
0
static int update_add_entry(struct libmnt_update *upd, struct libmnt_lock *lc)
{
	struct libmnt_table *tb;
	int rc = 0;

	assert(upd);
	assert(upd->fs);

	DBG(UPDATE, mnt_debug_h(upd, "%s: add entry", upd->filename));

	if (lc)
		rc = mnt_lock_file(lc);
	if (rc)
		return rc;

	tb = __mnt_new_table_from_file(upd->filename,
			upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
	if (tb) {
		struct libmnt_fs *fs = mnt_copy_fs(NULL, upd->fs);
		if (!fs)
			rc = -ENOMEM;
		else {
			mnt_table_add_fs(tb, fs);
			rc = update_table(upd, tb);
		}
	}

	if (lc)
		mnt_unlock_file(lc);

	mnt_free_table(tb);
	return rc;
}
Example #6
0
/**
 * mnt_unref_table:
 * @tb: table pointer
 *
 * De-increments reference counter, on zero the @tb is automatically
 * deallocated by mnt_free_table().
 */
void mnt_unref_table(struct libmnt_table *tb)
{
	if (tb) {
		tb->refcount--;
		/*DBG(FS, ul_debugobj(tb, "unref=%d", tb->refcount));*/
		if (tb->refcount <= 0)
			mnt_free_table(tb);
	}
}
Example #7
0
static int dir_to_device(const char *spec, dev_t *dev)
{
	struct libmnt_table *tb = mnt_new_table_from_file("/proc/self/mountinfo");
	struct libmnt_fs *fs;
	struct libmnt_cache *cache;
	int rc = -1;

	if (!tb) {
		/*
		 * Fallback. Traditional way to detect mountpoints. This way
		 * is independent on /proc, but not able to detect bind mounts.
		 */
		struct stat pst, st;
		char buf[PATH_MAX], *cn;
		int len;

		if (stat(spec, &st) != 0)
			return -1;

		cn = mnt_resolve_path(spec, NULL);	/* canonicalize */

		len = snprintf(buf, sizeof(buf), "%s/..", cn ? cn : spec);
		free(cn);

		if (len < 0 || (size_t) len + 1 > sizeof(buf))
			return -1;
		if (stat(buf, &pst) !=0)
			return -1;

		if ((st.st_dev != pst.st_dev) ||
		    (st.st_dev == pst.st_dev && st.st_ino == pst.st_ino)) {
			*dev = st.st_dev;
			return 0;
		}

		return -1;
	}

	/* to canonicalize all necessary paths */
	cache = mnt_new_cache();
	mnt_table_set_cache(tb, cache);

	fs = mnt_table_find_target(tb, spec, MNT_ITER_BACKWARD);
	if (fs && mnt_fs_get_target(fs)) {
		*dev = mnt_fs_get_devno(fs);
		rc = 0;
	}

	mnt_free_table(tb);
	mnt_free_cache(cache);
	return rc;
}
Example #8
0
/**
 * mnt_free_update:
 * @upd: update
 *
 * Deallocates struct libmnt_update handler.
 */
void mnt_free_update(struct libmnt_update *upd)
{
	if (!upd)
		return;

	DBG(UPDATE, mnt_debug_h(upd, "free"));

	mnt_free_fs(upd->fs);
	mnt_free_table(upd->mountinfo);
	free(upd->target);
	free(upd->filename);
	free(upd);
}
Example #9
0
/**
 * mnt_new_table_from_dir
 * @dirname: directory with *.fstab files
 *
 * Returns: newly allocated tab on success and NULL in case of error.
 */
struct libmnt_table *mnt_new_table_from_dir(const char *dirname)
{
	struct libmnt_table *tb;

	assert(dirname);
	if (!dirname)
		return NULL;
	tb = mnt_new_table();
	if (tb && mnt_table_parse_dir(tb, dirname) != 0) {
		mnt_free_table(tb);
		tb = NULL;
	}
	return tb;
}
Example #10
0
static char *dir_to_device(const char *spec)
{
	struct libmnt_table *tb = mnt_new_table_from_file("/proc/self/mountinfo");
	struct libmnt_fs *fs;
	char *res = NULL;

	if (!tb)
		return NULL;

	fs = mnt_table_find_target(tb, spec, MNT_ITER_BACKWARD);
	if (fs && mnt_fs_get_target(fs))
		res = xstrdup(mnt_fs_get_source(fs));

	mnt_free_table(tb);
	return res;
}
Example #11
0
int main(const int argc, const char* argv[]) {
    if (argc == 2) {
        if (strcmp(argv[1], "--verbose") == 0) {
            verbose_mode = 1;
        }
    }

    prepare();
    clearSupplementaryGroups();
    selfCheck();

    struct libmnt_table* mt = mnt_new_table_from_file("/opt/xware_desktop/mounts");
    if (mt == NULL) {
        fprintf(stderr, "mnt_new_table_from_file failed.\n");
        exit(EXIT_FAILURE);
    }
    struct libmnt_iter* itr = mnt_new_iter(MNT_ITER_FORWARD);
    struct libmnt_fs* fs = NULL;

    while(1) {
        int tmp = mnt_table_find_next_fs(mt, itr, &matchAll, NULL, &fs);
        if (tmp < 0) { // error
            fprintf(stderr, "mnt_table_find_next_fs failed.\n");
            break;
        } else {
            if (tmp == 1) { // reach EOF
                break;
            }
            const char* target = mnt_fs_get_target(fs);
            if (target == NULL) {
                fprintf(stderr, "mnt_fs_get_target failed.\n");
            } else {
                printf("%s%s%s\n", BOLD, target, NOSTYLE);
                printf("================================\n");
                if (checkDirXPermissions(target)) {
                    checkTargetDirPermissions(target);
                }
                printf("\n");
            }
        }
    }
    printf("%s", NOSTYLE);
    mnt_free_fs(fs);
    mnt_free_iter(itr);
    mnt_free_table(mt);
    return 0;
}
Example #12
0
int main (int argc, char *argv[])
{
	struct libmnt_fs *fs;
	struct libmnt_table *tab;

	mnt_init_debug(0xffff);

	tab = mnt_new_table_from_file("/proc/self/mounts");

	fs = mnt_table_find_target(tab, argv[2], MNT_ITER_BACKWARD);
	char *source = mnt_fs_get_source(fs);

	if (strcmp(source, argv[1]) == 0)
		printf("is mounted\n");
	else
		printf("could not find fs in tab\n");

	mnt_free_table(tab);

#if 0
	int rc;
	struct libmnt_fs *fs;
	struct libmnt_context *cxt = mnt_new_context();

	mnt_init_debug(0xffff);

	mnt_context_set_source(cxt, argv[1]);
	mnt_context_set_target(cxt, argv[2]);

	fs = mnt_context_get_fs(cxt);
	if (fs != NULL)
	{
		if (mnt_context_is_fs_mounted(cxt, fs, &rc))
			rc = 1;
		else
			printf("can't find fs in mtab\n");
	}
	else
		printf("Can't get fs from mnt context\n");

	mnt_free_context(cxt);
#endif

	return 0;
}
Example #13
0
struct libmnt_table *__mnt_new_table_from_file(const char *filename, int fmt)
{
	struct libmnt_table *tb;
	struct stat st;

	assert(filename);
	if (!filename)
		return NULL;
	if (stat(filename, &st))
		return NULL;
	tb = mnt_new_table();
	if (tb) {
		tb->fmt = fmt;
		if (mnt_table_parse_file(tb, filename) != 0) {
			mnt_free_table(tb);
			tb = NULL;
		}
	}
	return tb;
}
Example #14
0
static int update_modify_options(struct libmnt_update *upd, struct libmnt_lock *lc)
{
	struct libmnt_table *tb = NULL;
	int rc = 0;
	struct libmnt_fs *fs;

	assert(upd);
	assert(upd->fs);

	DBG(UPDATE, mnt_debug_h(upd, "%s: modify options", upd->filename));

	fs = upd->fs;

	if (lc)
		rc = mnt_lock_file(lc);
	if (rc)
		return rc;

	tb = __mnt_new_table_from_file(upd->filename,
			upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
	if (tb) {
		struct libmnt_fs *cur = mnt_table_find_target(tb,
					mnt_fs_get_target(fs),
					MNT_ITER_BACKWARD);
		if (cur) {
			if (upd->userspace_only)
				rc = mnt_fs_set_attributes(cur,	mnt_fs_get_attributes(fs));
			if (!rc)
				rc = mnt_fs_set_options(cur, mnt_fs_get_options(fs));
			if (!rc)
				rc = update_table(upd, tb);
		}
	}

	if (lc)
		mnt_unlock_file(lc);

	mnt_free_table(tb);
	return rc;
}
Example #15
0
/* main program */
int main(int argc, char **argv)
{
	char *device = NULL;
	char *disk = NULL;
	char *mountpoint = NULL;
	int worked = 0;    /* set to 1 when successfully ejected */
	int fd;            /* file descriptor for device */

	setlocale(LC_ALL,"");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	/* parse the command line arguments */
	parse_args(argc, argv, &device);

	/* handle -d option */
	if (d_option) {
		info(_("default device: `%s'"), EJECT_DEFAULT_DEVICE);
		return EXIT_SUCCESS;
	}

	if (!device) {
		device = mnt_resolve_path(EJECT_DEFAULT_DEVICE, NULL);
		verbose(_("using default device `%s'"), device);
	} else {
		char *p;

		if (device[strlen(device)-1] == '/')
			device[strlen(device)-1] = '\0';

		/* figure out full device or mount point name */
		p = find_device(device);
		if (p)
			free(device);
		else
			p = device;

		device = mnt_resolve_spec(p, NULL);
		free(p);
	}

	if (!device)
		errx(EXIT_FAILURE, _("%s: unable to find device"), device);

	verbose(_("device name is `%s'"), device);

	device_get_mountpoint(&device, &mountpoint);
	if (mountpoint)
		verbose(_("%s: mounted at %s"), device, mountpoint);
	else
		verbose(_("%s: not mounted"), device);

	disk = get_disk_devname(device);
	if (disk) {
		verbose(_("%s: disc device: %s (disk device will be used for eject)"), device, disk);
		free(device);
		device = disk;
		disk = NULL;
	} else
		verbose(_("%s: is whole-disk device"), device);

	if (F_option == 0 && is_hotpluggable(device) == 0)
		errx(EXIT_FAILURE, _("%s: is not hot-pluggable device"), device);

	/* handle -n option */
	if (n_option) {
		info(_("device is `%s'"), device);
		verbose(_("exiting due to -n/--noop option"));
		return EXIT_SUCCESS;
	}

	/* handle -i option */
	if (i_option) {
		fd = open_device(device);
		manual_eject(fd, i_arg);
		return EXIT_SUCCESS;
	}

	/* handle -a option */
	if (a_option) {
		if (a_arg)
			verbose(_("%s: enabling auto-eject mode"), device);
		else
			verbose(_("%s: disabling auto-eject mode"), device);
		fd = open_device(device);
		auto_eject(fd, a_arg);
		return EXIT_SUCCESS;
	}

	/* handle -t option */
	if (t_option) {
		verbose(_("%s: closing tray"), device);
		fd = open_device(device);
		close_tray(fd);
		set_device_speed(device);
		return EXIT_SUCCESS;
	}

	/* handle -T option */
	if (T_option) {
		verbose(_("%s: toggling tray"), device);
		fd = open_device(device);
		toggle_tray(fd);
		set_device_speed(device);
		return EXIT_SUCCESS;
	}

	/* handle -X option */
	if (X_option) {
		verbose(_("%s: listing CD-ROM speed"), device);
		fd = open_device(device);
		list_speeds(device, fd);
		return EXIT_SUCCESS;
	}

	/* handle -x option only */
	if (!c_option)
		set_device_speed(device);


	/* if it is a multipartition device, unmount any other partitions on
	   the device */
	if (m_option != 1) {
		if (mountpoint)
			umount_one(mountpoint);		/* usually whole-disk */
		umount_partitions(device);
	}

	/* handle -c option */
	if (c_option) {
		verbose(_("%s: selecting CD-ROM disc #%ld"), device, c_arg);
		fd = open_device(device);
		changer_select(fd, c_arg);
		set_device_speed(device);
		return EXIT_SUCCESS;
	}

	/* if user did not specify type of eject, try all four methods */
	if (r_option + s_option + f_option + q_option == 0)
		r_option = s_option = f_option = q_option = 1;

	/* open device */
	fd = open_device(device);

	/* try various methods of ejecting until it works */
	if (r_option) {
		verbose(_("%s: trying to eject using CD-ROM eject command"), device);
		worked = eject_cdrom(fd);
		verbose(worked ? _("CD-ROM eject command succeeded") :
				 _("CD-ROM eject command failed"));
	}

	if (s_option && !worked) {
		verbose(_("%s: trying to eject using SCSI commands"), device);
		worked = eject_scsi(fd);
		verbose(worked ? _("SCSI eject succeeded") :
				 _("SCSI eject failed"));
	}

	if (f_option && !worked) {
		verbose(_("%s: trying to eject using floppy eject command"), device);
		worked = eject_floppy(fd);
		verbose(worked ? _("floppy eject command succeeded") :
				 _("floppy eject command failed"));
	}

	if (q_option && !worked) {
		verbose(_("%s: trying to eject using tape offline command"), device);
		worked = eject_tape(fd);
		verbose(worked ? _("tape offline command succeeded") :
				 _("tape offline command failed"));
	}

	if (!worked)
		errx(EXIT_FAILURE, _("unable to eject"));

	/* cleanup */
	close(fd);
	free(device);
	free(mountpoint);

	mnt_free_table(mtab);
	mnt_free_cache(cache);

	return EXIT_SUCCESS;
}