138494Sobrien/* 2174294Sobrien * Copyright (c) 1997-2006 Erez Zadok 338494Sobrien * Copyright (c) 1989 Jan-Simon Pendry 438494Sobrien * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 538494Sobrien * Copyright (c) 1989 The Regents of the University of California. 638494Sobrien * All rights reserved. 738494Sobrien * 838494Sobrien * This code is derived from software contributed to Berkeley by 938494Sobrien * Jan-Simon Pendry at Imperial College, London. 1038494Sobrien * 1138494Sobrien * Redistribution and use in source and binary forms, with or without 1238494Sobrien * modification, are permitted provided that the following conditions 1338494Sobrien * are met: 1438494Sobrien * 1. Redistributions of source code must retain the above copyright 1538494Sobrien * notice, this list of conditions and the following disclaimer. 1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1738494Sobrien * notice, this list of conditions and the following disclaimer in the 1838494Sobrien * documentation and/or other materials provided with the distribution. 1938494Sobrien * 3. All advertising materials mentioning features or use of this software 2042629Sobrien * must display the following acknowledgment: 2138494Sobrien * This product includes software developed by the University of 2238494Sobrien * California, Berkeley and its contributors. 2338494Sobrien * 4. Neither the name of the University nor the names of its contributors 2438494Sobrien * may be used to endorse or promote products derived from this software 2538494Sobrien * without specific prior written permission. 2638494Sobrien * 2738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2938494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3038494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3738494Sobrien * SUCH DAMAGE. 3838494Sobrien * 3938494Sobrien * 40174294Sobrien * File: am-utils/amd/amfs_program.c 4138494Sobrien * 4238494Sobrien */ 4338494Sobrien 4438494Sobrien/* 4538494Sobrien * Program file system 4638494Sobrien */ 4738494Sobrien 4838494Sobrien#ifdef HAVE_CONFIG_H 4938494Sobrien# include <config.h> 5038494Sobrien#endif /* HAVE_CONFIG_H */ 5138494Sobrien#include <am_defs.h> 5238494Sobrien#include <amd.h> 5338494Sobrien 5438494Sobrien/* forward definitions */ 5538494Sobrienstatic char *amfs_program_match(am_opts *fo); 56174294Sobrienstatic int amfs_program_mount(am_node *am, mntfs *mf); 57174294Sobrienstatic int amfs_program_umount(am_node *am, mntfs *mf); 5838494Sobrienstatic int amfs_program_init(mntfs *mf); 5938494Sobrien 6038494Sobrien/* 6138494Sobrien * Ops structure 6238494Sobrien */ 6338494Sobrienam_ops amfs_program_ops = 6438494Sobrien{ 6538494Sobrien "program", 6638494Sobrien amfs_program_match, 6738494Sobrien amfs_program_init, 68174294Sobrien amfs_program_mount, 69174294Sobrien amfs_program_umount, 70174294Sobrien amfs_error_lookup_child, 71174294Sobrien amfs_error_mount_child, 7238494Sobrien amfs_error_readdir, 7338494Sobrien 0, /* amfs_program_readlink */ 7438494Sobrien 0, /* amfs_program_mounted */ 7538494Sobrien 0, /* amfs_program_umounted */ 76174294Sobrien amfs_generic_find_srvr, 77174294Sobrien 0, /* amfs_program_get_wchan */ 78174294Sobrien FS_MKMNT | FS_BACKGROUND | FS_AMQINFO, /* nfs_fs_flags */ 79174294Sobrien#ifdef HAVE_FS_AUTOFS 80174294Sobrien AUTOFS_PROGRAM_FS_FLAGS, 81174294Sobrien#endif /* HAVE_FS_AUTOFS */ 8238494Sobrien}; 8338494Sobrien 8438494Sobrien 8538494Sobrien/* 8638494Sobrien * Execute needs a mount and unmount command. 8738494Sobrien */ 8838494Sobrienstatic char * 8938494Sobrienamfs_program_match(am_opts *fo) 9038494Sobrien{ 9138494Sobrien char *prog; 9238494Sobrien 93174294Sobrien if (fo->opt_unmount && fo->opt_umount) { 94174294Sobrien plog(XLOG_ERROR, "program: cannot specify both unmount and umount options"); 9538494Sobrien return 0; 9638494Sobrien } 97174294Sobrien if (!fo->opt_mount) { 98174294Sobrien plog(XLOG_ERROR, "program: must specify mount command"); 99174294Sobrien return 0; 100174294Sobrien } 101174294Sobrien if (!fo->opt_unmount && !fo->opt_umount) { 102174294Sobrien fo->opt_unmount = str3cat(NULL, UNMOUNT_PROGRAM, " umount ", fo->opt_fs); 103174294Sobrien plog(XLOG_INFO, "program: un/umount not specified; using default \"%s\"", 104174294Sobrien fo->opt_unmount); 105174294Sobrien } 10638494Sobrien prog = strchr(fo->opt_mount, ' '); 10738494Sobrien 10838494Sobrien return strdup(prog ? prog + 1 : fo->opt_mount); 10938494Sobrien} 11038494Sobrien 11138494Sobrien 11238494Sobrienstatic int 11338494Sobrienamfs_program_init(mntfs *mf) 11438494Sobrien{ 115174294Sobrien /* check if already saved value */ 116174294Sobrien if (mf->mf_private != NULL) 117174294Sobrien return 0; 11838494Sobrien 119174294Sobrien /* save unmount (or umount) command */ 120174294Sobrien if (mf->mf_fo->opt_unmount != NULL) 121174294Sobrien mf->mf_private = (opaque_t) strdup(mf->mf_fo->opt_unmount); 122174294Sobrien else 123174294Sobrien mf->mf_private = (opaque_t) strdup(mf->mf_fo->opt_umount); 124174294Sobrien mf->mf_prfree = (void (*)(opaque_t)) free; 125174294Sobrien 12638494Sobrien return 0; 12738494Sobrien} 12838494Sobrien 12938494Sobrien 13038494Sobrienstatic int 13138494Sobrienamfs_program_exec(char *info) 13238494Sobrien{ 13338494Sobrien char **xivec; 13438494Sobrien int error; 13538494Sobrien 13638494Sobrien /* 13738494Sobrien * Split copy of command info string 13838494Sobrien */ 13938494Sobrien info = strdup(info); 14038494Sobrien if (info == 0) 14138494Sobrien return ENOBUFS; 14238494Sobrien xivec = strsplit(info, ' ', '\''); 14338494Sobrien 14438494Sobrien /* 14538494Sobrien * Put stdout to stderr 14638494Sobrien */ 14738494Sobrien (void) fclose(stdout); 14851292Sobrien if (!logfp) 14951292Sobrien logfp = stderr; /* initialize before possible first use */ 15038494Sobrien (void) dup(fileno(logfp)); 15138494Sobrien if (fileno(logfp) != fileno(stderr)) { 15238494Sobrien (void) fclose(stderr); 15338494Sobrien (void) dup(fileno(logfp)); 15438494Sobrien } 15538494Sobrien 15638494Sobrien /* 15738494Sobrien * Try the exec 15838494Sobrien */ 159174294Sobrien if (amuDebug(D_FULL)) { 16038494Sobrien char **cp = xivec; 16138494Sobrien plog(XLOG_DEBUG, "executing (un)mount command..."); 16238494Sobrien while (*cp) { 16351292Sobrien plog(XLOG_DEBUG, "arg[%ld] = '%s'", (long) (cp - xivec), *cp); 16438494Sobrien cp++; 16538494Sobrien } 16638494Sobrien } 16738494Sobrien 16838494Sobrien if (xivec[0] == 0 || xivec[1] == 0) { 16938494Sobrien errno = EINVAL; 17038494Sobrien plog(XLOG_USER, "1st/2nd args missing to (un)mount program"); 17138494Sobrien } else { 17238494Sobrien (void) execv(xivec[0], xivec + 1); 17338494Sobrien } 17438494Sobrien 17538494Sobrien /* 17638494Sobrien * Save error number 17738494Sobrien */ 17838494Sobrien error = errno; 17938494Sobrien plog(XLOG_ERROR, "exec failed: %m"); 18038494Sobrien 18138494Sobrien /* 18238494Sobrien * Free allocate memory 18338494Sobrien */ 18438494Sobrien XFREE(info); 18538494Sobrien XFREE(xivec); 18638494Sobrien 18738494Sobrien /* 18838494Sobrien * Return error 18938494Sobrien */ 19038494Sobrien return error; 19138494Sobrien} 19238494Sobrien 19338494Sobrien 19438494Sobrienstatic int 195174294Sobrienamfs_program_mount(am_node *am, mntfs *mf) 19638494Sobrien{ 19738494Sobrien return amfs_program_exec(mf->mf_fo->opt_mount); 19838494Sobrien} 19938494Sobrien 20038494Sobrien 20138494Sobrienstatic int 202174294Sobrienamfs_program_umount(am_node *am, mntfs *mf) 20338494Sobrien{ 20438494Sobrien return amfs_program_exec((char *) mf->mf_private); 20538494Sobrien} 206