xref: /titanic_50/usr/src/cmd/rmmount/rmmount.c (revision 18c2aff776a775d34a4c9893a4c72e0434d68e36)
1*18c2aff7Sartem /*
2*18c2aff7Sartem  * CDDL HEADER START
3*18c2aff7Sartem  *
4*18c2aff7Sartem  * The contents of this file are subject to the terms of the
5*18c2aff7Sartem  * Common Development and Distribution License (the "License").
6*18c2aff7Sartem  * You may not use this file except in compliance with the License.
7*18c2aff7Sartem  *
8*18c2aff7Sartem  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*18c2aff7Sartem  * or http://www.opensolaris.org/os/licensing.
10*18c2aff7Sartem  * See the License for the specific language governing permissions
11*18c2aff7Sartem  * and limitations under the License.
12*18c2aff7Sartem  *
13*18c2aff7Sartem  * When distributing Covered Code, include this CDDL HEADER in each
14*18c2aff7Sartem  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*18c2aff7Sartem  * If applicable, add the following below this CDDL HEADER, with the
16*18c2aff7Sartem  * fields enclosed by brackets "[]" replaced with your own identifying
17*18c2aff7Sartem  * information: Portions Copyright [yyyy] [name of copyright owner]
18*18c2aff7Sartem  *
19*18c2aff7Sartem  * CDDL HEADER END
20*18c2aff7Sartem  */
21*18c2aff7Sartem /*
22*18c2aff7Sartem  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*18c2aff7Sartem  * Use is subject to license terms.
24*18c2aff7Sartem  */
25*18c2aff7Sartem 
26*18c2aff7Sartem #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*18c2aff7Sartem 
28*18c2aff7Sartem #include <stdio.h>
29*18c2aff7Sartem #include <stdlib.h>
30*18c2aff7Sartem #include <sys/types.h>
31*18c2aff7Sartem #include <sys/stat.h>
32*18c2aff7Sartem #include <dirent.h>
33*18c2aff7Sartem #include <signal.h>
34*18c2aff7Sartem #include <unistd.h>
35*18c2aff7Sartem #include <fcntl.h>
36*18c2aff7Sartem #include <strings.h>
37*18c2aff7Sartem #include <libgen.h>
38*18c2aff7Sartem #include <libintl.h>
39*18c2aff7Sartem #include <errno.h>
40*18c2aff7Sartem #include <sys/syscall.h>
41*18c2aff7Sartem 
42*18c2aff7Sartem #include <dbus/dbus.h>
43*18c2aff7Sartem #include <dbus/dbus-glib.h>
44*18c2aff7Sartem #include <dbus/dbus-glib-lowlevel.h>
45*18c2aff7Sartem #include <libhal.h>
46*18c2aff7Sartem 
47*18c2aff7Sartem #include <rmm_common.h>
48*18c2aff7Sartem 
49*18c2aff7Sartem char	*progname;
50*18c2aff7Sartem 
51*18c2aff7Sartem static boolean_t d_opt, l_opt, o_opt, u_opt, eject_opt,
52*18c2aff7Sartem     closetray_opt, query_opt;
53*18c2aff7Sartem 
54*18c2aff7Sartem static void usage();
55*18c2aff7Sartem static void nomem();
56*18c2aff7Sartem 
57*18c2aff7Sartem static void
58*18c2aff7Sartem usage()
59*18c2aff7Sartem {
60*18c2aff7Sartem 	if (!u_opt) {
61*18c2aff7Sartem 		(void) fprintf(stderr,
62*18c2aff7Sartem 		    "%s: [-dlu] [-o options] [nickname | device] "
63*18c2aff7Sartem 		    "[mount_point]\n", progname);
64*18c2aff7Sartem 	} else {
65*18c2aff7Sartem 		(void) fprintf(stderr,
66*18c2aff7Sartem 		    "%s: [-dl] [nickname | device]\n", progname);
67*18c2aff7Sartem 	}
68*18c2aff7Sartem }
69*18c2aff7Sartem 
70*18c2aff7Sartem static int
71*18c2aff7Sartem rmmount(int argc, char **argv)
72*18c2aff7Sartem {
73*18c2aff7Sartem 	int		c;
74*18c2aff7Sartem 	action_t	action;
75*18c2aff7Sartem 	LibHalContext	*hal_ctx;
76*18c2aff7Sartem 	DBusError	error;
77*18c2aff7Sartem 	rmm_error_t	rmm_error;
78*18c2aff7Sartem 	LibHalDrive	*d;
79*18c2aff7Sartem 	GSList		*volumes;
80*18c2aff7Sartem 	const char	*default_name;
81*18c2aff7Sartem 	char		**opts = NULL;
82*18c2aff7Sartem 	int		num_opts = 0;
83*18c2aff7Sartem 	char		*mountpoint = NULL;
84*18c2aff7Sartem 	char		**p;
85*18c2aff7Sartem 	int		ret = 0;
86*18c2aff7Sartem 
87*18c2aff7Sartem 	progname = basename(argv[0]);
88*18c2aff7Sartem 
89*18c2aff7Sartem 	if (strcmp(progname, "rmumount") == 0) {
90*18c2aff7Sartem 		u_opt = B_TRUE;
91*18c2aff7Sartem 	}
92*18c2aff7Sartem 
93*18c2aff7Sartem 	if (getenv("RMMOUNT_DEBUG") != NULL) {
94*18c2aff7Sartem 		rmm_debug = 1;
95*18c2aff7Sartem 	}
96*18c2aff7Sartem 
97*18c2aff7Sartem 	while ((c = getopt(argc, argv, "?dlo:u")) != -1) {
98*18c2aff7Sartem 		switch (c) {
99*18c2aff7Sartem 		case 'd':
100*18c2aff7Sartem 			d_opt = B_TRUE;
101*18c2aff7Sartem 			break;
102*18c2aff7Sartem 		case 'l':
103*18c2aff7Sartem 			l_opt = B_TRUE;
104*18c2aff7Sartem 			break;
105*18c2aff7Sartem 		case 'o':
106*18c2aff7Sartem 			o_opt = B_TRUE;
107*18c2aff7Sartem 			if ((opts = g_strsplit(optarg, ",", 10)) == NULL) {
108*18c2aff7Sartem 				nomem();
109*18c2aff7Sartem 			}
110*18c2aff7Sartem 			for (num_opts = 0, p = &opts[0]; *p != NULL; p++) {
111*18c2aff7Sartem 				num_opts++;
112*18c2aff7Sartem 			}
113*18c2aff7Sartem 			break;
114*18c2aff7Sartem 		case 'u':
115*18c2aff7Sartem 			u_opt = B_TRUE;
116*18c2aff7Sartem 			break;
117*18c2aff7Sartem 		case '?':
118*18c2aff7Sartem 			usage();
119*18c2aff7Sartem 			return (0);
120*18c2aff7Sartem 		default:
121*18c2aff7Sartem 			usage();
122*18c2aff7Sartem 			return (1);
123*18c2aff7Sartem 		}
124*18c2aff7Sartem 	}
125*18c2aff7Sartem 
126*18c2aff7Sartem 	if (u_opt) {
127*18c2aff7Sartem 		action = UNMOUNT;
128*18c2aff7Sartem 	} else if (closetray_opt) {
129*18c2aff7Sartem 		action = CLOSETRAY;
130*18c2aff7Sartem 	} else if (eject_opt) {
131*18c2aff7Sartem 		action = EJECT;
132*18c2aff7Sartem 	} else {
133*18c2aff7Sartem 		action = INSERT;
134*18c2aff7Sartem 	}
135*18c2aff7Sartem 
136*18c2aff7Sartem 	if ((hal_ctx = rmm_hal_init(0, 0, 0, &error, &rmm_error)) == NULL) {
137*18c2aff7Sartem 		(void) fprintf(stderr, gettext("warning: %s\n"),
138*18c2aff7Sartem 		    rmm_strerror(&error, rmm_error));
139*18c2aff7Sartem 		rmm_dbus_error_free(&error);
140*18c2aff7Sartem 		if ((rmm_error == RMM_EDBUS_CONNECT) ||
141*18c2aff7Sartem 		    (rmm_error == RMM_EHAL_CONNECT)) {
142*18c2aff7Sartem 			return (99);
143*18c2aff7Sartem 		} else {
144*18c2aff7Sartem 			return (1);
145*18c2aff7Sartem 		}
146*18c2aff7Sartem 	}
147*18c2aff7Sartem 
148*18c2aff7Sartem 	if (d_opt) {
149*18c2aff7Sartem 		/* -d: print default name and exit */
150*18c2aff7Sartem 		if ((d = rmm_hal_volume_find_default(hal_ctx, &error,
151*18c2aff7Sartem 		    &default_name, &volumes)) == NULL) {
152*18c2aff7Sartem 			default_name = "nothing inserted";
153*18c2aff7Sartem 		} else {
154*18c2aff7Sartem 			rmm_volumes_free(volumes);
155*18c2aff7Sartem 			libhal_drive_free(d);
156*18c2aff7Sartem 		}
157*18c2aff7Sartem 		(void) printf(gettext("Default device is: %s\n"), default_name);
158*18c2aff7Sartem 	} else if (l_opt) {
159*18c2aff7Sartem 		/* -l: list volumes and exit */
160*18c2aff7Sartem 		rmm_print_volume_nicknames(hal_ctx, &error);
161*18c2aff7Sartem 	} else if (optind == argc) {
162*18c2aff7Sartem 		/* no name provided, use default */
163*18c2aff7Sartem 		if ((d = rmm_hal_volume_find_default(hal_ctx, &error,
164*18c2aff7Sartem 		    &default_name, &volumes)) == NULL) {
165*18c2aff7Sartem 			(void) fprintf(stderr,
166*18c2aff7Sartem 			    gettext("No default media available\n"));
167*18c2aff7Sartem 			ret = 1;
168*18c2aff7Sartem 		} else {
169*18c2aff7Sartem 			rmm_volumes_free(volumes);
170*18c2aff7Sartem 			libhal_drive_free(d);
171*18c2aff7Sartem 
172*18c2aff7Sartem 			if (query_opt) {
173*18c2aff7Sartem 				ret = rmm_rescan(hal_ctx, default_name,
174*18c2aff7Sartem 				    B_TRUE) ? 0 : 1;
175*18c2aff7Sartem 			} else {
176*18c2aff7Sartem 				ret = rmm_action(hal_ctx, default_name, action,
177*18c2aff7Sartem 				    0, 0, 0, 0) ? 0 : 1;
178*18c2aff7Sartem 			}
179*18c2aff7Sartem 		}
180*18c2aff7Sartem 	} else {
181*18c2aff7Sartem 		if (argc - optind > 1) {
182*18c2aff7Sartem 			mountpoint = argv[optind + 1];
183*18c2aff7Sartem 		}
184*18c2aff7Sartem 		if (query_opt) {
185*18c2aff7Sartem 			ret = rmm_rescan(hal_ctx, argv[optind],
186*18c2aff7Sartem 			    B_TRUE) ? 0 : 1;
187*18c2aff7Sartem 		} else {
188*18c2aff7Sartem 			ret = rmm_action(hal_ctx, argv[optind], action,
189*18c2aff7Sartem 			    0, opts, num_opts, mountpoint) ? 0 : 1;
190*18c2aff7Sartem 		}
191*18c2aff7Sartem 	}
192*18c2aff7Sartem 
193*18c2aff7Sartem 	rmm_dbus_error_free(&error);
194*18c2aff7Sartem 	rmm_hal_fini(hal_ctx);
195*18c2aff7Sartem 
196*18c2aff7Sartem 	return (ret);
197*18c2aff7Sartem }
198*18c2aff7Sartem 
199*18c2aff7Sartem static int
200*18c2aff7Sartem rmumount(int argc, char **argv)
201*18c2aff7Sartem {
202*18c2aff7Sartem 	return (rmmount(argc, argv));
203*18c2aff7Sartem }
204*18c2aff7Sartem 
205*18c2aff7Sartem static int
206*18c2aff7Sartem eject(int argc, char **argv)
207*18c2aff7Sartem {
208*18c2aff7Sartem 	if (getenv("EJECT_CLOSETRAY") != NULL) {
209*18c2aff7Sartem 		closetray_opt = B_TRUE;
210*18c2aff7Sartem 	} else if (getenv("EJECT_QUERY") != NULL) {
211*18c2aff7Sartem 		query_opt = B_TRUE;
212*18c2aff7Sartem 	} else {
213*18c2aff7Sartem 		eject_opt = B_TRUE;
214*18c2aff7Sartem 	}
215*18c2aff7Sartem 	return (rmmount(argc, argv));
216*18c2aff7Sartem }
217*18c2aff7Sartem 
218*18c2aff7Sartem static void
219*18c2aff7Sartem nomem(void)
220*18c2aff7Sartem {
221*18c2aff7Sartem 	(void) fprintf(stderr, gettext("%s: Out of memory\n"), progname);
222*18c2aff7Sartem 	exit(1);
223*18c2aff7Sartem }
224*18c2aff7Sartem 
225*18c2aff7Sartem 
226*18c2aff7Sartem /*
227*18c2aff7Sartem  * get the name by which this program was called
228*18c2aff7Sartem  */
229*18c2aff7Sartem static char *
230*18c2aff7Sartem get_progname(char *path)
231*18c2aff7Sartem {
232*18c2aff7Sartem 	char    *s;
233*18c2aff7Sartem 	char    *p;
234*18c2aff7Sartem 
235*18c2aff7Sartem 	if ((s = strdup(path)) == NULL) {
236*18c2aff7Sartem 		perror(path);
237*18c2aff7Sartem 		exit(1);
238*18c2aff7Sartem 	}
239*18c2aff7Sartem 
240*18c2aff7Sartem 	p = strrchr(s, '/');
241*18c2aff7Sartem 	if (p != NULL) {
242*18c2aff7Sartem 		strcpy(s, p + 1);
243*18c2aff7Sartem 	}
244*18c2aff7Sartem 
245*18c2aff7Sartem 	return (s);
246*18c2aff7Sartem }
247*18c2aff7Sartem 
248*18c2aff7Sartem int
249*18c2aff7Sartem main(int argc, char **argv)
250*18c2aff7Sartem {
251*18c2aff7Sartem 	int ret = 1;
252*18c2aff7Sartem 
253*18c2aff7Sartem 	vold_init(argc, argv);
254*18c2aff7Sartem 
255*18c2aff7Sartem 	progname = get_progname(argv[0]);
256*18c2aff7Sartem 
257*18c2aff7Sartem 	if (strcmp(progname, "rmmount") == 0) {
258*18c2aff7Sartem 		if ((getenv("VOLUME_ACTION") != NULL) &&
259*18c2aff7Sartem 		    (getenv("VOLUME_PATH") != NULL)) {
260*18c2aff7Sartem 			ret = vold_rmmount(argc, argv);
261*18c2aff7Sartem 		} else {
262*18c2aff7Sartem 			ret = rmmount(argc, argv);
263*18c2aff7Sartem 		}
264*18c2aff7Sartem 	} else if (strcmp(progname, "rmumount") == 0) {
265*18c2aff7Sartem 		ret = rmumount(argc, argv);
266*18c2aff7Sartem 	} else if (strcmp(progname, "eject") == 0) {
267*18c2aff7Sartem 		ret = eject(argc, argv);
268*18c2aff7Sartem 	} else {
269*18c2aff7Sartem 		(void) fprintf(stderr, "rmmount: invalid program name\n");
270*18c2aff7Sartem 		ret = 1;
271*18c2aff7Sartem 	}
272*18c2aff7Sartem 
273*18c2aff7Sartem 	return (ret);
274*18c2aff7Sartem }
275