summaryrefslogtreecommitdiffstats
path: root/disk-utils/mkfs.c
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:25:32 +0100
committerKarel Zak2006-12-07 00:25:32 +0100
commit6dbe3af945a63f025561abb83275cee9ff06c57b (patch)
tree19e59eac8ac465b5bc409b5adf815b582c92f633 /disk-utils/mkfs.c
downloadkernel-qcow2-util-linux-6dbe3af945a63f025561abb83275cee9ff06c57b.tar.gz
kernel-qcow2-util-linux-6dbe3af945a63f025561abb83275cee9ff06c57b.tar.xz
kernel-qcow2-util-linux-6dbe3af945a63f025561abb83275cee9ff06c57b.zip
Imported from util-linux-2.2 tarball.
Diffstat (limited to 'disk-utils/mkfs.c')
-rw-r--r--disk-utils/mkfs.c297
1 files changed, 297 insertions, 0 deletions
diff --git a/disk-utils/mkfs.c b/disk-utils/mkfs.c
new file mode 100644
index 000000000..018a53849
--- /dev/null
+++ b/disk-utils/mkfs.c
@@ -0,0 +1,297 @@
+/*
+ * fs-util A simple generic frontend for the for the fsck and mkfs
+ * programs under Linux. See the manual pages for details.
+ *
+ * Usage: fsck [-AV] [-t fstype] [fs-options] device
+ * mkfs [-V] [-t fstype] [fs-options] device< [size]
+ *
+ * Authors: David Engel, <david@ods.com>
+ * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ */
+
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <mntent.h>
+#include <unistd.h>
+#include <getopt.h>
+
+
+#ifndef DEFAULT_FSTYPE
+# define DEFAULT_FSTYPE "minix"
+#endif
+
+#define _PATH_PROG "%s.%s"
+#define _PROG_FSCK "fsck"
+
+#define EXIT_OK 0
+#define EXIT_NONDESTRUCT 1
+#define EXIT_DESTRUCT 2
+#define EXIT_UNCORRECTED 4
+#define EXIT_ERROR 8
+#define EXIT_USAGE 16
+#define EXIT_LIBRARY 128
+
+static char *Version = "1.8";
+static char *ignored_types[] = {
+ "ignore",
+ "iso9660",
+ "msdos",
+ "nfs",
+ "proc",
+ "sw",
+ "swap",
+ NULL
+};
+
+
+/* Execute a program. */
+int do_exec(char *prog, char **argv, int verbose)
+{
+ char *args[33];
+ register int i;
+ int pid, status;
+
+ /* Build the vector. */
+ i = 0;
+ args[i++] = prog;
+ while(*argv != NULL && i < 32)
+ args[i++] = *argv++;
+ args[i] = NULL;
+
+ if (verbose) {
+ i = 0;
+ while(args[i] != NULL) {
+ printf("%s ", args[i]);
+ i++;
+ }
+ printf("\n");
+ if (verbose > 1)
+ return EXIT_OK;
+ }
+
+ /* Fork and execute the correct program. */
+ if ((pid = fork()) < 0) {
+ perror("fork");
+ status = EXIT_ERROR;
+ } else if (pid == 0) {
+ (void) execvp(args[0], args);
+ perror(args[0]);
+ exit(EXIT_ERROR);
+ } else {
+ while(wait(&status) != pid)
+ ;
+ status = WEXITSTATUS(status);
+ }
+
+ return status;
+}
+
+
+/* Check if we have to ignore a file system type. */
+int ignore(char *type, char *opts)
+{
+ char *cp;
+ char **ip;
+
+ ip = ignored_types;
+ while (*ip != NULL) {
+ if (!strcmp(type, *ip))
+ return 1;
+ ip++;
+ }
+
+ for (cp = strtok(opts, ","); cp != NULL; cp = strtok(NULL, ",")) {
+ if (!strcmp(cp, "noauto"))
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* Check all file systems, using the /etc/fstab table. */
+int check_all(int verbose, char **argv)
+{
+ char path[PATH_MAX];
+ char *args[33];
+ FILE *mntfile;
+ struct mntent *mp;
+ register int i;
+ int status = EXIT_OK;
+
+ if (verbose)
+ printf("Checking all file systems.\n");
+
+ /* Create an array of arguments. */
+ i = 0;
+ while (*argv != NULL && i < 32)
+ args[i++] = *argv++;
+ args[i] = NULL;
+ args[i + 1] = NULL;
+
+ /* Open the mount table. */
+ if ((mntfile = setmntent(MNTTAB, "r")) == NULL) {
+ perror(MNTTAB);
+ exit(EXIT_ERROR);
+ }
+
+ /* Walk through the /etc/fstab file. */
+ while ((mp = getmntent(mntfile)) != NULL) {
+ if (verbose)
+ printf("%-7s %-15s %-15s ", mp->mnt_type,
+ mp->mnt_fsname, mp->mnt_dir);
+ if (ignore(mp->mnt_type, mp->mnt_opts)) {
+ if (verbose)
+ printf("(ignored)\n");
+ continue;
+ }
+
+ /* Build program name. */
+ sprintf(path, _PATH_PROG, _PROG_FSCK, mp->mnt_type);
+ args[i] = mp->mnt_fsname;
+ status |= do_exec(path, args, verbose);
+ }
+
+ (void) endmntent(mntfile);
+
+ return status;
+}
+
+
+/* Lookup filesys in /etc/fstab and return the corresponding entry. */
+struct mntent *lookup(char *filesys)
+{
+ FILE *mntfile;
+ struct mntent *mp;
+
+ /* No filesys name given. */
+ if (filesys == NULL)
+ return NULL;
+
+ /* Open the mount table. */
+ if ((mntfile = setmntent(MNTTAB, "r")) == NULL) {
+ perror(MNTTAB);
+ exit(EXIT_ERROR);
+ }
+
+ while ((mp = getmntent(mntfile)) != NULL) {
+ if (!strcmp(filesys, mp->mnt_fsname) ||
+ !strcmp(filesys, mp->mnt_dir))
+ break;
+ }
+
+ (void) endmntent(mntfile);
+
+ return mp;
+}
+
+
+void usage(int fsck, char *prog)
+{
+ if (fsck) {
+ fprintf(stderr, "Usage: fsck [-AV] [-t fstype] [fs-options] filesys\n");
+ } else {
+ fprintf(stderr, "Usage: mkfs [-V] [-t fstype] [fs-options] filesys [size]\n");
+ }
+
+ exit(EXIT_USAGE);
+}
+
+
+void main(int argc, char *argv[])
+{
+ char path[PATH_MAX];
+ char *oldpath, newpath[PATH_MAX];
+ register char *sp;
+ struct mntent *fsent;
+ char *fstype = NULL;
+ int verbose = 0;
+ int doall = 0;
+ int i, fsck, more;
+
+ /* Must be 1 for "fsck" and 0 for "mkfs". */
+ if ((sp = strrchr(argv[0], '/')) != NULL)
+ sp++;
+ else
+ sp = argv[0];
+ if (!strcmp(sp, _PROG_FSCK))
+ fsck = 1;
+ else
+ fsck = 0;
+
+ /* Check commandline options. */
+ opterr = 0;
+ more = 0;
+ while ((more == 0) && ((i = getopt(argc, argv, "AVt:")) != EOF))
+ switch(i) {
+ case 'A':
+ doall++;
+ break;
+ case 'V':
+ verbose++;
+ break;
+ case 't':
+ if (optarg == NULL)
+ usage(fsck, sp);
+ fstype = optarg;
+ break;
+ default:
+ more = 1;
+ break; /* start of specific arguments */
+ }
+
+ /* Did we get any specific arguments? */
+ if (more)
+ optind--;
+
+ /* Print our version number if requested. */
+ if (verbose)
+ printf("%s (fsutil) version %s (%s)\n", argv[0],
+ Version, __DATE__);
+
+ /* Update our PATH to include /etc/fs and /etc. */
+ strcpy(newpath, "PATH=/etc/fs:/etc:");
+ if ((oldpath = getenv("PATH")) != NULL)
+ strcat(newpath, oldpath);
+ putenv(newpath);
+
+ /* If -A was specified ("check all"), double-check. */
+ if (doall) {
+ if (!fsck || (fstype != NULL))
+ usage(fsck, sp);
+ exit(check_all(verbose, &argv[optind]));
+ } else {
+ /* If -t wasn't specified, we must deduce fstype. */
+ if (fstype == NULL) {
+ /* make sure that "filesys" was specified */
+ if (optind >= argc)
+ usage(fsck, sp);
+ /* then try looking for it in /etc/fstab */
+ if ((fsent = lookup(argv[argc - 1])) != NULL) {
+ argv[argc - 1] = fsent->mnt_fsname;
+ fstype = fsent->mnt_type;
+ } else {
+ if (!fsck && optind < argc-1) {
+ if ((fsent = lookup(argv[argc - 2])) != NULL) {
+ argv[argc - 2] = fsent->mnt_fsname;
+ fstype = fsent->mnt_type;
+ }
+ }
+ }
+ /* if we still don't know, use the default */
+ if (fstype == NULL) fstype = DEFAULT_FSTYPE;
+ }
+
+ /* Build program name. */
+ sprintf(path, _PATH_PROG, sp, fstype);
+ exit(do_exec(path, &argv[optind], verbose));
+ }
+ /*NOTREACHED*/
+}