source: trunk/athena/bin/quota/attachtab.c @ 6828

Revision 6828, 11.5 KB checked in by probe, 31 years ago (diff)
Added POSIX locking (for Solaris)
Line 
1/*
2 * $Id: attachtab.c,v 1.7 1993-07-25 01:24:47 probe Exp $
3 *
4 * Copyright (c) 1989,1991 by the Massachusetts Institute of Technology.
5 *
6 * Contains the routines which access the attachtab file.
7 */
8
9#ifndef lint
10static char rcsid_attachtab_c[] = "$Id: attachtab.c,v 1.7 1993-07-25 01:24:47 probe Exp $";
11#endif lint
12
13#include "attach.h"
14#include <fcntl.h>
15#include <sys/file.h>
16#include <pwd.h>
17#include <string.h>
18
19#define TOKSEP " \t\r\n"
20
21static int parse_attach();
22
23struct  _attachtab      *attachtab_first, *attachtab_last;
24
25extern char *sys_errlist[];
26static int debug_flag = 0;
27static char attachtab_fn[512];
28static char *abort_msg = "quota: aborting\n";
29
30/*
31 * LOCK the attachtab - wait for it if it's already locked
32 */
33static int attach_lock_fd = -1;
34static int attach_lock_count = 0;
35
36void lock_attachtab()
37{
38    register char *lockfn;
39    register FILE *fp;
40    register int status;
41    static char buf[512];
42    static int initd = 0;
43#ifdef POSIX
44    struct flock fl;
45#endif
46
47    if (!initd) {
48        if (fp = fopen("/etc/athena/attach.conf","r")) {
49            while (fgets(buf, sizeof(buf), fp)) {
50                if (sscanf(buf, "attachtab %s", attachtab_fn) == 1) {
51                    initd = 1;
52                    break;
53                }
54            }
55            fclose(fp);
56        }
57        if (!initd) {
58            strcpy(attachtab_fn, "/usr/tmp/attachtab");
59            initd = 1;
60        }
61    }
62   
63    if (debug_flag)
64        printf("Locking attachtab....");
65    if (attach_lock_count == 0) {
66        if (!(lockfn = malloc(strlen(attachtab_fn)+6))) {
67            fprintf(stderr,
68                    "Can't malloc for lockfile filename\n");
69            fprintf(stderr, abort_msg);
70            exit(ERR_FATAL);
71        }
72        (void) strcpy(lockfn, attachtab_fn);
73        (void) strcat(lockfn, ".lock");
74       
75        if (attach_lock_fd < 0) {
76            attach_lock_fd = open(lockfn, O_CREAT|O_RDWR, 0644);
77            if (attach_lock_fd < 0) {
78                fprintf(stderr,"Can't open %s: %s\n", lockfn,
79                        sys_errlist[errno]);
80                fprintf(stderr, abort_msg);
81                exit(ERR_FATAL);
82            }
83        }
84#ifdef POSIX
85        fl.l_type = F_WRLCK;
86        fl.l_whence = SEEK_SET;
87        fl.l_start = 0;
88        fl.l_len = 0;
89        fl.l_pid = getpid();
90        status = fcntl(attach_lock_fd, F_SETLKW, &fl);
91#else
92        status = flock(attach_lock_fd, LOCK_EX);
93#endif
94        if (status == -1) {
95            fprintf(stderr, "Unable to lock attachtab: %s\n",
96                    sys_errlist[errno]);
97            fprintf(stderr, abort_msg);
98            exit(ERR_FATAL);
99        }
100        free(lockfn);
101    }
102    attach_lock_count++;
103}
104
105
106/*
107 * UNLOCK the attachtab
108 */
109void unlock_attachtab()
110{
111    if (debug_flag)
112        printf("Unlocking attachtab\n");
113    attach_lock_count--;
114    if (attach_lock_count == 0) {
115        close(attach_lock_fd);
116        attach_lock_fd = -1;
117    } else if (attach_lock_count < 0) {
118        fprintf(stderr,
119                "Programming botch!  Tried to unlock unlocked attachtab\n");
120    }
121}
122
123/*
124 * get_attachtab - Reads in the attachtab file and sets up the doubly
125 *      linked list of attachtab entries.  Assumes attachtab is
126 *      already locked.
127 */
128void get_attachtab()
129{
130    register struct _attachtab  *atprev = NULL;
131    register struct _attachtab  *at = NULL;
132    register FILE                       *f;
133    char                                attach_buf[BUFSIZ];
134       
135    free_attachtab();
136    if ((f = fopen(attachtab_fn, "r")) == NULL) {
137        fprintf(stderr, "Unable to open %s: %s\n",
138                attachtab_fn, sys_errlist[errno]);
139        return;
140    }
141       
142    while (fgets(attach_buf, sizeof attach_buf, f)) {
143        if (!(at = (struct _attachtab *) malloc(sizeof(*at)))) {
144            fprintf(stderr,
145                    "Can't malloc while parsing attachtab\n");
146            fprintf(stderr, abort_msg);
147            exit(ERR_FATAL);
148        }
149        if (parse_attach(attach_buf, at, 0) != SUCCESS) {
150            free(at);
151            continue;
152        }
153        at->prev = atprev;
154        if (atprev)
155            atprev->next = at;
156        else
157            attachtab_first = at;
158        atprev = at;
159    }
160    attachtab_last = at;
161    fclose(f);
162}
163
164/*
165 * free the linked list of attachtab entries
166 */
167void free_attachtab()
168{
169    register struct _attachtab          *at, *next;
170       
171    if (!(at = attachtab_first))
172        return;
173    while (at) {
174        next = at->next;
175        free(at);
176        at = next;
177    }
178    attachtab_first = attachtab_last = NULL;
179}       
180
181#if 0
182/*
183 * put_attachtab - write out attachtab file from linked list and
184 *      unlocks attachtab
185 */
186put_attachtab()
187{
188    register FILE       *f;
189    register struct     _attachtab      *at;
190    register char       *tempfn;
191       
192    if (!(tempfn = malloc(strlen(attachtab_fn)+6))) {
193        fprintf(stderr,
194                "Can't malloc while writing attachtab.\n");
195        fprintf(stderr, abort_msg);
196        exit(ERR_FATAL);
197    }
198    (void) strcpy(tempfn, attachtab_fn);
199    (void) strcat(tempfn, ".temp");
200    if (!(f = fopen(tempfn, "w"))) {
201        fprintf(stderr,"Can't open %s for write: %s\n", attachtab_fn,
202                sys_errlist[errno]);
203        fprintf(stderr, abort_msg);
204        exit(ERR_FATAL);
205    }
206    at = attachtab_first;
207    while (at) {
208        register int i;
209
210        fprintf(f, "%s %c%c%s %s %s %s %s",
211                at->version, at->explicit ? '1' : '0',
212                at->status, (at->fs) ? at->fs->name : "---",
213                at->hesiodname, at->host, at->hostdir,
214                inet_ntoa(at->hostaddr[0]));
215        for (i=1; i<MAXHOSTS && at->hostaddr[i].s_addr; i++)
216            fprintf(f, ",%s", inet_ntoa(at->hostaddr[i]));
217        fprintf(f, " %d %s %d ",
218                at->rmdir, at->mntpt, at->flags);
219        if (at->nowners)
220            fprintf(f, "%d", at->owners[0]);
221        else
222            fprintf(f, ",");
223        for (i=1; i < at->nowners; i++)
224            fprintf(f, ",%d", at->owners[i]);
225        fprintf(f, " %d %c\n", at->drivenum, at->mode);
226
227        at = at->next;
228    }
229    fclose(f);
230
231    if (rename(tempfn, attachtab_fn)) {
232        fprintf(stderr,"Can't rename %s to %s\n", tempfn,
233                attachtab_fn);
234        fprintf(stderr, abort_msg);
235        exit(ERR_FATAL);
236    }
237}
238
239void lint_attachtab()
240{
241    register struct _attachtab  *atprev = NULL;
242    register struct _attachtab  *at = NULL;
243    FILE                                *f;
244    char                                attach_buf[BUFSIZ];
245       
246    free_attachtab();
247    if ((f = fopen(attachtab_fn, "r")) == NULL)
248        return;
249       
250    while (fgets(attach_buf, sizeof attach_buf, f)) {
251        if (!(at = (struct _attachtab *) malloc(sizeof(*at)))) {
252            fprintf(stderr,
253                    "Can't malloc while parsing attachtab\n");
254            fprintf(stderr, abort_msg);
255            exit(ERR_FATAL);
256        }
257        if(parse_attach(attach_buf, at, 1) == FAILURE)
258            continue;                           /* bad line -- ignore */
259        at->prev = atprev;
260        if (atprev)
261            atprev->next = at;
262        else
263            attachtab_first = at;
264        atprev = at;
265    }
266    attachtab_last = at;
267    fclose(f);
268    put_attachtab();
269    free_attachtab();
270}
271#endif
272
273/*
274 * Convert an attachtab line to an attachtab structure
275 */
276static int parse_attach(bfr, at, lintflag)
277    register char *bfr;
278    register struct _attachtab *at;
279    int lintflag;
280{
281    register char *cp;
282    register int i;
283
284    if (!*bfr)
285        goto bad_line;
286       
287    if (bfr[strlen(bfr)-1] < ' ')
288        bfr[strlen(bfr)-1] = '\0';
289       
290    if (!(cp = strtok(bfr, TOKSEP)))
291        goto bad_line;
292
293    if (strcmp(cp, ATTACH_VERSION)) {
294        fprintf(stderr, "Bad version number in %s\n", attachtab_fn);
295        if(lintflag)
296            return FAILURE;
297        fprintf(stderr, abort_msg);
298        exit(ERR_FATAL);
299    }
300    strcpy(at->version, cp);
301   
302    if (!(cp = strtok(NULL, TOKSEP)))
303        goto bad_line;
304
305    if (*cp != '0' && *cp != '1')
306        goto bad_line;
307    at->explicit = *cp++-'0';
308   
309    at->status = *cp++;
310    if (at->status != STATUS_ATTACHED && at->status != STATUS_ATTACHING &&
311        at->status != STATUS_DETACHING)
312        goto bad_line;
313    /* Quota doesn't care about this entry */
314    if (at->status != STATUS_ATTACHED)
315        return FAILURE;
316
317    at->fs = get_fs(cp);
318    if (at->fs == NULL)
319        goto bad_line;
320
321    if (!(cp = strtok(NULL, TOKSEP)))
322        goto bad_line;
323    (void) strcpy(at->hesiodname, cp);
324
325    if (!(cp = strtok(NULL, TOKSEP)))
326        goto bad_line;
327    (void) strcpy(at->host, cp);
328
329    if (!(cp = strtok(NULL, TOKSEP)))
330        goto bad_line;
331    (void) strcpy(at->hostdir, cp);
332
333    if (!(cp = strtok(NULL, TOKSEP)))
334        goto bad_line;
335
336    for (i=0; cp; i++) {
337        register char *dp;
338
339        if (dp = index(cp, ','))
340            *dp++ = '\0';
341        at->hostaddr[i].s_addr = inet_addr(cp);
342        cp = dp;
343    }
344
345    if (!(cp = strtok(NULL, TOKSEP)))
346        goto bad_line;
347    at->rmdir = atoi(cp);
348
349    if (!(cp = strtok(NULL, TOKSEP)))
350        goto bad_line;
351    (void) strcpy(at->mntpt, cp);
352
353    if (!(cp = strtok(NULL, TOKSEP)))
354        goto bad_line;
355    at->flags = atoi(cp);
356   
357    if (!(cp = strtok(NULL, TOKSEP)))
358        goto bad_line;
359    at->nowners = 0;
360    if (*cp == ',')                             /* If heading character is comma */
361        cp = 0;                                 /* we have a null list*/
362    while (cp) {
363        register char *dp;
364           
365        if (dp = index(cp, ','))
366            *dp++ = '\0';
367        at->owners[at->nowners++] = atoi(cp);
368        cp = dp;
369    }
370   
371    if (!(cp = strtok(NULL, TOKSEP)))
372        goto bad_line;
373   
374    at->drivenum = atoi(cp);
375   
376    if (!(cp = strtok(NULL, TOKSEP)))
377        goto bad_line;
378    at->mode = *cp;
379#if 0
380    if (at->fs->good_flags) {
381        if (!index(at->fs->good_flags, at->mode))
382            goto bad_line;                      /* Bad attach mode */
383    }
384#endif
385   
386    at->next = NULL;
387    at->prev = NULL;
388    return SUCCESS;
389   
390 bad_line:
391    fprintf(stderr,"Badly formatted entry in %s\n", attachtab_fn);
392    if (lintflag)
393        return FAILURE;
394    fprintf(stderr, abort_msg);
395    exit(ERR_FATAL);
396    /* NOTREACHED */
397}
398
399#if 0
400/*
401 * Routine to see if a host is in the attachtab - uses the linked list
402 * attachtab in memory
403 */
404host_occurs(name)
405    register char *name;
406{
407    register struct _attachtab  *p;
408
409    p = attachtab_first;
410    while (p) {
411        if (!strcasecmp(p->host, name))
412            return(1);
413        p = p->next;
414    }
415    return (0);
416}
417#endif
418
419/*
420 * Lookup an entry in attachtab  --- uses the linked list stored in memory
421 */
422struct _attachtab *attachtab_lookup(hesiod)
423    register char *hesiod;
424{
425    register struct _attachtab  *p;
426
427    p = attachtab_first;
428    while (p) {
429        if (!strcmp(p->hesiodname, hesiod))
430            return(p);
431        p = p->next;
432    }
433    return (NULL);
434}
435
436/*
437 * Lookup an entry in attachtab by mountpoint --- uses the linked list
438 *      stored in memory
439 */
440struct _attachtab *attachtab_lookup_mntpt(pt)
441    register char *pt;
442{
443    register struct _attachtab  *p;
444
445    p = attachtab_first;
446    while (p) {
447        if (!strcmp(p->mntpt, pt))
448            return(p);
449        p = p->next;
450    }
451    return (NULL);
452}
453
454#if 0
455/*
456 * Delete an entry from the attachtab --- unlinks the passed attachtab
457 *      record in the in-core linked list; assumes attachtab is locked.
458 *      You must call put_attachtab to actually affect the copy on disk.
459 */
460attachtab_delete(at)
461    register struct _attachtab  *at;
462{
463    if (!at)
464        return;
465       
466    if (at->prev)
467        at->prev->next = at->next;
468    else
469        attachtab_first = at->next;
470    if (at->next)
471        at->next->prev = at->prev;
472    else
473        attachtab_last = at->prev;
474    free(at);
475}
476
477/*
478 * Append an entry to the linked list database in attachtab
479 */
480attachtab_append(at)
481    register struct _attachtab *at;
482{
483
484    register struct _attachtab *atnew;
485
486    if (!(atnew = (struct _attachtab *)
487          malloc(sizeof(struct _attachtab)))) {
488        fprintf(stderr, "Can't malloc while adding to attachtab\n");
489        fprintf(stderr, abort_msg);
490        exit(ERR_FATAL);
491    }
492    *atnew = *at;
493
494    strcpy(atnew->version, ATTACH_VERSION);
495       
496    if (attachtab_last)
497        attachtab_last ->next = atnew;
498    else
499        attachtab_first = atnew;
500    atnew->prev = attachtab_last;
501    atnew->next = NULL;
502    attachtab_last = atnew;
503}
504
505/*
506 * Replace an entry in the linked list
507 */
508attachtab_replace(at)
509    register struct _attachtab *at;
510{
511    register struct _attachtab *p, *next, *prev;
512
513    strcpy(at->version, ATTACH_VERSION);
514       
515    p = attachtab_first;
516
517    while (p) {
518        if (!hescmp(p, at->hesiodname) && p->explicit == explicit) {
519            next = p->next;
520            prev = p->prev;
521            *p = *at;
522            p->next = next;
523            p->prev = prev;
524        }
525        p = p->next;
526    }
527}
528#endif
529
530
531struct _fstypes fstypes[] = {
532    "NFS", TYPE_NFS,
533    "RVD", TYPE_RVD,
534    "UFS", TYPE_UFS,
535    "ERR", TYPE_ERR,
536    "AFS", TYPE_AFS,
537    "MUL", TYPE_MUL,
538    0, 0 };
539
540/*
541 * Convert a string type to a filesystem type entry
542 */
543struct _fstypes *get_fs(s)
544    char *s;
545{
546    int i;
547
548    if (s && *s) {
549        for (i=0;fstypes[i].name;i++) {
550            if (!strcasecmp(fstypes[i].name, s))
551                return (&fstypes[i]);
552        }
553    }
554    return (NULL);
555}
Note: See TracBrowser for help on using the repository browser.