xref: /openbsd-src/usr.sbin/amd/amd/pfs_ops.c (revision 26d0c865b2e28f6e7d4c71090534c37cab976ea0)
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: @(#)pfs_ops.c	8.1 (Berkeley) 6/6/93
35  *	$Id: pfs_ops.c,v 1.8 2014/10/26 03:28:41 guenther Exp $
36  */
37 
38 #include "am.h"
39 
40 #include <unistd.h>
41 
42 #ifdef HAS_PFS
43 
44 /*
45  * Program file system
46  */
47 
48 /*
49  * Execute needs a mount and unmount command.
50  */
51 static char *
pfs_match(am_opts * fo)52 pfs_match(am_opts *fo)
53 {
54 	char *prog;
55 
56 	if (!fo->opt_mount || !fo->opt_unmount) {
57 		plog(XLOG_USER, "program: no mount/unmount specified");
58 		return 0;
59 	}
60 	prog = strchr(fo->opt_mount, ' ');
61 	return strdup(prog ? prog+1 : fo->opt_mount);
62 }
63 
64 static int
pfs_init(mntfs * mf)65 pfs_init(mntfs *mf)
66 {
67 	/*
68 	 * Save unmount command
69 	 */
70 	if (mf->mf_refc == 1) {
71 		mf->mf_private = strdup(mf->mf_fo->opt_unmount);
72 		mf->mf_prfree = free;
73 	}
74 	return 0;
75 }
76 
77 static int
pfs_exec(char * info)78 pfs_exec(char *info)
79 {
80 	char **xivec;
81 	int error;
82 	/*
83 	 * Split copy of command info string
84 	 */
85 	info = strdup(info);
86 	if (info == 0)
87 		return ENOBUFS;
88 	xivec = strsplit(info, ' ', '\'');
89 	/*
90 	 * Put stdout to stderr
91 	 */
92 	(void) fclose(stdout);
93 	(void) dup(fileno(logfp));
94 	if (fileno(logfp) != fileno(stderr)) {
95 		(void) fclose(stderr);
96 		(void) dup(fileno(logfp));
97 	}
98 	/*
99 	 * Try the exec
100 	 */
101 #ifdef DEBUG
102 	Debug(D_FULL) {
103 		char **cp = xivec;
104 		plog(XLOG_DEBUG, "executing (un)mount command...");
105 		while (*cp) {
106 			plog(XLOG_DEBUG, "arg[%d] = '%s'", cp-xivec, *cp);
107 			cp++;
108 		}
109 	}
110 #endif /* DEBUG */
111 	if (xivec[0] == 0 || xivec[1] == 0) {
112 		errno = EINVAL;
113 		plog(XLOG_USER, "1st/2nd args missing to (un)mount program");
114 	} else {
115 		(void) execv(xivec[0], xivec+1);
116 	}
117 	/*
118 	 * Save error number
119 	 */
120 	error = errno;
121 	plog(XLOG_ERROR, "exec failed: %m");
122 
123 	/*
124 	 * Free allocate memory
125 	 */
126 	free(info);
127 	free(xivec);
128 	/*
129 	 * Return error
130 	 */
131 	return error;
132 }
133 
134 static int
pfs_fmount(mntfs * mf)135 pfs_fmount(mntfs *mf)
136 {
137 	return pfs_exec(mf->mf_fo->opt_mount);
138 }
139 
140 static int
pfs_fumount(mntfs * mf)141 pfs_fumount(mntfs *mf)
142 {
143 	return pfs_exec((char *) mf->mf_private);
144 }
145 
146 /*
147  * Ops structure
148  */
149 am_ops pfs_ops = {
150 	"program",
151 	pfs_match,
152 	pfs_init,
153 	auto_fmount,
154 	pfs_fmount,
155 	auto_fumount,
156 	pfs_fumount,
157 	efs_lookuppn,
158 	efs_readdir,
159 	0, /* pfs_readlink */
160 	0, /* pfs_mounted */
161 	0, /* pfs_umounted */
162 	find_afs_srvr,
163 	FS_BACKGROUND|FS_AMQINFO
164 };
165 
166 #endif /* HAS_PFS */
167