source: trunk/athena/bin/attach/ufs.c @ 7152

Revision 7152, 3.9 KB checked in by miki, 30 years ago (diff)
replaced rindex with strrchr
Line 
1/*      Created by:  Theodore Ts'o
2 *
3 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/attach/ufs.c,v $
4 *      $Author: miki $
5 *
6 *      Copyright (c) 1988 by the Massachusetts Institute of Technology.
7 */
8
9#ifndef lint
10static char rcsid_ufs_c[] = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/attach/ufs.c,v 1.5 1994-03-25 15:56:54 miki Exp $";
11#endif
12
13#include "attach.h"
14#include <sys/stat.h>
15#include <sys/wait.h>
16#include <sys/file.h>
17
18#ifdef UFS
19/*
20 * Attach an Unix filesystem
21 */
22
23ufs_attach(at, mopt, errorout)
24        struct _attachtab *at;
25        struct mntopts  *mopt;
26        int errorout;
27{
28    if (at->mode == 'w' && !skip_fsck) {
29            if (perform_fsck(at->hostdir, at->hesiodname, 1) == FAILURE)
30                    return(FAILURE);
31    }
32   
33    /* XXX This is kind of bogus, because if a filesystem has a number
34     * of hesiod entries, and the mount point is busy, each one will
35     * be tried until the last one fails, then an error printed.
36     * C'est la vie.
37     */
38
39    if (mountfs(at, at->hostdir, mopt, errorout) == FAILURE) {
40        return (FAILURE);
41    }
42
43    return (SUCCESS);
44}
45
46/*
47 * Detach a Unix filesystem
48 */
49ufs_detach(at)
50    struct _attachtab *at;
51{
52    if (at->flags & FLAG_PERMANENT) {
53        if (debug_flag)
54            printf("Permanent flag on, skipping umount.\n");
55        return(SUCCESS);
56    }
57       
58    if (unmount_42(at->hesiodname, at->mntpt, at->hostdir) == FAILURE)
59        return (FAILURE);
60
61    return (SUCCESS);
62}
63#endif
64
65/*
66 * Attach an "error" filesystem.
67 * (Print an error message and go away; always fails)
68 * Not strictly UFS, but it's a good place to sneak it in...
69 */
70err_attach(at, mopt, errorout)
71        struct _attachtab *at;
72        struct mntopts  *mopt;
73        int errorout;           /* ignored */
74{
75        fprintf(stderr, "%s: error: %s\n", at->hesiodname, at->hostdir);
76        return(FAILURE);
77}
78
79#if defined(UFS) || defined(RVD)
80/*
81 * Subroutine to check a filesystem with fsck
82 */
83perform_fsck(device, errorname, useraw)
84        char    *device, *errorname;
85        int     useraw;
86{
87        static char     rdevice[512];
88        static char     *fsck_av[4];
89        int     error_ret, save_stderr;
90#ifdef POSIX
91        int     waitb;
92#else
93        union wait      waitb;
94#endif
95
96        strncpy(rdevice, device, sizeof(rdevice));
97       
98        /* Try to generate the raw device, since it's almost always faster */
99        if (useraw) {
100                char    *cpp, *cpp2;
101                struct stat     buf;
102               
103                if (!(cpp = strrchr(rdevice, '/')))
104                        cpp = rdevice;
105                else
106                        cpp++;
107                *cpp++ = 'r';
108                if (!(cpp2 = strrchr(device, '/')))
109                        cpp2 = device;
110                else
111                        cpp2++;
112                (void) strcpy(cpp, cpp2);
113       
114                /*
115                 * Try to stat the constructed rdevice.  If it isn't a
116                 * device file or if it doesn't exist, give up and use
117                 * the original file.
118                 */
119                if (stat(rdevice,&buf) || !(buf.st_mode & (S_IFCHR|S_IFBLK)))
120                        strcpy(rdevice,device);
121        }
122
123        if (debug_flag)
124                printf("performing an fsck on %s\n", rdevice);
125       
126        fsck_av[0] = FSCK_SHORTNAME;
127        fsck_av[1] = "-p";              /* Preen option */
128        fsck_av[2] = rdevice;
129        fsck_av[3] = NULL;
130        switch(vfork()) {
131        case -1:
132                perror("vfork: to fsck");
133                error_status = ERR_ATTACHFSCK;
134                return(FAILURE);
135        case 0:
136                if (!debug_flag) {
137                        save_stderr = dup(2);
138                        close(0);
139                        close(1);
140                        close(2);
141                        open("/dev/null", O_RDWR);
142                        dup(0);
143                        dup(0);
144                }
145
146                execv(FSCK_FULLNAME, fsck_av);
147                if (!debug_flag)
148                        dup2(save_stderr, 2);
149                perror(FSCK_FULLNAME);
150                exit(1);
151                /*NOTREACHED*/
152        default:
153                if (wait(&waitb) < 0) {
154                        perror("wait: for fsck");
155                        error_status = ERR_ATTACHFSCK;
156                        return(FAILURE);
157                }
158        }
159       
160#ifdef POSIX
161        if ((error_ret = WEXITSTATUS(waitb))) {
162#else
163        if (error_ret = waitb.w_retcode) {
164#endif
165                fprintf(stderr,
166                        "%s: fsck returned a bad exit status (%d)\n",
167                        errorname, error_ret);
168                error_status = ERR_ATTACHFSCK;
169                return (FAILURE);
170        }
171        return(SUCCESS);
172}
173
174/*
175 * Parsing of explicit UFS file types
176 */
177char **ufs_explicit(name)
178    char *name;
179{
180    extern char *exp_hesptr[2];
181       
182    sprintf(exp_hesline, "UFS %s %c %s", name, override_mode ?
183            override_mode : 'w', mntpt ? mntpt : "/mnt");
184    exp_hesptr[0] = exp_hesline;
185    exp_hesptr[1] = 0;
186    return(exp_hesptr);
187}
188
189#endif
Note: See TracBrowser for help on using the repository browser.