1 /*
2 * Copyright (c) 1990 Jan-Simon Pendry
3 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Jan-Simon Pendry at Imperial College, London.
9 *
10 * %sccs.include.redist.c%
11 *
12 * @(#)sfs_ops.c 8.1 (Berkeley) 06/06/93
13 *
14 * $Id: sfs_ops.c,v 5.2.2.1 1992/02/09 15:09:04 jsp beta $
15 *
16 */
17
18 #include "am.h"
19
20 #if defined(HAS_SFS) || defined(HAS_SFSX)
21 #define NEED_SFS_MATCH
22 #define NEED_SFS_UMOUNT
23 #endif
24
25 /*
26 * Symbol-link file system
27 */
28
29 #ifdef HAS_SFSX
30 #include <sys/stat.h>
31 #endif
32
33 #ifdef NEED_SFS_MATCH
34 /*
35 * SFS needs a link.
36 */
sfs_match(fo)37 static char *sfs_match(fo)
38 am_opts *fo;
39 {
40 if (!fo->opt_fs) {
41 plog(XLOG_USER, "link: no fs specified");
42 return 0;
43 }
44
45 /*
46 * Bug report (14/12/89) from Jay Plett <jay@princeton.edu>
47 * If an automount point has the same name as an existing
48 * link type mount Amd hits a race condition and either hangs
49 * or causes a symlink loop.
50 *
51 * If fs begins with a '/' change the opt_fs & opt_sublink
52 * fields so that the fs option doesn't end up pointing at
53 * an existing symlink.
54 *
55 * If sublink is nil then set sublink to fs
56 * else set sublink to fs / sublink
57 *
58 * Finally set fs to ".".
59 */
60 if (*fo->opt_fs == '/') {
61 char *fullpath;
62 char *link = fo->opt_sublink;
63 if (link) {
64 if (*link == '/')
65 fullpath = strdup(link);
66 else
67 fullpath = str3cat((char *)0, fo->opt_fs, "/", link);
68 } else {
69 fullpath = strdup(fo->opt_fs);
70 }
71
72 if (fo->opt_sublink)
73 free(fo->opt_sublink);
74 fo->opt_sublink = fullpath;
75 fo->opt_fs = str3cat(fo->opt_fs, ".", fullpath, "");
76 }
77
78 return strdup(fo->opt_fs);
79 }
80 #endif
81
82 #ifdef HAS_SFSX
83 /*ARGUSED*/
84 static int sfsx_mount P((am_node *mp));
sfsx_mount(mp)85 static int sfsx_mount(mp)
86 am_node *mp;
87 {
88 /*
89 * Check for existence of target.
90 */
91 struct stat stb;
92 char *ln;
93
94 if (mp->am_link)
95 ln = mp->am_link;
96 else /* should never occur */
97 ln = mp->am_mnt->mf_mount;
98
99 /*
100 * Use lstat, not stat, since we don't
101 * want to know if the ultimate target of
102 * a symlink chain exists, just the first.
103 */
104 if (lstat(ln, &stb) < 0)
105 return errno;
106
107 return 0;
108 }
109 #endif
110
111 #ifdef HAS_SFS
112 /*ARGUSED*/
sfs_fmount(mf)113 static int sfs_fmount(mf)
114 mntfs *mf;
115 {
116 /*
117 * Wow - this is hard to implement!
118 */
119
120 return 0;
121 }
122 #endif
123
124 #ifdef NEED_SFS_UMOUNT
125 /*ARGUSED*/
sfs_fumount(mf)126 static int sfs_fumount(mf)
127 mntfs *mf;
128 {
129 return 0;
130 }
131 #endif
132
133 /*
134 * Ops structures
135 */
136 #ifdef HAS_SFS
137 am_ops sfs_ops = {
138 "link",
139 sfs_match,
140 0, /* sfs_init */
141 auto_fmount,
142 sfs_fmount,
143 auto_fumount,
144 sfs_fumount,
145 efs_lookuppn,
146 efs_readdir,
147 0, /* sfs_readlink */
148 0, /* sfs_mounted */
149 0, /* sfs_umounted */
150 find_afs_srvr,
151 #ifdef FLUSH_KERNEL_NAME_CACHE
152 FS_UBACKGROUND
153 #else /* FLUSH_KERNEL_NAME_CACHE */
154 0
155 #endif /* FLUSH_KERNEL_NAME_CACHE */
156 };
157
158 #endif /* HAS_SFS */
159
160 #ifdef HAS_SFSX
161 struct am_ops sfsx_ops = {
162 "linkx",
163 sfs_match,
164 0, /* sfsx_init */
165 sfsx_mount,
166 0,
167 auto_fumount,
168 sfs_fumount,
169 efs_lookuppn,
170 efs_readdir,
171 0, /* sfsx_readlink */
172 0, /* sfsx_mounted */
173 0, /* sfsx_umounted */
174 find_afs_srvr,
175 #ifdef FLUSH_KERNEL_NAME_CACHE
176 FS_BACKGROUND
177 #else /* FLUSH_KERNEL_NAME_CACHE */
178 FS_MBACKGROUND
179 #endif /* FLUSH_KERNEL_NAME_CACHE */
180 };
181
182 #endif /* HAS_SFSX */
183