xref: /original-bsd/usr.sbin/amd/amd/sfs_ops.c (revision c3e32dec)
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  */
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));
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*/
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*/
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