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