1 /* $NetBSD: mount_msdos.c,v 1.18 1997/09/16 12:24:18 lukem Exp $ */
4 * Copyright (c) 1994 Christopher G. Demetriou
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christopher G. Demetriou.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * $FreeBSD: src/sbin/mount_msdos/mount_msdos.c,v 1.19.2.1 2000/07/20 10:35:13 kris Exp $
33 * $DragonFly: src/sbin/mount_msdos/mount_msdos.c,v 1.7 2005/04/02 23:41:06 dillon Exp $
36 #include <sys/param.h>
37 #include <sys/mount.h>
40 #include <vfs/msdosfs/msdosfsmount.h>
48 /* must be after stdio to declare fparseln */
58 * XXX - no way to specify "foo=<bar>"-type options; that's what we'd
59 * want for "-u", "-g", "-m", "-L", and "-W".
61 static struct mntopt mopts
[] = {
66 #ifdef MSDOSFSMNT_GEMDOSFS
67 { "gemdosfs", 0, MSDOSFSMNT_GEMDOSFS
, 1 },
69 { "shortnames", 0, MSDOSFSMNT_SHORTNAME
, 1 },
70 { "longnames", 0, MSDOSFSMNT_LONGNAME
, 1 },
71 { "nowin95", 0, MSDOSFSMNT_NOWIN95
, 1 },
75 static gid_t
a_gid(char *);
76 static uid_t
a_uid(char *);
77 static mode_t
a_mask(char *);
78 static void usage(void) __dead2
;
79 static void load_u2wtable(struct msdosfs_args
*, char *);
80 static void load_ultable(struct msdosfs_args
*, char *);
83 main(int argc
, char **argv
)
85 struct msdosfs_args args
;
87 int c
, error
, mntflags
, set_gid
, set_uid
, set_mask
;
88 char *dev
, *dir
, mntpath
[MAXPATHLEN
];
91 mntflags
= set_gid
= set_uid
= set_mask
= 0;
92 memset(&args
, '\0', sizeof(args
));
93 args
.magic
= MSDOSFS_ARGSMAGIC
;
95 while ((c
= getopt(argc
, argv
, "sl9u:g:m:o:L:W:")) != -1) {
97 #ifdef MSDOSFSMNT_GEMDOSFS
99 args
.flags
|= MSDOSFSMNT_GEMDOSFS
;
103 args
.flags
|= MSDOSFSMNT_SHORTNAME
;
106 args
.flags
|= MSDOSFSMNT_LONGNAME
;
109 args
.flags
|= MSDOSFSMNT_NOWIN95
;
112 args
.uid
= a_uid(optarg
);
116 args
.gid
= a_gid(optarg
);
120 args
.mask
= a_mask(optarg
);
124 load_ultable(&args
, optarg
);
125 args
.flags
|= MSDOSFSMNT_ULTABLE
;
128 load_u2wtable(&args
, optarg
);
129 args
.flags
|= MSDOSFSMNT_U2WTABLE
;
132 getmntopts(optarg
, mopts
, &mntflags
, &args
.flags
);
141 if (optind
+ 2 != argc
)
145 dir
= argv
[optind
+ 1];
148 * Resolve the mountpoint with realpath(3) and remove unnecessary
149 * slashes from the devicename if there are any.
151 checkpath(dir
, mntpath
);
155 args
.export
.ex_root
= -2; /* unchecked anyway on DOS fs */
156 if (mntflags
& MNT_RDONLY
)
157 args
.export
.ex_flags
= MNT_EXRDONLY
;
159 args
.export
.ex_flags
= 0;
160 if (!set_gid
|| !set_uid
|| !set_mask
) {
161 if (stat(mntpath
, &sb
) == -1)
162 err(EX_OSERR
, "stat %s", mntpath
);
165 args
.uid
= sb
.st_uid
;
167 args
.gid
= sb
.st_gid
;
169 args
.mask
= sb
.st_mode
& (S_IRWXU
| S_IRWXG
| S_IRWXO
);
172 error
= getvfsbyname("msdos", &vfc
);
173 if (error
&& vfsisloadable("msdos")) {
174 if (vfsload("msdos"))
175 err(EX_OSERR
, "vfsload(msdos)");
176 endvfsent(); /* clear cache */
177 error
= getvfsbyname("msdos", &vfc
);
180 errx(EX_OSERR
, "msdos filesystem is not available");
182 if (mount(vfc
.vfc_name
, mntpath
, mntflags
, &args
) < 0)
183 err(EX_OSERR
, "%s", dev
);
195 if ((gr
= getgrnam(s
)) != NULL
)
198 for (gname
= s
; *s
&& isdigit(*s
); ++s
);
202 errx(EX_NOUSER
, "unknown group id: %s", gname
);
214 if ((pw
= getpwnam(s
)) != NULL
)
217 for (uname
= s
; *s
&& isdigit(*s
); ++s
);
221 errx(EX_NOUSER
, "unknown user id: %s", uname
);
234 if (*s
>= '0' && *s
<= '7') {
236 rv
= strtol(optarg
, &ep
, 8);
238 if (!done
|| rv
< 0 || *ep
)
239 errx(EX_USAGE
, "invalid file mode: %s", s
);
246 fprintf(stderr
, "%s\n%s\n",
247 "usage: mount_msdos [-o options] [-u user] [-g group] [-m mask]",
248 " [-s] [-l] [-9] [-L locale] [-W table] bdev dir");
253 load_u2wtable (struct msdosfs_args
*pargs
, char *name
)
264 snprintf(buf
, sizeof(buf
), "/usr/libdata/msdosfs/%s", name
);
268 if ((f
= fopen(fn
, "r")) == NULL
)
269 err(EX_NOINPUT
, "%s", fn
);
271 for (i
= 0; i
< 16; i
++) {
273 if (p
!= NULL
) free(p
);
274 if ((p
= s
= fparseln(f
, NULL
, &line
, NULL
, 0)) == NULL
)
275 errx(EX_DATAERR
, "can't read u2w table row %d near line %d", i
, line
);
276 while (isspace((unsigned char)*s
))
278 } while (*s
== '\0');
279 if (sscanf(s
, "%i%i%i%i%i%i%i%i",
280 code
, code
+ 1, code
+ 2, code
+ 3, code
+ 4, code
+ 5, code
+ 6, code
+ 7) != 8)
281 errx(EX_DATAERR
, "u2w table: missing item(s) in row %d, line %d", i
, line
);
282 for (j
= 0; j
< 8; j
++)
283 pargs
->u2w
[i
* 8 + j
] = code
[j
];
285 for (i
= 0; i
< 16; i
++) {
288 if ((p
= s
= fparseln(f
, NULL
, &line
, NULL
, 0)) == NULL
)
289 errx(EX_DATAERR
, "can't read d2u table row %d near line %d", i
, line
);
290 while (isspace((unsigned char)*s
))
292 } while (*s
== '\0');
293 if (sscanf(s
, "%i%i%i%i%i%i%i%i",
294 code
, code
+ 1, code
+ 2, code
+ 3, code
+ 4, code
+ 5, code
+ 6, code
+ 7) != 8)
295 errx(EX_DATAERR
, "d2u table: missing item(s) in row %d, line %d", i
, line
);
296 for (j
= 0; j
< 8; j
++)
297 pargs
->d2u
[i
* 8 + j
] = code
[j
];
299 for (i
= 0; i
< 16; i
++) {
302 if ((p
= s
= fparseln(f
, NULL
, &line
, NULL
, 0)) == NULL
)
303 errx(EX_DATAERR
, "can't read u2d table row %d near line %d", i
, line
);
304 while (isspace((unsigned char)*s
))
306 } while (*s
== '\0');
307 if (sscanf(s
, "%i%i%i%i%i%i%i%i",
308 code
, code
+ 1, code
+ 2, code
+ 3, code
+ 4, code
+ 5, code
+ 6, code
+ 7) != 8)
309 errx(EX_DATAERR
, "u2d table: missing item(s) in row %d, line %d", i
, line
);
310 for (j
= 0; j
< 8; j
++)
311 pargs
->u2d
[i
* 8 + j
] = code
[j
];
318 load_ultable (struct msdosfs_args
*pargs
, char *name
)
322 if (setlocale(LC_CTYPE
, name
) == NULL
)
323 err(EX_CONFIG
, "%s", name
);
324 for (i
= 0; i
< 128; i
++) {
325 pargs
->ul
[i
] = tolower(i
| 0x80);
326 pargs
->lu
[i
] = toupper(i
| 0x80);