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 ret = 0; 86 87 progname = basename(argv[0]); 88 89 if (strcmp(progname, "rmumount") == 0) { 90 u_opt = B_TRUE; 91 } 92 93 if (getenv("RMMOUNT_DEBUG") != NULL) { 94 rmm_debug = 1; 95 } 96 97 while ((c = getopt(argc, argv, "?dlo:u")) != -1) { 98 switch (c) { 99 case 'd': 100 d_opt = B_TRUE; 101 break; 102 case 'l': 103 l_opt = B_TRUE; 104 break; 105 case 'o': 106 o_opt = B_TRUE; 107 if ((opts = g_strsplit(optarg, ",", 10)) == NULL) { 108 nomem(); 109 } 110 for (num_opts = 0, p = &opts[0]; *p != NULL; p++) { 111 num_opts++; 112 } 113 break; 114 case 'u': 115 u_opt = B_TRUE; 116 break; 117 case '?': 118 usage(); 119 return (0); 120 default: 121 usage(); 122 return (1); 123 } 124 } 125 126 if (u_opt) { 127 action = UNMOUNT; 128 } else if (closetray_opt) { 129 action = CLOSETRAY; 130 } else if (eject_opt) { 131 action = EJECT; 132 } else { 133 action = INSERT; 134 } 135 136 if ((hal_ctx = rmm_hal_init(0, 0, 0, &error, &rmm_error)) == NULL) { 137 (void) fprintf(stderr, gettext("warning: %s\n"), 138 rmm_strerror(&error, rmm_error)); 139 rmm_dbus_error_free(&error); 140 if ((rmm_error == RMM_EDBUS_CONNECT) || 141 (rmm_error == RMM_EHAL_CONNECT)) { 142 return (99); 143 } else { 144 return (1); 145 } 146 } 147 148 if (d_opt) { 149 /* -d: print default name and exit */ 150 if ((d = rmm_hal_volume_find_default(hal_ctx, &error, 151 &default_name, &volumes)) == NULL) { 152 default_name = "nothing inserted"; 153 } else { 154 rmm_volumes_free(volumes); 155 libhal_drive_free(d); 156 } 157 (void) printf(gettext("Default device is: %s\n"), default_name); 158 } else if (l_opt) { 159 /* -l: list volumes and exit */ 160 rmm_print_volume_nicknames(hal_ctx, &error); 161 } else if (optind == argc) { 162 /* no name provided, use default */ 163 if ((d = rmm_hal_volume_find_default(hal_ctx, &error, 164 &default_name, &volumes)) == NULL) { 165 (void) fprintf(stderr, 166 gettext("No default media available\n")); 167 ret = 1; 168 } else { 169 rmm_volumes_free(volumes); 170 libhal_drive_free(d); 171 172 if (query_opt) { 173 ret = rmm_rescan(hal_ctx, default_name, 174 B_TRUE) ? 0 : 1; 175 } else { 176 ret = rmm_action(hal_ctx, default_name, action, 177 0, 0, 0, 0) ? 0 : 1; 178 } 179 } 180 } else { 181 if (argc - optind > 1) { 182 mountpoint = argv[optind + 1]; 183 } 184 if (query_opt) { 185 ret = rmm_rescan(hal_ctx, argv[optind], 186 B_TRUE) ? 0 : 1; 187 } else { 188 ret = rmm_action(hal_ctx, argv[optind], action, 189 0, opts, num_opts, mountpoint) ? 0 : 1; 190 } 191 } 192 193 rmm_dbus_error_free(&error); 194 rmm_hal_fini(hal_ctx); 195 196 return (ret); 197 } 198 199 static int 200 rmumount(int argc, char **argv) 201 { 202 return (rmmount(argc, argv)); 203 } 204 205 static int 206 eject(int argc, char **argv) 207 { 208 if (getenv("EJECT_CLOSETRAY") != NULL) { 209 closetray_opt = B_TRUE; 210 } else if (getenv("EJECT_QUERY") != NULL) { 211 query_opt = B_TRUE; 212 } else { 213 eject_opt = B_TRUE; 214 } 215 return (rmmount(argc, argv)); 216 } 217 218 static void 219 nomem(void) 220 { 221 (void) fprintf(stderr, gettext("%s: Out of memory\n"), progname); 222 exit(1); 223 } 224 225 226 /* 227 * get the name by which this program was called 228 */ 229 static char * 230 get_progname(char *path) 231 { 232 char *s; 233 char *p; 234 235 if ((s = strdup(path)) == NULL) { 236 perror(path); 237 exit(1); 238 } 239 240 p = strrchr(s, '/'); 241 if (p != NULL) { 242 strcpy(s, p + 1); 243 } 244 245 return (s); 246 } 247 248 int 249 main(int argc, char **argv) 250 { 251 int ret = 1; 252 253 vold_init(argc, argv); 254 255 progname = get_progname(argv[0]); 256 257 if (strcmp(progname, "rmmount") == 0) { 258 if ((getenv("VOLUME_ACTION") != NULL) && 259 (getenv("VOLUME_PATH") != NULL)) { 260 ret = vold_rmmount(argc, argv); 261 } else { 262 ret = rmmount(argc, argv); 263 } 264 } else if (strcmp(progname, "rmumount") == 0) { 265 ret = rmumount(argc, argv); 266 } else if (strcmp(progname, "eject") == 0) { 267 ret = eject(argc, argv); 268 } else { 269 (void) fprintf(stderr, "rmmount: invalid program name\n"); 270 ret = 1; 271 } 272 273 return (ret); 274 } 275