kernel - Order ipfw3 module before other ipfw3_* modules
[dragonfly.git] / usr.sbin / fstyp / fstyp.c
blobd69ae75445b24cf8de7d5da37695e82a0249e3b8
1 /*-
2 * Copyright (c) 2016 The DragonFly Project
3 * Copyright (c) 2014 The FreeBSD Foundation
4 * All rights reserved.
6 * This software was developed by Edward Tomasz Napierala under sponsorship
7 * from the FreeBSD Foundation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
32 #include <sys/diskslice.h>
33 #include <sys/ioctl.h>
34 #include <sys/stat.h>
35 #include <err.h>
36 #include <errno.h>
37 #include <stdbool.h>
38 #include <stddef.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <vis.h>
45 #include "fstyp.h"
47 #define LABEL_LEN 256
49 typedef int (*fstyp_function)(FILE *, char *, size_t);
50 typedef int (*fsvtyp_function)(const char *, char *, size_t);
52 static struct {
53 const char *name;
54 fstyp_function function;
55 bool unmountable;
56 } fstypes[] = {
57 { "cd9660", &fstyp_cd9660, false },
58 { "ext2fs", &fstyp_ext2fs, false },
59 { "msdosfs", &fstyp_msdosfs, false },
60 { "ntfs", &fstyp_ntfs, false },
61 { "ufs", &fstyp_ufs, false },
62 { "hammer", &fstyp_hammer, false },
63 { NULL, NULL, NULL }
66 static struct {
67 const char *name;
68 fsvtyp_function function;
69 bool unmountable;
70 } fsvtypes[] = {
71 { "hammer", &fsvtyp_hammer, false }, /* Must be before partial */
72 { "hammer(partial)", &fsvtyp_hammer_partial, true },
73 { NULL, NULL, NULL }
76 void *
77 read_buf(FILE *fp, off_t off, size_t len)
79 int error;
80 size_t nread;
81 void *buf;
83 error = fseek(fp, off, SEEK_SET);
84 if (error != 0) {
85 warn("cannot seek to %jd", (uintmax_t)off);
86 return (NULL);
89 buf = malloc(len);
90 if (buf == NULL) {
91 warn("cannot malloc %zd bytes of memory", len);
92 return (NULL);
95 nread = fread(buf, len, 1, fp);
96 if (nread != 1) {
97 free(buf);
98 if (feof(fp) == 0)
99 warn("fread");
100 return (NULL);
103 return (buf);
106 char *
107 checked_strdup(const char *s)
109 char *c;
111 c = strdup(s);
112 if (c == NULL)
113 err(1, "strdup");
114 return (c);
117 void
118 rtrim(char *label, size_t size)
120 ptrdiff_t i;
122 for (i = size - 1; i >= 0; i--) {
123 if (label[i] == '\0')
124 continue;
125 else if (label[i] == ' ')
126 label[i] = '\0';
127 else
128 break;
132 static void
133 usage(void)
136 fprintf(stderr, "usage: fstyp [-l] [-s] [-u] special\n");
137 exit(1);
140 static void
141 type_check(const char *path, FILE *fp)
143 int error, fd;
144 struct stat sb;
145 struct partinfo pinfo;
147 fd = fileno(fp);
149 error = fstat(fd, &sb);
150 if (error != 0)
151 err(1, "%s: fstat", path);
153 if (S_ISREG(sb.st_mode))
154 return;
156 error = ioctl(fd, DIOCGPART, &pinfo);
157 if (error != 0)
158 errx(1, "%s: not a disk", path);
162 main(int argc, char **argv)
164 int ch, error, i, nbytes;
165 bool ignore_type = false, show_label = false, show_unmountable = false;
166 char label[LABEL_LEN + 1], strvised[LABEL_LEN * 4 + 1];
167 char *path;
168 const char *name = NULL;
169 FILE *fp;
170 fstyp_function fstyp_f;
171 fsvtyp_function fsvtyp_f;
173 while ((ch = getopt(argc, argv, "lsu")) != -1) {
174 switch (ch) {
175 case 'l':
176 show_label = true;
177 break;
178 case 's':
179 ignore_type = true;
180 break;
181 case 'u':
182 show_unmountable = true;
183 break;
184 default:
185 usage();
189 argc -= optind;
190 argv += optind;
191 if (argc != 1)
192 usage();
194 path = argv[0];
196 fp = fopen(path, "r");
197 if (fp == NULL)
198 goto fsvtyp; /* DragonFly */
200 if (ignore_type == false)
201 type_check(path, fp);
203 memset(label, '\0', sizeof(label));
205 for (i = 0;; i++) {
206 if (show_unmountable == false && fstypes[i].unmountable == true)
207 continue;
208 fstyp_f = fstypes[i].function;
209 if (fstyp_f == NULL)
210 break;
212 error = fstyp_f(fp, label, sizeof(label));
213 if (error == 0) {
214 name = fstypes[i].name;
215 goto done;
218 fsvtyp:
219 for (i = 0;; i++) {
220 if (show_unmountable == false && fsvtypes[i].unmountable == true)
221 continue;
222 fsvtyp_f = fsvtypes[i].function;
223 if (fsvtyp_f == NULL)
224 break;
226 error = fsvtyp_f(path, label, sizeof(label));
227 if (error == 0) {
228 name = fsvtypes[i].name;
229 goto done;
233 warnx("%s: filesystem not recognized", path);
234 return (1);
235 done:
236 if (show_label && label[0] != '\0') {
238 * XXX: I'd prefer VIS_HTTPSTYLE, but it unconditionally
239 * encodes spaces.
240 * XXX: DragonFly doesn't have strsnvis().
242 nbytes = strnvis(strvised, label, sizeof(strvised),
243 VIS_GLOB | VIS_NL);
244 if (nbytes == -1)
245 err(1, "strnvis");
247 printf("%s %s\n", name, strvised);
248 } else {
249 printf("%s\n", name);
252 return (0);