xref: /illumos-gate/usr/src/cmd/rmmount/rmmount.c (revision bb25c06c)
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		ret = 0;
86 
87 	progname = basename(argv[0]);
88 
89 	if (strcmp(progname, "rmumount") == 0) {
90 		u_opt = B_TRUE;
91 	}
92 
93 	if (getenv("RMMOUNT_DEBUG") != NULL) {
94 		rmm_debug = 1;
95 	}
96 
97 	while ((c = getopt(argc, argv, "?dlo:u")) != -1) {
98 		switch (c) {
99 		case 'd':
100 			d_opt = B_TRUE;
101 			break;
102 		case 'l':
103 			l_opt = B_TRUE;
104 			break;
105 		case 'o':
106 			o_opt = B_TRUE;
107 			if ((opts = g_strsplit(optarg, ",", 10)) == NULL) {
108 				nomem();
109 			}
110 			for (num_opts = 0, p = &opts[0]; *p != NULL; p++) {
111 				num_opts++;
112 			}
113 			break;
114 		case 'u':
115 			u_opt = B_TRUE;
116 			break;
117 		case '?':
118 			usage();
119 			return (0);
120 		default:
121 			usage();
122 			return (1);
123 		}
124 	}
125 
126 	if (u_opt) {
127 		action = UNMOUNT;
128 	} else if (closetray_opt) {
129 		action = CLOSETRAY;
130 	} else if (eject_opt) {
131 		action = EJECT;
132 	} else {
133 		action = INSERT;
134 	}
135 
136 	if ((hal_ctx = rmm_hal_init(0, 0, 0, &error, &rmm_error)) == NULL) {
137 		(void) fprintf(stderr, gettext("warning: %s\n"),
138 		    rmm_strerror(&error, rmm_error));
139 		rmm_dbus_error_free(&error);
140 		if ((rmm_error == RMM_EDBUS_CONNECT) ||
141 		    (rmm_error == RMM_EHAL_CONNECT)) {
142 			return (99);
143 		} else {
144 			return (1);
145 		}
146 	}
147 
148 	if (d_opt) {
149 		/* -d: print default name and exit */
150 		if ((d = rmm_hal_volume_find_default(hal_ctx, &error,
151 		    &default_name, &volumes)) == NULL) {
152 			default_name = "nothing inserted";
153 		} else {
154 			rmm_volumes_free(volumes);
155 			libhal_drive_free(d);
156 		}
157 		(void) printf(gettext("Default device is: %s\n"), default_name);
158 	} else if (l_opt) {
159 		/* -l: list volumes and exit */
160 		rmm_print_volume_nicknames(hal_ctx, &error);
161 	} else if (optind == argc) {
162 		/* no name provided, use default */
163 		if ((d = rmm_hal_volume_find_default(hal_ctx, &error,
164 		    &default_name, &volumes)) == NULL) {
165 			(void) fprintf(stderr,
166 			    gettext("No default media available\n"));
167 			ret = 1;
168 		} else {
169 			rmm_volumes_free(volumes);
170 			libhal_drive_free(d);
171 
172 			if (query_opt) {
173 				ret = rmm_rescan(hal_ctx, default_name,
174 				    B_TRUE) ? 0 : 1;
175 			} else {
176 				ret = rmm_action(hal_ctx, default_name, action,
177 				    0, 0, 0, 0) ? 0 : 1;
178 			}
179 		}
180 	} else {
181 		if (argc - optind > 1) {
182 			mountpoint = argv[optind + 1];
183 		}
184 		if (query_opt) {
185 			ret = rmm_rescan(hal_ctx, argv[optind],
186 			    B_TRUE) ? 0 : 1;
187 		} else {
188 			ret = rmm_action(hal_ctx, argv[optind], action,
189 			    0, opts, num_opts, mountpoint) ? 0 : 1;
190 		}
191 	}
192 
193 	rmm_dbus_error_free(&error);
194 	rmm_hal_fini(hal_ctx);
195 
196 	return (ret);
197 }
198 
199 static int
200 rmumount(int argc, char **argv)
201 {
202 	return (rmmount(argc, argv));
203 }
204 
205 static int
206 eject(int argc, char **argv)
207 {
208 	if (getenv("EJECT_CLOSETRAY") != NULL) {
209 		closetray_opt = B_TRUE;
210 	} else if (getenv("EJECT_QUERY") != NULL) {
211 		query_opt = B_TRUE;
212 	} else {
213 		eject_opt = B_TRUE;
214 	}
215 	return (rmmount(argc, argv));
216 }
217 
218 static void
219 nomem(void)
220 {
221 	(void) fprintf(stderr, gettext("%s: Out of memory\n"), progname);
222 	exit(1);
223 }
224 
225 
226 /*
227  * get the name by which this program was called
228  */
229 static char *
230 get_progname(char *path)
231 {
232 	char    *s;
233 	char    *p;
234 
235 	if ((s = strdup(path)) == NULL) {
236 		perror(path);
237 		exit(1);
238 	}
239 
240 	p = strrchr(s, '/');
241 	if (p != NULL) {
242 		strcpy(s, p + 1);
243 	}
244 
245 	return (s);
246 }
247 
248 int
249 main(int argc, char **argv)
250 {
251 	int ret = 1;
252 
253 	vold_init(argc, argv);
254 
255 	progname = get_progname(argv[0]);
256 
257 	if (strcmp(progname, "rmmount") == 0) {
258 		if ((getenv("VOLUME_ACTION") != NULL) &&
259 		    (getenv("VOLUME_PATH") != NULL)) {
260 			ret = vold_rmmount(argc, argv);
261 		} else {
262 			ret = rmmount(argc, argv);
263 		}
264 	} else if (strcmp(progname, "rmumount") == 0) {
265 		ret = rmumount(argc, argv);
266 	} else if (strcmp(progname, "eject") == 0) {
267 		ret = eject(argc, argv);
268 	} else {
269 		(void) fprintf(stderr, "rmmount: invalid program name\n");
270 		ret = 1;
271 	}
272 
273 	return (ret);
274 }
275