~vcs-imports/clamav/main-old

« back to all changes in this revision

Viewing changes to clamscan/options.c

  • Committer: nervoso
  • Date: 2006-05-21 15:16:39 UTC
  • Revision ID: Arch-1:clamav@arch.ubuntu.com%clamav--MAIN--0--patch-1959
repository moved to cvs.clamav.net

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  Copyright (C) 2001 - 2005 Tomasz Kojm <tkojm@clamav.net>
3
 
 *
4
 
 *  This program is free software; you can redistribute it and/or modify
5
 
 *  it under the terms of the GNU General Public License as published by
6
 
 *  the Free Software Foundation; either version 2 of the License, or
7
 
 *  (at your option) any later version.
8
 
 *
9
 
 *  This program is distributed in the hope that it will be useful,
10
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 *  GNU General Public License for more details.
13
 
 *
14
 
 *  You should have received a copy of the GNU General Public License
15
 
 *  along with this program; if not, write to the Free Software
16
 
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17
 
 *  MA 02110-1301, USA.
18
 
 *
19
 
 * Sat Sep 14 22:18:20 CEST 2002: included getfirst*(), getnext*() functions
20
 
 *                      from Alejandro Dubrovsky <s328940@student.uq.edu.au>
21
 
 */
22
 
 
23
 
#if HAVE_CONFIG_H
24
 
#include "clamav-config.h"
25
 
#endif
26
 
 
27
 
#include <stdio.h>
28
 
#include <stdlib.h>
29
 
#include <string.h>
30
 
#include <clamav.h>
31
 
#define _GNU_SOURCE
32
 
#include "getopt.h"
33
 
 
34
 
 
35
 
#include "options.h"
36
 
#include "shared.h"
37
 
#include "memory.h"
38
 
#include "output.h"
39
 
 
40
 
extern int clamscan(struct optstruct *opt);
41
 
 
42
 
static char *clamdscan_long[] = { "help", "version", "verbose", "quiet",
43
 
                                  "stdout", "log", "move", "remove",
44
 
                                  "config-file", "no-summary",
45
 
                                  "disable-summary", NULL };
46
 
 
47
 
static char clamdscan_short[] = { 'h', 'V', 'v', 'l', 0 };
48
 
 
49
 
int clamdscan_mode = 0;
50
 
 
51
 
short foreground = 1;
52
 
 
53
 
int main(int argc, char **argv)
54
 
