/* $NetBSD: mount_udf.c,v 1.14 2016/02/21 22:51:30 christos Exp $ */ /* * Copyright (c) 2006 Reinoud Zandijk * 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 for the * NetBSD Project. See http://www.NetBSD.org/ for * information about NetBSD. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. * */ #include #ifndef lint __RCSID("$NetBSD: mount_udf.c,v 1.14 2016/02/21 22:51:30 christos Exp $"); #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* mount specific options */ #include #include #include "mountprog.h" #include "mount_udf.h" /* options to pass on to the `mount' call */ static const struct mntopt mopts[] = { MOPT_STDOPTS, /* `normal' options */ MOPT_ASYNC, /* default */ MOPT_NOATIME, /* dont update access times */ MOPT_RELATIME, /* update access times on change*/ MOPT_UPDATE, /* not yet supported */ MOPT_GETARGS, /* printing */ MOPT_NULL, }; /* prototypes */ static void usage(void) __dead; /* code */ static void usage(void) { (void)fprintf(stderr, "Usage: %s [-g gid] [-o options] [-s session] " "[-t gmtoff] [-u uid] special node\n", getprogname()); exit(EXIT_FAILURE); } #ifndef MOUNT_NOMAIN int main(int argc, char **argv) { setprogname(argv[0]); return mount_udf(argc, argv); } #endif /* main routine */ void mount_udf_parseargs(int argc, char **argv, struct udf_args *args, int *mntflags, char *canon_dev, char *canon_dir) { struct tm *tm; time_t now; uid_t anon_uid, nobody_uid; gid_t anon_gid, nobody_gid; int ch, set_gmtoff; uint32_t sector_size; mntoptparse_t mp; /* initialise */ (void)memset(args, 0, sizeof(*args)); set_gmtoff = *mntflags = 0; sector_size = 0; /* get nobody */ nobody_uid = anon_uid = a_uid("nobody"); nobody_gid = anon_gid = a_gid("nobody"); /* NEVER EVER allow nobody_uid:nobody_gid to be 0:0 */ assert(nobody_uid != 0); assert(nobody_gid != 0); while ((ch = getopt(argc, argv, "cg:o:s:t:u:")) != -1) { switch (ch) { case 'c' : args->udfmflags |= UDFMNT_CLOSESESSION; break; case 'g' : /* convert groupname or numeric equiv. */ anon_gid = a_gid(optarg); break; case 'u' : /* convert username or numeric equiv. */ anon_uid = a_uid(optarg); break; case 'o' : /* process generic mount options */ mp = getmntopts(optarg, mopts, mntflags, 0); if (mp == NULL) err(EXIT_FAILURE, "getmntopts"); freemntopts(mp); break; case 's' : args->sessionnr = a_num(optarg, "session number"); break; case 't' : args->gmtoff = a_num(optarg, "gmtoff"); set_gmtoff = 1; break; default : usage(); /* NOTREACHED */ } } if (optind + 2 != argc) usage(); if (!set_gmtoff) { /* use user's time zone as default */ (void)time(&now); tm = localtime(&now); args->gmtoff = tm->tm_gmtoff; } /* get device and directory specifier */ pathadj(argv[optind], canon_dev); pathadj(argv[optind+1], canon_dir); args->version = UDFMNT_VERSION; args->fspec = canon_dev; args->anon_uid = anon_uid; args->anon_gid = anon_gid; args->nobody_uid = nobody_uid; args->nobody_gid = nobody_gid; args->sector_size = sector_size; /* invalid */ } int mount_udf(int argc, char *argv[]) { struct udf_args args; char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN]; int mntflags; mount_udf_parseargs(argc, argv, &args, &mntflags, canon_dev, canon_dir); /* mount it! :) */ if (mount(MOUNT_UDF, canon_dir, mntflags, &args, sizeof args) == -1) err(EXIT_FAILURE, "Cannot mount %s on %s", canon_dev,canon_dir); if (mntflags & MNT_GETARGS) { char buf[1024]; (void)snprintb(buf, sizeof(buf), UDFMNT_BITS, (uint64_t)args.udfmflags); (void)printf("gmtoffset=%d, sessionnr=%d, flags=%s\n", args.gmtoff, args.sessionnr, buf); } return EXIT_SUCCESS; }