source: trunk/athena/bin/attach/unmount.c @ 9447

Revision 9447, 7.7 KB checked in by ghudson, 28 years ago (diff)
Conditionalize xdr_fhandle() on MOUNTVERS3 not being defined, to avoid defining it on Solaris 2.5.1 where it conflicts with the system's definition. We should get rid of the definition when Solaris 2.4 is no longer a concern.
Line 
1/*
2 * $Id: unmount.c,v 1.13 1996-12-18 15:00:58 ghudson Exp $
3 *
4 * Copyright (c) 1988,1991 by the Massachusetts Institute of Technology.
5 *
6 * For redistribution rights, see "mit-copyright.h"
7 */
8
9static char *rcsid_mount_c = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/attach/unmount.c,v 1.13 1996-12-18 15:00:58 ghudson Exp $";
10
11#include "attach.h"
12
13
14#if !defined(ultrix) && !defined(_IBMR2) && !defined(SOLARIS)
15#include <mntent.h>
16#endif
17
18#if defined(_AIX) && (AIXV < 30)
19#include <rpc/nfsmount.h>
20#include <rpc/rpcmount.h>
21#endif
22#include <rpcsvc/mount.h>
23
24#ifdef _AIX
25#define unmount(x) umount(x)
26#endif
27
28#ifdef _IBMR2
29#include <sys/id.h>
30#endif
31
32
33/*
34 * Unmount a filesystem.
35 */
36unmount_42(errname, mntpt, dev)
37        char *errname;
38        char *mntpt;
39        char *dev;
40{
41#ifdef UMOUNT_CMD
42        int status;
43
44#ifdef _IBMR2
45        if (setuidx(ID_REAL|ID_EFFECTIVE, 0))
46#else
47#ifdef SOLARIS
48        if (setuid(0))
49#else
50        if (setreuid(0,0))
51#endif
52#endif
53        {
54                fprintf(stderr,"%s: unable to change the uid to 0\n", errname);
55                return(FAILURE);
56        }
57
58        switch (fork()) {
59        case -1:
60                fprintf(stderr, "%s: unable to fork\n", errname);
61                return(FAILURE);
62                /* NOTREACHED */
63        case 0:
64                execl(UMOUNT_CMD, UMOUNT_CMD, mntpt, (char *)0);
65                exit(1);
66                /* NOTREACHED */
67        default:
68                wait(&status);
69                break;
70        }
71#if !defined(SOLARIS) && !defined(linux)
72        return(status ? FAILURE : SUCCESS);
73#else
74        return(status == 0 || ! is_mountpoint (mntpt) ? SUCCESS : FAILURE);
75#endif
76#else /* !UMOUNT_CMD */
77
78#if defined(_AIX) && (AIXV > 30)
79#include <sys/fullstat.h>
80
81    struct stat statb;
82
83    if (statx(mntpt, &statb, 0, STX_NORMAL) < 0) {
84        fprintf(stderr,
85                "%s: Directory %s appears to have already been removed\n",
86                errname, mntpt);
87        return(SUCCESS);
88    }
89    if ((statb.st_flag & FS_MOUNT) == 0) {
90        fprintf(stderr,
91                "%s: Directory %s is no longer a mount point\n",
92                errname, mntpt);
93        return(SUCCESS);
94    }
95    if (uvmount(statb.st_vfs, 0)) {
96        if (errno == EINVAL || errno == ENOENT) {
97            fprintf(stderr,
98                    "%s: Directory %s appears to already be unmounted\n",
99                    errname, mntpt);
100            return(SUCCESS);
101        } else {
102            fprintf(stderr, "%s: Unable to unmount %s: %s\n", errname,
103                    mntpt, sys_errlist[errno]);
104            return (FAILURE);
105        }
106    }
107    return(SUCCESS);
108
109#else /* !AIX 3.1 */
110       
111        FILE *tmpmnt, *mnted;
112        char *tmpname;
113#ifndef ultrix
114        struct mntent *mnt;
115#endif
116        int tmpfd;
117
118#ifdef ultrix
119        int fsloc = 0, found = 0;
120        struct fs_data fsdata;
121
122        while (getmountent(&fsloc, &fsdata, 1) > 0) {
123                if (!strcmp(fsdata.fd_path, mntpt)) {
124                        found = 1;
125                        break;
126                }
127        }
128        if (!found) {
129                fprintf(stderr,
130                        "%s: Directory %s appears to already be unmounted\n",
131                        errname, mntpt);
132                return(SUCCESS);
133        }
134        /* this hack to avoid ugly ifdef's */
135#define unmount(x) umount(fsdata.fd_dev)
136#endif /* ultrix */
137
138#if defined(_AIX) && (AIXV < 30)
139        if (unmount(dev ? dev : mntpt) < 0)
140#else
141        if (unmount(mntpt) < 0)
142#endif
143        {
144                if (errno == EINVAL || errno == ENOENT
145#ifdef _AIX
146                    || errno == ENOTBLK
147#endif
148                    ) {
149                        fprintf(stderr,
150                                "%s: Directory %s appears to already be unmounted\n",
151                                errname, mntpt);
152                        /* Continue on, to flush mtab if necessary */
153                } else {
154                        fprintf(stderr, "%s: Unable to unmount %s: %s\n", errname,
155                                mntpt, sys_errlist[errno]);
156                        return (FAILURE);
157                }
158        }
159
160#ifdef ultrix
161#undef unmount
162        return(SUCCESS);
163#else                                           /* !ultrix */
164
165        lock_mtab();
166        if (!(tmpname = malloc(strlen(mtab_fn)+7))) {
167                fprintf(stderr, "Can't malloc temp filename for unmount!\n");
168                exit(ERR_FATAL);
169        }
170        (void) strcpy(tmpname, mtab_fn);
171        (void) strcat(tmpname, "XXXXXX");
172        mktemp(tmpname);
173        if ((tmpfd = open(tmpname, O_RDWR|O_CREAT|O_TRUNC, 0644)) < 0) {
174                fprintf(stderr, "Can't open temporary file for umount!\n");
175                exit(ERR_FATAL);
176        }
177        close(tmpfd);
178        tmpmnt = setmntent(tmpname, "w");
179        if (!tmpmnt) {
180                fprintf(stderr,
181                        "Can't open temporary file for writing in umount!\n");
182                exit(ERR_FATAL);
183        }
184        mnted = setmntent(mtab_fn, "r");
185        if (!mnted) {
186                fprintf(stderr, "Can't open %s for read:%s\n", mtab_fn,
187                        sys_errlist[errno]);
188                exit(ERR_FATAL);
189        }
190        /* Delete filesystem from /etc/mtab */
191        while (mnt = getmntent(mnted))
192                if (strcmp(mnt->mnt_dir, mntpt))
193                        addmntent(tmpmnt, mnt);
194
195        endmntent(tmpmnt);
196        endmntent(mnted);
197        if (rename(tmpname, mtab_fn) < 0) {
198                fprintf(stderr, "Unable to rename %s to %s: %s\n", tmpname,
199                        mtab_fn, sys_errlist[errno]);
200                exit(ERR_FATAL);
201        }
202        unlock_mtab();
203   
204        return (SUCCESS);
205#endif /* ultrix */
206#endif /* !AIX 3.1 */
207#endif /* !UMOUNT_CMD */
208}
209
210#ifdef SOLARIS
211bool_t
212xdr_path(xdrs, pathp)
213        XDR *xdrs;
214        char **pathp;
215{
216        if (xdr_string(xdrs, pathp, 1024)) {
217                return(TRUE);
218        }
219        return(FALSE);
220}
221
222xdr_fhstatus(xdrs, fhsp)
223        XDR *xdrs;
224        struct fhstatus *fhsp;
225{
226        if (!xdr_int(xdrs, &fhsp->fhs_status))
227                return FALSE;
228        if (fhsp->fhs_status == 0) {
229                if (!xdr_fhandle(xdrs, &fhsp->fhs_fh))
230                        return FALSE;
231        }
232}
233
234/* XXX kludge: Solaris 2.4 doesn't have this function; Solaris 2.5.1 defines
235 * it in a conflicting fashion (using the "fhandle" type, which isn't in
236 * Solaris 2.4).  Until we stop building on Solaris 2.4, conditionalize
237 * this function on the lack of MOUNTVERS3, which distinguishes 2.4 from
238 * 2.5.1. */
239#ifndef MOUNTVERS3
240xdr_fhandle(xdrs, fhp)
241        XDR *xdrs;
242        fhandle_t *fhp;
243{
244        if (xdr_opaque(xdrs, fhp, NFS_FHSIZE)) {
245                return (TRUE);
246        }
247        return (FALSE);
248}
249#endif
250
251#endif
252
253#ifdef NFS
254/*
255 * Unmount an NFS filesystem
256 */
257nfs_unmount(errname, host, hostaddr, mntpt, rmntpt)
258    char *errname;
259    char *host;
260    struct in_addr hostaddr;
261    char *mntpt;
262    char *rmntpt;
263{
264    static struct sockaddr_in sin;
265    struct timeval timeout;
266    CLIENT *client;
267    enum clnt_stat rpc_stat;
268
269    if (unmount_42(errname, mntpt, NULL) == FAILURE)
270        return (FAILURE);
271
272    /*
273     * If we can't contact the host, don't bother complaining;
274     * it won't actually hurt anything except that hosts rmtab.
275     */
276    if (errored_out(hostaddr))
277        return (SUCCESS);
278
279    if ((client = (CLIENT *)rpc_create(hostaddr, &sin)) == NULL) {
280        fprintf(stderr,
281                "%s: Server %s not responding\n",
282                errname, host);
283        return (SUCCESS);
284    }
285
286    client->cl_auth = spoofunix_create_default(spoofhost, real_uid);
287
288    timeout.tv_usec = 0;
289    timeout.tv_sec = 20;
290    rpc_stat = clnt_call(client, MOUNTPROC_UMNT, xdr_path, &rmntpt,
291                         xdr_void, NULL, timeout);
292    if (rpc_stat != RPC_SUCCESS) {
293        mark_errored(hostaddr);
294        switch (rpc_stat) {
295        case RPC_TIMEDOUT:
296            fprintf(stderr, "%s: Timeout while contacting mount daemon on %s\n",
297                    errname, host);
298            break;
299        case RPC_AUTHERROR:
300            fprintf(stderr, "%s: Authentication failed\n",
301                    errname, host);
302            break;
303        case RPC_PMAPFAILURE:
304            fprintf(stderr, "%s: Can't find mount daemon on %s\n",
305                    errname, host);
306            break;
307        case RPC_PROGUNAVAIL:
308        case RPC_PROGNOTREGISTERED:
309            fprintf(stderr, "%s: Mount daemon not available on %s\n",
310                    errname, host);
311            break;
312        default:
313            fprintf(stderr, "%s: System error contacting server %s\n",
314                    errname, host);
315            break;
316        }
317        if (debug_flag)
318            clnt_perror(client, "RPC return status");
319        return (SUCCESS);
320    }
321
322    return (SUCCESS);
323}
324#endif
325
326#if defined(SOLARIS) || defined(linux)
327#include <sys/types.h>
328#include <sys/stat.h>
329#include <string.h>
330
331int is_mountpoint (pathname)
332    char *pathname;
333{
334    struct stat rootstat, pointstat;
335    char *parent;
336    int len;
337
338    parent = strdup (pathname);
339    len = strlen (parent) - 1;
340    while (pathname[len] == '/') len--;
341    while (len > 0 && pathname[len] != '/') len--;
342    len++;
343    parent[len] = 0;
344
345    if (stat (parent, &rootstat) < 0) {
346      return (FALSE);
347    }
348    if (stat (pathname, &pointstat) < 0) {
349      return (FALSE);
350    }
351    free (parent);
352    return (rootstat.st_dev != pointstat.st_dev);
353}
354#endif
355
Note: See TracBrowser for help on using the repository browser.