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 #pragma ident "%Z%%M% %I% %E% SMI" 23 24 /* 25 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #include <sys/types.h> 30 #include <locale.h> 31 #include <stdio.h> 32 #include <time.h> 33 #include <signal.h> 34 #include <string.h> 35 #include <unistd.h> 36 #include <stdlib.h> 37 #include <errno.h> 38 #include <sys/mntent.h> 39 #include <sys/mnttab.h> 40 #include <sys/mount.h> 41 #include <sys/fs/pc_fs.h> 42 #include <fslib.h> 43 44 extern int daylight; 45 46 /* 47 * The "hidden/nohidden" option is private. It is not approved for 48 * use (see PSARC/1996/443), which is why it is not in the usage message. 49 */ 50 static int roflag = 0; 51 static char optbuf[MAX_MNTOPT_STR] = { '\0', }; 52 static int optsize = 0; 53 54 static struct pcfs_args tz; 55 56 int 57 main(int argc, char *argv[]) 58 { 59 char *mnt_special; 60 char *mnt_mountp; 61 int c; 62 char *myname; 63 char typename[64]; 64 char *savedoptbuf; 65 extern int optind; 66 extern char *optarg; 67 int error = 0; 68 int verbose = 0; 69 int mflg = 0; 70 int qflg = 0; 71 int optcnt = 0; 72 73 myname = strrchr(argv[0], '/'); 74 myname = myname ? myname + 1 : argv[0]; 75 (void) snprintf(typename, sizeof (typename), "%s_%s", 76 MNTTYPE_PCFS, myname); 77 argv[0] = typename; 78 79 while ((c = getopt(argc, argv, "Vvmr?o:Oq")) != EOF) { 80 switch (c) { 81 case 'V': 82 case 'v': 83 verbose++; 84 break; 85 case '?': 86 error++; 87 break; 88 case 'r': 89 roflag++; 90 break; 91 case 'm': 92 mflg |= MS_NOMNTTAB; 93 break; 94 case 'o': 95 if (strlcpy(optbuf, optarg, sizeof (optbuf)) >= 96 sizeof (optbuf)) { 97 (void) fprintf(stderr, 98 gettext("%s: Invalid argument: %s\n"), 99 myname, optarg); 100 return (2); 101 } 102 optsize = strlen(optbuf); 103 break; 104 case 'O': 105 mflg |= MS_OVERLAY; 106 break; 107 case 'q': 108 qflg = 1; 109 break; 110 } 111 } 112 113 if (verbose && !error) { 114 char *optptr; 115 116 (void) fprintf(stderr, "%s", typename); 117 for (optcnt = 1; optcnt < argc; optcnt++) { 118 optptr = argv[optcnt]; 119 if (optptr) 120 (void) fprintf(stderr, " %s", optptr); 121 } 122 (void) fprintf(stderr, "\n"); 123 } 124 125 if (argc - optind != 2 || error) { 126 /* 127 * don't hint at options yet (none are really supported) 128 */ 129 (void) fprintf(stderr, gettext( 130 "Usage: %s [generic options] [-o suboptions] " 131 "special mount_point\n"), typename); 132 (void) fprintf(stderr, gettext( 133 "\tpcfs-specific suboptions are:\n" 134 "\t foldcase,nofoldcase\n")); 135 exit(32); 136 } 137 138 mnt_special = argv[optind++]; 139 mnt_mountp = argv[optind++]; 140 141 (void) tzset(); 142 tz.secondswest = timezone; 143 tz.dsttime = daylight; 144 mflg |= MS_DATA; 145 if (roflag) 146 mflg |= MS_RDONLY; 147 148 if ((savedoptbuf = strdup(optbuf)) == NULL) { 149 (void) fprintf(stderr, gettext("%s: out of memory\n"), 150 myname); 151 exit(2); 152 } 153 (void) signal(SIGHUP, SIG_IGN); 154 (void) signal(SIGQUIT, SIG_IGN); 155 (void) signal(SIGINT, SIG_IGN); 156 157 if (verbose) { 158 (void) fprintf(stderr, "mount(%s, \"%s\", %d, %s", 159 mnt_special, mnt_mountp, mflg, MNTTYPE_PCFS); 160 } 161 if (mount(mnt_special, mnt_mountp, mflg | MS_OPTIONSTR, MNTTYPE_PCFS, 162 (char *)&tz, sizeof (struct pcfs_args), optbuf, MAX_MNTOPT_STR)) { 163 if (errno == EBUSY) { 164 (void) fprintf(stderr, gettext( 165 "mount: %s is already mounted or %s is busy\n"), 166 mnt_special, mnt_mountp); 167 } else if (errno == EINVAL) { 168 (void) fprintf(stderr, gettext( 169 "mount: %s is not a DOS filesystem.\n"), 170 mnt_special); 171 } else { 172 perror("mount"); 173 } 174 exit(32); 175 } 176 177 if (optsize && !qflg) 178 cmp_requested_to_actual_options(savedoptbuf, optbuf, 179 mnt_special, mnt_mountp); 180 return (0); 181 } 182