diff options
author | bp <bp@FreeBSD.org> | 1999-10-15 09:59:48 +0000 |
---|---|---|
committer | bp <bp@FreeBSD.org> | 1999-10-15 09:59:48 +0000 |
commit | 8b5d9028e2ee6ecb6046a21b4f7411da3c0819a0 (patch) | |
tree | 7fb571fc68137608ef4ac454a4a466b5851e34bc /usr.sbin/mount_nwfs/mount_nwfs.c | |
parent | 7b2a02340bd764d4cf4cbd6b4f4a5a7c6c579af7 (diff) | |
download | FreeBSD-src-8b5d9028e2ee6ecb6046a21b4f7411da3c0819a0.zip FreeBSD-src-8b5d9028e2ee6ecb6046a21b4f7411da3c0819a0.tar.gz |
Add mount_nwfs program. Now -current can mount NetWare volumes.
Diffstat (limited to 'usr.sbin/mount_nwfs/mount_nwfs.c')
-rw-r--r-- | usr.sbin/mount_nwfs/mount_nwfs.c | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/usr.sbin/mount_nwfs/mount_nwfs.c b/usr.sbin/mount_nwfs/mount_nwfs.c new file mode 100644 index 0000000..363b8cc --- /dev/null +++ b/usr.sbin/mount_nwfs/mount_nwfs.c @@ -0,0 +1,372 @@ +/* + * Copyright (c) 1999, Boris Popov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Boris Popov. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/errno.h> +#include <sys/time.h> +#include <sys/mount.h> + +#include <stdio.h> +#include <string.h> +#include <pwd.h> +#include <grp.h> +#include <unistd.h> +#include <ctype.h> +#include <stdlib.h> +#include <err.h> +#include <sysexits.h> + +#include <netncp/ncp_lib.h> +#include <netncp/ncp_rcfile.h> +#include <nwfs/nwfs.h> +#include <nwfs/nwfs_mount.h> +#include "mntopts.h" + +#define NWFS_VFSNAME "nwfs" + +extern char *__progname; +static char mount_point[MAXPATHLEN + 1]; +static void usage(void); +static int parsercfile(struct ncp_conn_loginfo *li, struct nwfs_args *mdata); + +static struct mntopt mopts[] = { + MOPT_STDOPTS, + { NULL } +}; + +static int +parsercfile(struct ncp_conn_loginfo *li, struct nwfs_args *mdata) { + return 0; +} + +int +main(int argc, char *argv[]) { + int opt, error, mntflags, nlsopt; + char *p, *p1, tmp[1024]; + u_char *pv; + NWCONN_HANDLE connHandle; + struct nwfs_args mdata; + struct ncp_conn_loginfo li; + struct stat st; + struct vfsconf vfc; + struct nw_entry_info einfo; + + if (argc < 2) { + usage(); + exit(1); + } + if (argc == 2) { + if (strcmp(argv[1], "-h") == 0) { + usage(); + exit(0); + } else if (strcmp(argv[1], "-v") == 0) { + errx(EX_OK, "version %d.%d.%d", NWFS_VERSION / 100000, + (NWFS_VERSION % 10000) / 1000, + (NWFS_VERSION % 1000) / 100); + } + } + + error = getvfsbyname(NWFS_VFSNAME, &vfc); + if (error && vfsisloadable(NWFS_VFSNAME)) { + if(vfsload(NWFS_VFSNAME)) + err(EX_OSERR, "vfsload("NWFS_VFSNAME")"); + endvfsent(); + error = getvfsbyname(NWFS_VFSNAME, &vfc); + } + if (error) + errx(EX_OSERR, "NetWare filesystem is not available"); + + if(ncp_initlib()) exit(1); + + mntflags = error = 0; + bzero(&mdata,sizeof(mdata)); + mdata.uid = mdata.gid = -1; + nlsopt = 0; + + if (ncp_li_init(&li, argc, argv)) return 1; + /* + * A little bit weird, but I should figure out which server/user to use + * _before_ reading .rc file + */ + if (argc >= 3 && argv[argc-1][0] != '-' && argv[argc-2][0] != '-' && + argv[argc-2][0] == '/') { + p = argv[argc-2]; + error = 1; + do { + if (*p++ != '/') break; + p1 = tmp; + while (*p != ':' && *p != 0) *p1++ = *p++; + if (*p++ == 0) break; + *p1 = 0; + if (ncp_li_setserver(&li, tmp)) break; + p1 = tmp; + while (*p != '/' && *p != 0) *p1++ = *p++; + if (*p++ == 0) break; + *p1 = 0; + if (ncp_li_setuser(&li, tmp)) break; + p1 = tmp; + while (*p != '/' && *p != 0) *p1++ = *p++; + *p1 = 0; + if (strlen(tmp) > NCP_VOLNAME_LEN) { + fprintf(stderr, "Volume name too long: %s\n", tmp); + break; + } + ncp_str_upper(strcpy(mdata.mounted_vol,tmp)); + if (*p == '/') + p++; + p1 = mdata.root_path + 2; + pv = mdata.root_path + 1; + for(;*p;) { + *pv = 0; + while (*p != '/' && *p) { + *p1++ = *p++; + (*pv)++; + } + if (*pv) { + ncp_nls_mem_u2n(pv + 1, pv + 1, *pv); + pv += (*pv) + 1; + mdata.root_path[0]++; + } + if (*p++ == 0) break; + p1++; + } + error = 0; + } while(0); + if (error) + errx(EX_DATAERR, + "An error occured while parsing '%s'", + argv[argc - 2]); + } + if (ncp_li_readrc(&li)) return 1; + if (ncp_rc) { + parsercfile(&li,&mdata); + rc_close(ncp_rc); + } + while ((opt = getopt(argc, argv, STDPARAM_OPT"V:c:d:f:g:l:n:o:u:w:")) != EOF) { + switch (opt) { + case STDPARAM_ARGS: + if (ncp_li_arg(&li, opt, optarg)) { + return 1; + } + break; + case 'V': + if (strlen(optarg) > NCP_VOLNAME_LEN) + errx(EX_DATAERR, "Volume too long: %s\n", optarg); + ncp_str_upper(strcpy(mdata.mounted_vol,optarg)); + break; + case 'u': { + struct passwd *pwd; + + pwd = isdigit(optarg[0]) ? + getpwuid(atoi(optarg)) : getpwnam(optarg); + if (pwd == NULL) + errx(EX_NOUSER, "unknown user '%s'", optarg); + mdata.uid = pwd->pw_uid; + break; + } + case 'g': { + struct group *grp; + + grp = isdigit(optarg[0]) ? + getgrgid(atoi(optarg)) : getgrnam(optarg); + if (grp == NULL) + errx(EX_NOUSER, "unknown group '%s'", optarg); + mdata.gid = grp->gr_gid; + break; + } + case 'd': + errno = 0; + mdata.dir_mode = strtol(optarg, &p, 8); + if (errno || *p != 0) + errx(EX_DATAERR, "invalid value for directory mode"); + break; + case 'f': + errno = 0; + mdata.file_mode = strtol(optarg, &p, 8); + if (errno || *p != 0) + errx(EX_DATAERR, "invalid value for file mode"); + break; + case '?': + usage(); + exit(1); /*NOTREACHED*/ + case 'n': { + char *inp, *nsp; + + nsp = inp = optarg; + while ((nsp = strsep(&inp, ",;:")) != NULL) { + if (strcasecmp(nsp, "OS2") == 0) + mdata.flags |= NWFS_MOUNT_NO_OS2; + else if (strcasecmp(nsp, "LONG") == 0) + mdata.flags |= NWFS_MOUNT_NO_LONG; + else if (strcasecmp(nsp, "NFS") == 0) + mdata.flags |= NWFS_MOUNT_NO_NFS; + else + errx(EX_DATAERR, "Unknown namespace '%s'", nsp); + } + break; + }; + case 'l': + if (ncp_nls_setlocale(optarg) != 0) return 1; + mdata.flags |= NWFS_MOUNT_HAVE_NLS; + break; + case 'o': + getmntopts(optarg, mopts, &mntflags, 0); + break; + case 'c': + switch (optarg[0]) { + case 'l': + nlsopt |= NWHP_LOWER; + break; + case 'u': + nlsopt |= NWHP_UPPER; + break; + case 'n': + nlsopt |= NWHP_LOWER | NWHP_UPPER; + break; + case 'L': + nlsopt |= NWHP_LOWER | NWHP_NOSTRICT; + break; + case 'U': + nlsopt |= NWHP_UPPER | NWHP_NOSTRICT; + break; + default: + errx(EX_DATAERR, "invalid suboption '%c' for -c", + optarg[0]); + } + break; + case 'w': + if (ncp_nls_setrecodebyname(optarg) != 0) + return 1; + mdata.flags |= NWFS_MOUNT_HAVE_NLS; + break; + default: + usage(); + return 1; + } + } + + if (optind == argc - 2) { + optind++; + } else if (mdata.mounted_vol[0] == 0) + errx(EX_USAGE, "Volume name should be specified"); + + if (optind != argc - 1) { + usage(); + return 1; + } + realpath(argv[optind], mount_point); + + if (stat(mount_point, &st) == -1) + err(EX_OSERR, "could not find mount point %s", mount_point); + if (!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + err(EX_OSERR, "can't mount on %s", mount_point); + } + if (ncp_geteinfo(mount_point, &einfo) == 0) + errx(EX_OSERR, "can't mount on %s twice", mount_point); + + if (mdata.uid == -1) { + mdata.uid = st.st_uid; + } + if (mdata.gid == -1) { + mdata.gid = st.st_gid; + } + if (mdata.file_mode == 0 ) { + mdata.file_mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); + } + if (mdata.dir_mode == 0) { + mdata.dir_mode = mdata.file_mode; + if ((mdata.dir_mode & S_IRUSR) != 0) + mdata.dir_mode |= S_IXUSR; + if ((mdata.dir_mode & S_IRGRP) != 0) + mdata.dir_mode |= S_IXGRP; + if ((mdata.dir_mode & S_IROTH) != 0) + mdata.dir_mode |= S_IXOTH; + } + if (li.access_mode == 0) { + li.access_mode = mdata.dir_mode; + } +/* if (mdata.flags & NWFS_MOUNT_HAVE_NLS) {*/ + mdata.nls = ncp_nls; +/* }*/ + mdata.nls.opt = nlsopt; + error = ncp_li_check(&li); + if (error) + return 1; + li.opt |= NCP_OPT_WDOG; + /* well, now we can try to login, or use already established connection */ + error = ncp_li_login(&li,&connHandle); + if( error ){ + fprintf(stderr,"Cannot login to server %s,%s\n",li.server,strerror(errno)); + ncp_disconnect(connHandle); + return(1); + } + error = ncp_conn2ref(connHandle, &mdata.connRef); + if (error) { + fprintf(stderr,"Cannot convert handle to refernce. Consider this as a big bug.\n"); + ncp_disconnect(connHandle); + return(1); + } + strcpy(mdata.mount_point,mount_point); + mdata.version = NWFS_VERSION; + error = mount(NWFS_VFSNAME, mdata.mount_point, mntflags, (void*)&mdata); + if (error) { + fprintf(stderr,"mount error: %s\n", strerror(errno)); + ncp_disconnect(connHandle); + exit(1); + } + /* + * I'm leave along my handle, but kernel should keep own ... + */ + ncp_disconnect(connHandle); + /* we are done ?, impossible ... */ + return 0; +} + +static void +usage(void) { + printf("usage: %s [connection options] [options] \n" + " server:user/volume[/path] mount-point\n\n", __progname); + printf( + "see ncplogin(1) for details on connection options\n" + " -A host Netware/IP host address\n" + " -u uid uid the mounted files get\n" + " -g gid gid the mounted files get\n" + " -f mode permission the files get\n" + " -d mode permission the dirs get\n" + " -h print this help text\n" + " -v print nwfs version number\n" + "\n" + ); +} |