1 /* $NetBSD: mount_udf.c,v 1.10 2007/07/14 15:57:27 dsl 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 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed for the 18 * NetBSD Project. See http://www.NetBSD.org/ for 19 * information about NetBSD. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * 34 */ 35 36 37 #include <sys/cdefs.h> 38 #ifndef lint 39 __RCSID("$NetBSD: mount_udf.c,v 1.10 2007/07/14 15:57:27 dsl Exp $"); 40 #endif /* not lint */ 41 42 43 #include <sys/param.h> 44 #include <sys/mount.h> 45 #include <sys/stat.h> 46 47 #include <assert.h> 48 #include <err.h> 49 #include <errno.h> 50 #include <grp.h> 51 #include <pwd.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <string.h> 55 #include <time.h> 56 #include <unistd.h> 57 #include <util.h> 58 59 60 /* mount specific options */ 61 #include <fs/udf/udf_mount.h> 62 #include <mntopts.h> 63 #include <fattr.h> 64 65 66 /* options to pass on to the `mount' call */ 67 static const struct mntopt mopts[] = { 68 MOPT_STDOPTS, /* `normal' options */ 69 MOPT_ASYNC, /* default */ 70 MOPT_NOATIME, /* dont update access times */ 71 MOPT_UPDATE, /* not yet supported */ 72 MOPT_GETARGS, /* printing */ 73 MOPT_NULL, 74 }; 75 76 77 /* prototypes */ 78 int mount_udf(int argc, char **argv); 79 static void usage(void) __attribute__((__noreturn__)); 80 81 82 /* code */ 83 84 static void 85 usage(void) 86 { 87 (void)fprintf(stderr, "Usage: %s [-g gid] [-o options] [-s session] " 88 "[-t gmtoff] [-u uid] special node\n", getprogname()); 89 exit(EXIT_FAILURE); 90 } 91 92 93 /* copied from mount_msdos; is it necessary still? */ 94 #ifndef MOUNT_NOMAIN 95 int 96 main(int argc, char **argv) 97 { 98 return mount_udf(argc, argv); 99 } 100 #endif 101 102 103 /* main routine */ 104 int 105 mount_udf(int argc, char **argv) 106 { 107 struct udf_args args; 108 struct tm *tm; 109 time_t now; 110 uid_t anon_uid, nobody_uid; 111 gid_t anon_gid, nobody_gid; 112 char *dev, *dir; 113 int ch, mntflags, set_gmtoff; 114 uint32_t sector_size; 115 mntoptparse_t mp; 116 117 /* set program name for error messages */ 118 setprogname(argv[0]); 119 120 /* initialise */ 121 (void)memset(&args, 0, sizeof(args)); 122 123 set_gmtoff = mntflags = 0; 124 sector_size = 0; 125 126 /* get nobody */ 127 nobody_uid = anon_uid = a_uid("nobody"); 128 nobody_gid = anon_gid = a_gid("nobody"); 129 130 /* NEVER EVER allow nobody_uid:nobody_gid to be 0:0 */ 131 assert(nobody_uid != 0); 132 assert(nobody_gid != 0); 133 134 while ((ch = getopt(argc, argv, "cg:o:s:t:u:")) != -1) { 135 switch (ch) { 136 #ifdef notyet 137 case 'c' : 138 args.udfmflags |= UDFMNT_CLOSESESSION; 139 break; 140 #endif 141 case 'g' : 142 /* convert groupname or numeric equiv. */ 143 anon_gid = a_gid(optarg); 144 break; 145 case 'u' : 146 /* convert username or numeric equiv. */ 147 anon_uid = a_uid(optarg); 148 break; 149 case 'o' : 150 /* process generic mount options */ 151 mp = getmntopts(optarg, mopts, &mntflags, 0); 152 if (mp == NULL) 153 err(EXIT_FAILURE, "getmntopts"); 154 freemntopts(mp); 155 break; 156 case 's' : 157 args.sessionnr = a_num(optarg, "session number"); 158 break; 159 case 't' : 160 args.gmtoff = a_num(optarg, "gmtoff"); 161 set_gmtoff = 1; 162 break; 163 default : 164 usage(); 165 /* NOTREACHED */ 166 } 167 } 168 169 if (optind + 2 != argc) 170 usage(); 171 172 if (!set_gmtoff) { 173 /* use user's time zone as default */ 174 (void)time(&now); 175 tm = localtime(&now); 176 args.gmtoff = tm->tm_gmtoff; 177 } 178 179 /* get device and directory specifier */ 180 dev = argv[optind]; 181 dir = argv[optind + 1]; 182 183 args.version = UDFMNT_VERSION; 184 args.fspec = dev; 185 args.anon_uid = anon_uid; 186 args.anon_gid = anon_gid; 187 args.nobody_uid = nobody_uid; 188 args.nobody_gid = nobody_gid; 189 args.sector_size = sector_size; /* invalid */ 190 191 /* mount it! :) */ 192 if (mount(MOUNT_UDF, dir, mntflags, &args, sizeof args) == -1) 193 err(EXIT_FAILURE, "Cannot mount %s on %s", dev, 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