Пример #1
0
int eject_main(int argc, char **argv)
{
	unsigned long flags;
	char *device;
	struct mntent *m;

	flags = bb_getopt_ulflags(argc, argv, "t");
	device = argv[optind] ? : DEFAULT_CDROM;

	if ((m = find_mount_point(device, bb_path_mtab_file))) {
		if (umount(m->mnt_dir)) {
			bb_error_msg_and_die("Can't umount");
		} else if (ENABLE_FEATURE_MTAB_SUPPORT) {
			erase_mtab(m->mnt_fsname);
		}
	}
	if (ioctl(bb_xopen(device, (O_RDONLY | O_NONBLOCK)),
				(flags ? CDROMCLOSETRAY : CDROMEJECT))) {
		bb_perror_msg_and_die("%s", device);
	}
	return (EXIT_SUCCESS);
}
Пример #2
0
extern int umount_main(int argc, char **argv)
{
	int doForce;
	char path[2*PATH_MAX];
	struct mntent me;
	FILE *fp;
	int status=EXIT_SUCCESS;
	unsigned long opt;
	struct mtab_list {
		char *dir;
		char *device;
		struct mtab_list *next;
	} *mtl, *m;

	/* Parse any options */

	opt = bb_getopt_ulflags (argc, argv, OPTION_STRING);

	argc -= optind;
	argv += optind;

	doForce = MAX((opt & OPT_FORCE), (opt & OPT_LAZY));

	/* Get a list of mount points from mtab.  We read them all in now mostly
	 * for umount -a (so we don't have to worry about the list changing while
	 * we iterate over it, or about getting stuck in a loop on the same failing
	 * entry.  Notice that this also naturally reverses the list so that -a
	 * umounts the most recent entries first. */

	m=mtl=0;
	if(!(fp = setmntent(bb_path_mtab_file, "r")))
		bb_error_msg_and_die("Cannot open %s", bb_path_mtab_file);
	while (getmntent_r(fp,&me,path,sizeof(path))) {
		m=xmalloc(sizeof(struct mtab_list));
		m->next=mtl;
		m->device=bb_xstrdup(me.mnt_fsname);
		m->dir=bb_xstrdup(me.mnt_dir);
		mtl=m;
	}
	endmntent(fp);

	/* If we're umounting all, then m points to the start of the list and
	 * the argument list should be empty (which will match all). */
	if(!(opt & OPT_ALL)) {
		m=0;
		if(argc <= 0) bb_show_usage();
	}

	// Loop through everything we're supposed to umount, and do so.
	for(;;) {
		int curstat;

		// Do we already know what to umount this time through the loop?
		if(m) safe_strncpy(path,m->dir,PATH_MAX);
		// For umount -a, end of mtab means time to exit.
		else if(opt & OPT_ALL) break;
		// Get next command line argument (and look it up in mtab list)
		else if(!argc--) break;
		else {
			// Get next command line argument (and look it up in mtab list)
			realpath(*argv++, path);
			for(m = mtl; m; m = m->next)
				if(!strcmp(path, m->dir) || !strcmp(path, m->device))
					break;
		}

		// Let's ask the thing nicely to unmount.
		curstat = umount(path);

		// Force the unmount, if necessary.
		if(curstat && doForce) {
			curstat = umount2(path, doForce);
			if(curstat)
				bb_error_msg_and_die("forced umount of %s failed!", path);
		}

		// If still can't umount, maybe remount read-only?
		if (curstat && (opt & OPT_REMOUNT) && errno == EBUSY && m) {
			curstat = mount(m->device, path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
			bb_error_msg(curstat ? "Cannot remount %s read-only" :
						 "%s busy - remounted read-only", m->device);
		}

		/* De-allocate the loop device.  This ioctl should be ignored on any
		 * non-loop block devices. */
		if(ENABLE_FEATURE_MOUNT_LOOP && !(opt & OPT_DONTFREELOOP) && m)
			del_loop(m->device);

		if(curstat) {
			/* Yes, the ENABLE is redundant here, but the optimizer for ARM
			 * can't do simple constant propagation in local variables... */
			if(ENABLE_FEATURE_MTAB_SUPPORT && !(opt & OPT_NO_MTAB) && m)
				erase_mtab(m->dir);
			status = EXIT_FAILURE;
			bb_perror_msg("Couldn't umount %s", path);
		}
		// Find next matching mtab entry for -a or umount /dev
		while(m && (m = m->next))
			if((opt & OPT_ALL) || !strcmp(path,m->device))
				break;
	}

	// Free mtab list if necessary

	if(ENABLE_FEATURE_CLEAN_UP) {
		while(mtl) {
			m=mtl->next;
			free(mtl->device);
			free(mtl->dir);
			free(mtl);
			mtl=m;
		}
	}

	return status;
}
Пример #3
0
static int
do_mount(char *specialfile, char *dir, char *filesystemtype,
		 long flags, void *string_flags, int useMtab, int fakeIt,
		 char *mtab_opts, int mount_all)
{
	int status = 0;
#if defined BB_FEATURE_MOUNT_LOOP
	char *lofile = NULL;
#endif

	if (! fakeIt)
	{
#if defined BB_FEATURE_MOUNT_LOOP
		if (use_loop==TRUE) {
			int loro = flags & MS_RDONLY;
			
			lofile = specialfile;

			specialfile = find_unused_loop_device();
			if (specialfile == NULL) {
				error_msg_and_die("Could not find a spare loop device");
			}
			if (set_loop(specialfile, lofile, 0, &loro)) {
				error_msg_and_die("Could not setup loop device");
			}
			if (!(flags & MS_RDONLY) && loro) {	/* loop is ro, but wanted rw */
				error_msg("WARNING: loop device is read-only");
				flags |= MS_RDONLY;
			}
		}
#endif
		status = mount(specialfile, dir, filesystemtype, flags, string_flags);
		if (status < 0 && errno == EROFS) {
			error_msg("%s is write-protected, mounting read-only", specialfile);
			status = mount(specialfile, dir, filesystemtype, flags |= MS_RDONLY, string_flags);
		}
		/* Don't whine about already mounted filesystems when mounting all. */
		if (status < 0 && errno == EBUSY && mount_all)
			return TRUE;
	}


	/* If the mount was sucessful, do anything needed, then return TRUE */
	if (status == 0 || fakeIt==TRUE) {

#if defined BB_FEATURE_MTAB_SUPPORT
		if (useMtab) {
			erase_mtab(specialfile);	// Clean any stale entries
			write_mtab(specialfile, dir, filesystemtype, flags, mtab_opts);
		}
#endif
		return (TRUE);
	}

	/* Bummer.  mount failed.  Clean up */
#if defined BB_FEATURE_MOUNT_LOOP
	if (lofile != NULL) {
		del_loop(specialfile);
	}
#endif

	if (errno == EPERM) {
		error_msg_and_die("permission denied. Are you root?");
	}

	return (FALSE);
}