1 1.76 rillig /* $NetBSD: mount_nfs.c,v 1.76 2025/01/03 00:49:24 rillig Exp $ */ 2 1.8 cgd 3 1.1 mycroft /* 4 1.1 mycroft * Copyright (c) 1992, 1993, 1994 5 1.1 mycroft * The Regents of the University of California. All rights reserved. 6 1.1 mycroft * 7 1.1 mycroft * This code is derived from software contributed to Berkeley by 8 1.1 mycroft * Rick Macklem at The University of Guelph. 9 1.1 mycroft * 10 1.1 mycroft * Redistribution and use in source and binary forms, with or without 11 1.1 mycroft * modification, are permitted provided that the following conditions 12 1.1 mycroft * are met: 13 1.1 mycroft * 1. Redistributions of source code must retain the above copyright 14 1.1 mycroft * notice, this list of conditions and the following disclaimer. 15 1.1 mycroft * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 mycroft * notice, this list of conditions and the following disclaimer in the 17 1.1 mycroft * documentation and/or other materials provided with the distribution. 18 1.45 agc * 3. Neither the name of the University nor the names of its contributors 19 1.1 mycroft * may be used to endorse or promote products derived from this software 20 1.1 mycroft * without specific prior written permission. 21 1.1 mycroft * 22 1.1 mycroft * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 1.1 mycroft * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 1.1 mycroft * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 1.1 mycroft * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 1.1 mycroft * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 1.1 mycroft * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 1.1 mycroft * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 1.1 mycroft * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 1.1 mycroft * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 1.1 mycroft * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 1.1 mycroft * SUCH DAMAGE. 33 1.1 mycroft */ 34 1.1 mycroft 35 1.17 lukem #include <sys/cdefs.h> 36 1.1 mycroft #ifndef lint 37 1.62 lukem __COPYRIGHT("@(#) Copyright (c) 1992, 1993, 1994\ 38 1.62 lukem The Regents of the University of California. All rights reserved."); 39 1.1 mycroft #endif /* not lint */ 40 1.1 mycroft 41 1.1 mycroft #ifndef lint 42 1.8 cgd #if 0 43 1.11 fvdl static char sccsid[] = "@(#)mount_nfs.c 8.11 (Berkeley) 5/4/95"; 44 1.8 cgd #else 45 1.76 rillig __RCSID("$NetBSD: mount_nfs.c,v 1.76 2025/01/03 00:49:24 rillig Exp $"); 46 1.8 cgd #endif 47 1.1 mycroft #endif /* not lint */ 48 1.1 mycroft 49 1.1 mycroft #include <sys/param.h> 50 1.1 mycroft #include <sys/mount.h> 51 1.1 mycroft #include <sys/socket.h> 52 1.1 mycroft #include <sys/stat.h> 53 1.9 jtc #include <syslog.h> 54 1.1 mycroft 55 1.74 christos #include <rpc/rpc.h> 56 1.74 christos #include <nfs/rpcv2.h> /* XXX: redefines enums */ 57 1.11 fvdl #include <nfs/nfsproto.h> 58 1.1 mycroft #include <nfs/nfs.h> 59 1.20 fvdl #include <nfs/nfsmount.h> 60 1.1 mycroft 61 1.1 mycroft #include <arpa/inet.h> 62 1.1 mycroft 63 1.1 mycroft #include <err.h> 64 1.1 mycroft #include <errno.h> 65 1.1 mycroft #include <fcntl.h> 66 1.1 mycroft #include <netdb.h> 67 1.1 mycroft #include <signal.h> 68 1.1 mycroft #include <stdio.h> 69 1.1 mycroft #include <stdlib.h> 70 1.19 perry #include <string.h> 71 1.1 mycroft #include <unistd.h> 72 1.34 christos #include <util.h> 73 1.1 mycroft 74 1.37 jdolecek #include <mntopts.h> 75 1.1 mycroft 76 1.64 pooka #include "mountprog.h" 77 1.48 dsl #include "mount_nfs.h" 78 1.48 dsl 79 1.40 christos #define ALTF_BG 0x00000001 80 1.40 christos #define ALTF_CONN 0x00000002 81 1.40 christos #define ALTF_DUMBTIMR 0x00000004 82 1.40 christos #define ALTF_INTR 0x00000008 83 1.73 christos #define ALTF_NOAC 0x00000010 84 1.40 christos #define ALTF_NFSV3 0x00000020 85 1.40 christos #define ALTF_RDIRPLUS 0x00000040 86 1.40 christos #define ALTF_MNTUDP 0x00000080 87 1.40 christos #define ALTF_NORESPORT 0x00000100 88 1.40 christos #define ALTF_SEQPACKET 0x00000200 89 1.40 christos #define ALTF_NQNFS 0x00000400 90 1.40 christos #define ALTF_SOFT 0x00000800 91 1.40 christos #define ALTF_TCP 0x00001000 92 1.40 christos #define ALTF_NFSV2 0x00002000 93 1.40 christos #define ALTF_PORT 0x00004000 94 1.40 christos #define ALTF_RSIZE 0x00008000 95 1.40 christos #define ALTF_WSIZE 0x00010000 96 1.40 christos #define ALTF_RDIRSIZE 0x00020000 97 1.40 christos #define ALTF_MAXGRPS 0x00040000 98 1.40 christos #define ALTF_LEASETERM 0x00080000 99 1.40 christos #define ALTF_READAHEAD 0x00100000 100 1.40 christos #define ALTF_DEADTHRESH 0x00200000 101 1.40 christos #define ALTF_TIMEO 0x00400000 102 1.40 christos #define ALTF_RETRANS 0x00800000 103 1.72 thorpej #define ALTF_UDP 0x01000000 104 1.11 fvdl 105 1.29 jdolecek static const struct mntopt mopts[] = { 106 1.1 mycroft MOPT_STDOPTS, 107 1.1 mycroft MOPT_FORCE, 108 1.1 mycroft MOPT_UPDATE, 109 1.34 christos MOPT_GETARGS, 110 1.11 fvdl { "bg", 0, ALTF_BG, 1 }, 111 1.14 christos { "conn", 0, ALTF_CONN, 1 }, 112 1.11 fvdl { "dumbtimer", 0, ALTF_DUMBTIMR, 1 }, 113 1.11 fvdl { "intr", 0, ALTF_INTR, 1 }, 114 1.73 christos { "ac", 1, ALTF_NOAC, 1 }, 115 1.11 fvdl { "nfsv3", 0, ALTF_NFSV3, 1 }, 116 1.11 fvdl { "rdirplus", 0, ALTF_RDIRPLUS, 1 }, 117 1.11 fvdl { "mntudp", 0, ALTF_MNTUDP, 1 }, 118 1.65 pooka { "resport", 1, ALTF_NORESPORT, 1 }, 119 1.11 fvdl { "nqnfs", 0, ALTF_NQNFS, 1 }, 120 1.11 fvdl { "soft", 0, ALTF_SOFT, 1 }, 121 1.11 fvdl { "tcp", 0, ALTF_TCP, 1 }, 122 1.72 thorpej { "udp", 0, ALTF_UDP, 1 }, 123 1.13 fvdl { "nfsv2", 0, ALTF_NFSV2, 1 }, 124 1.40 christos { "port", 0, ALTF_PORT, 1 }, 125 1.40 christos { "rsize", 0, ALTF_RSIZE, 1 }, 126 1.40 christos { "wsize", 0, ALTF_WSIZE, 1 }, 127 1.40 christos { "rdirsize", 0, ALTF_RDIRSIZE, 1 }, 128 1.40 christos { "maxgrps", 0, ALTF_MAXGRPS, 1 }, 129 1.40 christos { "leaseterm", 0, ALTF_LEASETERM, 1 }, 130 1.40 christos { "readahead", 0, ALTF_READAHEAD, 1 }, 131 1.40 christos { "deadthresh", 0, ALTF_DEADTHRESH, 1 }, 132 1.40 christos { "timeo", 0, ALTF_TIMEO, 1 }, 133 1.52 christos MOPT_NULL, 134 1.40 christos 135 1.1 mycroft }; 136 1.1 mycroft 137 1.1 mycroft struct nfs_args nfsdefargs = { 138 1.66 yamt .version = NFS_ARGSVERSION, 139 1.66 yamt .addr = NULL, 140 1.66 yamt .addrlen = sizeof(struct sockaddr_in), 141 1.72 thorpej .sotype = SOCK_STREAM, 142 1.66 yamt .proto = 0, 143 1.66 yamt .fh = NULL, 144 1.66 yamt .fhsize = 0, 145 1.66 yamt .flags = NFSMNT_NFSV3|NFSMNT_NOCONN|NFSMNT_RESVPORT, 146 1.66 yamt .wsize = NFS_WSIZE, 147 1.66 yamt .rsize = NFS_RSIZE, 148 1.66 yamt .readdirsize = NFS_READDIRSIZE, 149 1.66 yamt .timeo = 10, 150 1.66 yamt .retrans = NFS_RETRANS, 151 1.66 yamt .maxgrouplist = NFS_MAXGRPS, 152 1.66 yamt .readahead = NFS_DEFRAHEAD, 153 1.66 yamt .leaseterm = 0, /* Ignored; lease term */ 154 1.66 yamt .deadthresh = NFS_DEFDEADTHRESH, 155 1.66 yamt .hostname = NULL, 156 1.1 mycroft }; 157 1.1 mycroft 158 1.47 xtraeme static void shownfsargs(const struct nfs_args *); 159 1.47 xtraeme int mount_nfs(int argc, char **argv); 160 1.47 xtraeme /* void set_rpc_maxgrouplist(int); */ 161 1.69 joerg __dead static void usage(void); 162 1.1 mycroft 163 1.29 jdolecek #ifndef MOUNT_NOMAIN 164 1.1 mycroft int 165 1.47 xtraeme main(int argc, char **argv) 166 1.29 jdolecek { 167 1.64 pooka 168 1.64 pooka setprogname(argv[0]); 169 1.29 jdolecek return mount_nfs(argc, argv); 170 1.29 jdolecek } 171 1.29 jdolecek #endif 172 1.29 jdolecek 173 1.64 pooka void 174 1.64 pooka mount_nfs_dogetargs(struct nfs_args *nfsargsp, int mntflags, const char *spec) 175 1.1 mycroft { 176 1.67 pooka static struct sockaddr_storage sa; 177 1.64 pooka char *tspec; 178 1.64 pooka 179 1.64 pooka if ((mntflags & MNT_GETARGS) != 0) { 180 1.64 pooka memset(&sa, 0, sizeof(sa)); 181 1.64 pooka nfsargsp->addr = (struct sockaddr *)&sa; 182 1.64 pooka nfsargsp->addrlen = sizeof(sa); 183 1.64 pooka } else { 184 1.64 pooka if ((tspec = strdup(spec)) == NULL) { 185 1.74 christos err(EXIT_FAILURE, "strdup"); 186 1.64 pooka } 187 1.64 pooka if (!getnfsargs(tspec, nfsargsp)) { 188 1.74 christos exit(EXIT_FAILURE); 189 1.64 pooka } 190 1.64 pooka free(tspec); 191 1.64 pooka } 192 1.64 pooka } 193 1.64 pooka 194 1.74 christos static int 195 1.74 christos getnum(const char *s, int c) 196 1.74 christos { 197 1.74 christos char *es; 198 1.74 christos long num = strtol(s, &es, 10); 199 1.74 christos if (*es || num <= 0 || num > INT_MAX) 200 1.74 christos errx(EXIT_FAILURE, "Illegal value `%s' for option -%c", s, c); 201 1.74 christos return (int)num; 202 1.74 christos } 203 1.74 christos 204 1.74 christos static __dead void 205 1.74 christos conflicting(void) 206 1.74 christos { 207 1.74 christos errx(EXIT_FAILURE, "Conflicting version options"); 208 1.74 christos } 209 1.74 christos 210 1.64 pooka void 211 1.64 pooka mount_nfs_parseargs(int argc, char *argv[], 212 1.64 pooka struct nfs_args *nfsargsp, int *mntflags, 213 1.64 pooka char *spec, char *name) 214 1.64 pooka { 215 1.64 pooka int altflags, num; 216 1.64 pooka int c; 217 1.40 christos mntoptparse_t mp; 218 1.1 mycroft 219 1.64 pooka *mntflags = 0; 220 1.11 fvdl altflags = 0; 221 1.64 pooka memset(nfsargsp, 0, sizeof(*nfsargsp)); 222 1.64 pooka *nfsargsp = nfsdefargs; 223 1.1 mycroft while ((c = getopt(argc, argv, 224 1.76 rillig "23Aa:bcCdD:g:I:iL:lo:PpqR:r:sTt:w:x:UuX")) != -1) 225 1.1 mycroft switch (c) { 226 1.11 fvdl case '3': 227 1.53 yamt case 'q': 228 1.11 fvdl if (force2) 229 1.74 christos conflicting(); 230 1.11 fvdl force3 = 1; 231 1.11 fvdl break; 232 1.11 fvdl case '2': 233 1.11 fvdl if (force3) 234 1.74 christos conflicting(); 235 1.11 fvdl force2 = 1; 236 1.11 fvdl nfsargsp->flags &= ~NFSMNT_NFSV3; 237 1.11 fvdl break; 238 1.73 christos case 'A': 239 1.73 christos nfsargsp->flags |= NFSMNT_NOAC; 240 1.73 christos break; 241 1.1 mycroft case 'a': 242 1.74 christos nfsargsp->readahead = getnum(optarg, c); 243 1.1 mycroft nfsargsp->flags |= NFSMNT_READAHEAD; 244 1.1 mycroft break; 245 1.1 mycroft case 'b': 246 1.1 mycroft opflags |= BGRND; 247 1.1 mycroft break; 248 1.1 mycroft case 'c': 249 1.1 mycroft nfsargsp->flags |= NFSMNT_NOCONN; 250 1.1 mycroft break; 251 1.14 christos case 'C': 252 1.14 christos nfsargsp->flags &= ~NFSMNT_NOCONN; 253 1.14 christos break; 254 1.1 mycroft case 'D': 255 1.74 christos nfsargsp->deadthresh = getnum(optarg, c); 256 1.54 yamt nfsargsp->flags |= NFSMNT_DEADTHRESH; 257 1.1 mycroft break; 258 1.1 mycroft case 'd': 259 1.1 mycroft nfsargsp->flags |= NFSMNT_DUMBTIMR; 260 1.1 mycroft break; 261 1.1 mycroft case 'g': 262 1.74 christos num = getnum(optarg, c); 263 1.1 mycroft set_rpc_maxgrouplist(num); 264 1.1 mycroft nfsargsp->maxgrouplist = num; 265 1.1 mycroft nfsargsp->flags |= NFSMNT_MAXGRPS; 266 1.1 mycroft break; 267 1.11 fvdl case 'I': 268 1.74 christos nfsargsp->readdirsize = getnum(optarg, c); 269 1.11 fvdl nfsargsp->flags |= NFSMNT_READDIRSIZE; 270 1.11 fvdl break; 271 1.1 mycroft case 'i': 272 1.1 mycroft nfsargsp->flags |= NFSMNT_INT; 273 1.1 mycroft break; 274 1.1 mycroft case 'L': 275 1.53 yamt /* ignore */ 276 1.1 mycroft break; 277 1.1 mycroft case 'l': 278 1.11 fvdl nfsargsp->flags |= NFSMNT_RDIRPLUS; 279 1.1 mycroft break; 280 1.1 mycroft case 'o': 281 1.64 pooka mp = getmntopts(optarg, mopts, mntflags, &altflags); 282 1.40 christos if (mp == NULL) 283 1.74 christos err(EXIT_FAILURE, "getmntopts"); 284 1.35 itojun if (altflags & ALTF_BG) 285 1.11 fvdl opflags |= BGRND; 286 1.35 itojun if (altflags & ALTF_CONN) 287 1.14 christos nfsargsp->flags &= ~NFSMNT_NOCONN; 288 1.35 itojun if (altflags & ALTF_DUMBTIMR) 289 1.11 fvdl nfsargsp->flags |= NFSMNT_DUMBTIMR; 290 1.35 itojun if (altflags & ALTF_INTR) 291 1.11 fvdl nfsargsp->flags |= NFSMNT_INT; 292 1.73 christos if (altflags & ALTF_NOAC) 293 1.73 christos nfsargsp->flags |= NFSMNT_NOAC; 294 1.53 yamt if (altflags & (ALTF_NFSV3|ALTF_NQNFS)) { 295 1.13 fvdl if (force2) 296 1.74 christos conflicting(); 297 1.13 fvdl force3 = 1; 298 1.13 fvdl } 299 1.35 itojun if (altflags & ALTF_NFSV2) { 300 1.13 fvdl if (force3) 301 1.74 christos conflicting(); 302 1.13 fvdl force2 = 1; 303 1.13 fvdl nfsargsp->flags &= ~NFSMNT_NFSV3; 304 1.13 fvdl } 305 1.35 itojun if (altflags & ALTF_RDIRPLUS) 306 1.11 fvdl nfsargsp->flags |= NFSMNT_RDIRPLUS; 307 1.35 itojun if (altflags & ALTF_MNTUDP) 308 1.11 fvdl mnttcp_ok = 0; 309 1.35 itojun if (altflags & ALTF_NORESPORT) 310 1.15 fvdl nfsargsp->flags &= ~NFSMNT_RESVPORT; 311 1.35 itojun if (altflags & ALTF_SOFT) 312 1.11 fvdl nfsargsp->flags |= NFSMNT_SOFT; 313 1.72 thorpej if (altflags & ALTF_UDP) { 314 1.72 thorpej nfsargsp->sotype = SOCK_DGRAM; 315 1.72 thorpej } 316 1.72 thorpej /* 317 1.72 thorpej * After UDP, because TCP overrides if both 318 1.72 thorpej * are present. 319 1.72 thorpej */ 320 1.35 itojun if (altflags & ALTF_TCP) { 321 1.11 fvdl nfsargsp->sotype = SOCK_STREAM; 322 1.11 fvdl } 323 1.40 christos if (altflags & ALTF_PORT) { 324 1.74 christos port = (int)getmntoptnum(mp, "port"); 325 1.40 christos } 326 1.40 christos if (altflags & ALTF_RSIZE) { 327 1.40 christos nfsargsp->rsize = 328 1.40 christos (int)getmntoptnum(mp, "rsize"); 329 1.40 christos nfsargsp->flags |= NFSMNT_RSIZE; 330 1.40 christos } 331 1.40 christos if (altflags & ALTF_WSIZE) { 332 1.42 yamt nfsargsp->wsize = 333 1.40 christos (int)getmntoptnum(mp, "wsize"); 334 1.40 christos nfsargsp->flags |= NFSMNT_WSIZE; 335 1.40 christos } 336 1.40 christos if (altflags & ALTF_RDIRSIZE) { 337 1.40 christos nfsargsp->rsize = 338 1.40 christos (int)getmntoptnum(mp, "rdirsize"); 339 1.40 christos nfsargsp->flags |= NFSMNT_READDIRSIZE; 340 1.40 christos } 341 1.40 christos #if 0 342 1.40 christos if (altflags & ALTF_MAXGRPS) { 343 1.40 christos set_rpc_maxgrouplist(num); 344 1.40 christos nfsargsp->maxgrouplist = 345 1.40 christos (int)getmntoptnum(mp, "maxgrps"); 346 1.40 christos nfsargsp->flags |= NFSMNT_MAXGRPS; 347 1.40 christos } 348 1.40 christos #endif 349 1.40 christos if (altflags & ALTF_LEASETERM) { 350 1.40 christos nfsargsp->leaseterm = 351 1.40 christos (int)getmntoptnum(mp, "leaseterm"); 352 1.40 christos nfsargsp->flags |= NFSMNT_LEASETERM; 353 1.40 christos } 354 1.40 christos if (altflags & ALTF_READAHEAD) { 355 1.40 christos nfsargsp->readahead = 356 1.40 christos (int)getmntoptnum(mp, "readahead"); 357 1.40 christos nfsargsp->flags |= NFSMNT_READAHEAD; 358 1.40 christos } 359 1.40 christos if (altflags & ALTF_DEADTHRESH) { 360 1.40 christos nfsargsp->deadthresh = 361 1.40 christos (int)getmntoptnum(mp, "deadthresh"); 362 1.40 christos nfsargsp->flags |= NFSMNT_DEADTHRESH; 363 1.40 christos } 364 1.40 christos if (altflags & ALTF_TIMEO) { 365 1.40 christos nfsargsp->timeo = 366 1.40 christos (int)getmntoptnum(mp, "timeo"); 367 1.40 christos nfsargsp->flags |= NFSMNT_TIMEO; 368 1.40 christos } 369 1.40 christos if (altflags & ALTF_RETRANS) { 370 1.40 christos nfsargsp->retrans = 371 1.40 christos (int)getmntoptnum(mp, "retrans"); 372 1.40 christos nfsargsp->flags |= NFSMNT_RETRANS; 373 1.40 christos } 374 1.11 fvdl altflags = 0; 375 1.40 christos freemntopts(mp); 376 1.1 mycroft break; 377 1.1 mycroft case 'P': 378 1.1 mycroft nfsargsp->flags |= NFSMNT_RESVPORT; 379 1.1 mycroft break; 380 1.1 mycroft case 'p': 381 1.15 fvdl nfsargsp->flags &= ~NFSMNT_RESVPORT; 382 1.1 mycroft break; 383 1.1 mycroft case 'R': 384 1.74 christos retrycnt = getnum(optarg, c); 385 1.1 mycroft break; 386 1.1 mycroft case 'r': 387 1.74 christos nfsargsp->rsize = getnum(optarg, c); 388 1.1 mycroft nfsargsp->flags |= NFSMNT_RSIZE; 389 1.1 mycroft break; 390 1.1 mycroft case 's': 391 1.1 mycroft nfsargsp->flags |= NFSMNT_SOFT; 392 1.1 mycroft break; 393 1.1 mycroft case 'T': 394 1.1 mycroft nfsargsp->sotype = SOCK_STREAM; 395 1.1 mycroft break; 396 1.1 mycroft case 't': 397 1.74 christos nfsargsp->timeo = getnum(optarg, c); 398 1.1 mycroft nfsargsp->flags |= NFSMNT_TIMEO; 399 1.1 mycroft break; 400 1.1 mycroft case 'w': 401 1.74 christos nfsargsp->wsize = getnum(optarg, c); 402 1.1 mycroft nfsargsp->flags |= NFSMNT_WSIZE; 403 1.1 mycroft break; 404 1.1 mycroft case 'x': 405 1.74 christos nfsargsp->retrans = getnum(optarg, c); 406 1.1 mycroft nfsargsp->flags |= NFSMNT_RETRANS; 407 1.18 fvdl break; 408 1.18 fvdl case 'X': 409 1.18 fvdl nfsargsp->flags |= NFSMNT_XLATECOOKIE; 410 1.1 mycroft break; 411 1.72 thorpej case 'u': 412 1.72 thorpej nfsargsp->sotype = SOCK_DGRAM; 413 1.72 thorpej break; 414 1.11 fvdl case 'U': 415 1.11 fvdl mnttcp_ok = 0; 416 1.11 fvdl break; 417 1.1 mycroft default: 418 1.1 mycroft usage(); 419 1.1 mycroft } 420 1.1 mycroft argc -= optind; 421 1.1 mycroft argv += optind; 422 1.1 mycroft 423 1.1 mycroft if (argc != 2) 424 1.7 cgd usage(); 425 1.1 mycroft 426 1.64 pooka strlcpy(spec, *argv++, MAXPATHLEN); 427 1.64 pooka pathadj(*argv, name); 428 1.64 pooka mount_nfs_dogetargs(nfsargsp, *mntflags, spec); 429 1.64 pooka } 430 1.64 pooka 431 1.64 pooka int 432 1.64 pooka mount_nfs(int argc, char *argv[]) 433 1.64 pooka { 434 1.64 pooka char spec[MAXPATHLEN], name[MAXPATHLEN]; 435 1.64 pooka struct nfs_args args; 436 1.64 pooka int mntflags; 437 1.64 pooka int retval; 438 1.46 erh 439 1.64 pooka mount_nfs_parseargs(argc, argv, &args, &mntflags, spec, name); 440 1.51 yamt 441 1.64 pooka retry: 442 1.60 pooka if ((retval = mount(MOUNT_NFS, name, mntflags, 443 1.64 pooka &args, sizeof args)) == -1) { 444 1.33 wrstuden /* Did we just default to v3 on a v2-only kernel? 445 1.33 wrstuden * If so, default to v2 & try again */ 446 1.51 yamt if (errno == EPROGMISMATCH && 447 1.64 pooka (args.flags & NFSMNT_NFSV3) != 0 && !force3) { 448 1.51 yamt /* 449 1.51 yamt * fall back to v2. XXX lack of V3 umount. 450 1.51 yamt */ 451 1.64 pooka args.flags &= ~NFSMNT_NFSV3; 452 1.64 pooka mount_nfs_dogetargs(&args, mntflags, spec); 453 1.51 yamt goto retry; 454 1.33 wrstuden } 455 1.33 wrstuden } 456 1.60 pooka if (retval == -1) 457 1.74 christos err(EXIT_FAILURE, "%s on %s", spec, name); 458 1.34 christos if (mntflags & MNT_GETARGS) { 459 1.64 pooka shownfsargs(&args); 460 1.74 christos return EXIT_SUCCESS; 461 1.34 christos } 462 1.34 christos 463 1.74 christos exit(EXIT_SUCCESS); 464 1.34 christos } 465 1.34 christos 466 1.34 christos static void 467 1.47 xtraeme shownfsargs(const struct nfs_args *nfsargsp) 468 1.34 christos { 469 1.34 christos char fbuf[2048]; 470 1.36 enami char host[NI_MAXHOST], serv[NI_MAXSERV]; 471 1.36 enami int error; 472 1.34 christos 473 1.74 christos (void)snprintb(fbuf, sizeof(fbuf), NFSMNT_BITS, 474 1.74 christos (uint64_t)nfsargsp->flags); 475 1.36 enami if (nfsargsp->addr != NULL) { 476 1.74 christos error = getnameinfo(nfsargsp->addr, 477 1.74 christos (socklen_t)nfsargsp->addrlen, host, 478 1.36 enami sizeof(host), serv, sizeof(serv), 479 1.36 enami NI_NUMERICHOST | NI_NUMERICSERV); 480 1.36 enami if (error != 0) 481 1.36 enami warnx("getnameinfo: %s", gai_strerror(error)); 482 1.36 enami } else 483 1.36 enami error = -1; 484 1.36 enami 485 1.36 enami if (error == 0) 486 1.39 lukem printf("addr=%s, port=%s, addrlen=%d, ", 487 1.36 enami host, serv, nfsargsp->addrlen); 488 1.38 fvdl printf("sotype=%d, proto=%d, fhsize=%d, " 489 1.34 christos "flags=%s, wsize=%d, rsize=%d, readdirsize=%d, timeo=%d, " 490 1.34 christos "retrans=%d, maxgrouplist=%d, readahead=%d, leaseterm=%d, " 491 1.34 christos "deadthresh=%d\n", 492 1.34 christos nfsargsp->sotype, 493 1.34 christos nfsargsp->proto, 494 1.34 christos nfsargsp->fhsize, 495 1.34 christos fbuf, 496 1.34 christos nfsargsp->wsize, 497 1.34 christos nfsargsp->rsize, 498 1.34 christos nfsargsp->readdirsize, 499 1.34 christos nfsargsp->timeo, 500 1.34 christos nfsargsp->retrans, 501 1.34 christos nfsargsp->maxgrouplist, 502 1.34 christos nfsargsp->readahead, 503 1.34 christos nfsargsp->leaseterm, 504 1.34 christos nfsargsp->deadthresh); 505 1.1 mycroft } 506 1.1 mycroft 507 1.29 jdolecek static void 508 1.47 xtraeme usage(void) 509 1.1 mycroft { 510 1.74 christos (void)fprintf(stderr, "Usage: %s %s\n%s\n%s\n%s\n%s\n", getprogname(), 511 1.72 thorpej "[-23bCcdilPpqsTUuX] [-a maxreadahead] [-D deadthresh]", 512 1.50 wiz "\t[-g maxgroups] [-I readdirsize] [-L leaseterm]", 513 1.24 mjl "\t[-o options] [-R retrycnt] [-r readsize] [-t timeout]", 514 1.24 mjl "\t[-w writesize] [-x retrans]", 515 1.1 mycroft "\trhost:path node"); 516 1.74 christos exit(EXIT_FAILURE); 517 1.1 mycroft } 518