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 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <sys/types.h> 31 #include <sys/stat.h> 32 #include <dirent.h> 33 #include <signal.h> 34 #include <unistd.h> 35 #include <fcntl.h> 36 #include <strings.h> 37 #include <libgen.h> 38 #include <libintl.h> 39 #include <errno.h> 40 #include <sys/syscall.h> 41 42 #include <dbus/dbus.h> 43 #include <dbus/dbus-glib.h> 44 #include <dbus/dbus-glib-lowlevel.h> 45 #include <libhal.h> 46 47 #include <rmm_common.h> 48 49 char *progname; 50 51 static boolean_t d_opt, l_opt, o_opt, u_opt, eject_opt, 52 closetray_opt, query_opt; 53 54 static void usage(); 55 static void nomem(); 56 57 static void 58 usage() 59 { 60 if (!u_opt) { 61 (void) fprintf(stderr, 62 "%s: [-dlu] [-o options] [nickname | device] " 63 "[mount_point]\n", progname); 64 } else { 65 (void) fprintf(stderr, 66 "%s: [-dl] [nickname | device]\n", progname); 67 } 68 } 69 70 static int 71 rmmount(int argc, char **argv) 72 { 73 int c; 74 action_t action; 75 LibHalContext *hal_ctx; 76 DBusError error; 77 rmm_error_t rmm_error; 78 LibHalDrive *d; 79 GSList *volumes; 80 const char *default_name; 81 char **opts = NULL; 82 int num_opts = 0; 83 char *mountpoint = NULL; 84 char **p; 85 int print_mask; 86 int ret = 0; 87 88 progname = basename(argv[0]); 89 90 if (strcmp(progname, "rmumount") == 0) { 91 u_opt = B_TRUE; 92 } 93 94 if (getenv("RMMOUNT_DEBUG") != NULL) { 95 rmm_debug = 1; 96 } 97 98 while ((c = getopt(argc, argv, "?dlo:u")) != -1) { 99 switch (c) { 100 case 'd': 101 d_opt = B_TRUE; 102 break; 103 case 'l': 104 l_opt = B_TRUE; 105 break; 106 case 'o': 107 o_opt = B_TRUE; 108 if ((opts = g_strsplit(optarg, ",", 10)) == NULL) { 109 nomem(); 110 } 111 for (num_opts = 0, p = &opts[0]; *p != NULL; p++) { 112 num_opts++; 113 } 114 break; 115 case 'u': 116 u_opt = B_TRUE; 117 break; 118 case '?': 119 usage(); 120 return (0); 121 default: 122 usage(); 123 return (1); 124 } 125 } 126 127 if (u_opt) { 128 action = UNMOUNT; 129 } else if (closetray_opt) { 130 action = CLOSETRAY; 131 } else if (eject_opt) { 132 action = EJECT; 133 } else { 134 action = INSERT; 135 } 136 137 if ((hal_ctx = rmm_hal_init(0, 0, 0, &error, &rmm_error)) == NULL) { 138 (void) fprintf(stderr, gettext("warning: %s\n"), 139 rmm_strerror(&error, rmm_error)); 140 rmm_dbus_error_free(&error); 141 if ((rmm_error == RMM_EDBUS_CONNECT) || 142 (rmm_error == RMM_EHAL_CONNECT)) { 143 return (99); 144 } else { 145 return (1); 146 } 147 } 148 149 if (d_opt) { 150 /* -d: print default name and exit */ 151 if ((d = rmm_hal_volume_find_default(hal_ctx, &error, 152 &default_name, &volumes)) == NULL) { 153 default_name = "nothing inserted"; 154 } else { 155 rmm_volumes_free(volumes); 156 libhal_drive_free(d); 157 } 158 (void) printf(gettext("Default device is: %s\n"), default_name); 159 } else if (l_opt) { 160 /* -l: list volumes and exit */ 161 print_mask = RMM_PRINT_MOUNTABLE; 162 if (eject_opt) { 163 print_mask |= RMM_PRINT_EJECTABLE; 164 } 165 rmm_print_volume_nicknames(hal_ctx, &error, print_mask); 166 } else if (optind == argc) { 167 /* no name provided, use default */ 168 if ((d = rmm_hal_volume_find_default(hal_ctx, &error, 169 &default_name, &volumes)) == NULL) { 170 (void) fprintf(stderr, 171 gettext("No default media available\n")); 172 ret = 1; 173 } else { 174 rmm_volumes_free(volumes); 175 libhal_drive_free(d); 176 177 if (query_opt) { 178 ret = rmm_rescan(hal_ctx, default_name, 179 B_TRUE) ? 0 : 1; 180 } else { 181 ret = rmm_action(hal_ctx, default_name, action, 182 0, 0, 0, 0) ? 0 : 1; 183 } 184 } 185 } else { 186 if (argc - optind > 1) { 187 mountpoint = argv[optind + 1]; 188 } 189 if (query_opt) { 190 ret = rmm_rescan(hal_ctx, argv[optind], 191 B_TRUE) ? 0 : 1; 192 } else { 193 ret = rmm_action(hal_ctx, argv[optind], action, 194 0, opts, num_opts, mountpoint) ? 0 : 1; 195 } 196 } 197 198 rmm_dbus_error_free(&error); 199 rmm_hal_fini(hal_ctx); 200 201 return (ret); 202 } 203 204 static int 205 rmumount(int argc, char **argv) 206 { 207 return (rmmount(argc, argv)); 208 } 209 210 static int 211 eject(int argc, char **argv) 212 { 213 if (getenv("EJECT_CLOSETRAY") != NULL) { 214 closetray_opt = B_TRUE; 215 } else if (getenv("EJECT_QUERY") != NULL) { 216 query_opt = B_TRUE; 217 } else { 218 eject_opt = B_TRUE; 219 } 220 return (rmmount(argc, argv)); 221 } 222 223 static void 224 nomem(void) 225 { 226 (void) fprintf(stderr, gettext("%s: Out of memory\n"), progname); 227 exit(1); 228 } 229 230 231 /* 232 * get the name by which this program was called 233 */ 234 static char * 235 get_progname(char *path) 236 { 237 char *s; 238 char *p; 239 240 if ((s = strdup(path)) == NULL) { 241 perror(path); 242 exit(1); 243 } 244 245 p = strrchr(s, '/'); 246 if (p != NULL) { 247 strcpy(s, p + 1); 248 } 249 250 return (s); 251 } 252 253 int 254 main(int argc, char **argv) 255 { 256 int ret = 1; 257 258 vold_init(argc, argv); 259 260 progname = get_progname(argv[0]); 261 262 if (strcmp(progname, "rmmount") == 0) { 263 if ((getenv("VOLUME_ACTION") != NULL) && 264 (getenv("VOLUME_PATH") != NULL)) { 265 ret = vold_rmmount(argc, argv); 266 } else { 267 ret = rmmount(argc, argv); 268 } 269 } else if (strcmp(progname, "rmumount") == 0) { 270 ret = rmumount(argc, argv); 271 } else if (strcmp(progname, "eject") == 0) { 272 ret = eject(argc, argv); 273 } else { 274 (void) fprintf(stderr, "rmmount: invalid program name\n"); 275 ret = 1; 276 } 277 278 return (ret); 279 } 280