xref: /openbsd-src/usr.sbin/amd/amd/sfs_ops.c (revision c9899b11e3d79a7bf5a70dcb12f582cc0994240e)
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  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *	from: @(#)sfs_ops.c	8.1 (Berkeley) 6/6/93
35  *	$Id: sfs_ops.c,v 1.6 2016/03/16 15:41:11 krw Exp $
36  */
37 
38 #include "am.h"
39 
40 #if defined(HAS_SFS) || defined(HAS_SFSX)
41 #define NEED_SFS_MATCH
42 #define NEED_SFS_UMOUNT
43 #endif
44 
45 /*
46  * Symbol-link file system
47  */
48 
49 #ifdef HAS_SFSX
50 #include <sys/stat.h>
51 #endif
52 
53 #ifdef NEED_SFS_MATCH
54 /*
55  * SFS needs a link.
56  */
57 static char *
sfs_match(am_opts * fo)58 sfs_match(am_opts *fo)
59 {
60 	if (!fo->opt_fs) {
61 		plog(XLOG_USER, "link: no fs specified");
62 		return 0;
63 	}
64 
65 	/*
66 	 * Bug report (14/12/89) from Jay Plett <jay@princeton.edu>
67 	 * If an automount point has the same name as an existing
68 	 * link type mount Amd hits a race condition and either hangs
69 	 * or causes a symlink loop.
70 	 *
71 	 * If fs begins with a '/' change the opt_fs & opt_sublink
72 	 * fields so that the fs option doesn't end up pointing at
73 	 * an existing symlink.
74 	 *
75 	 * If sublink is nil then set sublink to fs
76 	 * else set sublink to fs / sublink
77 	 *
78 	 * Finally set fs to ".".
79 	 */
80 	if (*fo->opt_fs == '/') {
81 		char *fullpath;
82 		char *link = fo->opt_sublink;
83 		if (link) {
84 			if (*link == '/')
85 				fullpath = strdup(link);
86 			else
87 				fullpath = str3cat(NULL, fo->opt_fs, "/", link);
88 		} else {
89 			fullpath = strdup(fo->opt_fs);
90 		}
91 
92 		free(fo->opt_sublink);
93 		fo->opt_sublink = fullpath;
94 		fo->opt_fs = str3cat(fo->opt_fs, ".", fullpath, "");
95 	}
96 
97 	return strdup(fo->opt_fs);
98 }
99 #endif
100 
101 #ifdef HAS_SFSX
102 static int
sfsx_mount(am_node * mp)103 sfsx_mount(am_node *mp)
104 {
105 	/*
106 	 * Check for existence of target.
107 	 */
108 	struct stat stb;
109 	char *ln;
110 
111 	if (mp->am_link)
112 		ln = mp->am_link;
113 	else /* should never occur */
114 		ln = mp->am_mnt->mf_mount;
115 
116 	/*
117 	 * Use lstat, not stat, since we don't
118 	 * want to know if the ultimate target of
119 	 * a symlink chain exists, just the first.
120 	 */
121 	if (lstat(ln, &stb) < 0)
122 		return errno;
123 
124 	return 0;
125 }
126 #endif
127 
128 #ifdef HAS_SFS
129 static int
sfs_fmount(mntfs * mf)130 sfs_fmount(mntfs *mf)
131 {
132 	/*
133 	 * Wow - this is hard to implement!
134 	 */
135 
136 	return 0;
137 }
138 #endif
139 
140 #ifdef NEED_SFS_UMOUNT
141 static int
sfs_fumount(mntfs * mf)142 sfs_fumount(mntfs *mf)
143 {
144 	return 0;
145 }
146 #endif
147 
148 /*
149  * Ops structures
150  */
151 #ifdef HAS_SFS
152 am_ops sfs_ops = {
153 	"link",
154 	sfs_match,
155 	0, /* sfs_init */
156 	auto_fmount,
157 	sfs_fmount,
158 	auto_fumount,
159 	sfs_fumount,
160 	efs_lookuppn,
161 	efs_readdir,
162 	0, /* sfs_readlink */
163 	0, /* sfs_mounted */
164 	0, /* sfs_umounted */
165 	find_afs_srvr,
166 #ifdef FLUSH_KERNEL_NAME_CACHE
167 	FS_UBACKGROUND
168 #else /* FLUSH_KERNEL_NAME_CACHE */
169 	0
170 #endif /* FLUSH_KERNEL_NAME_CACHE */
171 };
172 
173 #endif /* HAS_SFS */
174 
175 #ifdef HAS_SFSX
176 struct am_ops sfsx_ops = {
177 	"linkx",
178 	sfs_match,
179 	0, /* sfsx_init */
180 	sfsx_mount,
181 	0,
182 	auto_fumount,
183 	sfs_fumount,
184 	efs_lookuppn,
185 	efs_readdir,
186 	0, /* sfsx_readlink */
187 	0, /* sfsx_mounted */
188 	0, /* sfsx_umounted */
189 	find_afs_srvr,
190 #ifdef FLUSH_KERNEL_NAME_CACHE
191 	FS_BACKGROUND
192 #else /* FLUSH_KERNEL_NAME_CACHE */
193 	FS_MBACKGROUND
194 #endif /* FLUSH_KERNEL_NAME_CACHE */
195 };
196 
197 #endif /* HAS_SFSX */
198