xref: /openbsd/usr.sbin/amd/amd/am_ops.c (revision 51b02dfe)
1 /*
2  * Copyright (c) 1989 Jan-Simon Pendry
3  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
4  * Copyright (c) 1989, 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: @(#)am_ops.c	8.1 (Berkeley) 6/6/93
35  *	$Id: am_ops.c,v 1.8 2015/12/05 21:15:01 mmcc Exp $
36  */
37 
38 #include "am.h"
39 
40 static am_ops *vops[] = {
41 #ifdef HAS_UFS
42 	&ufs_ops,
43 #endif
44 #ifdef HAS_NFS
45 	&nfs_ops,
46 #endif
47 #ifdef HAS_NFSX
48 	&nfsx_ops,
49 #endif
50 #ifdef HAS_HOST
51 	&host_ops,
52 #endif
53 #ifdef HAS_SFS
54 	&sfs_ops,
55 #endif
56 #ifdef HAS_SFSX
57 	&sfsx_ops,
58 #endif
59 #ifdef HAS_LOFS
60 	&lofs_ops,
61 #endif
62 #ifdef HAS_PFS
63 	&pfs_ops,
64 #endif
65 #ifdef HAS_UNION_FS
66 	&union_ops,
67 #endif
68 	&afs_ops,	/* These four should be last ... */
69 	&dfs_ops,	/* ... */
70 	&toplvl_ops,	/* ... */
71 	&efs_ops,	/* ... in the order afs; dfs; toplvl; efs */
72 	0
73 };
74 
75 void
ops_showfstypes(FILE * fp)76 ops_showfstypes(FILE *fp)
77 {
78 	struct am_ops **ap;
79 	int l = 0;
80 
81 	for (ap = vops; *ap; ap++) {
82 		fputs((*ap)->fs_type, fp);
83 		if (ap[1]) fputs(", ", fp);
84 		l += strlen((*ap)->fs_type) + 2;
85 		if (l > 60) { l = 0; fputs("\n    ", fp); }
86 	}
87 }
88 
89 #ifdef SUNOS4_COMPAT
90 #ifdef nomore
91 /*
92  * Crack a SunOS4-style host:fs:sub-link line
93  * Construct an amd-style line and call the
94  * normal amd matcher.
95  */
96 am_ops *
sunos4_match(am_opts * fo,char * key,char * g_key,char * path,char * keym,char * map)97 sunos4_match(am_opts *fo, char *key, char *g_key, char *path,
98     char *keym, char *map)
99 {
100 	char *host = key;
101 	char *fs = strchr(host, ':');
102 	char *sublink = fs ? strchr(fs+1, ':') : 0;
103 	char keybuf[MAXPATHLEN];
104 
105 	snprintf(keybuf, sizeof(keybuf),
106 		"type:=nfs;rhost:=%s;rfs:=%s;sublink:=%s;opts:=%s", host,
107 		fs ? fs+1 : "",
108 		sublink ? sublink+1  : "",
109 		g_key);
110 	return ops_match(fo, keybuf, "", path, keym, map);
111 }
112 #endif
113 #endif /* SUNOS4_COMPAT */
114 
115 am_ops *
ops_match(am_opts * fo,char * key,char * g_key,char * path,char * keym,char * map)116 ops_match(am_opts *fo, char *key, char *g_key, char *path, char *keym,
117     char *map)
118 {
119 	am_ops **vp;
120 	am_ops *rop = 0;
121 
122 	/*
123 	 * First crack the global opts and the local opts
124 	 */
125 	if (!eval_fs_opts(fo, key, g_key, path, keym, map)) {
126 		rop = &efs_ops;
127 	} else if (fo->opt_type == 0) {
128 		plog(XLOG_USER, "No fs type specified (key = \"%s\", map = \"%s\")", keym, map);
129 		rop = &efs_ops;
130 	} else {
131 		/*
132 		 * Next find the correct filesystem type
133 		 */
134 		for (vp = vops; (rop = *vp); vp++)
135 			if (strcmp(rop->fs_type, fo->opt_type) == 0)
136 				break;
137 
138 		if (!rop) {
139 			plog(XLOG_USER, "fs type \"%s\" not recognised", fo->opt_type);
140 			rop = &efs_ops;
141 		}
142 	}
143 
144 	/*
145 	 * Make sure we have a default mount option.
146 	 * Otherwise skip past any leading '-'.
147 	 */
148 	if (fo->opt_opts == 0)
149 		fo->opt_opts = "rw,defaults";
150 	else if (*fo->opt_opts == '-')
151 		fo->opt_opts++;
152 
153 	/*
154 	 * Check the filesystem is happy
155 	 */
156 	free(fo->fs_mtab);
157 
158 	if ((fo->fs_mtab = (*rop->fs_match)(fo)))
159 		return rop;
160 
161 	/*
162 	 * Return error file system
163 	 */
164 	fo->fs_mtab = (*efs_ops.fs_match)(fo);
165 	return &efs_ops;
166 }
167