1 /* $NetBSD: mount_udf.c,v 1.15 2019/10/16 21:52:22 maya Exp $ */ 2 3 /* 4 * Copyright (c) 2006 Reinoud Zandijk 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 */ 28 29 30 #include <sys/cdefs.h> 31 #ifndef lint 32 __RCSID("$NetBSD: mount_udf.c,v 1.15 2019/10/16 21:52:22 maya Exp $"); 33 #endif /* not lint */ 34 35 36 #include <sys/param.h> 37 #include <sys/mount.h> 38 #include <sys/stat.h> 39 40 #include <assert.h> 41 #include <err.h> 42 #include <errno.h> 43 #include <grp.h> 44 #include <pwd.h> 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <time.h> 49 #include <unistd.h> 50 #include <util.h> 51 52 53 /* mount specific options */ 54 #include <fs/udf/udf_mount.h> 55 #include <mntopts.h> 56 57 #include "mountprog.h" 58 #include "mount_udf.h" 59 60 /* options to pass on to the `mount' call */ 61 static const struct mntopt mopts[] = { 62 MOPT_STDOPTS, /* `normal' options */ 63 MOPT_ASYNC, /* default */ 64 MOPT_NOATIME, /* dont update access times */ 65 MOPT_RELATIME, /* update access times on change*/ 66 MOPT_UPDATE, /* not yet supported */ 67 MOPT_GETARGS, /* printing */ 68 MOPT_NULL, 69 }; 70 71 72 /* prototypes */ 73 static void usage(void) __dead; 74 75 76 /* code */ 77 78 static void 79 usage(void) 80 { 81 (void)fprintf(stderr, "Usage: %s [-g gid] [-o options] [-s session] " 82 "[-t gmtoff] [-u uid] special node\n", getprogname()); 83 exit(EXIT_FAILURE); 84 } 85 86 87 #ifndef MOUNT_NOMAIN 88 int 89 main(int argc, char **argv) 90 { 91 92 setprogname(argv[0]); 93 return mount_udf(argc, argv); 94 } 95 #endif 96 97 98 /* main routine */ 99 void 100 mount_udf_parseargs(int argc, char **argv, 101 struct udf_args *args, int *mntflags, 102 char *canon_dev, char *canon_dir) 103 { 104 struct tm *tm; 105 time_t now; 106 uid_t anon_uid, nobody_uid; 107 gid_t anon_gid, nobody_gid; 108 int ch, set_gmtoff; 109 uint32_t sector_size; 110 mntoptparse_t mp; 111 112 /* initialise */ 113 (void)memset(args, 0, sizeof(*args)); 114 115 set_gmtoff = *mntflags = 0; 116 sector_size = 0; 117 118 /* get nobody */ 119 nobody_uid = anon_uid = a_uid("nobody"); 120 nobody_gid = anon_gid = a_gid("nobody"); 121 122 /* NEVER EVER allow nobody_uid:nobody_gid to be 0:0 */ 123 assert(nobody_uid != 0); 124 assert(nobody_gid != 0); 125 126 while ((ch = getopt(argc, argv, "cg:o:s:t:u:")) != -1) { 127 switch (ch) { 128 case 'c' : 129 args->udfmflags |= UDFMNT_CLOSESESSION; 130 break; 131 case 'g' : 132 /* convert groupname or numeric equiv. */ 133 anon_gid = a_gid(optarg); 134 break; 135 case 'u' : 136 /* convert username or numeric equiv. */ 137 anon_uid = a_uid(optarg); 138 break; 139 case 'o' : 140 /* process generic mount options */ 141 mp = getmntopts(optarg, mopts, mntflags, 0); 142 if (mp == NULL) 143 err(EXIT_FAILURE, "getmntopts"); 144 freemntopts(mp); 145 break; 146 case 's' : 147 args->sessionnr = a_num(optarg, "session number"); 148 break; 149 case 't' : 150 args->gmtoff = a_num(optarg, "gmtoff"); 151 set_gmtoff = 1; 152 break; 153 default : 154 usage(); 155 /* NOTREACHED */ 156 } 157 } 158 159 if (optind + 2 != argc) 160 usage(); 161 162 if (!set_gmtoff) { 163 /* use user's time zone as default */ 164 (void)time(&now); 165 tm = localtime(&now); 166 args->gmtoff = tm->tm_gmtoff; 167 } 168 169 /* get device and directory specifier */ 170 pathadj(argv[optind], canon_dev); 171 pathadj(argv[optind+1], canon_dir); 172 173 args->version = UDFMNT_VERSION; 174 args->fspec = canon_dev; 175 args->anon_uid = anon_uid; 176 args->anon_gid = anon_gid; 177 args->nobody_uid = nobody_uid; 178 args->nobody_gid = nobody_gid; 179 args->sector_size = sector_size; /* invalid */ 180 } 181 182 int 183 mount_udf(int argc, char *argv[]) 184 { 185 struct udf_args args; 186 char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN]; 187 int mntflags; 188 189 mount_udf_parseargs(argc, argv, &args, &mntflags, canon_dev, canon_dir); 190 191 /* mount it! :) */ 192 if (mount(MOUNT_UDF, canon_dir, mntflags, &args, sizeof args) == -1) 193 err(EXIT_FAILURE, "Cannot mount %s on %s", canon_dev,canon_dir); 194 195 if (mntflags & MNT_GETARGS) { 196 char buf[1024]; 197 198 (void)snprintb(buf, sizeof(buf), UDFMNT_BITS, 199 (uint64_t)args.udfmflags); 200 (void)printf("gmtoffset=%d, sessionnr=%d, flags=%s\n", 201 args.gmtoff, args.sessionnr, buf); 202 } 203 204 return EXIT_SUCCESS; 205 } 206