blob: 99650ff032b290772ae7429a824ecee4a2c96050 [file] [log] [blame]
Eric Andersen0139ca92001-07-22 23:01:03 +00001/* vi: set sw=4 ts=4: */
2/*
Robert Grieblaead70b2002-07-26 15:54:20 +00003 * Modprobe written from scratch for BusyBox
Eric Andersen60e56f52002-04-26 06:04:01 +00004 *
Robert Griebl6859d762002-08-05 02:57:12 +00005 * Copyright (c) 2002 by Robert Griebl, griebl@gmx.de
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21*/
Eric Andersen0139ca92001-07-22 23:01:03 +000022
Robert Griebl52e8d062002-05-14 23:42:08 +000023#include <sys/utsname.h>
Eric Andersen0139ca92001-07-22 23:01:03 +000024#include <getopt.h>
25#include <stdlib.h>
26#include <unistd.h>
27#include <syslog.h>
28#include <string.h>
Eric Andersen60e56f52002-04-26 06:04:01 +000029#include <ctype.h>
Eric Andersenc06391b2002-06-04 13:28:43 +000030#include <fcntl.h>
Eric Andersen0139ca92001-07-22 23:01:03 +000031#include "busybox.h"
32
Eric Andersen0139ca92001-07-22 23:01:03 +000033
Eric Andersen60e56f52002-04-26 06:04:01 +000034
35struct dep_t {
36 char * m_module;
Robert Grieblaead70b2002-07-26 15:54:20 +000037 char * m_options;
Robert Griebl52e8d062002-05-14 23:42:08 +000038
Robert Griebl1d4ef2a2002-05-28 21:32:10 +000039 int m_isalias : 1;
40 int m_reserved : 15;
41
42 int m_depcnt : 16;
Eric Andersen60e56f52002-04-26 06:04:01 +000043 char ** m_deparr;
44
45 struct dep_t * m_next;
46};
47
Robert Griebl52e8d062002-05-14 23:42:08 +000048struct mod_list_t {
49 char * m_module;
Robert Grieblaead70b2002-07-26 15:54:20 +000050 char * m_options;
Robert Griebl52e8d062002-05-14 23:42:08 +000051
52 struct mod_list_t * m_prev;
53 struct mod_list_t * m_next;
54};
55
56
Robert Griebl236abbf2002-05-22 23:34:35 +000057static struct dep_t *depend;
58static int autoclean, show_only, quiet, do_syslog, verbose;
Robert Griebl52e8d062002-05-14 23:42:08 +000059
Robert Grieblaead70b2002-07-26 15:54:20 +000060int parse_tag_value ( char *buffer, char **ptag, char **pvalue )
61{
62 char *tag, *value;
63
64 while ( isspace ( *buffer ))
65 buffer++;
66 tag = value = buffer;
67 while ( !isspace ( *value ))
68 value++;
69 *value++ = 0;
70 while ( isspace ( *value ))
71 value++;
72
73 *ptag = tag;
74 *pvalue = value;
75
76 return xstrlen( tag ) && xstrlen( value );
77}
Eric Andersen60e56f52002-04-26 06:04:01 +000078
Robert Grieblbc28f7a2002-06-04 19:33:58 +000079/* Jump through hoops to simulate how fgets() grabs just one line at a
80 * time... Don't use any stdio since modprobe gets called from a kernel
81 * thread and stdio junk can overflow the limited stack...
82 */
83static char *reads ( int fd, char *buffer, size_t len )
84{
85 int n = read ( fd, buffer, len );
86
87 if ( n > 0 ) {
88 char *p;
89
90 buffer [len-1] = 0;
91 p = strchr ( buffer, '\n' );
92
93 if ( p ) {
94 off_t offset;
95
96 offset = lseek ( fd, 0L, SEEK_CUR ); // Get the current file descriptor offset
97 lseek ( fd, offset-n + (p-buffer) + 1, SEEK_SET ); // Set the file descriptor offset to right after the \n
98
99 p[1] = 0;
100 }
101 return buffer;
102 }
103
104 else
105 return 0;
106}
107
Eric Andersen864b7972002-05-03 15:48:26 +0000108static struct dep_t *build_dep ( void )
Eric Andersen60e56f52002-04-26 06:04:01 +0000109{
Robert Grieblbc28f7a2002-06-04 19:33:58 +0000110 int fd;
Eric Andersen60e56f52002-04-26 06:04:01 +0000111 struct utsname un;
Eric Andersen60e56f52002-04-26 06:04:01 +0000112 struct dep_t *first = 0;
113 struct dep_t *current = 0;
Eric Andersenc06391b2002-06-04 13:28:43 +0000114 char buffer[256];
Eric Andersen60e56f52002-04-26 06:04:01 +0000115 char *filename = buffer;
116 int continuation_line = 0;
117
118 if ( uname ( &un ))
119 return 0;
Robert Griebl236abbf2002-05-22 23:34:35 +0000120
121 // check for buffer overflow in following code
Eric Andersenc06391b2002-06-04 13:28:43 +0000122 if ( xstrlen ( un.release ) > ( sizeof( buffer ) - 64 )) {
Robert Griebl236abbf2002-05-22 23:34:35 +0000123 return 0;
Eric Andersenc06391b2002-06-04 13:28:43 +0000124 }
Robert Griebl236abbf2002-05-22 23:34:35 +0000125
Eric Andersen60e56f52002-04-26 06:04:01 +0000126 strcpy ( filename, "/lib/modules/" );
Eric Andersenc06391b2002-06-04 13:28:43 +0000127 strcat ( filename, un.release );
Eric Andersen60e56f52002-04-26 06:04:01 +0000128 strcat ( filename, "/modules.dep" );
129
Robert Grieblbc28f7a2002-06-04 19:33:58 +0000130 if (( fd = open ( filename, O_RDONLY )) < 0 )
Eric Andersen60e56f52002-04-26 06:04:01 +0000131 return 0;
Eric Andersenc06391b2002-06-04 13:28:43 +0000132
Robert Grieblbc28f7a2002-06-04 19:33:58 +0000133 while ( reads ( fd, buffer, sizeof( buffer ))) {
134 int l = xstrlen ( buffer );
Eric Andersen60e56f52002-04-26 06:04:01 +0000135 char *p = 0;
Robert Grieblbc28f7a2002-06-04 19:33:58 +0000136
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000137 while ( isspace ( buffer [l-1] )) {
Eric Andersen60e56f52002-04-26 06:04:01 +0000138 buffer [l-1] = 0;
139 l--;
140 }
141
142 if ( l == 0 ) {
143 continuation_line = 0;
144 continue;
145 }
146
147 if ( !continuation_line ) {
148 char *col = strchr ( buffer, ':' );
149
150 if ( col ) {
151 char *mods;
152 char *mod;
Eric Andersen864b7972002-05-03 15:48:26 +0000153 int ext = 0;
Eric Andersen60e56f52002-04-26 06:04:01 +0000154
155 *col = 0;
156 mods = strrchr ( buffer, '/' );
157
158 if ( !mods )
159 mods = buffer;
160 else
161 mods++;
162
Eric Andersen864b7972002-05-03 15:48:26 +0000163 if (( *(col-2) == '.' ) && ( *(col-1) == 'o' ))
164 ext = 2;
165
166 mod = xstrndup ( mods, col - mods - ext );
167
Eric Andersen60e56f52002-04-26 06:04:01 +0000168 if ( !current ) {
Eric Andersenc06391b2002-06-04 13:28:43 +0000169 first = current = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
Eric Andersen60e56f52002-04-26 06:04:01 +0000170 }
171 else {
Eric Andersenc06391b2002-06-04 13:28:43 +0000172 current-> m_next = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
Eric Andersen60e56f52002-04-26 06:04:01 +0000173 current = current-> m_next;
174 }
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000175 current-> m_module = mod;
Robert Grieblaead70b2002-07-26 15:54:20 +0000176 current-> m_options = 0;
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000177 current-> m_isalias = 0;
178 current-> m_depcnt = 0;
179 current-> m_deparr = 0;
180 current-> m_next = 0;
Eric Andersen60e56f52002-04-26 06:04:01 +0000181
Eric Andersen864b7972002-05-03 15:48:26 +0000182 //printf ( "%s:\n", mod );
Eric Andersen60e56f52002-04-26 06:04:01 +0000183
184 p = col + 1;
185 }
186 else
187 p = 0;
188 }
189 else
190 p = buffer;
191
192 if ( p && *p ) {
193 char *end = &buffer [l-1];
194 char *deps = strrchr ( end, '/' );
195 char *dep;
Eric Andersen864b7972002-05-03 15:48:26 +0000196 int ext = 0;
Eric Andersen60e56f52002-04-26 06:04:01 +0000197
198 while ( isblank ( *end ) || ( *end == '\\' ))
199 end--;
200
201 deps = strrchr ( p, '/' );
202
203 if ( !deps || ( deps < p )) {
204 deps = p;
205
206 while ( isblank ( *deps ))
207 deps++;
208 }
209 else
210 deps++;
211
Eric Andersen864b7972002-05-03 15:48:26 +0000212 if (( *(end-1) == '.' ) && ( *end == 'o' ))
213 ext = 2;
Eric Andersenb493dec2002-07-02 19:14:23 +0000214
215 /* Cope with blank lines */
216 if ((end-deps-ext+1) <= 0)
217 continue;
Eric Andersen864b7972002-05-03 15:48:26 +0000218
219 dep = xstrndup ( deps, end - deps - ext + 1 );
Eric Andersen60e56f52002-04-26 06:04:01 +0000220
221 current-> m_depcnt++;
Eric Andersen864b7972002-05-03 15:48:26 +0000222 current-> m_deparr = (char **) xrealloc ( current-> m_deparr, sizeof ( char *) * current-> m_depcnt );
Eric Andersen60e56f52002-04-26 06:04:01 +0000223 current-> m_deparr [current-> m_depcnt - 1] = dep;
224
Eric Andersen864b7972002-05-03 15:48:26 +0000225 //printf ( " %d) %s\n", current-> m_depcnt, current-> m_deparr [current-> m_depcnt -1] );
Eric Andersen60e56f52002-04-26 06:04:01 +0000226 }
227
228 if ( buffer [l-1] == '\\' )
229 continuation_line = 1;
230 else
231 continuation_line = 0;
232 }
Eric Andersenc06391b2002-06-04 13:28:43 +0000233 close ( fd );
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000234
235 // alias parsing is not 100% correct (no correct handling of continuation lines within an alias) !
236
Robert Grieblbc28f7a2002-06-04 19:33:58 +0000237 if (( fd = open ( "/etc/modules.conf", O_RDONLY )) < 0 )
238 if (( fd = open ( "/etc/conf.modules", O_RDONLY )) < 0 )
Eric Andersenc06391b2002-06-04 13:28:43 +0000239 return first;
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000240
Eric Andersenc06391b2002-06-04 13:28:43 +0000241 continuation_line = 0;
Robert Grieblbc28f7a2002-06-04 19:33:58 +0000242 while ( reads ( fd, buffer, sizeof( buffer ))) {
Eric Andersenc06391b2002-06-04 13:28:43 +0000243 int l;
244 char *p;
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000245
Robert Grieblbc28f7a2002-06-04 19:33:58 +0000246 p = strchr ( buffer, '#' );
Eric Andersenc06391b2002-06-04 13:28:43 +0000247 if ( p )
248 *p = 0;
249
250 l = xstrlen ( buffer );
251
252 while ( l && isspace ( buffer [l-1] )) {
253 buffer [l-1] = 0;
254 l--;
255 }
256
257 if ( l == 0 ) {
258 continuation_line = 0;
259 continue;
260 }
261
262 if ( !continuation_line ) {
263 if (( strncmp ( buffer, "alias", 5 ) == 0 ) && isspace ( buffer [5] )) {
264 char *alias, *mod;
265
Robert Grieblaead70b2002-07-26 15:54:20 +0000266 if ( parse_tag_value ( buffer + 6, &alias, &mod )) {
267 // fprintf ( stderr, "ALIAS: '%s' -> '%s'\n", alias, mod );
Eric Andersenc06391b2002-06-04 13:28:43 +0000268
Robert Grieblaead70b2002-07-26 15:54:20 +0000269 if ( !current ) {
270 first = current = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
271 }
272 else {
273 current-> m_next = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
274 current = current-> m_next;
275 }
276 current-> m_module = xstrdup ( alias );
277 current-> m_isalias = 1;
278
279 if (( strcmp ( alias, "off" ) == 0 ) || ( strcmp ( alias, "null" ) == 0 )) {
280 current-> m_depcnt = 0;
281 current-> m_deparr = 0;
282 }
283 else {
284 current-> m_depcnt = 1;
285 current-> m_deparr = xmalloc ( 1 * sizeof( char * ));
286 current-> m_deparr[0] = xstrdup ( mod );
287 }
288 current-> m_next = 0;
Eric Andersenc06391b2002-06-04 13:28:43 +0000289 }
Eric Andersenc06391b2002-06-04 13:28:43 +0000290 }
Robert Grieblaead70b2002-07-26 15:54:20 +0000291 else if (( strncmp ( buffer, "options", 7 ) == 0 ) && isspace ( buffer [7] )) {
292 char *mod, *opt;
293
294 if ( parse_tag_value ( buffer + 8, &mod, &opt )) {
295 struct dep_t *dt;
296
297 for ( dt = first; dt; dt = dt-> m_next ) {
298 if ( strcmp ( dt-> m_module, mod ) == 0 )
299 break;
300 }
301 if ( dt ) {
302 dt-> m_options = xrealloc ( dt-> m_options, xstrlen( opt ) + 1 );
303 strcpy ( dt-> m_options, opt );
304
305 // fprintf ( stderr, "OPTION: '%s' -> '%s'\n", dt-> m_module, dt-> m_options );
306 }
307 }
308 }
Eric Andersenc06391b2002-06-04 13:28:43 +0000309 }
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000310 }
Eric Andersenc06391b2002-06-04 13:28:43 +0000311 close ( fd );
Eric Andersen60e56f52002-04-26 06:04:01 +0000312
313 return first;
314}
315
316
Robert Griebl236abbf2002-05-22 23:34:35 +0000317static int mod_process ( struct mod_list_t *list, int do_insert )
Eric Andersen60e56f52002-04-26 06:04:01 +0000318{
Robert Griebl52e8d062002-05-14 23:42:08 +0000319 char lcmd [256];
320 int rc = 0;
Eric Andersen864b7972002-05-03 15:48:26 +0000321
Robert Griebl52e8d062002-05-14 23:42:08 +0000322 if ( !list )
323 return 1;
Eric Andersen864b7972002-05-03 15:48:26 +0000324
Robert Griebl52e8d062002-05-14 23:42:08 +0000325 while ( list ) {
326 if ( do_insert )
Robert Grieblaead70b2002-07-26 15:54:20 +0000327 snprintf ( lcmd, sizeof( lcmd ) - 1, "insmod %s %s %s %s %s 2>/dev/null", do_syslog ? "-s" : "", autoclean ? "-k" : "", quiet ? "-q" : "", list-> m_module, list-> m_options ? list-> m_options : "" );
Robert Griebl52e8d062002-05-14 23:42:08 +0000328 else
329 snprintf ( lcmd, sizeof( lcmd ) - 1, "rmmod %s %s 2>/dev/null", do_syslog ? "-s" : "", list-> m_module );
330
331 if ( verbose )
332 printf ( "%s\n", lcmd );
333 if ( !show_only )
334 rc |= system ( lcmd );
335
336 list = do_insert ? list-> m_prev : list-> m_next;
Eric Andersen60e56f52002-04-26 06:04:01 +0000337 }
Robert Griebl52e8d062002-05-14 23:42:08 +0000338 return rc;
Eric Andersen60e56f52002-04-26 06:04:01 +0000339}
340
Robert Griebl52e8d062002-05-14 23:42:08 +0000341static void check_dep ( char *mod, struct mod_list_t **head, struct mod_list_t **tail )
Eric Andersen60e56f52002-04-26 06:04:01 +0000342{
Robert Griebl52e8d062002-05-14 23:42:08 +0000343 struct mod_list_t *find;
Eric Andersen60e56f52002-04-26 06:04:01 +0000344 struct dep_t *dt;
Robert Grieblaead70b2002-07-26 15:54:20 +0000345 char *opt = 0;
Robert Griebl52e8d062002-05-14 23:42:08 +0000346 int lm;
347
348 // remove .o extension
349 lm = xstrlen ( mod );
350 if (( mod [lm-2] == '.' ) && ( mod [lm-1] == 'o' ))
351 mod [lm-2] = 0;
352
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000353 // check dependencies
354 for ( dt = depend; dt; dt = dt-> m_next ) {
Robert Grieblaead70b2002-07-26 15:54:20 +0000355 if ( strcmp ( dt-> m_module, mod ) == 0 ) {
356 opt = dt-> m_options;
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000357 break;
Robert Grieblaead70b2002-07-26 15:54:20 +0000358 }
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000359 }
Robert Grieblaead70b2002-07-26 15:54:20 +0000360
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000361 // resolve alias names
Robert Grieblaead70b2002-07-26 15:54:20 +0000362 while ( dt && dt-> m_isalias ) {
363 if ( dt-> m_depcnt == 1 ) {
364 struct dep_t *adt;
365
366 for ( adt = depend; adt; adt = adt-> m_next ) {
Robert Griebl70112da2002-07-29 20:28:38 +0000367 if ( strcmp ( adt-> m_module, dt-> m_deparr [0] ) == 0 )
Robert Grieblaead70b2002-07-26 15:54:20 +0000368 break;
Robert Grieblaead70b2002-07-26 15:54:20 +0000369 }
Robert Griebl70112da2002-07-29 20:28:38 +0000370 if ( adt ) {
371 dt = adt;
372 mod = dt-> m_module;
373 if ( !opt )
374 opt = dt-> m_options;
375 }
Robert Grieblaead70b2002-07-26 15:54:20 +0000376 else
Robert Griebl70112da2002-07-29 20:28:38 +0000377 return;
Robert Grieblaead70b2002-07-26 15:54:20 +0000378 }
379 else
380 return;
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000381 }
382
Robert Griebl52e8d062002-05-14 23:42:08 +0000383 // search for duplicates
384 for ( find = *head; find; find = find-> m_next ) {
385 if ( !strcmp ( mod, find-> m_module )) {
386 // found -> dequeue it
387
388 if ( find-> m_prev )
389 find-> m_prev-> m_next = find-> m_next;
390 else
391 *head = find-> m_next;
392
393 if ( find-> m_next )
394 find-> m_next-> m_prev = find-> m_prev;
395 else
396 *tail = find-> m_prev;
397
Robert Griebl52e8d062002-05-14 23:42:08 +0000398 break; // there can be only one duplicate
399 }
400 }
401
402 if ( !find ) { // did not find a duplicate
403 find = (struct mod_list_t *) xmalloc ( sizeof(struct mod_list_t));
404 find-> m_module = mod;
Robert Grieblaead70b2002-07-26 15:54:20 +0000405 find-> m_options = opt;
Robert Griebl52e8d062002-05-14 23:42:08 +0000406 }
407
408 // enqueue at tail
409 if ( *tail )
410 (*tail)-> m_next = find;
411 find-> m_prev = *tail;
412 find-> m_next = 0;
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000413
Robert Griebl52e8d062002-05-14 23:42:08 +0000414 if ( !*head )
415 *head = find;
416 *tail = find;
Eric Andersen60e56f52002-04-26 06:04:01 +0000417
Robert Griebl1d4ef2a2002-05-28 21:32:10 +0000418 if ( dt ) {
419 int i;
420
421 for ( i = 0; i < dt-> m_depcnt; i++ )
422 check_dep ( dt-> m_deparr [i], head, tail );
423 }
Robert Griebl52e8d062002-05-14 23:42:08 +0000424}
425
426
427
Robert Griebl236abbf2002-05-22 23:34:35 +0000428static int mod_insert ( char *mod, int argc, char **argv )
Robert Griebl52e8d062002-05-14 23:42:08 +0000429{
430 struct mod_list_t *tail = 0;
431 struct mod_list_t *head = 0;
432 int rc = 0;
433
434 // get dep list for module mod
435 check_dep ( mod, &head, &tail );
436
437 if ( head && tail ) {
Robert Grieblaead70b2002-07-26 15:54:20 +0000438 if ( argc ) {
439 int i;
440 int l = 0;
Robert Griebl52e8d062002-05-14 23:42:08 +0000441
Robert Grieblaead70b2002-07-26 15:54:20 +0000442 // append module args
443 for ( i = 0; i < argc; i++ )
444 l += ( xstrlen ( argv [i] ) + 1 );
Robert Griebl236abbf2002-05-22 23:34:35 +0000445
Robert Grieblaead70b2002-07-26 15:54:20 +0000446 head-> m_options = xrealloc ( head-> m_options, l + 1 );
447 head-> m_options [0] = 0;
Robert Griebl52e8d062002-05-14 23:42:08 +0000448
Robert Grieblaead70b2002-07-26 15:54:20 +0000449 for ( i = 0; i < argc; i++ ) {
450 strcat ( head-> m_options, argv [i] );
451 strcat ( head-> m_options, " " );
452 }
Robert Griebl52e8d062002-05-14 23:42:08 +0000453 }
Robert Grieblaead70b2002-07-26 15:54:20 +0000454
Robert Griebl52e8d062002-05-14 23:42:08 +0000455 // process tail ---> head
Robert Griebl236abbf2002-05-22 23:34:35 +0000456 rc |= mod_process ( tail, 1 );
Robert Griebl52e8d062002-05-14 23:42:08 +0000457 }
458 else
459 rc = 1;
460
461 return rc;
462}
463
Robert Griebl236abbf2002-05-22 23:34:35 +0000464static void mod_remove ( char *mod )
Robert Griebl52e8d062002-05-14 23:42:08 +0000465{
466 static struct mod_list_t rm_a_dummy = { "-a", 0, 0 };
467
468 struct mod_list_t *head = 0;
469 struct mod_list_t *tail = 0;
470
471 if ( mod )
472 check_dep ( mod, &head, &tail );
473 else // autoclean
474 head = tail = &rm_a_dummy;
475
Robert Griebl236abbf2002-05-22 23:34:35 +0000476 if ( head && tail )
477 mod_process ( head, 0 ); // process head ---> tail
Robert Griebl52e8d062002-05-14 23:42:08 +0000478}
479
480
Eric Andersen60e56f52002-04-26 06:04:01 +0000481
Eric Andersen0139ca92001-07-22 23:01:03 +0000482extern int modprobe_main(int argc, char** argv)
483{
Robert Griebl236abbf2002-05-22 23:34:35 +0000484 int opt;
485 int remove_opt = 0;
Eric Andersen0139ca92001-07-22 23:01:03 +0000486
Robert Griebl236abbf2002-05-22 23:34:35 +0000487 autoclean = show_only = quiet = do_syslog = verbose = 0;
488
489 while ((opt = getopt(argc, argv, "acdklnqrst:vVC:")) != -1) {
490 switch(opt) {
491 case 'c': // no config used
492 case 'l': // no pattern matching
493 return EXIT_SUCCESS;
Eric Andersen0139ca92001-07-22 23:01:03 +0000494 break;
Robert Griebl236abbf2002-05-22 23:34:35 +0000495 case 'C': // no config used
496 case 't': // no pattern matching
497 error_msg_and_die("-t and -C not supported");
498
499 case 'a': // ignore
500 case 'd': // ignore
Eric Andersen0139ca92001-07-22 23:01:03 +0000501 break;
502 case 'k':
503 autoclean++;
504 break;
Eric Andersen0139ca92001-07-22 23:01:03 +0000505 case 'n':
506 show_only++;
507 break;
508 case 'q':
509 quiet++;
510 break;
511 case 'r':
Eric Andersen1b064192001-07-25 07:23:38 +0000512 remove_opt++;
Eric Andersen0139ca92001-07-22 23:01:03 +0000513 break;
514 case 's':
515 do_syslog++;
516 break;
Eric Andersen0139ca92001-07-22 23:01:03 +0000517 case 'v':
518 verbose++;
519 break;
Eric Andersen0139ca92001-07-22 23:01:03 +0000520 case 'V':
521 default:
522 show_usage();
523 break;
524 }
Eric Andersen0139ca92001-07-22 23:01:03 +0000525 }
Eric Andersen0139ca92001-07-22 23:01:03 +0000526
Robert Griebl52e8d062002-05-14 23:42:08 +0000527 depend = build_dep ( );
528
Robert Griebl236abbf2002-05-22 23:34:35 +0000529 if ( !depend )
530 error_msg_and_die ( "could not parse modules.dep\n" );
Robert Griebl52e8d062002-05-14 23:42:08 +0000531
Eric Andersen1b064192001-07-25 07:23:38 +0000532 if (remove_opt) {
Eric Andersen0139ca92001-07-22 23:01:03 +0000533 do {
Aaron Lehmann0df910a2002-08-23 07:45:26 +0000534 mod_remove ( optind < argc ? xstrdup ( argv [optind] ) : NULL );
Robert Griebl52e8d062002-05-14 23:42:08 +0000535 } while ( ++optind < argc );
536
Robert Griebl236abbf2002-05-22 23:34:35 +0000537 return EXIT_SUCCESS;
Eric Andersen0139ca92001-07-22 23:01:03 +0000538 }
539
Robert Griebl236abbf2002-05-22 23:34:35 +0000540 if (optind >= argc)
541 error_msg_and_die ( "No module or pattern provided\n" );
Robert Griebl52e8d062002-05-14 23:42:08 +0000542
Robert Griebl3ba7cee2002-12-03 22:41:36 +0000543 if ( mod_insert ( xstrdup ( argv [optind] ), argc - optind - 1, argv + optind + 1 ))
544 error_msg_and_die ( "failed to load module %s", argv [optind] );
545
546 return EXIT_SUCCESS;
Eric Andersen0139ca92001-07-22 23:01:03 +0000547}
548
549