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

Revision 6270, 22.4 KB checked in by epeisach, 32 years ago (diff)
Don't use sigmask as a variable name due to conflicting defines
Line 
1/*      Created by:     Robert French
2 *
3 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/attach/util.c,v $
4 *      $Author: epeisach $
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.18 1992-08-02 11:32:55 epeisach 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/*
183 * Build a Hesiod line either from a Hesiod query or internal frobbing
184 * if explicit is set.
185 */
186char **build_hesiod_line(name)
187    char *name;
188{
189    char **realhes;
190    struct _fstypes     *fsp;
191   
192    if (!explicit) {
193            realhes = conf_filsys_resolve(name);
194#ifdef HESIOD
195            if (!realhes || !*realhes)
196                    realhes = hes_resolve(name, "filsys");
197#endif
198            if (!realhes || !*realhes)
199                    fprintf(stderr, "%s: Can't resolve name\n", name);
200            return (realhes);
201    }
202
203    fsp = get_fs(filsys_type ? filsys_type : "NFS");
204    if (!fsp)
205        return (NULL);
206    if (!fsp->explicit) {
207        fprintf(stderr, "Explicit definitions for type %s not allowed\n",
208                filsys_type);
209        return (NULL);
210    }
211
212    return ((fsp->explicit)(name));
213}
214
215/*
216 * Parse a Hesiod record
217 *
218 * Returns 0 on success, -1 on failure
219 */
220int parse_hes(hes, at, errorname)
221    char *hes, *errorname;
222    struct _attachtab *at;
223{
224    char        *cp, *t;
225    struct hostent *hent;
226    int         type;
227
228    bzero(at, sizeof(struct _attachtab));
229   
230    if (!*hes)
231            goto bad_hes_line;
232
233
234    at->fs = get_fs(strtok(hes, TOKSEP));
235    if (!at->fs)
236            goto bad_hes_line;
237    type = at->fs->type;
238
239    if (type & TYPE_ERR) {
240            strncpy(at->hostdir, strtok(NULL, ""), sizeof(at->hostdir));
241            return(0);
242    }
243
244    if (!(cp = strtok(NULL, (type & TYPE_MUL) ? "" : TOKSEP)))
245            goto bad_hes_line;
246    strcpy(at->hostdir, cp);
247
248    if (type & ~(TYPE_UFS | TYPE_AFS | TYPE_MUL)) {
249            if (!(cp = strtok(NULL, TOKSEP)))
250                    goto bad_hes_line;
251            strcpy(at->host, cp);
252    } else
253            strcpy(at->host, "localhost");
254
255    if (type & TYPE_MUL) {
256            t = at->hostdir;
257            while (t = index(t,' '))
258                    *t = ',';
259            at->mode = '-';
260            strcpy(at->mntpt, "localhost");
261    } else {
262
263            if (!(cp = strtok(NULL, TOKSEP)))
264                    goto bad_hes_line;
265            at->mode = *cp;
266            if (at->mode == 'x')
267                    at->mode = 'w';  /* Backwards compatibility */
268            if (at->fs->good_flags) {
269                    if (!index(at->fs->good_flags, at->mode))
270                            goto bad_hes_line;  /* Bad attach mode */
271            }
272
273            if (!(cp = strtok(NULL, TOKSEP)))
274                    goto bad_hes_line;
275            strcpy(at->mntpt, cp);
276    }
277
278    if (type & ~(TYPE_UFS | TYPE_AFS | TYPE_MUL)) {
279            hent = gethostbyname(at->host);
280            if (!hent) {
281                    fprintf(stderr,"%s: Can't resolve host %s\n",errorname,
282                            at->host);
283                    fprintf(stderr, abort_msg);
284                    return(-1);
285            }
286            bcopy(hent->h_addr_list[0], &at->hostaddr[0].s_addr, 4);
287            strcpy(at->host, hent->h_name);
288    } else
289            at->hostaddr[0].s_addr = (long) 0;
290    return(0);
291   
292bad_hes_line:
293    fprintf(stderr,"Badly formatted filesystem definition\n");
294    fprintf(stderr, abort_msg);
295    return(-1);
296}
297
298/*
299 * Make the directories necessary for a mount point - set the number
300 * of directories created in the attachtab structure
301 */
302int make_mntpt(at)
303    struct _attachtab *at;
304{
305    char bfr[BUFSIZ],*ptr;
306    int oldmask;
307    struct stat statbuf;
308
309    strcpy(bfr, at->mntpt);
310    if (at->fs->flags & AT_FS_PARENTMNTPT) {
311            ptr = rindex(bfr, '/');
312            if (ptr)
313                    *ptr = 0;
314            else
315                    return(SUCCESS);
316    }
317   
318    if (!stat(bfr, &statbuf)) {
319        if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
320            return (SUCCESS);
321        fprintf(stderr, "%s: %s is not a directory\n", at->hesiodname,
322                at->mntpt);
323        return (FAILURE);
324    }
325   
326    oldmask = umask(022);
327
328    ptr = bfr+1;                /* Pass initial / */
329
330    at->rmdir = 0;
331       
332    while (ptr && *ptr) {
333        strcpy(bfr, at->mntpt);
334        ptr = index(ptr, '/');
335        if (ptr)
336            *ptr++ = '\0';
337        if (debug_flag)
338                printf("Making directory %s (%s)\n", bfr, ptr ? ptr : "");
339        if (mkdir(bfr, 0777)) {
340            if (errno == EEXIST)
341                continue;
342            fprintf(stderr, "%s: Can't create directory %s: %s\n",
343                    at->hesiodname, bfr, sys_errlist[errno]);
344            umask(oldmask);
345            return (FAILURE);
346        }
347        else
348            at->rmdir++;
349    }
350    umask(oldmask);
351    return (SUCCESS);
352}
353
354/*
355 * Delete a previously main mountpoint
356 */
357int rm_mntpt(at)
358    struct _attachtab *at;
359{
360    char bfr[BUFSIZ], *ptr;
361
362    strcpy(bfr, at->mntpt);
363    ptr = bfr;
364
365    if (at->fs->flags & AT_FS_PARENTMNTPT) {
366            ptr = rindex(bfr, '/');
367            if (ptr)
368                    *ptr = 0;
369            else
370                    return(SUCCESS);
371    }
372    while (at->rmdir--) {
373        if (debug_flag)
374                printf("Deleting directory %s (%s)\n", bfr, ptr ? ptr : "");
375        if (rmdir(bfr)) {
376            if (errno != ENOENT) {
377                fprintf(stderr,
378                        "%s: Can't remove directory %s: %s\n",
379                        at->hesiodname, ptr,
380                        sys_errlist[errno]);
381                return (FAILURE);
382            }
383        }
384        ptr = rindex(bfr, '/');
385        if (ptr)
386            *ptr = '\0';
387        else
388            return (SUCCESS);
389    }
390    return (SUCCESS);
391}
392
393/*
394 * Internal spiffed up getopt
395 */
396char internal_getopt(arg, cl)
397    char *arg;
398    struct command_list *cl;
399{
400    int i;
401
402    for (i=0;cl[i].small;i++) {
403        if (cl[i].large && !strcmp(cl[i].large, arg))
404            return (cl[i].small[1]);
405        if (!strcmp(cl[i].small, arg))
406            return (cl[i].small[1]);
407    }
408    return ('?');
409}
410
411/*
412 * Format a hesiod name into a name in /tmp...including replacing /
413 * with @, etc.
414 */
415make_temp_name(filename, name)
416    char *filename;
417    char *name;
418{
419    strcpy(filename, "/tmp/attach_");
420    filename = filename+strlen(filename);
421   
422    while (*name) {
423        if (*name == '/')
424            *filename++ = '@';
425        else
426            *filename++ = *name;
427        name++;
428    }
429    *filename = '\0';
430}
431
432/*
433 * Check to see if a filesystem is really being frobbed with by
434 * another attach process.
435 */
436
437int really_in_use(name)
438    char *name;
439{
440    int fd, ret;
441    char filename[BUFSIZ];
442#ifdef POSIX
443    struct flock fl;
444#endif
445
446    make_temp_name(filename, name);
447
448    if (debug_flag)
449        printf("Checking lock on %s\n", filename);
450   
451    fd = open(filename, O_RDWR, 0644);
452    if (!fd)
453        return (0);
454
455#ifdef POSIX
456    fl.l_type = F_WRLCK;
457    fl.l_whence = SEEK_SET;
458    fl.l_start = 0;
459    fl.l_len = 0;
460    fl.l_pid = getpid();
461    ret = (fcntl(fd, F_SETLK, &fl)==-1 && errno == EAGAIN);
462#else
463    ret = (flock(fd, LOCK_EX | LOCK_NB) == -1 && errno == EWOULDBLOCK);
464#endif
465
466    close(fd);
467    return (ret);
468}
469
470/*
471 * Mark a filesystem as being frobbed with
472 */
473
474void mark_in_use(name)
475    char *name;
476{
477    static int fd;
478    static char filename[BUFSIZ];
479#ifdef POSIX
480    struct flock fl;
481#endif
482
483    if (!name) {
484        if (debug_flag)
485            printf("Removing lock on %s\n", filename);
486        close(fd);
487        unlink(filename);
488        return;
489    }
490
491    make_temp_name(filename, name);
492
493    if (debug_flag)
494        printf("Setting lock on %s: ", filename);
495
496    /*
497     * Unlink the old file in case someone else already has a lock on
498     * it...we'll override them with our new file.
499     */
500    unlink(filename);
501    fd = open(filename, O_CREAT|O_RDWR, 0644);
502    if (!fd) {
503            fprintf(stderr,"Can't open %s: %s\n", filename,
504                    sys_errlist[errno]);
505            fprintf(stderr, abort_msg);
506            exit(ERR_FATAL);
507    }
508
509    if (debug_flag)
510            printf("%d\n", fd);
511
512#ifdef POSIX
513    fl.l_type = F_WRLCK;
514    fl.l_whence = SEEK_SET;
515    fl.l_start = 0;
516    fl.l_len = 0;
517    fl.l_pid = getpid();
518    fcntl(fd, F_SETLKW, &fl);
519#else
520    flock(fd, LOCK_EX);
521#endif
522}
523
524#ifdef DEBUG
525/*
526 * Dump used file descriptors...useful for debugging
527 */
528
529fd_dump()
530{
531    int i;
532    char b;
533
534    printf("FD's in use: ");
535    for (i=0;i<64;i++)
536        if (read(i,&b,0) >= 0)
537            printf("%d ",i);
538    printf("\n");
539}
540#endif
541
542/*
543 * String comparison for filesystem names - case insensitive for hesiod,
544 * sensitive for explicit.
545 */
546
547int hescmp(at, s)
548    struct _attachtab *at;
549    char *s;
550{
551    if (at->explicit)
552        return (strcmp(at->hesiodname, s));
553    return (strcasecmp(at->hesiodname, s));
554}
555
556/*
557 * Duplicate a string in malloc'ed memory
558 */
559char *strdup(s)
560        char    *s;
561{
562        register char   *cp;
563       
564        if (!(cp = malloc(strlen(s)+1))) {
565                fprintf(stderr, "attach: out of memory, exiting...\n");
566                exit(1);
567        }
568        return(strcpy(cp,s));
569}
570
571/*
572 * Check to see if we have root priv's; give an error if we don't.
573 */
574void check_root_privs(progname)
575        char    *progname;
576{
577        if (!real_uid || !effective_uid || (debug_flag))
578                return;
579        fprintf(stderr,
580                "%s must be setuid to root for this operation to succeed.\n",
581                progname);
582        exit(ERR_FATAL);
583        /* NOTREACHED */
584}
585
586void add_options(mopt, string)
587        struct mntopts  *mopt;
588        char            *string;
589{
590        char    *next, *arg, *str, *orig_str;
591
592        orig_str = str = strdup(string);
593        while (str && *str) {
594                next = index(str, ',');
595                if (next) {
596                        *next++ = '\0';
597                }
598                arg = index(str, '=');
599                if (arg)
600                        *arg++ = '\0';
601                if (!strcmp(str, "ro")) {
602                        mopt->flags |= M_RDONLY;
603#if defined(ultrix) && defined(NFS)
604                        if (mopt->type == MOUNT_NFS) {
605                            mopt->tsa.nfs.gfs_flags |= M_RONLY;
606                            mopt->tsa.nfs.flags |= NFSMNT_RONLY;
607                        }
608#endif /* ultrix && NFS */
609                } else if (!strcmp(str, "rw")) {
610#ifdef ultrix
611                    mopt->flags &= ~M_RDONLY;
612                    mopt->tsa.nfs.gfs_flags &= ~M_RONLY;
613                    mopt->tsa.nfs.flags &= ~NFSMNT_RONLY;
614#else /* !ultrix */
615                    mopt->flags &= ~M_RDONLY;
616#endif /* ultrix */
617                }
618#ifdef ultrix
619                /* process other ultrix options */
620                else if (!strcmp(str, "force")) {
621#ifdef NFS
622                    if (mopt->type == MOUNT_NFS)
623                        mopt->tsa.nfs.gfs_flags |= M_FORCE;
624                    else
625#endif /* NFS */
626                    if (mopt->type == MOUNT_UFS)
627                        mopt->tsa.ufs.ufs_flags |= M_FORCE;
628                } else if (!strcmp(str, "sync")) {
629#ifdef NFS
630                    if (mopt->type == MOUNT_NFS)
631                        mopt->tsa.nfs.gfs_flags |= M_SYNC;
632                    else
633#endif /* NFS */
634                    if (mopt->type == MOUNT_UFS)
635                        mopt->tsa.ufs.ufs_flags |= M_SYNC;
636                } else if (!strcmp(str, "pgthresh")) {
637                    int pgthresh;
638
639                    if (!arg) {
640                        missarg("pgthresh");
641                        continue;
642                    }
643                    pgthresh = atoi(arg);
644                    pgthresh = max (pgthresh, MINPGTHRESH/PGUNITS);
645#ifdef NFS                 
646                    if (mopt->type == MOUNT_NFS) {
647                        mopt->tsa.nfs.pg_thresh = pgthresh;
648                        mopt->tsa.nfs.flags |= NFSMNT_PGTHRESH;
649                    } else
650#endif /* NFS */
651                    if (mopt->type == MOUNT_UFS)
652                        mopt->tsa.ufs.ufs_pgthresh = pgthresh;
653                } else if (!strcmp(str, "quota")) {
654                    if (mopt->type == MOUNT_UFS)
655                        mopt->tsa.ufs.ufs_flags |= M_QUOTA;
656                } else if (!strcmp(str, "noexec")) {
657#ifdef NFS
658                    if (mopt->type == MOUNT_NFS)
659                        mopt->tsa.nfs.gfs_flags |= M_NOEXEC;
660                    else
661#endif /* NFS */
662                    if (mopt->type == MOUNT_UFS)
663                        mopt->tsa.ufs.ufs_flags |= M_NOEXEC;
664                } else if (!strcmp(str, "nocache")) {
665#ifdef NFS
666                    if (mopt->type == MOUNT_NFS)
667                        mopt->tsa.nfs.gfs_flags |= M_NOCACHE;
668                    else
669#endif /* NFS */
670                    if (mopt->type == MOUNT_UFS)
671                        mopt->tsa.ufs.ufs_flags |= M_NOCACHE;
672                } else if (!strcmp(str, "nodev")) {
673#ifdef NFS
674                    if (mopt->type == MOUNT_NFS)
675                        mopt->tsa.nfs.gfs_flags |= M_NODEV;
676                    else
677#endif /* NFS */
678                    if (mopt->type == MOUNT_UFS)
679                        mopt->tsa.ufs.ufs_flags |= M_NODEV;
680                }
681#endif /* ultrix */
682#ifndef AIX
683                else if (!strcmp(str, "nosuid")) {
684#ifdef ultrix
685#ifdef NFS
686                    if (mopt->type == MOUNT_NFS)
687                        mopt->tsa.nfs.gfs_flags |= M_NOSUID;
688                    else
689#endif /* NFS */
690                    if (mopt->type == MOUNT_UFS)
691                        mopt->tsa.ufs.ufs_flags |= M_NOSUID;
692#else /* !ultrix */
693                    mopt->flags |= M_NOSUID;
694#endif /* ultrix */
695                }
696#endif  /* AIX */
697#ifdef NFS
698                else if (mopt->type == MOUNT_NFS) {
699                        if (!strcmp(str, "soft"))
700                                mopt->tsa.nfs.flags |= NFSMNT_SOFT;
701                        else if (!strcmp(str, "hard"))
702                                mopt->tsa.nfs.flags &= ~NFSMNT_SOFT;
703                        else if (!strcmp(str, "rsize")) {
704                                if (!arg) {
705                                        missarg("rsize");
706                                }
707                                mopt->tsa.nfs.rsize = atoi(arg);
708                                mopt->tsa.nfs.flags |= NFSMNT_RSIZE;
709                        } else if (!strcmp(str, "wsize")) {
710                                if (!arg) {
711                                        missarg("wsize");
712                                        continue;
713                                }
714                                mopt->tsa.nfs.wsize = atoi(arg);
715                                mopt->tsa.nfs.flags |= NFSMNT_WSIZE;
716                        } else if (!strcmp(str, "timeo")) {
717                                if (!arg) {
718                                        missarg("timeo");
719                                        continue;
720                                }
721                                mopt->tsa.nfs.timeo = atoi(arg);
722                                mopt->tsa.nfs.flags |= NFSMNT_TIMEO;
723                        } else if (!strcmp(str, "retrans")) {
724                                if (!arg) {
725                                        missarg("retrans");
726                                        continue;
727                                }
728                                mopt->tsa.nfs.retrans = atoi(arg);
729                                mopt->tsa.nfs.flags |= NFSMNT_RETRANS;
730                        } else if (!strcmp(str, "port")) {
731                                if (!arg) {
732                                        missarg("port");
733                                        continue;
734                                }
735                                mopt->nfs_port = atoi(arg);
736                        }
737#ifdef ultrix
738                        else if (!strcmp(str, "intr")) {
739                            mopt->tsa.nfs.flags |= NFSMNT_INT;
740                        }
741#endif /* ultrix */
742                    }
743#endif
744                str = next;
745        }
746        free(orig_str);
747}
748
749static missarg(arg)
750        char    *arg;
751{
752        fprintf(stderr,
753                "%s: missing argument to mount option; ignoring.\n",
754                arg);
755}
756
757/*
758 * Return a string describing the options in the mount options structure
759 */
760char *stropt(mopt)
761        struct mntopts  mopt;
762{
763        static char     buff[BUFSIZ];
764        char    tmp[80];
765
766        buff[0] = '\0';
767       
768        if (mopt.flags & M_RDONLY)
769                (void) strcat(buff, ",ro");
770        else
771                (void) strcat(buff, ",rw");
772#ifdef M_NOSUID
773#ifdef ultrix
774#ifdef NFS
775        if (mopt.type == MOUNT_NFS && (mopt.tsa.nfs.gfs_flags & M_NOSUID))
776            (void) strcat(buff, ",nosuid");
777        else
778#endif /* NFS */
779        if (mopt.type == MOUNT_UFS && (mopt.tsa.ufs.ufs_flags & M_NOSUID))
780            (void) strcat(buff, ",nosuid");
781#else /* !ultrix */
782        if (mopt.flags & M_NOSUID)
783                (void) strcat(buff, ",nosuid");
784#endif /* ultrix */
785#endif /* M_NOSUID */
786#ifdef NFS
787        if (mopt.type == MOUNT_NFS) {
788#ifdef ultrix
789                if (mopt.tsa.nfs.gfs_flags & M_FORCE)
790                        (void) strcat(buff, ",force");
791                if (mopt.tsa.nfs.gfs_flags & M_SYNC)
792                        (void) strcat(buff, ",force");
793                if (mopt.tsa.nfs.flags & NFSMNT_PGTHRESH) {
794                        (void) strcat(buff, ",pgthresh=");
795                        (void) sprintf(tmp, "%d", mopt.tsa.nfs.pg_thresh);
796                        (void) strcat(buff, tmp);
797                }
798                if (mopt.tsa.nfs.gfs_flags & M_NOEXEC)
799                        (void) strcat(buff, ",noexec");
800                if (mopt.tsa.nfs.gfs_flags & M_NOCACHE)
801                        (void) strcat(buff, ",nocache");
802                if (mopt.tsa.nfs.gfs_flags & M_NODEV)
803                        (void) strcat(buff, ",nodev");
804                if (mopt.tsa.nfs.flags & NFSMNT_INT)
805                        (void) strcat(buff, ",intr");
806#endif /* ultrix */
807                if (mopt.tsa.nfs.flags & NFSMNT_SOFT)
808                        (void) strcat(buff, ",soft");
809                if (mopt.tsa.nfs.flags & NFSMNT_RSIZE) {
810                        (void) strcat(buff, ",rsize=");
811                        (void) sprintf(tmp, "%d", mopt.tsa.nfs.rsize);
812                        (void) strcat(buff, tmp);
813                }
814                if (mopt.tsa.nfs.flags & NFSMNT_WSIZE) {
815                        (void) strcat(buff, ",wsize=");
816                        (void) sprintf(tmp, "%d", mopt.tsa.nfs.wsize);
817                        (void) strcat(buff, tmp);
818                }
819                if (mopt.tsa.nfs.flags & NFSMNT_TIMEO) {
820                        (void) strcat(buff, ",timeo=");
821                        (void) sprintf(tmp, "%d", mopt.tsa.nfs.timeo);
822                        (void) strcat(buff, tmp);
823                }
824                if (mopt.tsa.nfs.flags & NFSMNT_RETRANS) {
825                        (void) strcat(buff, ",retrans=");
826                        (void) sprintf(tmp, "%d", mopt.tsa.nfs.retrans);
827                        (void) strcat(buff, tmp);
828                }
829                if (mopt.nfs_port) {
830                        (void) strcat(buff, ",port=");
831                        (void) sprintf(tmp, "%d", mopt.nfs_port);
832                        (void) strcat(buff, tmp);
833                }
834        }
835#endif /* NFS */
836#ifdef ultrix
837        else if (mopt.type == MOUNT_UFS) {
838                if (mopt.tsa.ufs.ufs_flags & M_QUOTA)
839                        (void) strcat(buff, ",quota");
840                if (mopt.tsa.ufs.ufs_flags & M_FORCE)
841                        (void) strcat(buff, ",force");
842                if (mopt.tsa.ufs.ufs_flags & M_SYNC)
843                        (void) strcat(buff, ",force");
844                if (mopt.tsa.ufs.ufs_pgthresh != DEFPGTHRESH) {
845                        (void) strcat(buff, ",pgthresh=");
846                        (void) sprintf(tmp, "%d", mopt.tsa.ufs.ufs_pgthresh);
847                        (void) strcat(buff, tmp);
848                }
849                if (mopt.tsa.ufs.ufs_flags & M_NOEXEC)
850                        (void) strcat(buff, ",noexec");
851                if (mopt.tsa.ufs.ufs_flags & M_NOCACHE)
852                        (void) strcat(buff, ",nocache");
853                if (mopt.tsa.ufs.ufs_flags & M_NODEV)
854                        (void) strcat(buff, ",nodev");
855            }
856#endif /* ultrix */
857
858        return(buff+1);
859}
860
861/*
862 * Display the userid, given a uid (if possible)
863 */
864char *struid(uid)
865        int     uid;
866{
867        struct  passwd  *pw;
868        static char     buff[64];
869
870        pw = getpwuid(uid);
871        if (pw)
872                strncpy(buff, pw->pw_name, sizeof(buff));
873        else
874                sprintf(buff, "#%d", uid);
875        return(buff);
876}
877
878/*
879 * Compare if two hosts are the same
880 */
881int host_compare(host1, host2)
882        char    *host1;
883        char    *host2;
884{
885        char    bfr[BUFSIZ];
886        static  char    last_host[BUFSIZ] = "********";
887        static  struct in_addr  sin1, sin2;
888        struct hostent  *host;
889
890        /*
891         * Cache the last host1, for efficiency's sake.
892         */
893        if (strcmp(host1, last_host)) {
894                strcpy(last_host, host1);
895                if ((sin1.s_addr = inet_addr(host1)) == -1) {
896                        if (host = gethostbyname(host1))
897                                bcopy(host->h_addr, &sin1, (sizeof sin1));
898                        else {
899                                if (debug_flag) {
900                                        sprintf(bfr, "%s: gethostbyname",
901                                                host1);
902                                        perror(bfr);
903                                }
904                                return(!strcmp(host1, host2));
905                        }
906                }
907        }
908        if ((sin2.s_addr = inet_addr(host2)) == -1) {
909                if (host = gethostbyname(host2))
910                        bcopy(host->h_addr, &sin2, (sizeof sin2));
911                else {
912                        if (debug_flag) {
913                                sprintf(bfr, "%s: gethostbyname", host2);
914                                perror(bfr);
915                        }
916                        return(!strcmp(host1, host2));
917                }
918        }
919        return(!bcmp(&sin1, &sin2, (sizeof sin1)));
920}
921
922/*
923 * Owner list code, originally written by jfc
924 */
925int clean_attachtab(atp)
926        struct _attachtab *atp;
927{
928        struct passwd *pw;
929        int i;
930        for(i=0;i<atp->nowners;i++)
931                if(NULL == (pw = getpwuid(atp->owners[i]))) {
932                        int j;
933                        /* Unmap */
934                        if (atp->fs->type == TYPE_NFS && do_nfsid) {
935                                if (debug_flag)
936                                        fprintf(stderr,
937                                                "nfs unmap(%s, %d)\n",
938                                                atp->host, atp->owners[i]);
939                                (void) nfsid(atp->host, atp->hostaddr[0],
940                                             MOUNTPROC_KUIDUMAP, 1,
941                                             atp->hesiodname, 0, atp->owners[i]);
942                        }
943                        for(j=i+1;j<atp->nowners;j++)
944                                atp->owners[j-1] = atp->owners[j];
945                        atp->nowners--;
946                        i--;
947                }
948        return atp->nowners;
949}
950
951void add_an_owner(atp,uid)
952        uid_t uid;
953        struct _attachtab *atp;
954{
955        register int i;
956        for(i=0;i<atp->nowners;i++)
957                if(atp->owners[i] == uid)
958                        return;
959        if(atp->nowners < MAXOWNERS)
960                atp->owners[atp->nowners++] = uid;
961        else
962          /* fail silently */;
963}
964
965int is_an_owner(at,uid)
966        uid_t uid;
967        struct _attachtab *at;
968{
969        register int i;
970        if (!at->nowners)
971                return(1);      /* If no one claims it, anyone can have it */
972        for(i=0;i<at->nowners;i++)
973                if(at->owners[i] == uid)
974                        return 1;
975        return 0;
976}
977
978#ifdef ZEPHYR
979int wants_to_subscribe(at, uid, zero_too)
980        uid_t uid;
981        struct _attachtab *at;
982        int zero_too;           /* also true if root ? */
983{
984        register int i;
985
986        for(i = 0;i < at->nowners;i++)
987                if((zero_too && at->owners[i] == 0) || at->owners[i] == uid)
988                        return 1;
989        return 0;
990}
991#endif
992
993int del_an_owner(at,uid)
994        uid_t uid;
995        struct _attachtab *at;
996{
997        register int i;
998        for(i=0;i<at->nowners;i++)
999                if(at->owners[i] == uid) {
1000                        --at->nowners;
1001                        for(;i<at->nowners;i++)
1002                                at->owners[i] = at->owners[i+1];
1003                        return at->nowners;
1004                }
1005        if(at->nowners == 0)
1006                at->owners[0] = -1;
1007        return at->nowners;
1008}
1009
1010char *ownerlist(atp)
1011        struct _attachtab *atp;
1012{
1013        static char ret[256];
1014        int i,len=1;
1015        if(atp->nowners == 0)
1016                return("{}");
1017        else if(atp->nowners == 1)
1018                return struid(atp->owners[0]);
1019
1020        ret[0] = '{';
1021        for(i=0;i<atp->nowners;i++) {
1022                char *u = struid(atp->owners[i]);
1023                int tmp = strlen(u);
1024                if(i)
1025                        ret[len++] = ',';
1026                if(len+tmp >= 255) {
1027                        ret[len++] = '}';
1028                        ret[len] = '\0';
1029                        return ret;
1030                }
1031                strcpy(ret+len,u);
1032                len += tmp;
1033        }
1034        ret[len++] = '}';
1035        ret[len] = '\0';
1036        return ret;
1037}
1038
1039
1040int parse_username(s)
1041        const char *s;
1042{
1043        struct passwd   *pw;
1044        const char      *os = s;
1045       
1046        pw = getpwnam((char *)s);
1047        if (pw)
1048                return(pw->pw_uid);
1049        else {
1050                if (*s == '#')
1051                        s++;
1052                if (isdigit(*s))
1053                        return(atoi(s));
1054                fprintf(stderr, "Can't parse username/uid string: %s\n", os);
1055                exit(1);
1056                /* NOTREACHED */
1057        }
1058}
1059
1060
1061int parse_groupname(s)
1062        const char *s;
1063{
1064        struct group *gr;
1065       
1066        gr = getgrnam((char *)s);
1067        if (gr)
1068                return(gr->gr_gid);
1069        else {
1070                if (*s == '#')
1071                        s++;
1072                if (isdigit(*s))
1073                        return(atoi(s));
1074                fprintf(stderr, "Can't parse groupname/gid string: %s\n", s);
1075                exit(1);
1076                /* NOTREACHED */
1077        }
1078}
1079
1080
1081char *errstr(e)
1082    int e;
1083{
1084  if(e < sys_nerr)
1085    return sys_errlist[e];
1086  else
1087    return "Unknown error";
1088}
Note: See TracBrowser for help on using the repository browser.