xref: /illumos-gate/usr/src/cmd/rmmount/rmmount.c (revision 97ddcdce)
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