1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <ctype.h> 30 #include <string.h> 31 #include <stdio.h> 32 #include <stdlib.h> /* for getopt(3) */ 33 #include <signal.h> 34 #include <locale.h> 35 #include <fslib.h> 36 #include <errno.h> 37 #include <sys/types.h> 38 #include <sys/mnttab.h> 39 #include <sys/mount.h> 40 41 #define FSTYPE "udfs" 42 #define NAME_MAX 64 43 44 static int roflag = 0; 45 static int mflag = 0; 46 static int Oflag = 0; 47 static int qflag = 0; 48 49 static char optbuf[MAX_MNTOPT_STR] = { '\0', }; 50 static int optsize = 0; 51 52 static char fstype[] = FSTYPE; 53 54 static char typename[NAME_MAX], *myname; 55 56 static void do_mount(char *, char *, int); 57 static void rpterr(char *, char *); 58 static void usage(void); 59 60 int 61 main(int argc, char **argv) 62 { 63 char *special, *mountp; 64 int flags = 0; 65 int c; 66 67 (void) setlocale(LC_ALL, ""); 68 69 #if !defined(TEXT_DOMAIN) 70 #define TEXT_DOMAIN "SYS_TEST" 71 #endif 72 (void) textdomain(TEXT_DOMAIN); 73 74 myname = strrchr(argv[0], '/'); 75 if (myname) { 76 myname++; 77 } else { 78 myname = argv[0]; 79 } 80 (void) snprintf(typename, sizeof (typename), "%s %s", fstype, myname); 81 argv[0] = typename; 82 83 /* check for proper arguments */ 84 85 while ((c = getopt(argc, argv, "mo:rOq")) != EOF) { 86 switch (c) { 87 case 'm': 88 mflag++; 89 break; 90 case 'o': 91 if (strlcpy(optbuf, optarg, sizeof (optbuf)) >= 92 sizeof (optbuf)) { 93 (void) fprintf(stderr, 94 gettext("%s: Invalid argument: %s\n"), 95 myname, optarg); 96 return (2); 97 } 98 optsize = strlen(optbuf); 99 break; 100 case 'r': 101 roflag++; 102 break; 103 case 'O': 104 Oflag++; 105 break; 106 case 'q': 107 qflag = 1; 108 break; 109 default : 110 break; 111 } 112 } 113 114 if ((argc - optind) != 2) 115 usage(); 116 117 special = argv[optind++]; 118 mountp = argv[optind++]; 119 120 if (roflag) 121 flags = MS_RDONLY; 122 123 if (optsize > 0) { 124 struct mnttab m; 125 126 m.mnt_mntopts = optbuf; 127 if (hasmntopt(&m, "m")) 128 mflag++; 129 } 130 131 flags |= (Oflag ? MS_OVERLAY : 0); 132 flags |= (mflag ? MS_NOMNTTAB : 0); 133 134 135 /* 136 * Perform the mount. 137 * Only the low-order bit of "roflag" is used by the system 138 * calls (to denote read-only or read-write). 139 */ 140 do_mount(special, mountp, flags); 141 return (0); 142 } 143 144 145 static void 146 rpterr(char *bs, char *mp) 147 { 148 switch (errno) { 149 case EPERM: 150 (void) fprintf(stderr, 151 gettext("%s: insufficient privileges\n"), myname); 152 break; 153 case ENXIO: 154 (void) fprintf(stderr, 155 gettext("%s: %s no such device\n"), myname, bs); 156 break; 157 case ENOTDIR: 158 (void) fprintf(stderr, 159 gettext("%s: %s not a directory\n\t" 160 "or a component of %s is not a directory\n"), 161 myname, mp, bs); 162 break; 163 case ENOENT: 164 (void) fprintf(stderr, 165 gettext("%s: %s or %s, no such file or directory\n"), 166 myname, bs, mp); 167 break; 168 case EINVAL: 169 (void) fprintf(stderr, 170 gettext("%s: %s is not an udfs file system.\n"), 171 typename, bs); 172 break; 173 case EBUSY: 174 (void) fprintf(stderr, 175 gettext("%s: %s is already mounted or %s is busy\n"), 176 myname, bs, mp); 177 break; 178 case ENOTBLK: 179 (void) fprintf(stderr, 180 gettext("%s: %s not a block device\n"), myname, bs); 181 break; 182 case EROFS: 183 (void) fprintf(stderr, 184 gettext("%s: %s write-protected\n"), 185 myname, bs); 186 break; 187 case ENOSPC: 188 (void) fprintf(stderr, 189 gettext("%s: %s is corrupted. needs checking\n"), 190 myname, bs); 191 break; 192 default: 193 perror(myname); 194 (void) fprintf(stderr, 195 gettext("%s: cannot mount %s\n"), myname, bs); 196 } 197 } 198 199 200 static void 201 do_mount(char *special, char *mountp, int flag) 202 { 203 char *savedoptbuf; 204 205 if ((savedoptbuf = strdup(optbuf)) == NULL) { 206 (void) fprintf(stderr, gettext("%s: out of memory\n"), 207 myname); 208 exit(2); 209 } 210 if (mount(special, mountp, flag | MS_DATA | MS_OPTIONSTR, 211 fstype, NULL, 0, optbuf, MAX_MNTOPT_STR) == -1) { 212 rpterr(special, mountp); 213 exit(31+2); 214 } 215 if (optsize && !qflag) 216 cmp_requested_to_actual_options(savedoptbuf, optbuf, 217 special, mountp); 218 } 219 220 221 static void 222 usage(void) 223 { 224 (void) fprintf(stdout, gettext("udfs usage:\n" 225 "mount [-F udfs] [generic options] " 226 "[-o suboptions] {special | mount_point}\n")); 227 (void) fprintf(stdout, gettext("\tsuboptions are: \n" 228 "\t ro,rw,nosuid,remount,m\n")); 229 (void) fprintf(stdout, gettext( 230 "\t only one of ro, rw can be " 231 "used at the same time\n")); 232 (void) fprintf(stdout, gettext( 233 "\t remount can be used only with rw\n")); 234 235 exit(32); 236 } 237