xref: /titanic_50/usr/src/cmd/rmmount/rmmount.c (revision 0ebe310024a809595007753781dc9969750affbc)
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