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