X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=utils%2Fmount%2Fnfsumount.c;h=f6294d4e5c83fcd96a09c057a41d163f33e4fc06;hb=f0e018fa18ac7726a67144c73e8ca0f33190b7dd;hp=d1d476ae2564f8bd4fc399ff75f9eab61c57af31;hpb=a0520fa1a41bd33815b331b660b4545f2723495c;p=nfs-utils.git diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c index d1d476a..f6294d4 100644 --- a/utils/mount/nfsumount.c +++ b/utils/mount/nfsumount.c @@ -30,7 +30,7 @@ #include "conn.h" #include "mount_constants.h" -#include "nfsmount.h" +#include "mount.h" #include "nfsumount.h" #if !defined(MNT_FORCE) @@ -55,24 +55,11 @@ extern int probe_mntport(clnt_addr_t *); extern int nfs_gethostbyname(const char *, struct sockaddr_in *); static inline enum clnt_stat -nfs3_umount(dirpath *argp, CLIENT *clnt) +nfs_umount(dirpath *argp, CLIENT *clnt) { - static char clnt_res; - memset (&clnt_res, 0, sizeof(clnt_res)); return clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath, (caddr_t)argp, - (xdrproc_t) xdr_void, (caddr_t) &clnt_res, - TIMEOUT); -} - -static inline enum clnt_stat -nfs2_umount(dirpath *argp, CLIENT *clnt) -{ - static char clnt_res; - memset (&clnt_res, 0, sizeof(clnt_res)); - return clnt_call(clnt, MOUNTPROC_UMNT, - (xdrproc_t) xdr_dirpath, (caddr_t)argp, - (xdrproc_t) xdr_void, (caddr_t) &clnt_res, + (xdrproc_t) xdr_void, NULL, TIMEOUT); } @@ -82,54 +69,50 @@ int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp) enum clnt_stat res = 0; int msock; - clnt = mnt_openclnt(mnt_server, &msock); - if (!clnt) - goto out_bad; switch (mnt_server->pmap.pm_vers) { case 3: - res = nfs3_umount(argp, clnt); - break; case 2: case 1: - res = nfs2_umount(argp, clnt); + if (!probe_mntport(mnt_server)) + goto out_bad; + clnt = mnt_openclnt(mnt_server, &msock); + if (!clnt) + goto out_bad; + res = nfs_umount(argp, clnt); + mnt_closeclnt(clnt, msock); + if (res == RPC_SUCCESS) + return 1; break; default: + res = 1; break; } - mnt_closeclnt(clnt, msock); - if (res == RPC_SUCCESS) - return 1; out_bad: - return 0; + return res; } -u_int get_mntproto(const char *); -u_int -get_mntproto(const char *dirname) +struct mntentchn * +getmntentchn(const char *dir) { - FILE *mtab; - struct mntent mntbuf; - char tmpbuf[BUFSIZ]; - u_int proto = IPPROTO_TCP; /* assume tcp */ - - mtab = setmntent ("/proc/mounts", "r"); - if (mtab == NULL) - mtab = setmntent (_PATH_MOUNTED, "r"); - if (mtab == NULL) - return proto; - - while(getmntent_r(mtab, &mntbuf, tmpbuf, sizeof (tmpbuf))) { - if (strcmp(mntbuf.mnt_type, "nfs")) - continue; - if (strcmp(dirname, mntbuf.mnt_fsname)) + mntFILE *mfp; + nfs_mntent_t *mnt; + struct mntentchn *mc = NULL; + + mfp = nfs_setmntent ("/proc/mounts", "r"); + if (mfp == NULL || mfp->mntent_fp == NULL) + return NULL; + + while ((mnt = nfs_getmntent(mfp)) != NULL) { + if(strcmp(mnt->mnt_fsname, dir) && strcmp(mnt->mnt_dir, dir)) continue; - if (hasmntopt(&mntbuf, "udp")) - proto = IPPROTO_UDP; - break; + + if (!mc) + mc = (struct mntentchn *)xmalloc(sizeof(*mc)); + mc->m = *mnt; } - endmntent (mtab); - return proto; + nfs_endmntent(mfp); + return mc; } /* complain about a failed umount */ @@ -156,7 +139,7 @@ static void complain(int err, const char *dev) { } } -int add_mtab2(const char *spec, const char *node, const char *type, +int del_mtab(const char *spec, const char *node, const char *type, const char *opts, struct mntentchn *mc) { int umnt_err, umnt_err2, res; @@ -257,6 +240,7 @@ int _nfsumount(const char *spec, const char *opts) char *hostname; char *dirname; clnt_addr_t mnt_server = { &hostname, }; + struct mntent mnt = { .mnt_opts = opts }; struct pmap *pmap = &mnt_server.pmap; char *p; @@ -290,21 +274,27 @@ int _nfsumount(const char *spec, const char *opts) } pmap->pm_prog = MOUNTPROG; - pmap->pm_vers = MOUNTVERS; - pmap->pm_prot = get_mntproto(spec); + pmap->pm_vers = MOUNTVERS_NFSV3; + pmap->pm_prot = IPPROTO_TCP; if (opts && (p = strstr(opts, "mountprog=")) && isdigit(*(p+10))) pmap->pm_prog = atoi(p+10); if (opts && (p = strstr(opts, "mountport=")) && isdigit(*(p+10))) pmap->pm_port = atoi(p+10); - if (opts && (p = strstr(opts, "nfsvers=")) && isdigit(*(p+8))) - pmap->pm_vers = nfsvers_to_mnt(atoi(p+8)); + if (opts && hasmntopt(&mnt, "v2")) + pmap->pm_vers = nfsvers_to_mnt(2); + if (opts && hasmntopt(&mnt, "v3")) + pmap->pm_vers = nfsvers_to_mnt(3); + if (opts && hasmntopt(&mnt, "v4")) + pmap->pm_vers = nfsvers_to_mnt(4); + if (opts && (p = strstr(opts, "vers=")) && isdigit(*(p+5))) + pmap->pm_vers = nfsvers_to_mnt(atoi(p+5)); if (opts && (p = strstr(opts, "mountvers=")) && isdigit(*(p+10))) pmap->pm_vers = atoi(p+10); + if (opts && (hasmntopt(&mnt, "udp") || hasmntopt(&mnt, "proto=udp"))) + pmap->pm_prot = IPPROTO_UDP; if (!nfs_gethostbyname(hostname, &mnt_server.saddr)) goto out_bad; - if (!probe_mntport(&mnt_server)) - goto out_bad; return nfs_call_umount(&mnt_server, &dirname); out_bad: printf("%s: %s: not found or not mounted\n", progname, spec); @@ -368,8 +358,15 @@ int nfsumount(int argc, char *argv[]) return 0; } } + + if (spec == NULL || (*spec != '/' && strchr(spec,':') == NULL)) { + printf(_("umount: %s: not found\n"), spec); + return 0; + } - mc = getmntdirbackward(spec, NULL); + mc = getmntentchn(spec); + if (!mc) + mc = getmntdirbackward(spec, NULL); if (!mc) mc = getmntdevbackward(spec, NULL); if (!mc && verbose) @@ -378,13 +375,13 @@ int nfsumount(int argc, char *argv[]) if(mc) { ret = _nfsumount(mc->m.mnt_fsname, mc->m.mnt_opts); if(ret) - ret = add_mtab2(mc->m.mnt_fsname, mc->m.mnt_dir, + ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir, mc->m.mnt_type, mc->m.mnt_opts, mc); } else { ret = _nfsumount(spec, NULL); if(ret) - ret = add_mtab2(spec, spec, spec, spec, NULL); + ret = del_mtab(spec, spec, spec, spec, NULL); } return(ret);