source: trunk/athena/bin/attach/attach.c @ 7153

Revision 7153, 10.9 KB checked in by miki, 30 years ago (diff)
replaced bzero with memset
Line 
1/*      Created by:     Robert French
2 *
3 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/attach/attach.c,v $
4 *      $Author: miki $
5 *
6 *      Copyright (c) 1988 by the Massachusetts Institute of Technology.
7 */
8
9#ifndef lint
10static char rcsid_attach_c[] = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/attach/attach.c,v 1.18 1994-03-25 15:57:14 miki Exp $";
11#endif
12
13#include "attach.h"
14#include <signal.h>
15
16extern int mul_attach();
17
18/*
19 * Attempt to attach a filesystem.  Lookup the name with Hesiod as
20 * necessary, and try all possible results in order.  Also handles
21 * the explicit flag for explicitly defined hostname/directory
22 * arguments.  Branches to NFS or RVD attach routines as necessary.
23 */
24
25attach(name)
26    const char *name;
27{
28    struct _attachtab at, *atp;
29    char **hes;
30    int i;
31    int print_wait;
32    extern int caught_signal;
33       
34    hes = build_hesiod_line(name);
35
36    if (!hes || !*hes) {
37        error_status = ERR_ATTACHBADFILSYS;
38        return (FAILURE);
39    }
40
41    if (lookup || debug_flag) {
42        printf("%s resolves to:\n", name);
43        for (i=0;hes[i];i++)
44            printf("%s\n", hes[i]);
45        putchar('\n');
46    }
47
48    if (lookup)
49            return(SUCCESS);
50
51    print_wait = 2;
52retry:
53    lock_attachtab();
54    get_attachtab();
55    if (atp = attachtab_lookup(name)) {
56        switch (atp->status) {
57        case STATUS_ATTACHING:
58            if (!force && really_in_use(name)) {
59                unlock_attachtab();
60                free_attachtab();
61                if (print_path) {
62                        sleep(print_wait);  /* Wait a few seconds */
63                        if (print_wait < 30)
64                                print_wait *= 2;
65                        goto retry;
66                }
67                fprintf(stderr,
68                        "%s: Filesystem \"%s\" already being attached by another process\n",
69                        progname, name);
70                error_status = ERR_ATTACHINUSE;
71                return (FAILURE);
72            }
73            attachtab_delete(atp);
74            put_attachtab();
75            break;
76        case STATUS_DETACHING:
77            if (!force && really_in_use(name)) {
78                fprintf(stderr, "%s: Filesystem \"%s\" is being detached by another process\n",
79                        progname, name);
80                error_status = ERR_ATTACHINUSE;
81                unlock_attachtab();
82                free_attachtab();
83                return (FAILURE);
84            }
85            attachtab_delete(atp);
86            put_attachtab();
87            break;
88        case STATUS_ATTACHED:
89            if (force)
90                break;
91            if (lock_filesystem)
92                    atp->flags |= FLAG_LOCKED;
93            if (owner_list)
94                    add_an_owner(atp,owner_uid);
95            if (owner_list || lock_filesystem)
96                    put_attachtab();
97            unlock_attachtab();
98
99            if (atp->fs->type == TYPE_MUL)
100                return mul_attach(atp, (struct mntopts *)0, 0);
101           
102            if (print_path)
103                printf("%s\n", atp->mntpt);
104            else if(verbose)
105                printf("%s: Filesystem \"%s\" is already attached", progname, name);
106#ifdef NFS
107            if (map_anyway && atp->mode != 'n' && atp->fs->type == TYPE_NFS) {
108                int ret;
109                if (verbose && !print_path)
110                    printf(" (mapping)\n");
111               
112                ret = nfsid(atp->host, atp->hostaddr[0],
113                            MOUNTPROC_KUIDMAP, 1, name, 1, real_uid);
114                if(atp->mode != 'm')
115                  return ret;
116                if (ret == FAILURE)
117                  {
118                    error_status = 0;
119                    clear_errored(atp->hostaddr[0]);
120                  }
121                return SUCCESS;
122            }
123#endif
124#ifdef AFS
125            if (map_anyway && atp->mode != 'n' && atp->fs->type == TYPE_AFS) {
126                    if (verbose && !print_path)
127                            printf(" (authenticating)\n");
128                    return(afs_auth(atp->hesiodname, atp->hostdir));
129            }
130#endif
131            if (verbose && !print_path)
132                putchar('\n');
133            /* No error code set on already attached */
134            free_attachtab();
135            return (FAILURE);
136        }
137    }
138
139    /* Note: attachtab is still locked at this point */
140   
141    /* We don't really care about ANY of the values besides status */
142    at.status = STATUS_ATTACHING;
143    at.explicit = explicit;
144    at.fs = NULL;
145    strcpy(at.hesiodname, name);
146    strcpy(at.host, "?");
147    strcpy(at.hostdir, "?");
148    memset((char *)&at.hostaddr, 0, sizeof(at.hostaddr));
149    at.rmdir = 0;
150    at.drivenum = 0;
151    at.mode = 'r';
152    at.flags = 0;
153    at.nowners = 1;
154    at.owners[0] = owner_uid;
155    strcpy(at.mntpt, "?");
156
157    /*
158     * Mark the filsys as "being attached".
159     */
160    start_critical_code();      /* Don't let us be interrupted */
161    mark_in_use(name);
162    attachtab_append(&at);
163    put_attachtab();
164    unlock_attachtab();
165
166   for (i=0;hes[i];i++) {
167        if (debug_flag)
168            printf("Processing line %s\n", hes[i]);
169        if (caught_signal) {
170                if (debug_flag)
171                        printf("Caught signal; cleaning up attachtab....\n");
172                free_attachtab();
173                lock_attachtab();
174                get_attachtab();
175                attachtab_delete(attachtab_lookup(at.hesiodname));
176                put_attachtab();
177                unlock_attachtab();
178                free_attachtab();
179                terminate_program();
180        }
181        /*
182         * Note try_attach will change attachtab appropriately if
183         * successful.
184         */
185        if (try_attach(name, hes[i], !hes[i+1]) == SUCCESS) {
186                free_attachtab();
187                mark_in_use(NULL);
188                end_critical_code();
189                return (SUCCESS);
190        }
191    }
192    free_attachtab();
193
194    if (error_status == ERR_ATTACHNOTALLOWED)
195            fprintf(stderr, "%s: You are not allowed to attach %s.\n",
196                    progname, name);
197
198    if (error_status == ERR_ATTACHBADMNTPT)
199            fprintf(stderr,
200                    "%s: You are not allowed to attach a filesystem here\n",
201                    progname);
202    /*
203     * We've failed -- delete the partial entry and unlock the in-use file.
204     */
205    lock_attachtab();
206    get_attachtab();
207    attachtab_delete(attachtab_lookup(at.hesiodname));
208    put_attachtab();
209    mark_in_use(NULL);
210    unlock_attachtab();
211    free_attachtab();
212    end_critical_code();
213
214    /* Assume error code already set by whatever made us fail */
215    return (FAILURE);
216}
217
218/*
219 * Given a Hesiod line and a filesystem name, try to attach it.  If
220 * successful, change the attachtab accordingly.
221 */
222
223try_attach(name, hesline, errorout)
224    char *name, *hesline;
225    int errorout;
226{
227    struct _attachtab at, *atp;
228    int status;
229    int attach_suid;
230#ifdef ZEPHYR
231    char instbfr[BUFSIZ];
232#endif
233    struct mntopts      mopt;
234    char        *default_options;
235
236    if (parse_hes(hesline, &at, name)) {
237            error_status = ERR_BADFSDSC;
238            return(FAILURE);
239    }
240    if (filsys_type && *filsys_type && strcasecmp(filsys_type, at.fs->name)) {
241            error_status = ERR_ATTACHBADFILSYS;
242            return FAILURE;
243    }
244    if (!override && !allow_filsys(name, at.fs->type)) {
245            error_status = ERR_ATTACHNOTALLOWED;
246            return(FAILURE);
247    }
248
249    at.status = STATUS_ATTACHING;
250    at.explicit = explicit;
251    strcpy(at.hesiodname, name);
252    add_an_owner(&at, owner_uid);
253
254    if (mntpt)
255        strcpy(at.mntpt, mntpt);
256
257    /*
258     * Note if a filesystem does nothave AT_FS_MNTPT_CANON as a property,
259     * it must also somehow call check_mntpt, if it wants mountpoint
260     * checking to happen at all.
261     */
262    if (at.fs->flags & AT_FS_MNTPT_CANON) {
263            char *path;
264
265            /* Perform path canonicalization */
266            if ((path = path_canon(at.mntpt)) == NULL) {
267                    fprintf(stderr, "%s: Cannot get information about the mountpoint %s\n",
268                            at.hesiodname, at.mntpt);
269                    error_status = ERR_SOMETHING;
270                    return(FAILURE);
271            }
272            strcpy(at.mntpt, path);
273            if (debug_flag)
274                    printf("Mountpoint canonicalized as: %s\n", at.mntpt);
275            if (!override && !check_mountpt(at.mntpt, at.fs->type)) {
276                    error_status = ERR_ATTACHBADMNTPT;
277                    return(FAILURE);
278            }
279    }
280   
281    if (at.fs->flags & AT_FS_MNTPT && (atp=attachtab_lookup_mntpt(at.mntpt))) {
282            fprintf(stderr,"%s: Filesystem %s is already mounted on %s\n",
283                    at.hesiodname, atp->hesiodname, at.mntpt);
284            error_status = ERR_ATTACHDIRINUSE;
285            return(FAILURE);
286    }
287
288    if (override_mode)
289        at.mode = override_mode;
290       
291    if (override_suid == -1)
292            attach_suid = !nosetuid_filsys(name, at.fs->type);
293    else
294            attach_suid = override_suid;
295    at.flags = (attach_suid ? 0 : FLAG_NOSETUID) +
296            (lock_filesystem ? FLAG_LOCKED : 0);
297
298    /* Prepare mount options structure */
299    memset(&mopt, 0, sizeof(mopt));
300    mopt.type = at.fs->mount_type;
301   
302    /* Read in default options */
303    default_options = filsys_options(at.hesiodname, at.fs->type);
304    add_options(&mopt, "soft");         /* Soft by default */
305    if (mount_options && *mount_options)
306            add_options(&mopt, mount_options);
307    if (default_options && *default_options)
308            add_options(&mopt, default_options);
309   
310    if (at.mode == 'r')
311            add_options(&mopt, "ro");
312    if (at.flags & FLAG_NOSETUID)
313            add_options(&mopt, "nosuid");
314       
315    if (at.fs->attach) {
316            if (at.fs->flags & AT_FS_MNTPT) {
317                    if (make_mntpt(&at) == FAILURE) {
318                            rm_mntpt(&at);
319                            return (FAILURE);
320                    }
321            }
322            status = (at.fs->attach)(&at, &mopt, errorout);
323    } else {
324            fprintf(stderr,
325                    "%s: Can't attach filesystem type \"%s\"\n",
326                    progname, at.fs->name);
327            status = ERR_FATAL;
328            return(FAILURE);
329    }
330   
331    if (status == SUCCESS) {
332        char    tmp[BUFSIZ];
333        if (at.fs->flags & AT_FS_REMOTE)
334                sprintf(tmp, "%s:%s", at.host, at.hostdir);
335        else
336                strcpy(tmp, at.hostdir);
337        if (verbose)
338                if(at.fs->type == TYPE_AFS)
339                  printf("%s: %s linked to %s for filesystem %s\n", progname,
340                         tmp, at.mntpt, at.hesiodname);
341                else
342                  printf("%s: filesystem %s (%s) mounted on %s (%s)\n",
343                         progname, at.hesiodname, tmp,
344                         at.mntpt, (mopt.flags & M_RDONLY) ? "read-only" :
345                         "read-write");
346        if (print_path)
347                printf("%s\n", at.mntpt);
348        at.status = STATUS_ATTACHED;
349        lock_attachtab();
350        get_attachtab();
351        attachtab_replace(&at);
352        put_attachtab();
353        unlock_attachtab();
354        /*
355         * Do Zephyr stuff as necessary
356         */
357#ifdef ZEPHYR
358        if (use_zephyr && at.fs->flags & AT_FS_REMOTE) {
359                if(at.fs->type == TYPE_AFS) {
360                        afs_zinit(at.hesiodname, at.hostdir);
361                } else {
362                        sprintf(instbfr, "%s:%s", at.host, at.hostdir);
363                        zephyr_addsub(instbfr);
364                        zephyr_addsub(at.host);
365                }
366        }
367#endif
368        free_attachtab();
369    } else
370            if (at.fs->flags & AT_FS_MNTPT)
371                    rm_mntpt(&at);
372    return (status);
373}
374
375
376char *attach_list_format = "%-22s %-22s %c%-18s%s\n";
377
378int attach_print(host)
379    char *host;
380{
381    static int print_banner = 1;
382    struct _attachtab *atp;
383    extern struct _attachtab *attachtab_first;
384    char optstr[40];
385    int bad = 0;
386    int i;
387
388    lock_attachtab();
389    get_attachtab();
390    unlock_attachtab();
391    atp = attachtab_first;
392    if (!atp) {
393        printf("No filesystems currently attached.\n");
394        free_attachtab();
395        return(ERR_NONE);
396    }
397    if (print_banner) {
398        printf(attach_list_format, "filesystem", "mountpoint",
399               ' ', "user", "mode");
400        printf(attach_list_format, "----------", "----------",
401               ' ', "----", "----");
402        print_banner = 0;
403    }
404    while (atp) {
405        optstr[0] = atp->mode;
406        optstr[1] = '\0';
407        if (atp->flags & FLAG_NOSETUID)
408            strcat(optstr, ",nosuid");
409        if (atp->flags & FLAG_LOCKED)
410            strcat(optstr, ",locked");
411        if (atp->flags & FLAG_PERMANENT)
412            strcat(optstr, ",perm");
413        if (host) {
414            bad = 1;
415            for (i=0; i<MAXHOSTS && atp->hostaddr[i].s_addr; i++) {
416                if (host_compare(host, inet_ntoa(atp->hostaddr[i]))) {
417                    bad = 0;
418                    break;
419                }
420            }
421        }
422        if (!bad && atp->status == STATUS_ATTACHED) {
423            printf(attach_list_format, atp->hesiodname,
424                   (atp->fs->type&TYPE_MUL) ? "-" : atp->mntpt,
425                   atp->flags & FLAG_ANYONE ? '*' : ' ',
426                   ownerlist(atp), optstr);
427        }
428        atp = atp->next;
429    }
430    free_attachtab();
431    return (ERR_NONE);
432}
Note: See TracBrowser for help on using the repository browser.