GC !__DragonFly__ section.
[dragonfly.git] / sbin / mount_hpfs / mount_hpfs.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1994 Christopher G. Demetriou
3 * Copyright (c) 1999 Semen Ustimenko (semenu@FreeBSD.org)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Christopher G. Demetriou.
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * $FreeBSD: src/sbin/mount_hpfs/mount_hpfs.c,v 1.1 1999/12/09 19:09:15 semenu Exp $
7cee7052 32 * $DragonFly: src/sbin/mount_hpfs/mount_hpfs.c,v 1.6 2004/12/18 21:43:39 swildner Exp $
984263bc
MD
33 */
34
35#include <sys/cdefs.h>
36#include <sys/param.h>
37#include <sys/mount.h>
38#include <sys/stat.h>
38a690d7 39#include <vfs/hpfs/hpfsmount.h>
984263bc
MD
40#include <ctype.h>
41#include <err.h>
42#include <grp.h>
43#include <pwd.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <sysexits.h>
48#include <unistd.h>
49
50#include "mntopts.h"
51
52static struct mntopt mopts[] = {
53 MOPT_STDOPTS,
54 { NULL }
55};
56
9a76cd75
DR
57static gid_t a_gid(char *);
58static uid_t a_uid(char *);
59static mode_t a_mask(char *);
60static void usage(void) __dead2;
61static void load_u2wtable(struct hpfs_args *, char *);
984263bc
MD
62
63int
b5744197 64main(int argc, char **argv)
984263bc
MD
65{
66 struct hpfs_args args;
67 struct stat sb;
68 int c, mntflags, set_gid, set_uid, set_mask,error;
69 int forcerw = 0;
70 char *dev, *dir, ndir[MAXPATHLEN+1];
71#if __FreeBSD_version >= 300000
72 struct vfsconf vfc;
73#else
74 struct vfsconf *vfc;
75#endif
76
77 mntflags = set_gid = set_uid = set_mask = 0;
7cee7052 78 memset(&args, '\0', sizeof(args));
984263bc
MD
79
80 while ((c = getopt(argc, argv, "u:g:m:o:c:W:F")) != -1) {
81 switch (c) {
82 case 'F':
83 forcerw=1;
84 break;
85 case 'u':
86 args.uid = a_uid(optarg);
87 set_uid = 1;
88 break;
89 case 'g':
90 args.gid = a_gid(optarg);
91 set_gid = 1;
92 break;
93 case 'm':
94 args.mode = a_mask(optarg);
95 set_mask = 1;
96 break;
97 case 'o':
98 getmntopts(optarg, mopts, &mntflags, 0);
99 break;
100 case 'W':
101 load_u2wtable(&args, optarg);
102 args.flags |= HPFSMNT_TABLES;
103 break;
104 case '?':
105 default:
106 usage();
107 break;
108 }
109 }
110
111 if (optind + 2 != argc)
112 usage();
113
114 if (!(mntflags & MNT_RDONLY) && !forcerw) {
115 warnx("Write support is BETA, you need -F flag to enable RW mount!");
116 exit (111);
117 }
118
119 dev = argv[optind];
120 dir = argv[optind + 1];
121 if (dir[0] != '/') {
122 warnx("\"%s\" is a relative path", dir);
123 if (getcwd(ndir, sizeof(ndir)) == NULL)
124 err(EX_OSERR, "getcwd");
125 strncat(ndir, "/", sizeof(ndir) - strlen(ndir) - 1);
126 strncat(ndir, dir, sizeof(ndir) - strlen(ndir) - 1);
127 dir = ndir;
128 warnx("using \"%s\" instead", dir);
129 }
130
131 args.fspec = dev;
132 args.export.ex_root = 65534; /* unchecked anyway on DOS fs */
133 if (mntflags & MNT_RDONLY)
134 args.export.ex_flags = MNT_EXRDONLY;
135 else
136 args.export.ex_flags = 0;
137
138 if (!set_gid || !set_uid || !set_mask) {
139 if (stat(dir, &sb) == -1)
140 err(EX_OSERR, "stat %s", dir);
141
142 if (!set_uid)
143 args.uid = sb.st_uid;
144 if (!set_gid)
145 args.gid = sb.st_gid;
146 if (!set_mask)
147 args.mode = sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
148 }
149
150#if __FreeBSD_version >= 300000
151 error = getvfsbyname("hpfs", &vfc);
152 if(error && vfsisloadable("hpfs")) {
153 if(vfsload("hpfs"))
154#else
155 vfc = getvfsbyname("hpfs");
156 if(!vfc && vfsisloadable("hpfs")) {
157 if(vfsload("hpfs"))
158#endif
159 err(EX_OSERR, "vfsload(hpfs)");
160 endvfsent(); /* clear cache */
161#if __FreeBSD_version >= 300000
162 error = getvfsbyname("hpfs", &vfc);
163#else
164 vfc = getvfsbyname("hpfs");
165#endif
166 }
167#if __FreeBSD_version >= 300000
168 if (error)
169#else
170 if (!vfc)
171#endif
172 errx(EX_OSERR, "hpfs filesystem is not available");
173
174#if __FreeBSD_version >= 300000
175 if (mount(vfc.vfc_name, dir, mntflags, &args) < 0)
176#else
177 if (mount(vfc->vfc_index, dir, mntflags, &args) < 0)
178#endif
179 err(EX_OSERR, "%s", dev);
180
181 exit (0);
182}
183
184gid_t
b5744197 185a_gid(char *s)
984263bc
MD
186{
187 struct group *gr;
188 char *gname;
189 gid_t gid;
190
191 if ((gr = getgrnam(s)) != NULL)
192 gid = gr->gr_gid;
193 else {
194 for (gname = s; *s && isdigit(*s); ++s);
195 if (!*s)
196 gid = atoi(gname);
197 else
198 errx(EX_NOUSER, "unknown group id: %s", gname);
199 }
200 return (gid);
201}
202
203uid_t
b5744197 204a_uid(char *s)
984263bc
MD
205{
206 struct passwd *pw;
207 char *uname;
208 uid_t uid;
209
210 if ((pw = getpwnam(s)) != NULL)
211 uid = pw->pw_uid;
212 else {
213 for (uname = s; *s && isdigit(*s); ++s);
214 if (!*s)
215 uid = atoi(uname);
216 else
217 errx(EX_NOUSER, "unknown user id: %s", uname);
218 }
219 return (uid);
220}
221
222mode_t
b5744197 223a_mask(char *s)
984263bc
MD
224{
225 int done, rv=0;
226 char *ep;
227
228 done = 0;
229 if (*s >= '0' && *s <= '7') {
230 done = 1;
231 rv = strtol(optarg, &ep, 8);
232 }
233 if (!done || rv < 0 || *ep)
234 errx(EX_USAGE, "invalid file mode: %s", s);
235 return (rv);
236}
237
238void
b5744197 239usage(void)
984263bc
MD
240{
241 fprintf(stderr, "usage: mount_hpfs [-u user] [-g group] [-m mask] bdev dir\n");
242 exit(EX_USAGE);
243}
244
245void
b5744197 246load_u2wtable (struct hpfs_args *pargs, char *name)
984263bc
MD
247{
248 FILE *f;
249 int i, code;
250 char buf[128];
251 char *fn;
252
253 if (*name == '/')
254 fn = name;
255 else {
256 snprintf(buf, sizeof(buf), "/usr/libdata/msdosfs/%s", name);
257 buf[127] = '\0';
258 fn = buf;
259 }
260 if ((f = fopen(fn, "r")) == NULL)
261 err(EX_NOINPUT, "%s", fn);
262 for (i = 0; i < 128; i++) {
263 if (fscanf(f, "%i", &code) != 1)
264 errx(EX_DATAERR, "u2w: missing item number %d", i);
265 /* pargs->u2w[i] = code; */
266 }
267 for (i = 0; i < 128; i++) {
268 if (fscanf(f, "%i", &code) != 1)
269 errx(EX_DATAERR, "d2u: missing item number %d", i);
270 pargs->d2u[i] = code;
271 }
272 for (i = 0; i < 128; i++) {
273 if (fscanf(f, "%i", &code) != 1)
274 errx(EX_DATAERR, "u2d: missing item number %d", i);
275 pargs->u2d[i] = code;
276 }
277 fclose(f);
278}