GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/mount_msdos/mount_msdos.c Lines: 0 72 0.0 %
Date: 2017-11-07 Branches: 0 46 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: mount_msdos.c,v 1.33 2016/05/21 19:14:02 jmc Exp $	*/
2
/*	$NetBSD: mount_msdos.c,v 1.16 1996/10/24 00:12:50 cgd Exp $	*/
3
4
/*
5
 * Copyright (c) 1994 Christopher G. Demetriou
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. All advertising materials mentioning features or use of this software
17
 *    must display the following acknowledgement:
18
 *      This product includes software developed by Christopher G. Demetriou.
19
 * 4. The name of the author may not be used to endorse or promote products
20
 *    derived from this software without specific prior written permission
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
 */
33
34
#include <sys/types.h>
35
#include <sys/mount.h>
36
#include <sys/stat.h>
37
#include <ctype.h>
38
#include <err.h>
39
#include <grp.h>
40
#include <pwd.h>
41
#include <stdio.h>
42
#include <stdlib.h>
43
#include <string.h>
44
#include <unistd.h>
45
#include <limits.h>
46
#include <errno.h>
47
48
#include "mntopts.h"
49
50
const struct mntopt mopts[] = {
51
	MOPT_STDOPTS,
52
	MOPT_UPDATE,
53
	MOPT_ASYNC,
54
	{ NULL }
55
};
56
57
gid_t	a_gid(char *);
58
uid_t	a_uid(char *);
59
mode_t	a_mask(char *);
60
void	usage(void);
61
62
int
63
main(int argc, char **argv)
64
{
65
	struct msdosfs_args args;
66
	struct stat sb;
67
	int c, mntflags, set_gid, set_uid, set_mask;
68
	char *dev, dir[PATH_MAX];
69
	char *errcause;
70
71
	mntflags = set_gid = set_uid = set_mask = 0;
72
	(void)memset(&args, '\0', sizeof(args));
73
74
	while ((c = getopt(argc, argv, "sl9u:g:m:o:")) != -1) {
75
		switch (c) {
76
		case 's':
77
			args.flags |= MSDOSFSMNT_SHORTNAME;
78
			break;
79
		case 'l':
80
			args.flags |= MSDOSFSMNT_LONGNAME;
81
			break;
82
		case '9':
83
			args.flags |= MSDOSFSMNT_NOWIN95;
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.mask = a_mask(optarg);
95
			set_mask = 1;
96
			break;
97
		case 'o':
98
			getmntopts(optarg, mopts, &mntflags);
99
			break;
100
		case '?':
101
		default:
102
			usage();
103
			break;
104
		}
105
	}
106
107
	if (optind + 2 != argc)
108
		usage();
109
110
	dev = argv[optind];
111
	if (realpath(argv[optind + 1], dir) == NULL)
112
		err(1, "realpath %s", argv[optind + 1]);
113
114
	args.fspec = dev;
115
	args.export_info.ex_root = -2;	/* unchecked anyway on DOS fs */
116
	if (mntflags & MNT_RDONLY)
117
		args.export_info.ex_flags = MNT_EXRDONLY;
118
	else
119
		args.export_info.ex_flags = 0;
120
	if (!set_gid || !set_uid || !set_mask) {
121
		if (stat(dir, &sb) == -1)
122
			err(1, "stat %s", dir);
123
124
		if (!set_uid)
125
			args.uid = sb.st_uid;
126
		if (!set_gid)
127
			args.gid = sb.st_gid;
128
		if (!set_mask)
129
			args.mask = sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
130
	}
131
132
	if (mount(MOUNT_MSDOS, dir, mntflags, &args) < 0) {
133
		switch (errno) {
134
		case EOPNOTSUPP:
135
			errcause = "filesystem not supported by kernel";
136
			break;
137
		case EMFILE:
138
			errcause = "mount table full";
139
			break;
140
		case EINVAL:
141
			errcause =
142
			    "not an MSDOS filesystem";
143
			break;
144
		default:
145
			errcause = strerror(errno);
146
			break;
147
		}
148
		errx(1, "%s on %s: %s", args.fspec, dir, errcause);
149
	}
150
151
	exit (0);
152
}
153
154
gid_t
155
a_gid(char *s)
156
{
157
	struct group *gr;
158
	const char *errstr;
159
	gid_t gid;
160
161
	if ((gr = getgrnam(s)) != NULL)
162
		return gr->gr_gid;
163
	gid = strtonum(s, 0, GID_MAX, &errstr);
164
	if (errstr)
165
		errx(1, "group is %s: %s", errstr, s);
166
	return (gid);
167
}
168
169
uid_t
170
a_uid(char *s)
171
{
172
	struct passwd *pw;
173
	const char *errstr;
174
	uid_t uid;
175
176
	if ((pw = getpwnam(s)) != NULL)
177
		return pw->pw_uid;
178
	uid = strtonum(s, 0, UID_MAX, &errstr);
179
	if (errstr)
180
		errx(1, "user is %s: %s", errstr, s);
181
	return (uid);
182
}
183
184
mode_t
185
a_mask(char *s)
186
{
187
	int done, rv;
188
	char *ep;
189
190
	done = 0;
191
	if (*s >= '0' && *s <= '7') {
192
		done = 1;
193
		rv = strtol(optarg, &ep, 8);
194
	}
195
	if (!done || rv < 0 || *ep)
196
		errx(1, "invalid file mode: %s", s);
197
	return (rv);
198
}
199
200
void
201
usage(void)
202
{
203
204
	fprintf(stderr,
205
	    "usage: mount_msdos [-9ls] [-g gid] [-m mask] [-o options] [-u uid] special node\n");
206
	exit(1);
207
}