118c2aff7Sartem /* 218c2aff7Sartem * CDDL HEADER START 318c2aff7Sartem * 418c2aff7Sartem * The contents of this file are subject to the terms of the 518c2aff7Sartem * Common Development and Distribution License (the "License"). 618c2aff7Sartem * You may not use this file except in compliance with the License. 718c2aff7Sartem * 818c2aff7Sartem * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 918c2aff7Sartem * or http://www.opensolaris.org/os/licensing. 1018c2aff7Sartem * See the License for the specific language governing permissions 1118c2aff7Sartem * and limitations under the License. 1218c2aff7Sartem * 1318c2aff7Sartem * When distributing Covered Code, include this CDDL HEADER in each 1418c2aff7Sartem * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1518c2aff7Sartem * If applicable, add the following below this CDDL HEADER, with the 1618c2aff7Sartem * fields enclosed by brackets "[]" replaced with your own identifying 1718c2aff7Sartem * information: Portions Copyright [yyyy] [name of copyright owner] 1818c2aff7Sartem * 1918c2aff7Sartem * CDDL HEADER END 2018c2aff7Sartem */ 2118c2aff7Sartem /* 22*97ddcdceSArtem Kachitchkine * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2318c2aff7Sartem * Use is subject to license terms. 2418c2aff7Sartem */ 2518c2aff7Sartem 2618c2aff7Sartem #include <stdio.h> 2718c2aff7Sartem #include <stdlib.h> 2818c2aff7Sartem #include <sys/types.h> 2918c2aff7Sartem #include <sys/stat.h> 3018c2aff7Sartem #include <dirent.h> 3118c2aff7Sartem #include <signal.h> 3218c2aff7Sartem #include <unistd.h> 3318c2aff7Sartem #include <fcntl.h> 3418c2aff7Sartem #include <strings.h> 3518c2aff7Sartem #include <libgen.h> 3618c2aff7Sartem #include <libintl.h> 3718c2aff7Sartem #include <errno.h> 3818c2aff7Sartem #include <sys/syscall.h> 3918c2aff7Sartem 4018c2aff7Sartem #include <dbus/dbus.h> 4118c2aff7Sartem #include <dbus/dbus-glib.h> 4218c2aff7Sartem #include <dbus/dbus-glib-lowlevel.h> 4318c2aff7Sartem #include <libhal.h> 4418c2aff7Sartem 4518c2aff7Sartem #include <rmm_common.h> 4618c2aff7Sartem 4718c2aff7Sartem char *progname; 4818c2aff7Sartem 4918c2aff7Sartem static boolean_t d_opt, l_opt, o_opt, u_opt, eject_opt, 5018c2aff7Sartem closetray_opt, query_opt; 5118c2aff7Sartem 5218c2aff7Sartem static void usage(); 5318c2aff7Sartem static void nomem(); 5418c2aff7Sartem 5518c2aff7Sartem static void 5618c2aff7Sartem usage() 5718c2aff7Sartem { 5818c2aff7Sartem if (!u_opt) { 5918c2aff7Sartem (void) fprintf(stderr, 6018c2aff7Sartem "%s: [-dlu] [-o options] [nickname | device] " 6118c2aff7Sartem "[mount_point]\n", progname); 6218c2aff7Sartem } else { 6318c2aff7Sartem (void) fprintf(stderr, 6418c2aff7Sartem "%s: [-dl] [nickname | device]\n", progname); 6518c2aff7Sartem } 6618c2aff7Sartem } 6718c2aff7Sartem 6818c2aff7Sartem static int 6918c2aff7Sartem rmmount(int argc, char **argv) 7018c2aff7Sartem { 7118c2aff7Sartem int c; 7218c2aff7Sartem action_t action; 7318c2aff7Sartem LibHalContext *hal_ctx; 7418c2aff7Sartem DBusError error; 7518c2aff7Sartem rmm_error_t rmm_error; 7618c2aff7Sartem LibHalDrive *d; 7718c2aff7Sartem GSList *volumes; 7818c2aff7Sartem const char *default_name; 7918c2aff7Sartem char **opts = NULL; 8018c2aff7Sartem int num_opts = 0; 8118c2aff7Sartem char *mountpoint = NULL; 8218c2aff7Sartem char **p; 830ebe3100Sartem int print_mask; 8418c2aff7Sartem int ret = 0; 8518c2aff7Sartem 8618c2aff7Sartem progname = basename(argv[0]); 8718c2aff7Sartem 8818c2aff7Sartem if (strcmp(progname, "rmumount") == 0) { 8918c2aff7Sartem u_opt = B_TRUE; 9018c2aff7Sartem } 9118c2aff7Sartem 9218c2aff7Sartem if (getenv("RMMOUNT_DEBUG") != NULL) { 9318c2aff7Sartem rmm_debug = 1; 9418c2aff7Sartem } 9518c2aff7Sartem 9618c2aff7Sartem while ((c = getopt(argc, argv, "?dlo:u")) != -1) { 9718c2aff7Sartem switch (c) { 9818c2aff7Sartem case 'd': 9918c2aff7Sartem d_opt = B_TRUE; 10018c2aff7Sartem break; 10118c2aff7Sartem case 'l': 10218c2aff7Sartem l_opt = B_TRUE; 10318c2aff7Sartem break; 10418c2aff7Sartem case 'o': 10518c2aff7Sartem o_opt = B_TRUE; 10618c2aff7Sartem if ((opts = g_strsplit(optarg, ",", 10)) == NULL) { 10718c2aff7Sartem nomem(); 10818c2aff7Sartem } 10918c2aff7Sartem for (num_opts = 0, p = &opts[0]; *p != NULL; p++) { 11018c2aff7Sartem num_opts++; 11118c2aff7Sartem } 11218c2aff7Sartem break; 11318c2aff7Sartem case 'u': 11418c2aff7Sartem u_opt = B_TRUE; 11518c2aff7Sartem break; 11618c2aff7Sartem case '?': 11718c2aff7Sartem usage(); 11818c2aff7Sartem return (0); 11918c2aff7Sartem default: 12018c2aff7Sartem usage(); 12118c2aff7Sartem return (1); 12218c2aff7Sartem } 12318c2aff7Sartem } 12418c2aff7Sartem 12518c2aff7Sartem if (u_opt) { 12618c2aff7Sartem action = UNMOUNT; 12718c2aff7Sartem } else if (closetray_opt) { 12818c2aff7Sartem action = CLOSETRAY; 12918c2aff7Sartem } else if (eject_opt) { 13018c2aff7Sartem action = EJECT; 13118c2aff7Sartem } else { 13218c2aff7Sartem action = INSERT; 13318c2aff7Sartem } 13418c2aff7Sartem 135*97ddcdceSArtem Kachitchkine if ((hal_ctx = rmm_hal_init(0, 0, 0, 0, &error, &rmm_error)) == NULL) { 13618c2aff7Sartem (void) fprintf(stderr, gettext("warning: %s\n"), 13718c2aff7Sartem rmm_strerror(&error, rmm_error)); 13818c2aff7Sartem rmm_dbus_error_free(&error); 13918c2aff7Sartem if ((rmm_error == RMM_EDBUS_CONNECT) || 14018c2aff7Sartem (rmm_error == RMM_EHAL_CONNECT)) { 14118c2aff7Sartem return (99); 14218c2aff7Sartem } else { 14318c2aff7Sartem return (1); 14418c2aff7Sartem } 14518c2aff7Sartem } 14618c2aff7Sartem 14718c2aff7Sartem if (d_opt) { 14818c2aff7Sartem /* -d: print default name and exit */ 14918c2aff7Sartem if ((d = rmm_hal_volume_find_default(hal_ctx, &error, 15018c2aff7Sartem &default_name, &volumes)) == NULL) { 15118c2aff7Sartem default_name = "nothing inserted"; 15218c2aff7Sartem } else { 15318c2aff7Sartem rmm_volumes_free(volumes); 15418c2aff7Sartem libhal_drive_free(d); 15518c2aff7Sartem } 15618c2aff7Sartem (void) printf(gettext("Default device is: %s\n"), default_name); 15718c2aff7Sartem } else if (l_opt) { 15818c2aff7Sartem /* -l: list volumes and exit */ 1590ebe3100Sartem print_mask = RMM_PRINT_MOUNTABLE; 1600ebe3100Sartem if (eject_opt) { 1610ebe3100Sartem print_mask |= RMM_PRINT_EJECTABLE; 1620ebe3100Sartem } 1630ebe3100Sartem rmm_print_volume_nicknames(hal_ctx, &error, print_mask); 16418c2aff7Sartem } else if (optind == argc) { 16518c2aff7Sartem /* no name provided, use default */ 16618c2aff7Sartem if ((d = rmm_hal_volume_find_default(hal_ctx, &error, 16718c2aff7Sartem &default_name, &volumes)) == NULL) { 16818c2aff7Sartem (void) fprintf(stderr, 16918c2aff7Sartem gettext("No default media available\n")); 17018c2aff7Sartem ret = 1; 17118c2aff7Sartem } else { 17218c2aff7Sartem rmm_volumes_free(volumes); 17318c2aff7Sartem libhal_drive_free(d); 17418c2aff7Sartem 17518c2aff7Sartem if (query_opt) { 17618c2aff7Sartem ret = rmm_rescan(hal_ctx, default_name, 17718c2aff7Sartem B_TRUE) ? 0 : 1; 17818c2aff7Sartem } else { 17918c2aff7Sartem ret = rmm_action(hal_ctx, default_name, action, 18018c2aff7Sartem 0, 0, 0, 0) ? 0 : 1; 18118c2aff7Sartem } 18218c2aff7Sartem } 18318c2aff7Sartem } else { 18418c2aff7Sartem if (argc - optind > 1) { 18518c2aff7Sartem mountpoint = argv[optind + 1]; 18618c2aff7Sartem } 18718c2aff7Sartem if (query_opt) { 18818c2aff7Sartem ret = rmm_rescan(hal_ctx, argv[optind], 18918c2aff7Sartem B_TRUE) ? 0 : 1; 19018c2aff7Sartem } else { 19118c2aff7Sartem ret = rmm_action(hal_ctx, argv[optind], action, 19218c2aff7Sartem 0, opts, num_opts, mountpoint) ? 0 : 1; 19318c2aff7Sartem } 19418c2aff7Sartem } 19518c2aff7Sartem 19618c2aff7Sartem rmm_dbus_error_free(&error); 19718c2aff7Sartem rmm_hal_fini(hal_ctx); 19818c2aff7Sartem 19918c2aff7Sartem return (ret); 20018c2aff7Sartem } 20118c2aff7Sartem 20218c2aff7Sartem static int 20318c2aff7Sartem rmumount(int argc, char **argv) 20418c2aff7Sartem { 20518c2aff7Sartem return (rmmount(argc, argv)); 20618c2aff7Sartem } 20718c2aff7Sartem 20818c2aff7Sartem static int 20918c2aff7Sartem eject(int argc, char **argv) 21018c2aff7Sartem { 21118c2aff7Sartem if (getenv("EJECT_CLOSETRAY") != NULL) { 21218c2aff7Sartem closetray_opt = B_TRUE; 21318c2aff7Sartem } else if (getenv("EJECT_QUERY") != NULL) { 21418c2aff7Sartem query_opt = B_TRUE; 21518c2aff7Sartem } else { 21618c2aff7Sartem eject_opt = B_TRUE; 21718c2aff7Sartem } 21818c2aff7Sartem return (rmmount(argc, argv)); 21918c2aff7Sartem } 22018c2aff7Sartem 22118c2aff7Sartem static void 22218c2aff7Sartem nomem(void) 22318c2aff7Sartem { 22418c2aff7Sartem (void) fprintf(stderr, gettext("%s: Out of memory\n"), progname); 22518c2aff7Sartem exit(1); 22618c2aff7Sartem } 22718c2aff7Sartem 22818c2aff7Sartem 22918c2aff7Sartem /* 23018c2aff7Sartem * get the name by which this program was called 23118c2aff7Sartem */ 23218c2aff7Sartem static char * 23318c2aff7Sartem get_progname(char *path) 23418c2aff7Sartem { 23518c2aff7Sartem char *s; 23618c2aff7Sartem char *p; 23718c2aff7Sartem 23818c2aff7Sartem if ((s = strdup(path)) == NULL) { 23918c2aff7Sartem perror(path); 24018c2aff7Sartem exit(1); 24118c2aff7Sartem } 24218c2aff7Sartem 24318c2aff7Sartem p = strrchr(s, '/'); 24418c2aff7Sartem if (p != NULL) { 24518c2aff7Sartem strcpy(s, p + 1); 24618c2aff7Sartem } 24718c2aff7Sartem 24818c2aff7Sartem return (s); 24918c2aff7Sartem } 25018c2aff7Sartem 25118c2aff7Sartem int 25218c2aff7Sartem main(int argc, char **argv) 25318c2aff7Sartem { 25418c2aff7Sartem int ret = 1; 25518c2aff7Sartem 25618c2aff7Sartem vold_init(argc, argv); 25718c2aff7Sartem 25818c2aff7Sartem progname = get_progname(argv[0]); 25918c2aff7Sartem 26018c2aff7Sartem if (strcmp(progname, "rmmount") == 0) { 26118c2aff7Sartem if ((getenv("VOLUME_ACTION") != NULL) && 26218c2aff7Sartem (getenv("VOLUME_PATH") != NULL)) { 26318c2aff7Sartem ret = vold_rmmount(argc, argv); 26418c2aff7Sartem } else { 26518c2aff7Sartem ret = rmmount(argc, argv); 26618c2aff7Sartem } 26718c2aff7Sartem } else if (strcmp(progname, "rmumount") == 0) { 26818c2aff7Sartem ret = rmumount(argc, argv); 26918c2aff7Sartem } else if (strcmp(progname, "eject") == 0) { 27018c2aff7Sartem ret = eject(argc, argv); 27118c2aff7Sartem } else { 27218c2aff7Sartem (void) fprintf(stderr, "rmmount: invalid program name\n"); 27318c2aff7Sartem ret = 1; 27418c2aff7Sartem } 27518c2aff7Sartem 27618c2aff7Sartem return (ret); 27718c2aff7Sartem } 278