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 $
35 #include <sys/param.h>
36 #include <sys/mount.h>
38 #include <sys/iconv.h>
39 #include <sys/linker.h>
40 #include <sys/module.h>
41 #include <vfs/msdosfs/msdosfsmount.h>
50 /* 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 "-D".
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 int set_charset(struct msdosfs_args
*, const char*, const char*);
82 main(int argc
, char **argv
)
84 struct msdosfs_args args
;
86 int c
, error
, mntflags
, set_gid
, set_uid
, set_mask
;
87 char *dev
, *dir
, mntpath
[MAXPATHLEN
], *csp
;
88 const char *quirk
= NULL
;
89 char *cs_local
= NULL
;
92 mntflags
= set_gid
= set_uid
= set_mask
= 0;
93 memset(&args
, '\0', sizeof(args
));
94 args
.magic
= MSDOSFS_ARGSMAGIC
;
96 while ((c
= getopt(argc
, argv
, "sl9u:g:m:o:L:D:")) != -1) {
98 #ifdef MSDOSFSMNT_GEMDOSFS
100 args
.flags
|= MSDOSFSMNT_GEMDOSFS
;
104 args
.flags
|= MSDOSFSMNT_SHORTNAME
;
107 args
.flags
|= MSDOSFSMNT_LONGNAME
;
110 args
.flags
|= MSDOSFSMNT_NOWIN95
;
113 args
.uid
= a_uid(optarg
);
117 args
.gid
= a_gid(optarg
);
121 args
.mask
= a_mask(optarg
);
125 if (setlocale(LC_CTYPE
, optarg
) == NULL
)
126 err(EX_CONFIG
, "%s", optarg
);
127 csp
= strchr(optarg
,'.');
129 err(EX_CONFIG
, "%s", optarg
);
130 quirk
= kiconv_quirkcs(csp
+ 1, KICONV_VENDOR_MICSFT
);
131 cs_local
= strdup(quirk
);
132 args
.flags
|= MSDOSFSMNT_KICONV
;
136 cs_dos
= strdup(optarg
);
137 args
.flags
|= MSDOSFSMNT_KICONV
;
140 getmntopts(optarg
, mopts
, &mntflags
, &args
.flags
);
149 if (optind
+ 2 != argc
)
153 dir
= argv
[optind
+ 1];
156 * Resolve the mountpoint with realpath(3) and remove unnecessary
157 * slashes from the devicename if there are any.
159 checkpath(dir
, mntpath
);
163 args
.export
.ex_root
= -2; /* unchecked anyway on DOS fs */
165 if (cs_local
!= NULL
) {
166 if (set_charset(&args
, cs_local
, cs_dos
) == -1)
167 err(EX_OSERR
, "msdos_iconv");
168 } else if (cs_dos
!= NULL
) {
169 if (set_charset(&args
, "ISO8859-1", cs_dos
) == -1)
170 err(EX_OSERR
, "msdos_iconv");
173 if (mntflags
& MNT_RDONLY
)
174 args
.export
.ex_flags
= MNT_EXRDONLY
;
176 args
.export
.ex_flags
= 0;
177 if (!set_gid
|| !set_uid
|| !set_mask
) {
178 if (stat(mntpath
, &sb
) == -1)
179 err(EX_OSERR
, "stat %s", mntpath
);
182 args
.uid
= sb
.st_uid
;
184 args
.gid
= sb
.st_gid
;
186 args
.mask
= sb
.st_mode
& (S_IRWXU
| S_IRWXG
| S_IRWXO
);
189 error
= getvfsbyname("msdos", &vfc
);
190 if (error
&& vfsisloadable("msdos")) {
191 if (vfsload("msdos"))
192 err(EX_OSERR
, "vfsload(msdos)");
193 endvfsent(); /* clear cache */
194 error
= getvfsbyname("msdos", &vfc
);
197 errx(EX_OSERR
, "msdos filesystem is not available");
199 if (mount(vfc
.vfc_name
, mntpath
, mntflags
, &args
) < 0)
200 err(EX_OSERR
, "%s", dev
);
212 if ((gr
= getgrnam(s
)) != NULL
)
215 for (gname
= s
; *s
&& isdigit(*s
); ++s
);
219 errx(EX_NOUSER
, "unknown group id: %s", gname
);
231 if ((pw
= getpwnam(s
)) != NULL
)
234 for (uname
= s
; *s
&& isdigit(*s
); ++s
);
238 errx(EX_NOUSER
, "unknown user id: %s", uname
);
251 if (*s
>= '0' && *s
<= '7') {
253 rv
= strtol(optarg
, &ep
, 8);
255 if (!done
|| rv
< 0 || *ep
)
256 errx(EX_USAGE
, "invalid file mode: %s", s
);
263 fprintf(stderr
, "%s\n%s\n",
264 "usage: mount_msdos [-9ls] [-D DOS_codepage] [-g gid] [-L locale]",
265 " [-m mask] [-o options] [-u uid] special node");
270 set_charset(struct msdosfs_args
*args
, const char *cs_local
, const char *cs_dos
)
273 if (modfind("msdos_iconv") < 0) {
274 if (kldload("msdos_iconv") < 0 || modfind("msdos_iconv") < 0)
276 warnx("cannot find or load \"msdos_iconv\" kernel module");
280 snprintf(args
->cs_local
, ICONV_CSNMAXLEN
, "%s", cs_local
);
281 error
= kiconv_add_xlat16_cspairs(ENCODING_UNICODE
, cs_local
);
285 cs_dos
= strdup("CP437");
286 snprintf(args
->cs_dos
, ICONV_CSNMAXLEN
, "%s", cs_dos
);
287 error
= kiconv_add_xlat16_cspairs(cs_dos
, cs_local
);