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 /* 2218c2aff7Sartem * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 2318c2aff7Sartem * Use is subject to license terms. 2418c2aff7Sartem */ 2518c2aff7Sartem 2618c2aff7Sartem #pragma ident "%Z%%M% %I% %E% SMI" 2718c2aff7Sartem 2818c2aff7Sartem #include <stdio.h> 2918c2aff7Sartem #include <stdlib.h> 3018c2aff7Sartem #include <sys/types.h> 3118c2aff7Sartem #include <sys/stat.h> 3218c2aff7Sartem #include <dirent.h> 3318c2aff7Sartem #include <signal.h> 3418c2aff7Sartem #include <unistd.h> 3518c2aff7Sartem #include <fcntl.h> 3618c2aff7Sartem #include <strings.h> 3718c2aff7Sartem #include <libgen.h> 3818c2aff7Sartem #include <libintl.h> 3918c2aff7Sartem #include <errno.h> 4018c2aff7Sartem #include <sys/syscall.h> 4118c2aff7Sartem 4218c2aff7Sartem #include <dbus/dbus.h> 4318c2aff7Sartem #include <dbus/dbus-glib.h> 4418c2aff7Sartem #include <dbus/dbus-glib-lowlevel.h> 4518c2aff7Sartem #include <libhal.h> 4618c2aff7Sartem 4718c2aff7Sartem #include <rmm_common.h> 4818c2aff7Sartem 4918c2aff7Sartem char *progname; 5018c2aff7Sartem 5118c2aff7Sartem static boolean_t d_opt, l_opt, o_opt, u_opt, eject_opt, 5218c2aff7Sartem closetray_opt, query_opt; 5318c2aff7Sartem 5418c2aff7Sartem static void usage(); 5518c2aff7Sartem static void nomem(); 5618c2aff7Sartem 5718c2aff7Sartem static void 5818c2aff7Sartem usage() 5918c2aff7Sartem { 6018c2aff7Sartem if (!u_opt) { 6118c2aff7Sartem (void) fprintf(stderr, 6218c2aff7Sartem "%s: [-dlu] [-o options] [nickname | device] " 6318c2aff7Sartem "[mount_point]\n", progname); 6418c2aff7Sartem } else { 6518c2aff7Sartem (void) fprintf(stderr, 6618c2aff7Sartem "%s: [-dl] [nickname | device]\n", progname); 6718c2aff7Sartem } 6818c2aff7Sartem } 6918c2aff7Sartem 7018c2aff7Sartem static int 7118c2aff7Sartem rmmount(int argc, char **argv) 7218c2aff7Sartem { 7318c2aff7Sartem int c; 7418c2aff7Sartem action_t action; 7518c2aff7Sartem LibHalContext *hal_ctx; 7618c2aff7Sartem DBusError error; 7718c2aff7Sartem rmm_error_t rmm_error; 7818c2aff7Sartem LibHalDrive *d; 7918c2aff7Sartem GSList *volumes; 8018c2aff7Sartem const char *default_name; 8118c2aff7Sartem char **opts = NULL; 8218c2aff7Sartem int num_opts = 0; 8318c2aff7Sartem char *mountpoint = NULL; 8418c2aff7Sartem char **p; 85*0ebe3100Sartem int print_mask; 8618c2aff7Sartem int ret = 0; 8718c2aff7Sartem 8818c2aff7Sartem progname = basename(argv[0]); 8918c2aff7Sartem 9018c2aff7Sartem if (strcmp(progname, "rmumount") == 0) { 9118c2aff7Sartem u_opt = B_TRUE; 9218c2aff7Sartem } 9318c2aff7Sartem 9418c2aff7Sartem if (getenv("RMMOUNT_DEBUG") != NULL) { 9518c2aff7Sartem rmm_debug = 1; 9618c2aff7Sartem } 9718c2aff7Sartem 9818c2aff7Sartem while ((c = getopt(argc, argv, "?dlo:u")) != -1) { 9918c2aff7Sartem switch (c) { 10018c2aff7Sartem case 'd': 10118c2aff7Sartem d_opt = B_TRUE; 10218c2aff7Sartem break; 10318c2aff7Sartem case 'l': 10418c2aff7Sartem l_opt = B_TRUE; 10518c2aff7Sartem break; 10618c2aff7Sartem case 'o': 10718c2aff7Sartem o_opt = B_TRUE; 10818c2aff7Sartem if ((opts = g_strsplit(optarg, ",", 10)) == NULL) { 10918c2aff7Sartem nomem(); 11018c2aff7Sartem } 11118c2aff7Sartem for (num_opts = 0, p = &opts[0]; *p != NULL; p++) { 11218c2aff7Sartem num_opts++; 11318c2aff7Sartem } 11418c2aff7Sartem break; 11518c2aff7Sartem case 'u': 11618c2aff7Sartem u_opt = B_TRUE; 11718c2aff7Sartem break; 11818c2aff7Sartem case '?': 11918c2aff7Sartem usage(); 12018c2aff7Sartem return (0); 12118c2aff7Sartem default: 12218c2aff7Sartem usage(); 12318c2aff7Sartem return (1); 12418c2aff7Sartem } 12518c2aff7Sartem } 12618c2aff7Sartem 12718c2aff7Sartem if (u_opt) { 12818c2aff7Sartem action = UNMOUNT; 12918c2aff7Sartem } else if (closetray_opt) { 13018c2aff7Sartem action = CLOSETRAY; 13118c2aff7Sartem } else if (eject_opt) { 13218c2aff7Sartem action = EJECT; 13318c2aff7Sartem } else { 13418c2aff7Sartem action = INSERT; 13518c2aff7Sartem } 13618c2aff7Sartem 13718c2aff7Sartem if ((hal_ctx = rmm_hal_init(0, 0, 0, &error, &rmm_error)) == NULL) { 13818c2aff7Sartem (void) fprintf(stderr, gettext("warning: %s\n"), 13918c2aff7Sartem rmm_strerror(&error, rmm_error)); 14018c2aff7Sartem rmm_dbus_error_free(&error); 14118c2aff7Sartem if ((rmm_error == RMM_EDBUS_CONNECT) || 14218c2aff7Sartem (rmm_error == RMM_EHAL_CONNECT)) { 14318c2aff7Sartem return (99); 14418c2aff7Sartem } else { 14518c2aff7Sartem return (1); 14618c2aff7Sartem } 14718c2aff7Sartem } 14818c2aff7Sartem 14918c2aff7Sartem if (d_opt) { 15018c2aff7Sartem /* -d: print default name and exit */ 15118c2aff7Sartem if ((d = rmm_hal_volume_find_default(hal_ctx, &error, 15218c2aff7Sartem &default_name, &volumes)) == NULL) { 15318c2aff7Sartem default_name = "nothing inserted"; 15418c2aff7Sartem } else { 15518c2aff7Sartem rmm_volumes_free(volumes); 15618c2aff7Sartem libhal_drive_free(d); 15718c2aff7Sartem } 15818c2aff7Sartem (void) printf(gettext("Default device is: %s\n"), default_name); 15918c2aff7Sartem } else if (l_opt) { 16018c2aff7Sartem /* -l: list volumes and exit */ 161*0ebe3100Sartem print_mask = RMM_PRINT_MOUNTABLE; 162*0ebe3100Sartem if (eject_opt) { 163*0ebe3100Sartem print_mask |= RMM_PRINT_EJECTABLE; 164*0ebe3100Sartem } 165*0ebe3100Sartem rmm_print_volume_nicknames(hal_ctx, &error, print_mask); 16618c2aff7Sartem } else if (optind == argc) { 16718c2aff7Sartem /* no name provided, use default */ 16818c2aff7Sartem if ((d = rmm_hal_volume_find_default(hal_ctx, &error, 16918c2aff7Sartem &default_name, &volumes)) == NULL) { 17018c2aff7Sartem (void) fprintf(stderr, 17118c2aff7Sartem gettext("No default media available\n")); 17218c2aff7Sartem ret = 1; 17318c2aff7Sartem } else { 17418c2aff7Sartem rmm_volumes_free(volumes); 17518c2aff7Sartem libhal_drive_free(d); 17618c2aff7Sartem 17718c2aff7Sartem if (query_opt) { 17818c2aff7Sartem ret = rmm_rescan(hal_ctx, default_name, 17918c2aff7Sartem B_TRUE) ? 0 : 1; 18018c2aff7Sartem } else { 18118c2aff7Sartem ret = rmm_action(hal_ctx, default_name, action, 18218c2aff7Sartem 0, 0, 0, 0) ? 0 : 1; 18318c2aff7Sartem } 18418c2aff7Sartem } 18518c2aff7Sartem } else { 18618c2aff7Sartem if (argc - optind > 1) { 18718c2aff7Sartem mountpoint = argv[optind + 1]; 18818c2aff7Sartem } 18918c2aff7Sartem if (query_opt) { 19018c2aff7Sartem ret = rmm_rescan(hal_ctx, argv[optind], 19118c2aff7Sartem B_TRUE) ? 0 : 1; 19218c2aff7Sartem } else { 19318c2aff7Sartem ret = rmm_action(hal_ctx, argv[optind], action, 19418c2aff7Sartem 0, opts, num_opts, mountpoint) ? 0 : 1; 19518c2aff7Sartem } 19618c2aff7Sartem } 19718c2aff7Sartem 19818c2aff7Sartem rmm_dbus_error_free(&error); 19918c2aff7Sartem rmm_hal_fini(hal_ctx); 20018c2aff7Sartem 20118c2aff7Sartem return (ret); 20218c2aff7Sartem } 20318c2aff7Sartem 20418c2aff7Sartem static int 20518c2aff7Sartem rmumount(int argc, char **argv) 20618c2aff7Sartem { 20718c2aff7Sartem return (rmmount(argc, argv)); 20818c2aff7Sartem } 20918c2aff7Sartem 21018c2aff7Sartem static int 21118c2aff7Sartem eject(int argc, char **argv) 21218c2aff7Sartem { 21318c2aff7Sartem if (getenv("EJECT_CLOSETRAY") != NULL) { 21418c2aff7Sartem closetray_opt = B_TRUE; 21518c2aff7Sartem } else if (getenv("EJECT_QUERY") != NULL) { 21618c2aff7Sartem query_opt = B_TRUE; 21718c2aff7Sartem } else { 21818c2aff7Sartem eject_opt = B_TRUE; 21918c2aff7Sartem } 22018c2aff7Sartem return (rmmount(argc, argv)); 22118c2aff7Sartem } 22218c2aff7Sartem 22318c2aff7Sartem static void 22418c2aff7Sartem nomem(void) 22518c2aff7Sartem { 22618c2aff7Sartem (void) fprintf(stderr, gettext("%s: Out of memory\n"), progname); 22718c2aff7Sartem exit(1); 22818c2aff7Sartem } 22918c2aff7Sartem 23018c2aff7Sartem 23118c2aff7Sartem /* 23218c2aff7Sartem * get the name by which this program was called 23318c2aff7Sartem */ 23418c2aff7Sartem static char * 23518c2aff7Sartem get_progname(char *path) 23618c2aff7Sartem { 23718c2aff7Sartem char *s; 23818c2aff7Sartem char *p; 23918c2aff7Sartem 24018c2aff7Sartem if ((s = strdup(path)) == NULL) { 24118c2aff7Sartem perror(path); 24218c2aff7Sartem exit(1); 24318c2aff7Sartem } 24418c2aff7Sartem 24518c2aff7Sartem p = strrchr(s, '/'); 24618c2aff7Sartem if (p != NULL) { 24718c2aff7Sartem strcpy(s, p + 1); 24818c2aff7Sartem } 24918c2aff7Sartem 25018c2aff7Sartem return (s); 25118c2aff7Sartem } 25218c2aff7Sartem 25318c2aff7Sartem int 25418c2aff7Sartem main(int argc, char **argv) 25518c2aff7Sartem { 25618c2aff7Sartem int ret = 1; 25718c2aff7Sartem 25818c2aff7Sartem vold_init(argc, argv); 25918c2aff7Sartem 26018c2aff7Sartem progname = get_progname(argv[0]); 26118c2aff7Sartem 26218c2aff7Sartem if (strcmp(progname, "rmmount") == 0) { 26318c2aff7Sartem if ((getenv("VOLUME_ACTION") != NULL) && 26418c2aff7Sartem (getenv("VOLUME_PATH") != NULL)) { 26518c2aff7Sartem ret = vold_rmmount(argc, argv); 26618c2aff7Sartem } else { 26718c2aff7Sartem ret = rmmount(argc, argv); 26818c2aff7Sartem } 26918c2aff7Sartem } else if (strcmp(progname, "rmumount") == 0) { 27018c2aff7Sartem ret = rmumount(argc, argv); 27118c2aff7Sartem } else if (strcmp(progname, "eject") == 0) { 27218c2aff7Sartem ret = eject(argc, argv); 27318c2aff7Sartem } else { 27418c2aff7Sartem (void) fprintf(stderr, "rmmount: invalid program name\n"); 27518c2aff7Sartem ret = 1; 27618c2aff7Sartem } 27718c2aff7Sartem 27818c2aff7Sartem return (ret); 27918c2aff7Sartem } 280