From 91af0d68b1f662e02ec061e80f50c4a2faa84975 Mon Sep 17 00:00:00 2001 From: jmmv Date: Sun, 26 Nov 2006 16:16:31 +0000 Subject: [PATCH] Add a '-l' flag and a 'L' command to interactive mode to list all known file system types. (Similar to what fdisk does for partition types.) Closes PR bin/12954. --- sbin/disklabel/disklabel.8 | 15 +++-- sbin/disklabel/extern.h | 3 +- sbin/disklabel/interact.c | 14 ++++- sbin/disklabel/main.c | 112 +++++++++++++++++++++++++++++++++++-- 4 files changed, 133 insertions(+), 11 deletions(-) diff --git a/sbin/disklabel/disklabel.8 b/sbin/disklabel/disklabel.8 index 23e4338ea50c..8821f3475941 100644 --- a/sbin/disklabel/disklabel.8 +++ b/sbin/disklabel/disklabel.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: disklabel.8,v 1.59 2006/02/04 20:10:53 wiz Exp $ +.\" $NetBSD: disklabel.8,v 1.60 2006/11/26 16:16:31 jmmv Exp $ .\" .\" Copyright (c) 1987, 1988, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -32,7 +32,7 @@ .\" .\" @(#)disklabel.8 8.2 (Berkeley) 4/19/94 .\" -.Dd January 29, 2006 +.Dd November 26, 2006 .Dt DISKLABEL 8 .Os .Sh NAME @@ -69,6 +69,9 @@ .Nm .Op Fl NW .Ar disk +.\" disklabel -l: list all know file system types +.Nm +.Fl l .Sh DESCRIPTION .Nm can be used to install, examine, or modify the label on a disk drive or pack. @@ -76,10 +79,11 @@ When writing the label, it can be used to change the drive identification, the disk partitions on the drive, or to replace a damaged label. .Pp The -.Fl e , i , R , w , N , +.Fl e , i , l , R , w , N , and .Fl W -options determine the basic operation, if none are specified the label +options determine the basic operation. +If none are specified the label is displayed. .Bl -tag -width flag .It Fl e @@ -93,6 +97,9 @@ is undefined, then is used. .It Fl i Interactively update the existing label and write it back to the disk. +.It Fl l +Show all known file system types (those that can be specified along a +partition within the label) and exit. .It Fl R Write (restore) a label by reading it from .Ar protofile . diff --git a/sbin/disklabel/extern.h b/sbin/disklabel/extern.h index a102cb7fddbf..d5d4da00723f 100644 --- a/sbin/disklabel/extern.h +++ b/sbin/disklabel/extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.9 2005/10/19 21:22:21 dsl Exp $ */ +/* $NetBSD: extern.h,v 1.10 2006/11/26 16:16:31 jmmv Exp $ */ /* * Copyright (c) 1997 Christos Zoulas. All rights reserved. @@ -35,6 +35,7 @@ void showinfo(FILE *, struct disklabel *, const char *); void showpartitions(FILE *, struct disklabel *, int); void showpartition(FILE *, struct disklabel *, int, int); void interact(struct disklabel *, int); +int list_fs_types(void); extern char specname[]; extern int Cflag; diff --git a/sbin/disklabel/interact.c b/sbin/disklabel/interact.c index 7adbd197cd86..c881adf1e51a 100644 --- a/sbin/disklabel/interact.c +++ b/sbin/disklabel/interact.c @@ -1,4 +1,4 @@ -/* $NetBSD: interact.c,v 1.29 2006/03/18 12:48:35 dsl Exp $ */ +/* $NetBSD: interact.c,v 1.30 2006/11/26 16:16:31 jmmv Exp $ */ /* * Copyright (c) 1997 Christos Zoulas. All rights reserved. @@ -35,7 +35,7 @@ #include #ifndef lint -__RCSID("$NetBSD: interact.c,v 1.29 2006/03/18 12:48:35 dsl Exp $"); +__RCSID("$NetBSD: interact.c,v 1.30 2006/11/26 16:16:31 jmmv Exp $"); #endif /* lint */ #include @@ -66,6 +66,7 @@ static void cmd_part(struct disklabel *, char *, int); static void cmd_label(struct disklabel *, char *, int); static void cmd_round(struct disklabel *, char *, int); static void cmd_name(struct disklabel *, char *, int); +static void cmd_listfstypes(struct disklabel *, char *, int); static int runcmd(struct disklabel *, char *, int); static int getinput(const char *, const char *, const char *, char *); static int alphacmp(const void *, const void *); @@ -85,6 +86,7 @@ static struct cmds { { "C", cmd_chain, "make partitions contiguous" }, { "E", cmd_printall, "print disk label and current partition table"}, { "I", cmd_info, "change label information" }, + { "L", cmd_listfstypes,"list all known file system types" }, { "N", cmd_name, "name the label" }, { "P", cmd_print, "print current partition table" }, { "Q", NULL, "quit" }, @@ -579,6 +581,14 @@ cmd_label(struct disklabel *lp, char *s, int fd) } +static void +cmd_listfstypes(struct disklabel *lp, char *s, int fd) +{ + + (void)list_fs_types(); +} + + static int runcmd(struct disklabel *lp, char *line, int fd) { diff --git a/sbin/disklabel/main.c b/sbin/disklabel/main.c index a4f4875d0366..e369159872eb 100644 --- a/sbin/disklabel/main.c +++ b/sbin/disklabel/main.c @@ -1,4 +1,40 @@ -/* $NetBSD: main.c,v 1.12 2006/06/25 21:32:39 christos Exp $ */ +/* $NetBSD: main.c,v 1.13 2006/11/26 16:16:31 jmmv Exp $ */ + +/* + * Copyright (c) 2006 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Julio M. Merino Vidal. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ /* * Copyright (c) 1987, 1993 @@ -47,7 +83,7 @@ __COPYRIGHT("@(#) Copyright (c) 1987, 1993\n\ static char sccsid[] = "@(#)disklabel.c 8.4 (Berkeley) 5/4/95"; /* from static char sccsid[] = "@(#)disklabel.c 1.2 (Symmetric) 11/28/85"; */ #else -__RCSID("$NetBSD: main.c,v 1.12 2006/06/25 21:32:39 christos Exp $"); +__RCSID("$NetBSD: main.c,v 1.13 2006/11/26 16:16:31 jmmv Exp $"); #endif #endif /* not lint */ @@ -123,6 +159,7 @@ static int tflag; /* Format output as disktab */ int Cflag; /* CHS format output */ static int Dflag; /* Delete old labels (use with write) */ static int Iflag; /* Read/write direct, but default if absent */ +static int lflag; /* List all known file system types and exit */ static int mflag; /* Expect disk to contain an MBR */ static int verbose; static int read_all; /* set if op = READ && Aflag */ @@ -143,6 +180,7 @@ static char *skip(char *); static char *word(char *); static int getasciilabel(FILE *, struct disklabel *); static void usage(void); +static int qsort_strcmp(const void *, const void *); static int getulong(const char *, char, char **, unsigned long *, unsigned long); #define GETNUM32(a, v) getulong(a, '\0', NULL, v, UINT32_MAX) @@ -221,7 +259,7 @@ main(int argc, char *argv[]) #endif error = 0; - while ((ch = getopt(argc, argv, "ABCDFINRWb:ef:imrs:tvw")) != -1) { + while ((ch = getopt(argc, argv, "ABCDFINRWb:ef:ilmrs:tvw")) != -1) { old_op = op; switch (ch) { case 'A': /* Action all labels */ @@ -262,6 +300,9 @@ main(int argc, char *argv[]) case 'i': /* Edit using built-in editor */ op = INTERACT; break; + case 'l': /* List all known file system types and exit */ + lflag = 1; + break; case 'm': /* Expect disk to have an MBR */ mflag ^= 1; break; @@ -287,6 +328,9 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; + if (lflag) + exit(list_fs_types() ? EXIT_SUCCESS : EXIT_FAILURE); + if (op == UNSPEC) op = Dflag ? DELETE : READ; @@ -1568,8 +1612,10 @@ getasciilabel(FILE *f, struct disklabel *lp) } else v = FSMAXTYPES; if ((unsigned)v >= FSMAXTYPES) { - warnx("line %d: warning, unknown filesystem type: %s", + warnx("line %d: warning, unknown file system type: %s", lineno, cp); + warnx("tip: use -l to see all valid file system " + "types"); v = FS_UNUSED; } pp->p_fstype = v; @@ -1736,6 +1782,7 @@ usage(void) { "-D [-v] disk", "(to delete existing label(s))" }, { "-R [-DFrv] disk protofile", "(to restore label)" }, { "[-NW] disk", "(to write disable/enable label)" }, + { "-l", "(to show all known file system types)" }, { NULL, NULL } }; int i; @@ -1770,3 +1817,60 @@ getulong(const char *str, char sep, char **epp, unsigned long *ul, return 0; } + +/* + * This is a wrapper over the standard strcmp function to be used with + * qsort on an array of pointers to strings. + */ +static int +qsort_strcmp(const void *v1, const void *v2) +{ + const char *const *sp1 = (const char *const *)v1; + const char *const *sp2 = (const char *const *)v2; + + return strcmp(*sp1, *sp2); +} + +/* + * Prints all know file system types for a partition. + * Returns 1 on success, 0 on failure. + */ +int +list_fs_types(void) +{ + int ret; + size_t nelems; + + nelems = 0; + { + const char *const *namep; + + namep = fstypenames; + while (*namep++ != NULL) + nelems++; + } + + ret = 1; + if (nelems > 0) { + const char **list; + size_t i; + + list = (const char **)malloc(sizeof(char *) * nelems); + if (list == NULL) { + warnx("sorry, could not allocate memory for list"); + ret = 0; + } else { + for (i = 0; i < nelems; i++) + list[i] = fstypenames[i]; + + qsort(list, nelems, sizeof(char *), qsort_strcmp); + + for (i = 0; i < nelems; i++) + (void)printf("%s\n", list[i]); + + free(list); + } + } + + return ret; +}