/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