{
55
 
        int ret, opt_index, i, len;
56
 
        struct optstruct *opt;
57
 
 
58
 
        const char *getopt_parameters = "hvd:wriVl:m";
59
 
 
60
 
        static struct option long_options[] = {
61
 
            /* 
62
 
             * WARNING: For compatibility reasons options marked as "not used"
63
 
             *          must still be accepted !
64
 
             */
65
 
            {"help", 0, 0, 'h'},            /* clamscan + clamdscan */
66
 
            {"quiet", 0, 0, 0},             /* clamscan + clamdscan */
67
 
            {"stdout", 0, 0, 0},            /* clamscan + clamdscan */
68
 
            {"verbose", 0, 0, 'v'},         /* clamscan + clamdscan */
69
 
            {"debug", 0, 0, 0},
70
 
            {"version", 0, 0, 'V'},         /* clamscan + clamdscan */
71
 
            {"tempdir", 1, 0, 0},
72
 
            {"leave-temps", 0, 0, 0},
73
 
            {"config-file", 1, 0, 0}, /* clamdscan */
74
 
            {"database", 1, 0, 'd'},
75
 
            {"whole-file", 0, 0, 'w'}, /* not used */
76
 
            {"force", 0, 0, 0},
77
 
            {"recursive", 0, 0, 'r'},
78
 
            {"bell", 0, 0, 0},
79
 
            {"disable-summary", 0, 0, 0}, /* obsolete */
80
 
            {"no-summary", 0, 0, 0},
81
 
            {"infected", 0, 0, 'i'},
82
 
            {"log", 1, 0, 'l'},
83
 
            {"log-verbose", 0, 0, 0}, /* not used */
84
 
            {"threads", 1, 0, 0}, /* not used */
85
 
            {"one-virus", 0, 0, 0}, /* not used */
86
 
            {"move", 1, 0, 0},
87
 
            {"remove", 0, 0, 0},
88
 
            {"exclude", 1, 0, 0},
89
 
            {"exclude-dir", 1, 0, 0},
90
 
            {"include", 1, 0, 0},
91
 
            {"include-dir", 1, 0, 0},
92
 
            {"max-files", 1, 0, 0},
93
 
            {"max-space", 1, 0, 0},
94
 
            {"max-ratio", 1, 0, 0},
95
 
            {"max-recursion", 1, 0, 0},
96
 
            {"max-dir-recursion", 1, 0, 0},
97
 
#ifdef HAVE_HWACCEL
98
 
            {"hwaccel", 0, 0, 0},
99
 
#endif
100
 
            {"disable-archive", 0, 0, 0},
101
 
            {"no-archive", 0, 0, 0},
102
 
            {"detect-broken", 0, 0, 0},
103
 
            {"block-encrypted", 0, 0, 0},
104
 
            {"block-max", 0, 0, 0},
105
 
            {"no-pe", 0, 0, 0},
106
 
            {"no-ole2", 0, 0, 0},
107
 
            {"no-html", 0, 0, 0},
108
 
            {"mbox", 0, 0, 'm'}, /* not used */
109
 
            {"no-mail", 0, 0, 0},
110
 
            {"mail-follow-urls", 0, 0, 0},
111
 
            {"no-phishing", 0, 0, 0},
112
 
            {"no-algorithmic", 0, 0, 0},
113
 
            {"unzip", 2, 0, 0},
114
 
            {"unrar", 2, 0, 0},
115
 
            {"unace", 2, 0, 0}, /* not used */
116
 
            {"unarj", 2, 0, 0}, /* not used */
117
 
            {"arj", 2, 0, 0},
118
 
            {"zoo", 2, 0, 0}, /* not used */
119
 
            {"unzoo", 2, 0, 0},
120
 
            {"lha", 2, 0, 0},
121
 
            {"jar", 2, 0, 0},
122
 
            {"tar", 2, 0, 0},
123
 
            {"tgz", 2, 0, 0},
124
 
            {"deb", 2, 0, 0},
125
 
 
126
 
            /* developers only */
127
 
            {"dev-ac-only", 0, 0, 0},
128
 
            {"dev-ac-depth", 1, 0, 0},
129
 
 
130
 
            {0, 0, 0, 0}
131
 
        };
132
 
 
133
 
 
134
 
    opt=(struct optstruct*) mcalloc(1, sizeof(struct optstruct));
135
 
    opt->optlist = NULL;
136
 
 
137
 
    if(strstr(argv[0], "clamdscan"))
138
 
        clamdscan_mode = 1;
139
 
 
140
 
    while(1) {
141
 
 
142
 
        opt_index=0;
143
 
        ret=getopt_long(argc, argv, getopt_parameters, long_options, &opt_index);
144
 
 
145
 
        if (ret == -1)
146
 
            break;
147
 
 
148
 
        switch (ret) {
149
 
            case 0:
150
 
                register_long_option(opt, long_options[opt_index].name);
151
 
                break;
152
 
 
153
 
            default:
154
 
                if(strchr(getopt_parameters, ret)) {
155
 
                    if(opt_index)
156
 
                        register_char_option(opt, ret, long_options[opt_index].name);
157
 
                    else
158
 
                        register_char_option(opt, ret, NULL);
159
 
 
160
 
                } else {
161
 
                    logg("!Unknown option passed.\n");
162
 
                    free_opt(opt);
163
 
                    if(clamdscan_mode)
164
 
                        exit(2);
165
 
                    else
166
 
                        exit(40);
167
 
                }
168
 
        }
169
 
    }
170
 
 
171
 
    if (optind < argc) {
172
 
 
173
 
        len=0;
174
 
 
175
 
        /* count length of non-option arguments */
176
 
 
177
 
        for(i=optind; i<argc; i++)
178
 
            len+=strlen(argv[i]);
179
 
 
180
 
        len=len+argc-optind-1; /* add spaces between arguments */
181
 
        opt->filename=(char*)mcalloc(len + 256, sizeof(char));
182
 
 
183
 
        for(i=optind; i<argc; i++) {
184
 
            strncat(opt->filename, argv[i], strlen(argv[i]));
185
 
            if(i != argc-1)
186
 
                strncat(opt->filename, "\t", 1);
187
 
        }
188
 
 
189
 
    }
190
 
    ret = clamscan(opt);
191
 
 
192
 
    free_opt(opt);
193
 
 
194
 
    return  ret;
195
 
}
196
 
 
197
 
