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