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
usage()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
rmmount(int argc,char ** argv)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
rmumount(int argc,char ** argv)20318c2aff7Sartem rmumount(int argc, char **argv)
20418c2aff7Sartem {
20518c2aff7Sartem return (rmmount(argc, argv));
20618c2aff7Sartem }
20718c2aff7Sartem
20818c2aff7Sartem static int
eject(int argc,char ** argv)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
nomem(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 *
get_progname(char * path)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
main(int argc,char ** argv)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