source: trunk/athena/bin/attach/util.c @ 9809

Revision 9809, 24.2 KB checked in by ghudson, 27 years ago (diff)
Move attachtab and the attach temporary files to /var/athena. Note that the attach temporary files were previously incorrectly documented as being /tmp/attach.<filesystem> instead of /tmp/attach_<filesystem>.
Line 
1/*      Created by:     Robert French
2 *
3 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/attach/util.c,v $
4 *      $Author: ghudson $
5 *
6 *      Copyright (c) 1988 by the Massachusetts Institute of Technology.
7 */
8
9static char *rcsid_util_c = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/attach/util.c,v 1.23 1997-04-01 01:01:43 ghudson Exp $";
10
11#include "attach.h"
12
13#include <sys/stat.h>
14#include <fcntl.h>
15#include <pwd.h>
16#include <grp.h>
17#include <signal.h>
18#ifdef HESIOD
19#include <hesiod.h>
20#endif
21
22#define TOKSEP " \t\r\n"
23       
24#ifdef ultrix
25#define max(a,b) (((a) > (b)) ? (a) : (b))
26#endif
27
28extern int sys_nerr;
29extern char *sys_errlist[];
30
31char exp_hesline[BUFSIZ];       /* Place to store explicit */
32char *exp_hesptr[2];            /* ``hesiod'' entry */
33char *abort_msg = "Operation aborted\n";
34
35static missarg();
36
37/*
38 * These routines provide a way of locking out interrupts during
39 * critical sections of code.  After the critical sections of code are
40 * executed, if a SIGTERM or SIGINT had arrived before, the program
41 * terminates then.
42 */
43
44int             caught_signal = 0;
45static int      in_critical_code_p = 0;
46
47#ifdef POSIX
48static sigset_t osigmask;
49#else
50static int      osigmask;
51#endif
52
53/*
54 * Signal handler for SIGTERM & SIGINT
55 */
56sig_catch sig_trap()
57{
58    if (in_critical_code_p) {
59        caught_signal++;
60        return;
61    }
62    terminate_program();
63}
64
65/*
66 * Enter critical section of code
67 */
68start_critical_code()
69{
70#ifdef POSIX
71    sigset_t mysigmask;
72
73    sigemptyset(&mysigmask);
74    sigaddset(&mysigmask, SIGTSTP);
75    sigaddset(&mysigmask, SIGTTIN);
76    sigaddset(&mysigmask, SIGTTOU);
77
78    if (in_critical_code_p++ == 0)
79        sigprocmask(SIG_BLOCK, &mysigmask, &osigmask);
80#else
81    if (in_critical_code_p++ == 0)
82        osigmask=sigblock(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU));
83#endif
84}
85
86/*
87 * Exit critical section of code
88 */
89end_critical_code()
90{
91    if (--in_critical_code_p == 0) {
92        if (caught_signal)
93            terminate_program();
94#ifdef POSIX
95        sigprocmask(SIG_SETMASK, &osigmask, (sigset_t *)0);
96#else
97        sigsetmask(osigmask);
98#endif
99    }
100}
101
102/*
103 * terminate the program
104 */
105terminate_program()
106{
107    exit(ERR_INTERRUPT);
108}
109
110/*
111 * LOCK the mtab - wait for it if it's already locked
112 */
113
114/*
115 * Unfortunately, mount and umount don't honor lock files, so these
116 * locks are only valid for other attach processes.
117 */
118
119static int mtab_lock_fd = -1;
120
121lock_mtab()
122{
123        char    *lockfn;
124#ifdef POSIX
125        struct flock fl;
126#endif
127       
128        if (mtab_lock_fd < 0) {
129                if (!(lockfn = malloc(strlen(mtab_fn)+6))) {
130                        fprintf(stderr, "Can't malloc lockfile filename.\n");
131                        fprintf(stderr, abort_msg);
132                        exit(ERR_FATAL);
133                }
134                (void) strcpy(lockfn, mtab_fn);
135                (void) strcat(lockfn, ".lock");
136                mtab_lock_fd = open(lockfn, O_CREAT|O_RDWR, 0644);
137                if (mtab_lock_fd < 0) {
138                        fprintf(stderr,"Can't open %s: %s\n", lockfn,
139                                sys_errlist[errno]);
140                        fprintf(stderr, abort_msg);
141                        exit(ERR_FATAL);
142                }
143        }
144#ifdef POSIX
145        fl.l_type = F_WRLCK;
146        fl.l_whence = SEEK_SET;
147        fl.l_start = 0;
148        fl.l_len = 0;
149        fl.l_pid = getpid();
150        fcntl(mtab_lock_fd, F_SETLKW, &fl);
151#else
152        flock(mtab_lock_fd, LOCK_EX);
153#endif
154}
155
156/*
157 * UNLOCK the mtab
158 */
159unlock_mtab()
160{
161        close(mtab_lock_fd);
162        mtab_lock_fd = -1;
163}
164
165/*
166 * Convert a string type to a filesystem type entry
167 */
168struct _fstypes *get_fs(s)
169    char *s;
170{
171    int i;
172
173    if (s && *s) {
174            for (i=0;fstypes[i].name;i++) {
175                    if (!strcasecmp(fstypes[i].name, s))
176                            return (&fstypes[i]);
177            }
178    }
179    return (NULL);
180}
181
182/* Return the preference of a hesiod line, or -1 if the filesystem type
183 * does not admit a preference field. */
184static int get_preference(hesline)
185    char *hesline;
186{
187    char *p;
188    int i;
189
190    p = strchr(hesline, ' ');
191    if (p == NULL || (p - hesline == 3 && strncasecmp(hesline, "MUL", 3) == 0))
192        return (-1);
193
194    /* FS type okay; return the value of the fifth field. */
195    while (isspace(*p))
196        p++;
197    for (i = 2; i < 5; i++) {
198        while (*p && !isspace(*p))
199            p++;
200        while (isspace(*p))
201            p++;
202    }
203    return ((*p) ? atoi(p) : 0);
204}
205
206/* Reorder non-MUL entries in increasing order of their preference
207 * fields (fifth field), if present.  Anything with no preference field is
208 * assumed to have preference 0.  This sort has to be stable, so that we
209 * don't break DNS ordering if we happen to have it.  (That is, don't
210 * replace this function with a call to qsort(), at least until you're sure
211 * nobody is going to be relying on DNS ordering.)
212 *
213 * Note that lower preference is better, and anything with no preference
214 * field will have the best preference.  Hopefully any hesiod response that
215 * uses preference fields will use them everywhere. */
216static void sort_hesiod_data(hes)
217    char **hes;
218{
219    char **p1, **p2, **slot, *p;
220    int pref, pref2;
221
222    /* This doesn't need to be fast; do an insertion sort. */
223    for (p1 = hes; *p1; p1++) {
224        p = *p1;
225        pref = get_preference(p);
226        if (pref == -1)
227            continue;
228        slot = p1;
229        for (p2 = p1 - 1; p2 >= hes; p2--) {
230            pref2 = get_preference(*p2);
231            if (pref2 == -1)
232                continue;
233            /* If we have the right slot for p, stop. */
234            if (pref2 <= pref)
235                break;
236            /* Otherwise, shift the slot down one position. */
237            *slot = *p2;
238            slot = p2;
239        }
240        *slot = p;
241    }
242}
243
244/*
245 * Build a Hesiod line either from a Hesiod query or internal frobbing
246 * if explicit is set.
247 */
248char **build_hesiod_line(name)
249    char *name;
250{
251    char **realhes;
252    struct _fstypes     *fsp;
253   
254    if (!explicit) {
255            realhes = conf_filsys_resolve(name);
256#ifdef HESIOD
257            if (!realhes || !*realhes)
258                    realhes = hes_resolve(name, "filsys");
259#endif
260            if (!realhes || !*realhes)
261                    fprintf(stderr, "%s: Can't resolve name\n", name);
262            else
263                    sort_hesiod_data(realhes);
264            return (realhes);
265    }
266
267    fsp = get_fs(filsys_type ? filsys_type : "NFS");
268    if (!fsp)
269        return (NULL);
270    if (!fsp->explicit) {
271        fprintf(stderr, "Explicit definitions for type %s not allowed\n",
272                filsys_type);
273        return (NULL);
274    }
275
276    return ((fsp->explicit)(name));
277}
278
279/*
280 * Parse a Hesiod record
281 *
282 * Returns 0 on success, -1 on failure
283 */
284int parse_hes(hes, at, errorname)
285    char *hes, *errorname;
286    struct _attachtab *at;
287{
288    char        *cp, *t;
289    struct hostent *hent;
290    int         type;
291
292    memset(at, 0, sizeof(struct _attachtab));
293   
294    if (!*hes)
295            goto bad_hes_line;
296
297
298    at->fs = get_fs(strtok(hes, TOKSEP));
299    if (!at->fs)
300            goto bad_hes_line;
301    type = at->fs->type;
302
303    if (type & TYPE_ERR) {
304            strncpy(at->hostdir, strtok(NULL, ""), sizeof(at->hostdir));
305            return(0);
306    }
307
308    if (!(cp = strtok(NULL, (type & TYPE_MUL) ? "" : TOKSEP)))
309            goto bad_hes_line;
310    strcpy(at->hostdir, cp);
311
312    if (type & ~(TYPE_UFS | TYPE_AFS | TYPE_MUL)) {
313            if (!(cp = strtok(NULL, TOKSEP)))
314                    goto bad_hes_line;
315            strcpy(at->host, cp);
316    } else
317            strcpy(at->host, "localhost");
318
319    if (type & TYPE_MUL) {
320            t = at->hostdir;
321            while (t = strchr(t,' '))
322                    *t = ',';
323            at->mode = '-';
324            strcpy(at->mntpt, "localhost");
325    } else {
326
327            if (!(cp = strtok(NULL, TOKSEP)))
328                    goto bad_hes_line;
329            at->mode = *cp;
330            if (at->mode == 'x')
331                    at->mode = 'w';  /* Backwards compatibility */
332            if (at->fs->good_flags) {
333                    if (!strchr(at->fs->good_flags, at->mode))
334                            goto bad_hes_line;  /* Bad attach mode */
335            }
336
337            if (!(cp = strtok(NULL, TOKSEP)))
338                    goto bad_hes_line;
339            strcpy(at->mntpt, cp);
340    }
341
342    if (type & ~(TYPE_UFS | TYPE_AFS | TYPE_MUL)) {
343            hent = gethostbyname(at->host);
344            if (!hent) {
345                    fprintf(stderr,"%s: Can't resolve host %s\n",errorname,
346                            at->host);
347                    fprintf(stderr, abort_msg);
348                    return(-1);
349            }
350#ifdef POSIX
351            memmove(&at->hostaddr[0].s_addr, hent->h_addr_list[0], 4);
352#else
353            bcopy(hent->h_addr_list[0], &at->hostaddr[0].s_addr, 4);
354#endif
355            strcpy(at->host, hent->h_name);
356    } else
357            at->hostaddr[0].s_addr = (long) 0;
358    return(0);
359   
360bad_hes_line:
361    fprintf(stderr,"Badly formatted filesystem definition\n");
362    fprintf(stderr, abort_msg);
363    return(-1);
364}
365
366/*
367 * Make the directories necessary for a mount point - set the number
368 * of directories created in the attachtab structure
369 */
370int make_mntpt(at)
371    struct _attachtab *at;
372{
373    char bfr[BUFSIZ],*ptr;
374    int oldmask;
375    struct stat statbuf;
376
377    strcpy(bfr, at->mntpt);
378    if (at->fs->flags & AT_FS_PARENTMNTPT) {
379            ptr = strrchr(bfr, '/');
380            if (ptr)
381                    *ptr = 0;
382            else
383                    return(SUCCESS);
384    }
385   
386    if (!stat(bfr, &statbuf)) {
387        if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
388            return (SUCCESS);
389        fprintf(stderr, "%s: %s is not a directory\n", at->hesiodname,
390                at->mntpt);
391        return (FAILURE);
392    }
393   
394    oldmask = umask(022);
395
396    ptr = bfr+1;                /* Pass initial / */
397
398    at->rmdir = 0;
399       
400    while (ptr && *ptr) {
401        strcpy(bfr, at->mntpt);
402        ptr = strchr(ptr, '/');
403        if (ptr)
404            *ptr++ = '\0';
405        if (debug_flag)
406                printf("Making directory %s (%s)\n", bfr, ptr ? ptr : "");
407        if (mkdir(bfr, 0777)) {
408            if (errno == EEXIST)
409                continue;
410            fprintf(stderr, "%s: Can't create directory %s: %s\n",
411                    at->hesiodname, bfr, sys_errlist[errno]);
412            umask(oldmask);
413            return (FAILURE);
414        }
415        else
416            at->rmdir++;
417    }
418    umask(oldmask);
419    return (SUCCESS);
420}
421
422/*
423 * Delete a previously main mountpoint
424 */
425int rm_mntpt(at)
426    struct _attachtab *at;
427{
428    char bfr[BUFSIZ], *ptr;
429
430    strcpy(bfr, at->mntpt);
431    ptr = bfr;
432
433    if (at->fs->flags & AT_FS_PARENTMNTPT) {
434            ptr = strrchr(bfr, '/');
435            if (ptr)
436                    *ptr = 0;
437            else
438                    return(SUCCESS);
439    }
440    while (at->rmdir--) {
441        if (debug_flag)
442                printf("Deleting directory %s (%s)\n", bfr, ptr ? ptr : "");
443        if (rmdir(bfr)) {
444            if (errno != ENOENT) {
445                fprintf(stderr,
446                        "%s: Can't remove directory %s: %s\n",
447                        at->hesiodname, ptr,
448                        sys_errlist[errno]);
449                return (FAILURE);
450            }
451        }
452        ptr = strrchr(bfr, '/');
453        if (ptr)
454            *ptr = '\0';
455        else
456            return (SUCCESS);
457    }
458    return (SUCCESS);
459}
460
461/*
462 * Internal spiffed up getopt
463 */
464char internal_getopt(arg, cl)
465    char *arg;
466    struct command_list *cl;
467{
468    int i;
469
470    for (i=0;cl[i].small;i++) {
471        if (cl[i].large && !strcmp(cl[i].large, arg))
472            return (cl[i].small[1]);
473        if (!strcmp(cl[i].small, arg))
474            return (cl[i].small[1]);
475    }
476    return ('?');
477}
478
479/*
480 * Format a hesiod name into a name in /var/athena...including replacing /
481 * with @, etc.
482 */
483make_temp_name(filename, name)
484    char *filename;
485    char *name;
486{
487    strcpy(filename, "/var/athena/attach_");
488    filename = filename+strlen(filename);
489   
490    while (*name) {
491        if (*name == '/')
492            *filename++ = '@';
493        else
494            *filename++ = *name;
495        name++;
496    }
497    *filename = '\0';
498}
499
500/*
501 * Check to see if a filesystem is really being frobbed with by
502 * another attach process.
503 */
504
505int really_in_use(name)
506    char *name;
507{
508    int fd, ret;
509    char filename[BUFSIZ];
510#ifdef POSIX
511    struct flock fl;
512#endif
513
514    make_temp_name(filename, name);
515
516    if (debug_flag)
517        printf("Checking lock on %s\n", filename);
518   
519    fd = open(filename, O_RDWR, 0644);
520    if (!fd)
521        return (0);
522
523#ifdef POSIX
524    fl.l_type = F_WRLCK;
525    fl.l_whence = SEEK_SET;
526    fl.l_start = 0;
527    fl.l_len = 0;
528    fl.l_pid = getpid();
529    ret = (fcntl(fd, F_SETLK, &fl)==-1 && errno == EAGAIN);
530#else
531    ret = (flock(fd, LOCK_EX | LOCK_NB) == -1 && errno == EWOULDBLOCK);
532#endif
533
534    close(fd);
535    return (ret);
536}
537
538/*
539 * Mark a filesystem as being frobbed with
540 */
541
542void mark_in_use(name)
543    char *name;
544{
545    static int fd;
546    static char filename[BUFSIZ];
547#ifdef POSIX
548    struct flock fl;
549#endif
550
551    if (!name) {
552        if (debug_flag)
553            printf("Removing lock on %s\n", filename);
554        close(fd);
555        unlink(filename);
556        return;
557    }
558
559    make_temp_name(filename, name);
560
561    if (debug_flag)
562        printf("Setting lock on %s: ", filename);
563
564    /*
565     * Unlink the old file in case someone else already has a lock on
566     * it...we'll override them with our new file.
567     */
568    unlink(filename);
569    fd = open(filename, O_CREAT|O_RDWR, 0644);
570    if (!fd) {
571            fprintf(stderr,"Can't open %s: %s\n", filename,
572                    sys_errlist[errno]);
573            fprintf(stderr, abort_msg);
574            exit(ERR_FATAL);
575    }
576
577    if (debug_flag)
578            printf("%d\n", fd);
579
580#ifdef POSIX
581    fl.l_type = F_WRLCK;
582    fl.l_whence = SEEK_SET;
583    fl.l_start = 0;
584    fl.l_len = 0;
585    fl.l_pid = getpid();
586    fcntl(fd, F_SETLKW, &fl);
587#else
588    flock(fd, LOCK_EX);
589#endif
590}
591
592#ifdef DEBUG
593/*
594 * Dump used file descriptors...useful for debugging
595 */
596
597fd_dump()
598{
599    int i;
600    char b;
601
602    printf("FD's in use: ");
603    for (i=0;i<64;i++)
604        if (read(i,&b,0) >= 0)
605            printf("%d ",i);
606    printf("\n");
607}
608#endif
609
610/*
611 * String comparison for filesystem names - case insensitive for hesiod,
612 * sensitive for explicit.
613 */
614
615int hescmp(at, s)
616    struct _attachtab *at;
617    char *s;
618{
619    if (at->explicit)
620        return (strcmp(at->hesiodname, s));
621    return (strcasecmp(at->hesiodname, s));
622}
623
624/*
625 * Check to see if we have root priv's; give an error if we don't.
626 */
627void check_root_privs(progname)
628        char    *progname;
629{
630        if (!real_uid || !effective_uid || (debug_flag))
631                return;
632        fprintf(stderr,
633                "%s must be setuid to root for this operation to succeed.\n",
634                progname);
635        exit(ERR_FATAL);
636        /* NOTREACHED */
637}
638
639void add_options(mopt, string)
640        struct mntopts  *mopt;
641        char            *string;
642{
643        char    *next, *arg, *str, *orig_str;
644
645        orig_str = str = strdup(string);
646        while (str && *str) {
647                next = strchr(str, ',');
648                if (next) {
649                        *next++ = '\0';
650                }
651                arg = strchr(str, '=');
652                if (arg)
653                        *arg++ = '\0';
654                if (!strcmp(str, "ro")) {
655                        mopt->flags |= M_RDONLY;
656#if defined(ultrix) && defined(NFS)
657                        if (mopt->type == MOUNT_NFS) {
658                            mopt->tsa.nfs.gfs_flags |= M_RONLY;
659                            mopt->tsa.nfs.flags |= NFSMNT_RONLY;
660                        }
661#endif /* ultrix && NFS */
662                } else if (!strcmp(str, "rw")) {
663#ifdef ultrix
664                    mopt->flags &= ~M_RDONLY;
665                    mopt->tsa.nfs.gfs_flags &= ~M_RONLY;
666                    mopt->tsa.nfs.flags &= ~NFSMNT_RONLY;
667#else /* !ultrix */
668                    mopt->flags &= ~M_RDONLY;
669#endif /* ultrix */
670                }
671#ifdef ultrix
672                /* process other ultrix options */
673                else if (!strcmp(str, "force")) {
674#ifdef NFS
675                    if (mopt->type == MOUNT_NFS)
676                        mopt->tsa.nfs.gfs_flags |= M_FORCE;
677                    else
678#endif /* NFS */
679                    if (mopt->type == MOUNT_UFS)
680                        mopt->tsa.ufs.ufs_flags |= M_FORCE;
681                } else if (!strcmp(str, "sync")) {
682#ifdef NFS
683                    if (mopt->type == MOUNT_NFS)
684                        mopt->tsa.nfs.gfs_flags |= M_SYNC;
685                    else
686#endif /* NFS */
687                    if (mopt->type == MOUNT_UFS)
688                        mopt->tsa.ufs.ufs_flags |= M_SYNC;
689                } else if (!strcmp(str, "pgthresh")) {
690                    int pgthresh;
691
692                    if (!arg) {
693                        missarg("pgthresh");
694                        continue;
695                    }
696                    pgthresh = atoi(arg);
697                    pgthresh = max (pgthresh, MINPGTHRESH/PGUNITS);
698#ifdef NFS                 
699                    if (mopt->type == MOUNT_NFS) {
700                        mopt->tsa.nfs.pg_thresh = pgthresh;
701                        mopt->tsa.nfs.flags |= NFSMNT_PGTHRESH;
702                    } else
703#endif /* NFS */
704                    if (mopt->type == MOUNT_UFS)
705                        mopt->tsa.ufs.ufs_pgthresh = pgthresh;
706                } else if (!strcmp(str, "quota")) {
707                    if (mopt->type == MOUNT_UFS)
708                        mopt->tsa.ufs.ufs_flags |= M_QUOTA;
709                } else if (!strcmp(str, "noexec")) {
710#ifdef NFS
711                    if (mopt->type == MOUNT_NFS)
712                        mopt->tsa.nfs.gfs_flags |= M_NOEXEC;
713                    else
714#endif /* NFS */
715                    if (mopt->type == MOUNT_UFS)
716                        mopt->tsa.ufs.ufs_flags |= M_NOEXEC;
717                } else if (!strcmp(str, "nocache")) {
718#ifdef NFS
719                    if (mopt->type == MOUNT_NFS)
720                        mopt->tsa.nfs.gfs_flags |= M_NOCACHE;
721                    else
722#endif /* NFS */
723                    if (mopt->type == MOUNT_UFS)
724                        mopt->tsa.ufs.ufs_flags |= M_NOCACHE;
725                } else if (!strcmp(str, "nodev")) {
726#ifdef NFS
727                    if (mopt->type == MOUNT_NFS)
728                        mopt->tsa.nfs.gfs_flags |= M_NODEV;
729                    else
730#endif /* NFS */
731                    if (mopt->type == MOUNT_UFS)
732                        mopt->tsa.ufs.ufs_flags |= M_NODEV;
733                }
734#endif /* ultrix */
735#ifndef AIX
736                else if (!strcmp(str, "nosuid")) {
737#ifdef ultrix
738#ifdef NFS
739                    if (mopt->type == MOUNT_NFS)
740                        mopt->tsa.nfs.gfs_flags |= M_NOSUID;
741                    else
742#endif /* NFS */
743                    if (mopt->type == MOUNT_UFS)
744                        mopt->tsa.ufs.ufs_flags |= M_NOSUID;
745#else /* !ultrix */
746                    mopt->flags |= M_NOSUID;
747#endif /* ultrix */
748                }
749#endif  /* AIX */
750#ifdef NFS
751                else if (mopt->type == MOUNT_NFS) {
752                        if (!strcmp(str, "soft"))
753                                mopt->tsa.nfs.flags |= NFSMNT_SOFT;
754                        else if (!strcmp(str, "hard"))
755                                mopt->tsa.nfs.flags &= ~NFSMNT_SOFT;
756                        else if (!strcmp(str, "rsize")) {
757                                if (!arg) {
758                                        missarg("rsize");
759                                }
760                                mopt->tsa.nfs.rsize = atoi(arg);
761                                mopt->tsa.nfs.flags |= NFSMNT_RSIZE;
762                        } else if (!strcmp(str, "wsize")) {
763                                if (!arg) {
764                                        missarg("wsize");
765                                        continue;
766                                }
767                                mopt->tsa.nfs.wsize = atoi(arg);
768                                mopt->tsa.nfs.flags |= NFSMNT_WSIZE;
769                        } else if (!strcmp(str, "timeo")) {
770                                if (!arg) {
771                                        missarg("timeo");
772                                        continue;
773                                }
774                                mopt->tsa.nfs.timeo = atoi(arg);
775                                mopt->tsa.nfs.flags |= NFSMNT_TIMEO;
776                        } else if (!strcmp(str, "retrans")) {
777                                if (!arg) {
778                                        missarg("retrans");
779                                        continue;
780                                }
781                                mopt->tsa.nfs.retrans = atoi(arg);
782                                mopt->tsa.nfs.flags |= NFSMNT_RETRANS;
783                        } else if (!strcmp(str, "port")) {
784                                if (!arg) {
785                                        missarg("port");
786                                        continue;
787                                }
788                                mopt->nfs_port = atoi(arg);
789                        }
790#ifdef ultrix
791                        else if (!strcmp(str, "intr")) {
792                            mopt->tsa.nfs.flags |= NFSMNT_INT;
793                        }
794#endif /* ultrix */
795                    }
796#endif
797                str = next;
798        }
799        free(orig_str);
800}
801
802static missarg(arg)
803        char    *arg;
804{
805        fprintf(stderr,
806                "%s: missing argument to mount option; ignoring.\n",
807                arg);
808}
809
810/*
811 * Return a string describing the options in the mount options structure
812 */
813char *stropt(mopt)
814        struct mntopts  mopt;
815{
816        static char     buff[BUFSIZ];
817        char    tmp[80];
818
819        buff[0] = '\0';
820       
821        if (mopt.flags & M_RDONLY)
822                (void) strcat(buff, ",ro");
823        else
824                (void) strcat(buff, ",rw");
825#ifdef M_NOSUID
826#ifdef ultrix
827#ifdef NFS
828        if (mopt.type == MOUNT_NFS && (mopt.tsa.nfs.gfs_flags & M_NOSUID))
829            (void) strcat(buff, ",nosuid");
830        else
831#endif /* NFS */
832        if (mopt.type == MOUNT_UFS && (mopt.tsa.ufs.ufs_flags & M_NOSUID))
833            (void) strcat(buff, ",nosuid");
834#else /* !ultrix */
835        if (mopt.flags & M_NOSUID)
836                (void) strcat(buff, ",nosuid");
837#endif /* ultrix */
838#endif /* M_NOSUID */
839#ifdef NFS
840        if (mopt.type == MOUNT_NFS) {
841#ifdef ultrix
842                if (mopt.tsa.nfs.gfs_flags & M_FORCE)
843                        (void) strcat(buff, ",force");
844                if (mopt.tsa.nfs.gfs_flags & M_SYNC)
845                        (void) strcat(buff, ",force");
846                if (mopt.tsa.nfs.flags & NFSMNT_PGTHRESH) {
847                        (void) strcat(buff, ",pgthresh=");
848                        (void) sprintf(tmp, "%d", mopt.tsa.nfs.pg_thresh);
849                        (void) strcat(buff, tmp);
850                }
851                if (mopt.tsa.nfs.gfs_flags & M_NOEXEC)
852                        (void) strcat(buff, ",noexec");
853                if (mopt.tsa.nfs.gfs_flags & M_NOCACHE)
854                        (void) strcat(buff, ",nocache");
855                if (mopt.tsa.nfs.gfs_flags & M_NODEV)
856                        (void) strcat(buff, ",nodev");
857                if (mopt.tsa.nfs.flags & NFSMNT_INT)
858                        (void) strcat(buff, ",intr");
859#endif /* ultrix */
860                if (mopt.tsa.nfs.flags & NFSMNT_SOFT)
861                        (void) strcat(buff, ",soft");
862                if (mopt.tsa.nfs.flags & NFSMNT_RSIZE) {
863                        (void) strcat(buff, ",rsize=");
864                        (void) sprintf(tmp, "%d", mopt.tsa.nfs.rsize);
865                        (void) strcat(buff, tmp);
866                }
867                if (mopt.tsa.nfs.flags & NFSMNT_WSIZE) {
868                        (void) strcat(buff, ",wsize=");
869                        (void) sprintf(tmp, "%d", mopt.tsa.nfs.wsize);
870                        (void) strcat(buff, tmp);
871                }
872                if (mopt.tsa.nfs.flags & NFSMNT_TIMEO) {
873                        (void) strcat(buff, ",timeo=");
874                        (void) sprintf(tmp, "%d", mopt.tsa.nfs.timeo);
875                        (void) strcat(buff, tmp);
876                }
877                if (mopt.tsa.nfs.flags & NFSMNT_RETRANS) {
878                        (void) strcat(buff, ",retrans=");
879                        (void) sprintf(tmp, "%d", mopt.tsa.nfs.retrans);
880                        (void) strcat(buff, tmp);
881                }
882                if (mopt.nfs_port) {
883                        (void) strcat(buff, ",port=");
884                        (void) sprintf(tmp, "%d", mopt.nfs_port);
885                        (void) strcat(buff, tmp);
886                }
887        }
888#endif /* NFS */
889#ifdef ultrix
890        else if (mopt.type == MOUNT_UFS) {
891                if (mopt.tsa.ufs.ufs_flags & M_QUOTA)
892                        (void) strcat(buff, ",quota");
893                if (mopt.tsa.ufs.ufs_flags & M_FORCE)
894                        (void) strcat(buff, ",force");
895                if (mopt.tsa.ufs.ufs_flags & M_SYNC)
896                        (void) strcat(buff, ",force");
897                if (mopt.tsa.ufs.ufs_pgthresh != DEFPGTHRESH) {
898                        (void) strcat(buff, ",pgthresh=");
899                        (void) sprintf(tmp, "%d", mopt.tsa.ufs.ufs_pgthresh);
900                        (void) strcat(buff, tmp);
901                }
902                if (mopt.tsa.ufs.ufs_flags & M_NOEXEC)
903                        (void) strcat(buff, ",noexec");
904                if (mopt.tsa.ufs.ufs_flags & M_NOCACHE)
905                        (void) strcat(buff, ",nocache");
906                if (mopt.tsa.ufs.ufs_flags & M_NODEV)
907                        (void) strcat(buff, ",nodev");
908            }
909#endif /* ultrix */
910
911        return(buff+1);
912}
913
914/*
915 * Display the userid, given a uid (if possible)
916 */
917char *struid(uid)
918        int     uid;
919{
920        struct  passwd  *pw;
921        static char     buff[64];
922
923        pw = getpwuid(uid);
924        if (pw)
925                strncpy(buff, pw->pw_name, sizeof(buff));
926        else
927                sprintf(buff, "#%d", uid);
928        return(buff);
929}
930
931/*
932 * Compare if two hosts are the same
933 */
934int host_compare(host1, host2)
935        char    *host1;
936        char    *host2;
937{
938        char    bfr[BUFSIZ];
939        static  char    last_host[BUFSIZ] = "********";
940        static  struct in_addr  sin1, sin2;
941        struct hostent  *host;
942
943        /*
944         * Cache the last host1, for efficiency's sake.
945         */
946        if (strcmp(host1, last_host)) {
947                strcpy(last_host, host1);
948                if ((sin1.s_addr = inet_addr(host1)) == -1) {
949                        if (host = gethostbyname(host1))
950#ifdef POSIX
951                                memmove(&sin1, host->h_addr, (sizeof sin1));
952#else
953                                bcopy(host->h_addr, &sin1, (sizeof sin1));
954#endif
955                        else {
956                                if (debug_flag) {
957                                        sprintf(bfr, "%s: gethostbyname",
958                                                host1);
959                                        perror(bfr);
960                                }
961                                return(!strcmp(host1, host2));
962                        }
963                }
964        }
965        if ((sin2.s_addr = inet_addr(host2)) == -1) {
966                if (host = gethostbyname(host2))
967#ifdef POSIX
968                        memmove(&sin2, host->h_addr, (sizeof sin2));
969#else
970                        bcopy(host->h_addr, &sin2, (sizeof sin2));
971#endif
972                else {
973                        if (debug_flag) {
974                                sprintf(bfr, "%s: gethostbyname", host2);
975                                perror(bfr);
976                        }
977                        return(!strcmp(host1, host2));
978                }
979        }
980        return(!memcmp(&sin1, &sin2, (sizeof sin1)));
981}
982
983/*
984 * Owner list code, originally written by jfc
985 */
986int clean_attachtab(atp)
987        struct _attachtab *atp;
988{
989        struct passwd *pw;
990        int i;
991        for(i=0;i<atp->nowners;i++)
992                if(NULL == (pw = getpwuid(atp->owners[i]))) {
993                        int j;
994                        /* Unmap */
995                        if (atp->fs->type == TYPE_NFS && do_nfsid) {
996                                if (debug_flag)
997                                        fprintf(stderr,
998                                                "nfs unmap(%s, %d)\n",
999                                                atp->host, atp->owners[i]);
1000                                (void) nfsid(atp->host, atp->hostaddr[0],
1001                                             MOUNTPROC_KUIDUMAP, 1,
1002                                             atp->hesiodname, 0, atp->owners[i]);
1003                        }
1004                        for(j=i+1;j<atp->nowners;j++)
1005                                atp->owners[j-1] = atp->owners[j];
1006                        atp->nowners--;
1007                        i--;
1008                }
1009        return atp->nowners;
1010}
1011
1012void add_an_owner(atp,uid)
1013        uid_t uid;
1014        struct _attachtab *atp;
1015{
1016        register int i;
1017        for(i=0;i<atp->nowners;i++)
1018                if(atp->owners[i] == uid)
1019                        return;
1020        if(atp->nowners < MAXOWNERS)
1021                atp->owners[atp->nowners++] = uid;
1022        else
1023          /* fail silently */;
1024}
1025
1026int is_an_owner(at,uid)
1027        uid_t uid;
1028        struct _attachtab *at;
1029{
1030        register int i;
1031        if (!at->nowners)
1032                return(1);      /* If no one claims it, anyone can have it */
1033        for(i=0;i<at->nowners;i++)
1034                if(at->owners[i] == uid)
1035                        return 1;
1036        return 0;
1037}
1038
1039#ifdef ZEPHYR
1040int wants_to_subscribe(at, uid, zero_too)
1041        uid_t uid;
1042        struct _attachtab *at;
1043        int zero_too;           /* also true if root ? */
1044{
1045        register int i;
1046
1047        for(i = 0;i < at->nowners;i++)
1048                if((zero_too && at->owners[i] == 0) || at->owners[i] == uid)
1049                        return 1;
1050        return 0;
1051}
1052#endif
1053
1054int del_an_owner(at,uid)
1055        uid_t uid;
1056        struct _attachtab *at;
1057{
1058        register int i;
1059        for(i=0;i<at->nowners;i++)
1060                if(at->owners[i] == uid) {
1061                        --at->nowners;
1062                        for(;i<at->nowners;i++)
1063                                at->owners[i] = at->owners[i+1];
1064                        return at->nowners;
1065                }
1066        if(at->nowners == 0)
1067                at->owners[0] = -1;
1068        return at->nowners;
1069}
1070
1071char *ownerlist(atp)
1072        struct _attachtab *atp;
1073{
1074        static char ret[256];
1075        int i,len=1;
1076        if(atp->nowners == 0)
1077                return("{}");
1078        else if(atp->nowners == 1)
1079                return struid(atp->owners[0]);
1080
1081        ret[0] = '{';
1082        for(i=0;i<atp->nowners;i++) {
1083                char *u = struid(atp->owners[i]);
1084                int tmp = strlen(u);
1085                if(i)
1086                        ret[len++] = ',';
1087                if(len+tmp >= 255) {
1088                        ret[len++] = '}';
1089                        ret[len] = '\0';
1090                        return ret;
1091                }
1092                strcpy(ret+len,u);
1093                len += tmp;
1094        }
1095        ret[len++] = '}';
1096        ret[len] = '\0';
1097        return ret;
1098}
1099
1100
1101int parse_username(s)
1102        const char *s;
1103{
1104        struct passwd   *pw;
1105        const char      *os = s;
1106       
1107        pw = getpwnam((char *)s);
1108        if (pw)
1109                return(pw->pw_uid);
1110        else {
1111                if (*s == '#')
1112                        s++;
1113                if (isdigit(*s))
1114                        return(atoi(s));
1115                fprintf(stderr, "Can't parse username/uid string: %s\n", os);
1116                exit(1);
1117                /* NOTREACHED */
1118        }
1119}
1120
1121
1122int parse_groupname(s)
1123        const char *s;
1124{
1125        struct group *gr;
1126       
1127        gr = getgrnam((char *)s);
1128        if (gr)
1129                return(gr->gr_gid);
1130        else {
1131                if (*s == '#')
1132                        s++;
1133                if (isdigit(*s))
1134                        return(atoi(s));
1135                fprintf(stderr, "Can't parse groupname/gid string: %s\n", s);
1136                exit(1);
1137                /* NOTREACHED */
1138        }
1139}
1140
1141
1142char *errstr(e)
1143    int e;
1144{
1145  if(e < sys_nerr)
1146    return sys_errlist[e];
1147  else
1148    return "Unknown error";
1149}
Note: See TracBrowser for help on using the repository browser.