void register_char_option(struct optstruct *opt, char ch, const char *longname)
198
 
{
199
 
        struct optnode *newnode;
200
 
        int i, found = 0;
201
 
 
202
 
 
203
 
    if(clamdscan_mode) {
204
 
        for(i = 0; clamdscan_short[i]; i++)
205
 
            if(clamdscan_short[i] == ch)
206
 
                found = 1;
207
 
 
208
 
        if(!found) {
209
 
            if(longname)
210
 
                logg("WARNING: Ignoring option -%c (--%s): please edit clamd.conf instead.\n", ch, longname);
211
 
            else
212
 
                logg("WARNING: Ignoring option -%c: please edit clamd.conf instead.\n", ch);
213
 
 
214
 
            return;
215
 
        }
216
 
    }
217
 
 
218
 
    newnode = (struct optnode *) mmalloc(sizeof(struct optnode));
219
 
    newnode->optchar = ch;
220
 
    if(optarg != NULL) {
221
 
        newnode->optarg = (char *) mcalloc(strlen(optarg) + 1, sizeof(char));
222
 
        strcpy(newnode->optarg, optarg);
223
 
    } else newnode->optarg = NULL;
224
 
 
225
 
    newnode->optname = NULL;
226
 
    newnode->next = opt->optlist;
227
 
    opt->optlist = newnode;
228
 
}
229
 
 
230
 
void register_long_option(struct optstruct *opt, const char *optname)
231
 
{
232
 
        struct optnode *newnode;
233
 
        int i, found = 0;
234
 
 
235
 
 
236
 
    if(clamdscan_mode) {
237
 
        for(i = 0; clamdscan_long[i]; i++)
238
 
            if(!strcmp(clamdscan_long[i], optname))
239
 
                found = 1;
240
 
 
241
 
        if(!found) {
242
 
            logg("WARNING: Ignoring option --%s: please edit clamd.conf instead.\n", optname);
243
 
            return;
244
 
        }
245
 
    }
246
 
 
247
 
    newnode = (struct optnode *) mmalloc(sizeof(struct optnode));
248
 
    newnode->optchar = 0;
249
 
    if(optarg != NULL) {
250
 
        newnode->optarg = (char *) mcalloc(strlen(optarg) + 1, sizeof(char));
251
 
        strcpy(newnode->optarg, optarg);
252
 
    } else newnode->optarg = NULL;
253
 
 
254
 
    newnode->optname = (char *) mcalloc(strlen(optname) + 1, sizeof(char));
255
 
    strcpy(newnode->optname, optname);
256
 
    newnode->next = opt->optlist;
257
 
    opt->optlist = newnode;
258
 
}
259
 
 
260
 
int optc(const struct optstruct *opt, char ch)
261
 
{
262
 
        struct optnode *handler;
263
 
 
264
 
    handler = opt->optlist;
265
 
 
266
 
    while(1) {
267
 
        if(handler) {
268
 
            if(handler->optchar == ch) return 1;
269
 
        } else break;
270
 
        handler = handler->next;
271
 
    }
272
 
 
273
 
    return(0);
274
 
}
275
 
 
276
 
int optl(const struct optstruct *opt, const char *optname)
277
 
{
278
 
        struct optnode *handler;
279
 
 
280
 
    handler = opt->optlist;
281
 
 
282
 
    while(1) {
283
 
        if(handler) {
284
 
            if(handler->optname)
285
 
                if(!strcmp(handler->optname, optname)) return 1;
286
 
        } else break;
287
 
        handler = handler->next;
288
 
    }
289
 
 
290
 
    return(0);
291
 
}
292
 
 
293
 
