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

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