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 #include <ctype.h> 28 #include <string.h> 29 #include <stdio.h> 30 #include <stdlib.h> /* for getopt(3) */ 31 #include <signal.h> 32 #include <locale.h> 33 #include <fslib.h> 34 #include <errno.h> 35 #include <sys/types.h> 36 #include <sys/mnttab.h> 37 #include <sys/mount.h> 38 39 #define FSTYPE "udfs" 40 #define NAME_MAX 64 41 42 static int roflag = 0; 43 static int mflag = 0; 44 static int Oflag = 0; 45 static int qflag = 0; 46 47 static char optbuf[MAX_MNTOPT_STR] = { '\0', }; 48 static int optsize = 0; 49 50 static char fstype[] = FSTYPE; 51 52 static char typename[NAME_MAX], *myname; 53 54 static void do_mount(char *, char *, int); 55 static void rpterr(char *, char *); 56 static void usage(void); 57 58 int 59 main(int argc, char **argv) 60 { 61 char *special, *mountp; 62 int flags = 0; 63 int c; 64 65 (void) setlocale(LC_ALL, ""); 66 67 #if !defined(TEXT_DOMAIN) 68 #define TEXT_DOMAIN "SYS_TEST" 69 #endif 70 (void) textdomain(TEXT_DOMAIN); 71 72 myname = strrchr(argv[0], '/'); 73 if (myname) { 74 myname++; 75 } else { 76 myname = argv[0]; 77 } 78 (void) snprintf(typename, sizeof (typename), "%s %s", fstype, myname); 79 argv[0] = typename; 80 81 /* check for proper arguments */ 82 83 while ((c = getopt(argc, argv, "mo:rOq")) != EOF) { 84 switch (c) { 85 case 'm': 86 mflag++; 87 break; 88 case 'o': 89 if (strlcpy(optbuf, optarg, sizeof (optbuf)) >= 90 sizeof (optbuf)) { 91 (void) fprintf(stderr, 92 gettext("%s: Invalid argument: %s\n"), 93 myname, optarg); 94 return (2); 95 } 96 optsize = strlen(optbuf); 97 break; 98 case 'r': 99 roflag++; 100 break; 101 case 'O': 102 Oflag++; 103 break; 104 case 'q': 105 qflag = 1; 106 break; 107 default : 108 break; 109 } 110 } 111 112 if ((argc - optind) != 2) 113 usage(); 114 115 special = argv[optind++]; 116 mountp = argv[optind++]; 117 118 if (roflag) 119 flags = MS_RDONLY; 120 121 if (optsize > 0) { 122 struct mnttab m; 123 124 m.mnt_mntopts = optbuf; 125 if (hasmntopt(&m, "m")) 126 mflag++; 127 } 128 129 flags |= (Oflag ? MS_OVERLAY : 0); 130 flags |= (mflag ? MS_NOMNTTAB : 0); 131 132 133 /* 134 * Perform the mount. 135 * Only the low-order bit of "roflag" is used by the system 136 * calls (to denote read-only or read-write). 137 */ 138 do_mount(special, mountp, flags); 139 return (0); 140 } 141 142 143 static void 144 rpterr(char *bs, char *mp) 145 { 146 switch (errno) { 147 case EPERM: 148 (void) fprintf(stderr, 149 gettext("%s: insufficient privileges\n"), myname); 150 break; 151 case ENXIO: 152 (void) fprintf(stderr, 153 gettext("%s: %s no such device\n"), myname, bs); 154 break; 155 case ENOTDIR: 156 (void) fprintf(stderr, 157 gettext("%s: %s not a directory\n\t" 158 "or a component of %s is not a directory\n"), 159 myname, mp, bs); 160 break; 161 case ENOENT: 162 (void) fprintf(stderr, 163 gettext("%s: %s or %s, no such file or directory\n"), 164 myname, bs, mp); 165 break; 166 case EINVAL: 167 (void) fprintf(stderr, 168 gettext("%s: %s is not an udfs file system.\n"), 169 typename, bs); 170 break; 171 case EBUSY: 172 (void) fprintf(stderr, 173 gettext("%s: %s is already mounted or %s is busy\n"), 174 myname, bs, mp); 175 break; 176 case ENOTBLK: 177 (void) fprintf(stderr, 178 gettext("%s: %s not a block device\n"), myname, bs); 179 break; 180 case EROFS: 181 (void) fprintf(stderr, 182 gettext("%s: %s write-protected\n"), 183 myname, bs); 184 break; 185 case ENOSPC: 186 (void) fprintf(stderr, 187 gettext("%s: %s is corrupted. needs checking\n"), 188 myname, bs); 189 break; 190 default: 191 perror(myname); 192 (void) fprintf(stderr, 193 gettext("%s: cannot mount %s\n"), myname, bs); 194 } 195 } 196 197 198 static void 199 do_mount(char *special, char *mountp, int flag) 200 { 201 char *savedoptbuf; 202 203 if ((savedoptbuf = strdup(optbuf)) == NULL) { 204 (void) fprintf(stderr, gettext("%s: out of memory\n"), 205 myname); 206 exit(2); 207 } 208 if (mount(special, mountp, flag | MS_DATA | MS_OPTIONSTR, 209 fstype, NULL, 0, optbuf, MAX_MNTOPT_STR) == -1) { 210 rpterr(special, mountp); 211 exit(31+2); 212 } 213 if (optsize && !qflag) 214 cmp_requested_to_actual_options(savedoptbuf, optbuf, 215 special, mountp); 216 } 217 218 219 static void 220 usage(void) 221 { 222 (void) fprintf(stdout, gettext("udfs usage:\n" 223 "mount [-F udfs] [generic options] " 224 "[-o suboptions] {special | mount_point}\n")); 225 (void) fprintf(stdout, gettext("\tsuboptions are: \n" 226 "\t ro,rw,nosuid,remount,m\n")); 227 (void) fprintf(stdout, gettext( 228 "\t only one of ro, rw can be " 229 "used at the same time\n")); 230 (void) fprintf(stdout, gettext( 231 "\t remount can be used only with rw\n")); 232 233 exit(32); 234 } 235