char *getargc(const struct optstruct *opt, char ch)
294
 
{
295
 
        struct optnode *handler;
296
 
 
297
 
    handler = opt->optlist;
298
 
 
299
 
    while(1) {
300
 
        if(handler) {
301
 
            if(handler->optchar == ch) return handler->optarg;
302
 
        } else break;
303
 
        handler = handler->next;
304
 
    }
305
 
 
306
 
    return(NULL);
307
 
}
308
 
 
309
 
char *getfirstargc(const struct optstruct *opt, char ch, struct optnode **optnode)
310
 
{
311
 
        struct optnode *handler;
312
 
 
313
 
    handler = opt->optlist;
314
 
 
315
 
    while(1) {
316
 
        if(handler) {
317
 
            if(handler->optchar == ch) {
318
 
                *optnode = handler;
319
 
                return handler->optarg;
320
 
            }
321
 
        } else break;
322
 
        handler = handler->next;
323
 
    }
324
 
    *optnode = NULL;
325
 
    return(NULL);
326
 
}
327
 
 
328
 
char *getnextargc(struct optnode **optnode, char ch)
329
 
{
330
 
        struct optnode *handler;
331
 
 
332
 
    handler = (*optnode)->next;
333
 
 
334
 
    while(1) {
335
 
        if(handler) {
336
 
            if(handler->optchar == ch) {
337
 
                *optnode = handler;
338
 
                return handler->optarg;
339
 
            }
340
 
        } else break;
341
 
        handler = handler->next;
342
 
    }
343
 
    *optnode = NULL;
344
 
    return(NULL);
345
 
}
346
 
 
347
 
char *getargl(const struct optstruct *opt, const char *optname)
348
 
{
349
 
        struct optnode *handler;
350
 
 
351
 
    handler = opt->optlist;
352
 
 
353
 
    while(1) {
354
 
        if(handler) {
355
 
            if(handler->optname)
356
 
                if(!strcmp(handler->optname, optname)) return handler->optarg;
357
 
        } else break;
358
 
        handler = handler->next;
359
 
    }
360
 
 
361
 
    return(NULL);
362
 
}
363
 
 
364
 
char *getfirstargl(const struct optstruct *opt, const char *optname, struct optnode **optnode)
365
 
{
366
 
        struct optnode *handler;
367
 
 
368
 
    handler = opt->optlist;
369
 
 
370
 
    while(1) {
371
 
        if(handler) {
372
 
            if(handler->optname)
373
 
                if(!strcmp(handler->optname, optname)) {
374
 
                        *optnode = handler;
375
 
                        return handler->optarg;
376
 
                }
377
 
        } else break;
378
 
        handler = handler->next;
379
 
    }
380
 
    
381
 
    *optnode = NULL;
382
 
    return(NULL);
383
 
}
384
 
 
385
 
char *getnextargl(struct optnode **optnode, const char *optname)
386
 
{
387
 
        struct optnode *handler;
388
 
 
389
 
    handler = (*optnode)->next;
390
 
 
391
 
    while(1) {
392
 
        if(handler) {
393
 
            if(handler->optname)
394
 
                if(!strcmp(handler->optname, optname)) {
395
 
                        *optnode = handler;
396
 
                        return handler->optarg;
397
 
                }
398
 
        } else break;
399
 
        handler = handler->next;
400
 
    }
401
 
    
402
 
    *optnode = NULL;
403
 
    return(NULL);
404
 
}
405
 
 
406
 
void free_opt(struct optstruct *opt)
407
 
{
408
 
        struct optnode *handler, *prev;
409
 
 
410
 
    if(!opt)
411
 
        return;
412
 
 
413
 
    handler = opt->optlist;
414
 
 
415
 
    while(handler != NULL) {
416
 
        handler->optchar = 0;
417
 
        if(handler->optarg) free(handler->optarg);
418
 
        if(handler->optname) free(handler->optname);
419
 
        prev = handler;
420
 
        handler = handler->next;
421
 
        free(prev);
422
 
    }
423
 
 
424
 
    if (opt->filename)
425
 
        free(opt->filename);
426
 
    free(opt);
427
 
}