rmmount.c revision 3168:18866604610a
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 49char *progname; 50 51static boolean_t d_opt, l_opt, o_opt, u_opt, eject_opt, 52 closetray_opt, query_opt; 53 54static void usage(); 55static void nomem(); 56 57static void 58usage() 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 70static int 71rmmount(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 204static int 205rmumount(int argc, char **argv) 206{ 207 return (rmmount(argc, argv)); 208} 209 210static int 211eject(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 223static void 224nomem(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 */ 234static char * 235get_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 253int 254main(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