source: trunk/athena/bin/attach/mount.c @ 10914

Revision 10914, 9.1 KB checked in by ghudson, 27 years ago (diff)
Use strerror.
Line 
1/*      Created by:     Robert French
2 *
3 *      $Id: mount.c,v 1.11 1997-12-17 18:17:34 ghudson Exp $
4 *
5 *      Copyright (c) 1988 by the Massachusetts Institute of Technology.
6 */
7
8static char *rcsid_mount_c = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/attach/mount.c,v 1.11 1997-12-17 18:17:34 ghudson Exp $";
9
10#include "attach.h"
11
12#ifdef MOUNT_CMD
13
14#ifdef _IBMR2
15#include <sys/id.h>
16#endif
17
18mountfs(at, fsname, mopt, errorout)
19        struct  _attachtab *at;
20        char    *fsname;
21        struct  mntopts *mopt;
22        int errorout;
23{
24        int status;
25
26#ifdef _IBMR2
27        if (setuidx(ID_REAL|ID_EFFECTIVE, 0))
28#else
29#ifdef SOLARIS
30        if (setuid(0))
31#else
32        if (setreuid(0,0))
33#endif
34#endif
35        {
36                fprintf(stderr, "Unable to change the uid to 0\n");
37                return(FAILURE);
38        }
39
40        switch (fork()) {
41        case -1:
42                fprintf(stderr, "Unable to fork\n");
43                return(FAILURE);
44                /* NOTREACHED */
45        case 0:
46                execl(MOUNT_CMD, MOUNT_CMD,
47                      "-o", stropt(*mopt),
48                      fsname, at->mntpt,
49                      (char *)0);
50                exit(1);
51                /* NOTREACHED */
52        default:
53                wait(&status);
54                break;
55        }
56
57        return(status ? FAILURE : SUCCESS);
58}
59
60
61#else /* !MOUNT_CMD */
62
63#ifndef ultrix
64#include <mntent.h>
65#endif
66#if defined(_AIX) && (AIXV < 30)
67#include <sys/dstat.h>
68#include <rpc/rpcmount.h>
69#include <rpc/nfsmount.h>
70struct ufs_args { char *fspec;};
71#endif
72#ifdef _AUX_SOURCE
73#define mount(type,dir,flags,data)      fsmount(type,dir,flags,data)
74#endif
75
76/*
77 * Mount a filesystem
78 */
79mountfs(at, fsname, mopt, errorout)
80        struct  _attachtab      *at;
81        char    *fsname;
82        struct  mntopts *mopt;
83        int errorout;
84{
85        struct  mntent  mnt;
86        union data {
87#if defined(UFS) || defined(RVD)
88                struct ufs_args ufs_args;
89#endif
90#ifdef NFS
91                struct nfs_args nfs_args;
92#endif
93        } data;
94
95        mnt.mnt_fsname = fsname;
96        mnt.mnt_dir = at->mntpt;
97#if !defined(_AIX) && !defined(ultrix)
98        mnt.mnt_type = (at->fs->mount_type==MOUNT_NFS) ? MNTTYPE_NFS
99                : MNTTYPE_42;
100#endif
101        mnt.mnt_opts = stropt(*mopt);
102        mnt.mnt_freq = 0;
103#if defined(_AIX) && (AIXV<30)
104        mnt.mnt_type = at->fs->mount_type == MOUNT_NFS ? "nfs" : "ufs";
105        mnt.mnt_checkno = 0;
106#else
107        mnt.mnt_passno = 0;
108#endif
109#if defined(sun)
110        mnt.mnt_type = at->fs->mount_type == MOUNT_NFS ? "nfs" : "ufs";
111#endif         
112        bzero(&data, sizeof(data));
113        /* Already mounted? Why lose? */
114        if (mounted(&mnt)) {
115                fprintf(stderr,
116                        "%s: Already mounted, continuing...\n",
117                        at->hesiodname);
118                if (keep_mount)
119                        at->flags |= FLAG_PERMANENT;
120                return (SUCCESS);
121        }
122#if defined(UFS) || defined(RVD)
123        if (at->fs->mount_type == MOUNT_UFS)
124                if (mount_42(&mnt, &data.ufs_args) == FAILURE)
125                        return (FAILURE);
126#endif
127#ifdef NFS
128        if (at->fs->mount_type == MOUNT_NFS) {
129                if (mount_nfs(at, mopt, &data.nfs_args,
130                              errorout) == FAILURE)
131                        return (FAILURE);
132#ifdef _AIX
133                if (nfs_mount(mnt.mnt_dir, &data.nfs_args, mopt->flags) != 0) {
134                        if (errorout)
135                                fprintf(stderr,
136                                        "%s: Can't mount %s on %s - %s\n",
137                                        at->hesiodname, fsname, mnt.mnt_dir,
138                                        strerror(errno));
139                        return (FAILURE);
140                } else {
141                  /* We need to get the filesystem's gfs for mtab */
142                  struct dstat st_buf;
143                  if(dstat(mnt.mnt_dir, &st_buf, sizeof(st_buf)) != 0) {
144                    if (errorout)
145                      fprintf(stderr,
146                              "%s: Can't stat %s to verify mount: %s\n",
147                              at->hesiodname, mnt.mnt_dir, strerror(errno));
148                    return (FAILURE);
149                  } else {
150                    mnt.mnt_gfs = st_buf.dst_gfs;
151                    goto done;
152                  }
153                }
154#endif
155        }
156#endif /* NFS */
157
158#ifdef ultrix
159        if (mount(mnt.mnt_fsname, mnt.mnt_dir, mopt->flags,
160                  at->fs->mount_type, (char *)&data) < 0) {
161#else /* !ultrix */
162#ifdef _AIX
163        if (mount(mnt.mnt_fsname, mnt.mnt_dir, mopt->flags) < 0) {
164#else
165#if defined(sun)
166        if (mount(mnt.mnt_type, mnt.mnt_dir, M_NEWTYPE | mopt->flags, &data) < 0) {
167#else
168        if (mount(at->fs->mount_type, mnt.mnt_dir, mopt->flags, &data) < 0) {
169#endif /* sun */
170#endif
171#endif /* ultrix */
172                if (errorout) {
173                        fprintf(stderr,
174                                "%s: Can't mount %s on %s - %s\n",
175                                at->hesiodname, fsname, mnt.mnt_dir,
176                                strerror(errno));
177                        error_status = ERR_SOMETHING;
178                }
179                return (FAILURE);
180        }
181
182#ifdef _AIX
183        else {
184          struct dstat st_buf;
185          if(dstat(mnt.mnt_dir, &st_buf, sizeof(st_buf)) != 0) {
186            if (errorout)
187              fprintf(stderr,
188                      "%s: Can't stat %s to verify mount: %s\n",
189                      at->hesiodname, mnt.mnt_dir, strerror(errno));
190            return (FAILURE);
191          } else {
192            mnt.mnt_gfs = st_buf.dst_gfs;
193          }
194        }
195#endif
196#ifndef ultrix
197      done:
198        addtomtab(&mnt);
199#endif /* !ultrix */
200        return (SUCCESS);
201}
202
203#if defined(UFS) || defined(RVD)
204/*
205 * Prepare to mount a 4.2 style file system
206 */
207
208mount_42(mnt, args)
209    struct mntent *mnt;
210    struct ufs_args *args;
211{
212#ifndef ultrix
213    args->fspec = mnt->mnt_fsname;
214#endif
215    return (SUCCESS);
216}
217
218#endif /* UFS || RVD */
219
220#ifdef NFS
221/*
222 * Mount an NFS file system
223 */
224mount_nfs(at, mopt, args, errorout)
225        struct  _attachtab      *at;
226        struct  mntopts         *mopt;
227        struct nfs_args *args;
228        int errorout;
229{
230        static struct fhstatus fhs;
231        static struct sockaddr_in sin;
232        struct timeval timeout;
233        CLIENT *client;
234        enum clnt_stat rpc_stat;
235        char    *hostdir = at->hostdir;
236
237        if (errored_out(at->hostaddr[0])) {
238                if (errorout)
239                        fprintf(stderr,
240                "%s: Ignoring %s due to previous host errors\n",
241                                at->hesiodname, at->host);
242                return (FAILURE);
243        }
244   
245        if ((client = rpc_create(at->hostaddr[0], &sin)) == NULL) {
246                if (errorout)
247                        fprintf(stderr, "%s: Server %s not responding\n",
248                                at->hesiodname, at->host);
249                return (FAILURE);
250        }
251   
252        client->cl_auth = spoofunix_create_default(spoofhost, real_uid);
253
254        timeout.tv_usec = 0;
255        timeout.tv_sec = 20;
256        rpc_stat = clnt_call(client, MOUNTPROC_MNT, xdr_path, &hostdir,
257                             xdr_fhstatus, &fhs, timeout);
258        if (rpc_stat != RPC_SUCCESS) {
259                mark_errored(at->hostaddr[0]);
260                if (debug_flag)
261                        clnt_perror(client, "RPC return status");
262                if (!errorout)
263                        return(FAILURE);
264                switch (rpc_stat) {
265                case RPC_TIMEDOUT:
266                        fprintf(stderr,
267                        "%s: Timeout while contacting mount daemon on %s\n",
268                                at->hesiodname, at->host);
269                        break;
270                case RPC_AUTHERROR:
271                        fprintf(stderr, "%s: Authentication failed\n",
272                                at->hesiodname, at->host);
273                        break;
274                case RPC_PMAPFAILURE:
275                        fprintf(stderr, "%s: Can't find mount daemon on %s\n",
276                                at->hesiodname, at->host);
277                        break;
278                case RPC_PROGUNAVAIL:
279                case RPC_PROGNOTREGISTERED:
280                        fprintf(stderr,
281                                "%s: Mount daemon not available on %s\n",
282                                at->hesiodname, at->host);
283                        break;
284                default:
285                        fprintf(stderr,
286                                "%s: System error contacting server %s\n",
287                                at->hesiodname, at->host);
288                        break;
289                }
290                return (FAILURE);
291        }
292
293        if (errno = fhs.fhs_status) {
294                if (errorout) {
295                        if (errno == EACCES) {
296                                fprintf(stderr,
297                                "%s: Mount access denied by server %s\n",
298                                        at->hesiodname, at->host);
299                                error_status = ERR_ATTACHNOTALLOWED;
300                        } else {
301                                error_status = (errno == ENOENT) ?
302                                  ERR_ATTACHNOFILSYS : ERR_ATTACHNOTALLOWED;
303                                fprintf(stderr,
304                        "%s: Error message returned from server %s: %s\n",
305                                        at->hesiodname, at->host,
306                                        strerror(errno));
307                        }
308                }
309                return (FAILURE);
310        }
311
312        *args = mopt->tsa.nfs;
313        args->hostname = at->host;
314        args->fh = &fhs.fhs_fh;
315        args->flags |= NFSMNT_HOSTNAME;
316        if (mopt->nfs_port)
317                sin.sin_port = mopt->nfs_port;
318        else
319                sin.sin_port = htons(NFS_PORT); /* XXX should use portmapper */
320        args->addr = &sin;
321#ifdef ultrix
322        args->optstr = stropt(*mopt);
323#endif
324        return (SUCCESS);
325}
326#endif
327
328#ifdef ultrix
329mounted(mntck)
330    struct mntent *mntck;
331{
332    int done = 0;
333    int fsloc = 0;
334    int found = 0;
335    struct fs_data fsdata;
336
337    while (getmountent(&fsloc, &fsdata, 1) > 0) {
338        if (!strcmp(fsdata.fd_path, mntck->mnt_dir) &&
339            !strcmp(fsdata.fd_devname, mntck->mnt_fsname)) {
340            return(1);
341            break;
342        }
343    }
344    return(0);
345}
346
347#else /* !ultrix */
348
349/*
350 * Add an entry to /etc/mtab
351 */
352
353addtomtab(mnt)
354    struct mntent *mnt;
355{
356    FILE *mnted;
357
358    lock_mtab();
359    mnted = setmntent(mtab_fn, "r+");
360    if (!mnted || addmntent(mnted, mnt)) {
361            fprintf(stderr, "Can't append to %s: %s\n", mtab_fn,
362                    strerror(errno));
363            unlock_mtab();
364            exit(ERR_FATAL);
365    }
366    endmntent(mnted);
367    unlock_mtab();
368}
369
370mounted(mntck)
371    struct mntent *mntck;
372{
373    int found = 0;
374    struct mntent *mnt;
375    FILE *mnttab;
376
377    lock_mtab();
378    mnttab = setmntent(mtab_fn, "r");
379    if (!mnttab) {
380            fprintf(stderr, "Can't open %s for read\n", mtab_fn);
381            exit(ERR_FATAL);
382    }
383    while (mnt = getmntent(mnttab)) {
384        if (!strcmp(mnt->mnt_type, MNTTYPE_IGNORE))
385            continue;
386        if ((!strcmp(mntck->mnt_dir, mnt->mnt_dir)) &&
387            (!strcmp(mntck->mnt_type, mnt->mnt_type))) {
388                if (!strcmp(mnt->mnt_type, MNTTYPE_NFS)) {
389                        if (nfs_fsname_compare(mntck->mnt_fsname,
390                                               mnt->mnt_fsname)) {
391                                found = 1;
392                                break;
393                        }
394                } else if (!strcmp(mntck->mnt_fsname,
395                                   mnt->mnt_fsname)) {
396                        found = 1;
397                        break;
398                }
399        }
400    }
401    endmntent(mnttab);
402    unlock_mtab();
403    return (found);
404}
405
406/*
407 * Returns true if two NFS fsnames are the same.
408 */
409nfs_fsname_compare(fsname1, fsname2)
410        char    *fsname1;
411        char    *fsname2;
412{
413        char    host1[BUFSIZ], host2[BUFSIZ];
414        char    *rmdir1, *rmdir2;
415
416        (void) strcpy(host1, fsname1);
417        (void) strcpy(host2, fsname2);
418        if (rmdir1 = strchr(host1, ':'))
419                *rmdir1++ = '\0';
420        if (rmdir2 = strchr(host2, ':'))
421                *rmdir2++ = '\0';
422        if (host_compare(host1, host2)) {
423                if (!rmdir1 || !rmdir2)
424                        return(0);
425                return(!strcmp(rmdir1, rmdir2));
426        } else
427                return(0);
428}
429
430#endif /* !ultrix */
431
432#endif /* !MOUNT_CMD */
Note: See TracBrowser for help on using the repository browser.