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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 #pragma ident "%Z%%M% %I% %E% SMI" 22 23 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #include <sys/types.h> 29 #include <locale.h> 30 #include <stdio.h> 31 #include <time.h> 32 #include <signal.h> 33 #include <string.h> 34 #include <unistd.h> 35 #include <stdlib.h> 36 #include <errno.h> 37 #include <sys/mntent.h> 38 #include <sys/mnttab.h> 39 #include <sys/mount.h> 40 #include <sys/fs/pc_fs.h> 41 #include <fslib.h> 42 43 extern int daylight; 44 45 /* 46 * The "hidden/nohidden" option is private. It is not approved for 47 * use (see PSARC/1996/443), which is why it is not in the usage message. 48 */ 49 static int roflag = 0; 50 static char optbuf[MAX_MNTOPT_STR] = { '\0', }; 51 static int optsize = 0; 52 53 static struct pcfs_args tz; 54 55 int 56 main(int argc, char *argv[]) 57 { 58 char *mnt_special; 59 char *mnt_mountp; 60 int c; 61 char *myname; 62 char typename[64]; 63 char *savedoptbuf; 64 extern int optind; 65 extern char *optarg; 66 int error = 0; 67 int verbose = 0; 68 int mflg = 0; 69 int qflg = 0; 70 int optcnt = 0; 71 72 myname = strrchr(argv[0], '/'); 73 myname = myname ? myname + 1 : argv[0]; 74 (void) snprintf(typename, sizeof (typename), "%s_%s", 75 MNTTYPE_PCFS, myname); 76 argv[0] = typename; 77 78 while ((c = getopt(argc, argv, "Vvmr?o:Oq")) != EOF) { 79 switch (c) { 80 case 'V': 81 case 'v': 82 verbose++; 83 break; 84 case '?': 85 error++; 86 break; 87 case 'r': 88 roflag++; 89 break; 90 case 'm': 91 mflg |= MS_NOMNTTAB; 92 break; 93 case 'o': 94 if (strlcpy(optbuf, optarg, sizeof (optbuf)) >= 95 sizeof (optbuf)) { 96 (void) fprintf(stderr, 97 gettext("%s: Invalid argument: %s\n"), 98 myname, optarg); 99 return (2); 100 } 101 optsize = strlen(optbuf); 102 break; 103 case 'O': 104 mflg |= MS_OVERLAY; 105 break; 106 case 'q': 107 qflg = 1; 108 break; 109 } 110 } 111 112 if (verbose && !error) { 113 char *optptr; 114 115 (void) fprintf(stderr, "%s", typename); 116 for (optcnt = 1; optcnt < argc; optcnt++) { 117 optptr = argv[optcnt]; 118 if (optptr) 119 (void) fprintf(stderr, " %s", optptr); 120 } 121 (void) fprintf(stderr, "\n"); 122 } 123 124 if (argc - optind != 2 || error) { 125 /* 126 * don't hint at options yet (none are really supported) 127 */ 128 (void) fprintf(stderr, gettext( 129 "Usage: %s [generic options] [-o suboptions] " 130 "special mount_point\n"), typename); 131 (void) fprintf(stderr, gettext( 132 "\tpcfs-specific suboptions are:\n" 133 "\t clamptime,noclamptime\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