コード例 #1
0
int main(int argc, char **argv)
{
	char *device;
	unsigned drive;
	unsigned type;
	unsigned media_size;
	unsigned drive_size;
	int verify= 0;
	struct stat st0, st;
	char special[PATH_MAX + 1], mounted_on[PATH_MAX + 1];
	char version[MNTNAMELEN], rw_flag[MNTFLAGLEN];

	/* Option -v. */
	while (argc > 1 && argv[1][0] == '-') {
		char *p;

		for (p= argv[1]; *p == '-' || *p == 'v'; p++) {
			if (*p == 'v') verify= 1;
		}
		if (*p != 0) usage();
		argc--;
		argv++;
		if (strcmp(argv[0], "--") == 0) break;
	}

	if (argc < 2 || argc > 4) usage();

	/* Check if the caller has read-write permission.  Use the access()
	 * call to check with the real uid & gid.  This program is usually
	 * set-uid root.
	 */
	device= argv[1];
	if (stat(device, &st0) < 0
		|| access(device, R_OK|W_OK) < 0
		|| stat(device, &st) < 0
		|| (errno= EACCES, 0)	/* set errno for following tests */
		|| st.st_dev != st0.st_dev
		|| st.st_ino != st0.st_ino
	) {
		fatal(device);
	}

	if (!S_ISBLK(st.st_mode) || !isfloppy(st.st_rdev)) {
		fprintf(stderr, "format: %s: not a floppy device\n", device);
		exit(1);
	}

	drive= fl_drive(st.st_rdev);
	type= fl_type(st.st_rdev);

	/* The drive should not be mounted. */
	if (load_mtab("mkfs") < 0) exit(1);

	while (get_mtab_entry(special, mounted_on, version, rw_flag) == 0) {
		if (stat(special, &st) >= 0 && isfloppy(st.st_rdev)
					&& fl_drive(st.st_rdev) == drive) {
			fprintf(stderr, "format: %s is mounted on %s\n",
				device, mounted_on);
			exit(1);
		}
	}

	if (isflauto(type)) {
		/* Auto type 0 requires size(s). */
		unsigned long lmedia, ldrive;
		char *end;

		if (argc < 3) {
			fprintf(stderr,
			"format: no size specified for auto floppy device %s\n",
				device);
			usage();
		}

		lmedia= strtoul(argv[2], &end, 10);
		if (end == argv[2] || *end != 0 || lmedia > 20 * 1024)
			usage();

		if (argc == 4) {
			ldrive= strtoul(argv[3], &end, 10);
			if (end == argv[3] || *end != 0 || ldrive > 20 * 1024)
				usage();
		} else {
			ldrive= lmedia;
		}

		/* Silently correct wrong ordered sizes. */
		if (lmedia > ldrive) {
			media_size= ldrive;
			drive_size= lmedia;
		} else {
			media_size= lmedia;
			drive_size= ldrive;
		}

		/* A 1.44M drive can do 720k diskettes with no extra tricks.
		 * Diddle with the 720k params so it is found.
		 */
		if (media_size == 720 && drive_size == 1440)
			parameters[4 - 1].drive_size= 1440;

		/* Translate the auto type to a known type. */
		for (type= 1; type <= NR_TYPES; type++) {
			if (parameters[type - 1].media_size == media_size
				&& parameters[type - 1].drive_size == drive_size
			) break;
		}

		if (!isfltyped(type)) {
			fprintf(stderr,
			"format: can't format a %uk floppy in a %uk drive\n",
				media_size, drive_size);
			exit(1);
		}
	} else
	if (isfltyped(type)) {
		/* No sizes needed for a non-auto type. */

		if (argc > 2) {
			fprintf(stderr,
	"format: no sizes need to be specified for non-auto floppy device %s\n",
				device);
			usage();
		}
	} else
	if (isflpart(type)) {
		fprintf(stderr,
			"format: floppy partition %s can't be formatted\n",
			device);
		exit(1);
	} else {
		fprintf(stderr,
			"format: %s: can't format strange type %d\n",
			device, type);
	}

	format_device(drive, type, verify);
	exit(0);
}
コード例 #2
0
ファイル: mkfs.c プロジェクト: anuragpeshne/minix
/*
 * Check to see if the special file named 'device' is mounted.
 */
