/vesta/vestasys.org/vesta/vmount/8/src/vmount_freebsd.c attribs
1 /*
2 ** Copyright (C) 2001, Compaq Computer Corporation
3 **
4 ** This file is part of Vesta.
5 **
6 ** Vesta is free software; you can redistribute it and/or
7 ** modify it under the terms of the GNU Lesser General Public
8 ** License as published by the Free Software Foundation; either
9 ** version 2.1 of the License, or (at your option) any later version.
10 **
11 ** Vesta is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** Lesser General Public License for more details.
15 **
16 ** You should have received a copy of the GNU Lesser General Public
17 ** License along with Vesta; if not, write to the Free Software
18 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 /*
22 * vmount.c
23 * Last modified on Sun Feb 6 21:51:05 EST 2005 by ken@xorian.net
24 * modified on Tue Jul 16 15:49:19 PDT 1996 by mann
25 *
26 * Mount an NFS file system by handle, without using mountd.
27 *
28 * Usage:
29 * vmount [-p:rxsdyfugSW:R:T:E:H:ICAN:X:D:Y:OPU] host handle /directory
30 *
31 * -p port UDP port number for NFS server, default 2049
32 *
33 * -r M_RDONLY The file system should be treated as read only; no
34 * writing is allowed (even by a process with appropriate
35 * privilege). Physically write-protected and magnetic
36 * tape file systems must be mounted read only or errors
37 * will occur when access times are updated, whether or
38 * not any explicit write is attempted.
39 *
40 * -x M_NOEXEC Do not allow files to be executed from the file system.
41 *
42 * -s M_NOSUID Do not honor setuid or setgid bits on files when exe-
43 * cuting them.
44 *
45 * -d M_NODEV Do not interpret special files on the file system.
46 *
47 * -y M_SYNCHRONOUS
48 * All I/O to the file system should be done synchro-
49 * nously.
50 *
51 * -u M_UPDATE The mount command is being applied to an already
52 * mounted file system. This allows the mount flags to be
53 * changed without requiring that the file system be
54 * unmounted and remounted.
55 *
56 * -S NFSMNT_SOFT soft mount (hard is default)
57 * -W size NFSMNT_WSIZE set write size (default 8192)
58 * -R size NFSMNT_RSIZE set read size (default 8192)
59 * -T tnths NFSMNT_TIMEO set initial timeout (in 1/10 secs; default 11)
60 * -E count NFSMNT_RETRANS set number of request retries (default 4)
61 * -I NFSMNT_INT allow interrupts on hard mount
62 * -C NFSMNT_NOCONN no connect on mount - any responder
63 * -N sec NFSMNT_ACREGMIN set min seconds for file attr cache (def 3600)
64 * -X sec NFSMNT_ACREGMAX set max seconds for file attr cache (def 36000)
65 * -D sec NFSMNT_ACDIRMIN set min seconds for dir attr cache (def 3600)
66 * -Y sec NFSMNT_ACDIRMAX set max seconds for dir attr cache (def 36000)
67 */
68
69 #include <sys/cdefs.h>
70 #include <sys/param.h>
71 #include <sys/mount.h>
72 #include <stdlib.h>
73 #define _SOCKADDR_LEN
74 #include <sys/socket.h>
75 #include <netinet/in.h>
76 #include <netdb.h>
77 #include <stdio.h>
78 #include <errno.h>
79
80 /* getopt */
81 #include <unistd.h>
82
83 /* nfs_args */
84 #include <nfs/rpcv2.h>
85 #include <nfs/nfsproto.h>
86 #include <nfsclient/nfs.h>
87 #include <nfsclient/nfsargs.h>
88
89 #define DEFAULT_PORT 2049
90
91 #define ARGS "p:rxsdyuSW:R:T:E:ICN:X:D:Y:"
92
93 int
94 main(int argc, char *argv[])
95 {
96 char *hostname, *handlestr, *dirname;
97 int flags = 0;
98 int i, c, errflg = 0;
99 struct nfs_args nfsargs;
100 struct sockaddr_in hostaddr;
101 struct hostent *hp;
102 unsigned char handle[NFSX_V2FH];
103 unsigned short uport = DEFAULT_PORT;
104 char errname[1024];
105
106 memset((char *) &nfsargs, (int) 0, sizeof(struct nfs_args));
107
108 nfsargs.version = NFS_ARGSVERSION;
109 nfsargs.sotype = SOCK_DGRAM;
110
111 optarg = NULL;
112 while (!errflg && (c = getopt(argc, argv, ARGS)) != -1) {
113 switch (c) {
114 case 'p':
115 uport = (unsigned short) atoi(optarg);
116 break;
117 case 'r':
118 flags |= MNT_RDONLY;
119 break;
120 case 'x':
121 flags |= MNT_NOEXEC;
122 break;
123 case 's':
124 flags |= MNT_NOSUID;
125 break;
126 case 'd':
127 flags |= MNT_NODEV;
128 break;
129 case 'y':
130 flags |= MNT_SYNCHRONOUS;
131 break;
132 case 'u':
133 flags |= MNT_UPDATE;
134 break;
135 case 'S':
136 nfsargs.flags |= NFSMNT_SOFT;
137 break;
138 case 'W':
139 nfsargs.flags |= NFSMNT_WSIZE;
140 nfsargs.wsize = atoi(optarg);
141 break;
142 case 'R':
143 nfsargs.flags |= NFSMNT_RSIZE;
144 nfsargs.rsize = atoi(optarg);
145 break;
146 case 'T':
147 nfsargs.flags |= NFSMNT_TIMEO;
148 nfsargs.timeo = atoi(optarg);
149 break;
150 case 'E':
151 nfsargs.flags |= NFSMNT_RETRANS;
152 nfsargs.retrans = atoi(optarg);
153 break;
154 case 'I':
155 nfsargs.flags |= NFSMNT_INT;
156 break;
157 case 'C':
158 nfsargs.flags |= NFSMNT_NOCONN;
159 break;
160 case 'N':
161 nfsargs.flags |= NFSMNT_ACREGMIN;
162 nfsargs.acregmin = atoi(optarg);
163 break;
164 case 'X':
165 nfsargs.flags |= NFSMNT_ACREGMAX;
166 nfsargs.acregmax = atoi(optarg);
167 break;
168 case 'D':
169 nfsargs.flags |= NFSMNT_ACDIRMIN;
170 nfsargs.acdirmin = atoi(optarg);
171 break;
172 case 'Y':
173 nfsargs.flags |= NFSMNT_ACDIRMAX;
174 nfsargs.acdirmax = atoi(optarg);
175 break;
176 default:
177 errflg++;
178 break;
179 }
180 }
181
182 if (errflg || argc < optind + 3) {
183 fprintf(stderr,
184 "Usage: %s [-%s] host handle /dir\n", argv[0], ARGS);
185 exit(1);
186 }
187
188 hostname = argv[optind++];
189 handlestr = argv[optind++];
190 dirname = argv[optind];
191
192 if (dirname[0] != '/') {
193 fprintf(stderr,
194 "%s: directory name must begin with '/'\n", argv[0]);
195 exit(1);
196 }
197
198 /* Convert handlestr to handle */
199 for (i = 0; i < NFSX_V2FH; i++) {
200 int byte;
201 if (sscanf(&handlestr[i*2], "%2x", &byte) != 1) break;
202 handle[i] = byte;
203 if (handlestr[i*2 + 1] == '\0') {
204 handle[i] <<= 4;
205 break;
206 }
207 }
208 for (; i < NFSX_V2FH; i++) {
209 handle[i] = 0;
210 }
211
212 /* Look up host name */
213 memset((char *) &hostaddr, (int) 0, sizeof(struct sockaddr_in));
214 if (!(hp = gethostbyname(hostname))) {
215 int b0, b1, b2, b3;
216 if (sscanf(hostname, "%d.%d.%d.%d", &b0, &b1, &b2, &b3) == 4) {
217 hp = (struct hostent *) calloc(1, sizeof(struct hostent));
218 hp->h_addrtype = AF_INET;
219 hp->h_length = 4;
220 hp->h_addr_list = (char **) calloc(2, sizeof(char *));
221 hp->h_addr_list[0] = (char *) malloc(4);
222 hp->h_addr_list[0][0] = b0;
223 hp->h_addr_list[0][1] = b1;
224 hp->h_addr_list[0][2] = b2;
225 hp->h_addr_list[0][3] = b3;
226 } else {
227 fprintf(stderr, "%s error: no such host: %s\n", argv[0], hostname);
228 exit(1);
229 }
230 }
231 hostaddr.sin_family = hp->h_addrtype;
232 memcpy((char *) &hostaddr.sin_addr, hp->h_addr, hp->h_length);
233 hostaddr.sin_port = htons(uport);
234
235 /* Fill in remaining NFS mount args */
236 nfsargs.addr = (struct sockaddr *) &hostaddr;
237 nfsargs.addrlen = sizeof(hostaddr);
238 nfsargs.fh = (caddr_t) handle;
239 nfsargs.fhsize = NFSX_V2FH;
240
241 if (uport != DEFAULT_PORT) {
242 sprintf(errname, "%s:%hu/%s", hostname, uport, handlestr);
243 } else {
244 sprintf(errname, "%s/%s", hostname, handlestr);
245 }
246 nfsargs.hostname = errname;
247
248 if (mount("nfs", dirname, flags, (caddr_t) &nfsargs) == -1) {
249 fprintf(stderr, "%s %s: %s\n", argv[0], dirname, sys_errlist[errno]);
250 exit(2);
251 }
252 exit(0);
253 }
254