void
check_mtab(const char *device)		/* /dev/hd1 or whatever */
{
#if defined(__minix)
  int n, r;
  struct stat sb;
  char dev[PATH_MAX], mount_point[PATH_MAX],
	type[MNTNAMELEN], flags[MNTFLAGLEN];

  r= stat(device, &sb);
  if (r == -1)
  {
	if (errno == ENOENT)
		return;	/* Does not exist, and therefore not mounted. */
	err(1, "stat %s failed", device);
  }
  if (!S_ISBLK(sb.st_mode))
  {
	/* Not a block device and therefore not mounted. */
	return;
  }

  if (load_mtab(__UNCONST("mkfs")) < 0) return;
  while (1) {
	n = get_mtab_entry(dev, mount_point, type, flags);
	if (n < 0) return;
	if (strcmp(device, dev) == 0) {
		/* Can't mkfs on top of a mounted file system. */
		errx(1, "%s is mounted on %s", device, mount_point);
	}
  }
#elif defined(__linux__)
/* XXX: this code is copyright Theodore T'so and distributed under the GPLv2. Rewrite.
 */
	struct mntent 	*mnt;
	struct stat	st_buf;
	dev_t		file_dev=0, file_rdev=0;
	ino_t		file_ino=0;
	FILE 		*f;
	int		fd;
	char 		*mtab_file = "/proc/mounts";

	if ((f = setmntent (mtab_file, "r")) == NULL)
		goto error;

	if (stat(device, &st_buf) == 0) {
		if (S_ISBLK(st_buf.st_mode)) {
			file_rdev = st_buf.st_rdev;
		} else {
			file_dev = st_buf.st_dev;
			file_ino = st_buf.st_ino;
		}
	}
	
	while ((mnt = getmntent (f)) != NULL) {
		if (strcmp(device, mnt->mnt_fsname) == 0)
			break;
		if (stat(mnt->mnt_fsname, &st_buf) == 0) {
			if (S_ISBLK(st_buf.st_mode)) {
				if (file_rdev && (file_rdev == st_buf.st_rdev))
					break;
			} else {
				if (file_dev && ((file_dev == st_buf.st_dev) &&
						 (file_ino == st_buf.st_ino)))
					break;
			}
		}
	}

	if (mnt == NULL) {
		/*
		 * Do an extra check to see if this is the root device.  We
		 * can't trust /etc/mtab, and /proc/mounts will only list
		 * /dev/root for the root filesystem.  Argh.  Instead we
		 * check if the given device has the same major/minor number
		 * as the device that the root directory is on.
		 */
		if (file_rdev && stat("/", &st_buf) == 0) {
			if (st_buf.st_dev == file_rdev) {
				goto is_root;
			}
		}
		goto test_busy;
	}
	/* Validate the entry in case /etc/mtab is out of date */
	/* 
	 * We need to be paranoid, because some broken distributions
	 * (read: Slackware) don't initialize /etc/mtab before checking
	 * all of the non-root filesystems on the disk.
	 */
	if (stat(mnt->mnt_dir, &st_buf) < 0) {
		if (errno == ENOENT) {
			goto test_busy;
		}
		goto error;
	}
	if (file_rdev && (st_buf.st_dev != file_rdev)) {
		goto error;
	}

	fprintf(stderr, "Device %s is mounted, exiting\n", device);
	exit(-1);

	/*
	 * Check to see if we're referring to the root filesystem.
	 * If so, do a manual check to see if we can open /etc/mtab
	 * read/write, since if the root is mounted read/only, the
	 * contents of /etc/mtab may not be accurate.
	 */
	if (!strcmp(mnt->mnt_dir, "/")) {
is_root:
		fprintf(stderr, "Device %s is mounted as root file system!\n",
				device);
		exit(-1);
	}
	
test_busy:

	endmntent (f);
	if ((stat(device, &st_buf) != 0) ||
			!S_ISBLK(st_buf.st_mode))
		return;
	fd = open(device, O_RDONLY | O_EXCL);
	if (fd < 0) {
		if (errno == EBUSY) {
			fprintf(stderr, "Device %s is used by the system\n", device);
			exit(-1);
		}
	} else
		close(fd);

	return;

error:
	endmntent (f);
	fprintf(stderr, "Error while checking if device %s is mounted\n", device);
	exit(-1);
#else
	(void) device;	/* shut up warnings about unused variable... */
#endif
}