~ubuntu-branches/ubuntu/saucy/clamav/saucy-backports

« back to all changes in this revision

Viewing changes to shared/optparser.c

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman
  • Date: 2014-07-15 01:08:10 UTC
  • mfrom: (0.35.47 sid)
  • Revision ID: package-import@ubuntu.com-20140715010810-ru66ek4fun2iseba
Tags: 0.98.4+dfsg-2~ubuntu13.10.1
No-change backport to saucy (LP: #1341962)

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#endif
39
39
#include <ctype.h>
40
40
 
 
41
#include <openssl/ssl.h>
 
42
#include <openssl/err.h>
 
43
#include "libclamav/crypto.h"
 
44
 
41
45
#include "shared/optparser.h"
42
46
#include "shared/misc.h"
43
47
 
77
81
    { NULL, "daemon", 'd', TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM, "", "" },
78
82
    { NULL, "no-dns", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM, "", "" },
79
83
    { NULL, "list-mirrors", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM, "", "" },
80
 
    { NULL, "submit-stats", 0, TYPE_STRING, NULL, 0, CONFDIR_CLAMD, 0, OPT_FRESHCLAM, "", "" }, /* Don't merge this one with SubmitDetectionStats */
81
84
    { NULL, "update-db", 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_FRESHCLAM, "", "" },
82
85
    { NULL, "reload", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMDSCAN, "", "" },
83
86
    { NULL, "multiscan", 'm', TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMDSCAN, "", "" },
113
116
    { NULL, "build", 'b', TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
114
117
    { NULL, "max-bad-sigs", 0, TYPE_NUMBER, MATCH_NUMBER, 3000, NULL, 0, OPT_SIGTOOL, "Maximum number of mismatched signatures when building a CVD. Zero disables this limit.", "3000" },
115
118
    { NULL, "flevel", 0, TYPE_NUMBER, MATCH_NUMBER, CL_FLEVEL, NULL, 0, OPT_SIGTOOL, "Feature level to put in the CVD", "" },
 
119
    { NULL, "cvd-version", 0, TYPE_NUMBER, MATCH_NUMBER, 0, NULL, 0, OPT_SIGTOOL, "Version number of the CVD to build", "" },
116
120
    { NULL, "unsigned", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
117
121
    { NULL, "no-cdiff", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
118
122
    { NULL, "server", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
180
184
    /* config file/cmdline options */
181
185
    { "LogFile", "log", 'l', TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD | OPT_MILTER | OPT_CLAMSCAN | OPT_CLAMDSCAN, "Save all reports to a log file.", "/tmp/clamav.log" },
182
186
 
 
187
    { "StatsHostID", "stats-host-id", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_FRESHCLAM | OPT_CLAMD | OPT_CLAMSCAN, "HostID in the form of an UUID to use when submitting statistical information. See the clamscan manpage for more information.", "default" },
 
188
 
 
189
    { "StatsEnabled", "enable-stats", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_FRESHCLAM | OPT_CLAMSCAN, "Enable submission of statistical data", "yes" },
 
190
 
 
191
    { "StatsPEDisabled", "disable-pe-stats", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Disable submission of PE section statistical data", "no" },
 
192
 
 
193
    { "StatsTimeout", "stats-timeout", 0, TYPE_NUMBER, MATCH_NUMBER, -1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN | OPT_FRESHCLAM, "Timeout in seconds to timeout communication with the stats server.", "10" },
 
194
 
183
195
    { "LogFileUnlock", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_MILTER, "By default the log file is locked for writing and only a single\ndaemon process can write to it. This option disables the lock.", "yes" },
184
196
 
185
197
    { "LogFileMaxSize", NULL, 0, TYPE_SIZE, MATCH_SIZE, 1048576, NULL, 0, OPT_CLAMD | OPT_FRESHCLAM | OPT_MILTER, "Maximum size of the log file.\nValue of 0 disables the limit.", "5M" },
217
229
    { "TCPSocket", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, -1, NULL, 0, OPT_CLAMD, "A TCP port number the daemon will listen on.", "3310" },
218
230
 
219
231
    /* FIXME: add a regex for IP addr */
220
 
    { "TCPAddr", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD, "By default clamd binds to INADDR_ANY.\nThis option allows you to restrict the TCP address and provide\nsome degree of protection from the outside world.", "127.0.0.1" },
 
232
    { "TCPAddr", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD, "By default clamd binds to INADDR_ANY.\nThis option allows you to restrict the TCP address and provide\nsome degree of protection from the outside world.", "127.0.0.1" },
221
233
 
222
234
    { "MaxConnectionQueueLength", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 200, NULL, 0, OPT_CLAMD, "Maximum length the queue of pending connections may grow to.", "30" },
223
235
 
253
265
 
254
266
    { "SelfCheck", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 600, NULL, 0, OPT_CLAMD, "This option specifies the time intervals (in seconds) in which clamd\nshould perform a database check.", "600" },
255
267
 
 
268
    { "DisableCache", "disable-cache", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option allows you to disable clamd's caching feature.", "no" },
 
269
 
256
270
    { "VirusEvent", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD, "Execute a command when a virus is found. In the command string %v will be\nreplaced with the virus name. Additionally, two environment variables will\nbe defined: $CLAM_VIRUSEVENT_FILENAME and $CLAM_VIRUSEVENT_VIRUSNAME.", "/usr/bin/mailx -s \"ClamAV VIRUS ALERT: %v\" alert < /dev/null" },
257
271
 
258
272
    { "ExitOnOOM", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD, "Stop the daemon when libclamav reports an out of memory condition.", "yes" },
284
298
    { "BytecodeMode", "bytecode-mode", 0, TYPE_STRING, "^(Auto|ForceJIT|ForceInterpreter|Test)$", -1, "Auto", FLAG_REQUIRED, OPT_CLAMD | OPT_CLAMSCAN,
285
299
        "Set bytecode execution mode.\nPossible values:\n\tAuto - automatically choose JIT if possible, fallback to interpreter\nForceJIT - always choose JIT, fail if not possible\nForceIntepreter - always choose interpreter\nTest - run with both JIT and interpreter and compare results. Make all failures fatal.","Auto"},
286
300
 
287
 
    { "BytecodeStatistics", "bytecode-statistics", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMSCAN, "Collect and print bytecode execution statistics.", "no" },
 
301
    { "BytecodeStatistics", "bytecode-statistics", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMSCAN | OPT_CLAMBC, "Collect and print bytecode execution statistics.", "no" },
288
302
 
289
303
   { "DetectPUA", "detect-pua", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Detect Potentially Unwanted Applications.", "yes" },
290
304
 
312
326
 
313
327
    { "PhishingAlwaysBlockSSLMismatch", "phishing-ssl", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Always block SSL mismatches in URLs, even if they're not in the database.\nThis feature can lead to false positives.", "" },
314
328
 
 
329
    { "PartitionIntersection", "partition-intersection", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Detect partition intersections in raw disk images using heuristics.", "yes" },
 
330
 
315
331
    { "HeuristicScanPrecedence", "heuristic-scan-precedence", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Allow heuristic match to take precedence.\nWhen enabled, if a heuristic scan (such as phishingScan) detects\na possible virus/phish it will stop scan immediately. Recommended, saves CPU\nscan-time.\nWhen disabled, virus/phish detected by heuristic scans will be reported only\nat the end of a scan. If an archive contains both a heuristically detected\nvirus/phish, and a real malware, the real malware will be reported.\nKeep this disabled if you intend to handle \"*.Heuristics.*\" viruses\ndifferently from \"real\" malware.\nIf a non-heuristically-detected virus (signature-based) is found first,\nthe scan is interrupted immediately, regardless of this config option.", "yes" },
316
332
 
317
333
    { "StructuredDataDetection", "detect-structured", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Enable the Data Loss Prevention module.", "no" },
359
375
 
360
376
    { "MaxZipTypeRcg", "max-ziptypercg", 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXZIPTYPERCG, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum size of a ZIP file to reanalyze type recognition.\nZIP files larger than this value will skip the step to potentially reanalyze as PE.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "1M" },
361
377
 
 
378
    { "MaxPartitions", "max-partitions", 0, TYPE_NUMBER, MATCH_NUMBER, CLI_DEFAULT_MAXPARTITIONS, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum number of partitions of a raw disk image to be scanned.\nRaw disk images with more partitions than this value will have up to the value number partitions scanned.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "128" },
 
379
 
 
380
    { "MaxIconsPE", "max-iconspe", 0, TYPE_NUMBER, MATCH_NUMBER, CLI_DEFAULT_MAXICONSPE, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum number of icons within a PE to be scanned.\nPE files with more icons than this value will have up to the value number icons scanned.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "100" },
 
381
 
362
382
    /* OnAccess settings */
363
383
    { "ScanOnAccess", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD, "This option enables on-access scanning (Linux only)", "no" },
364
384
 
439
459
 
440
460
    { "DetectionStatsHostID", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_FRESHCLAM, "This option enables support for our \"Personal Statistics\" service.\nWhen this option is enabled, the information on malware detected by\nyour clamd installation is made available to you through our website.\nTo get your HostID, log on http://www.stats.clamav.net and add a new\nhost to your host list. Once you have the HostID, uncomment this option\nand paste the HostID here. As soon as your freshclam starts submitting\ninformation to our stats collecting service, you will be able to view\nthe statistics of this clamd installation by logging into\nhttp://www.stats.clamav.net with the same credentials you used to\ngenerate the HostID. For more information refer to:\nhttp://www.clamav.net/support/faq/faq-cctts/\nThis feature requires SubmitDetectionStats to be enabled.", "unique-id" },
441
461
 
442
 
    { "SafeBrowsing", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM, "This option enables support for Google Safe Browsing. When activated for\nthe first time, freshclam will download a new database file (safebrowsing.cvd)\nwhich will be automatically loaded by clamd and clamscan during the next\nreload, provided that the heuristic phishing detection is turned on. This\ndatabase includes information about websites that may be phishing sites or\npossible sources of malware. When using this option, it's mandatory to run\nfreshclam at least every 30 minutes.\nFreshclam uses the ClamAV's mirror infrastructure to distribute the\ndatabase and its updates but all the contents are provided under Google's\nterms of use. See http://code.google.com/support/bin/answer.py?answer=70015\nand http://safebrowsing.clamav.net for more information.", "yes" },
 
462
    { "SafeBrowsing", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM, "This option enables support for Google Safe Browsing. When activated for\nthe first time, freshclam will download a new database file (safebrowsing.cvd)\nwhich will be automatically loaded by clamd and clamscan during the next\nreload, provided that the heuristic phishing detection is turned on. This\ndatabase includes information about websites that may be phishing sites or\npossible sources of malware. When using this option, it's mandatory to run\nfreshclam at least every 30 minutes.\nFreshclam uses the ClamAV's mirror infrastructure to distribute the\ndatabase and its updates but all the contents are provided under Google's\nterms of use. See http://www.google.com/transparencyreport/safebrowsing\nand https://github.com/vrtadmin/clamav-faq/blob/master/faq/faq-safebrowsing.md for more information.", "yes" },
443
463
 
444
464
    { "Bytecode", NULL, 0, TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_FRESHCLAM, "This option enables downloading of bytecode.cvd, which includes additional\ndetection mechanisms and improvements to the ClamAV engine.", "yes" },
445
465
 
483
503
 
484
504
    { "OnFail", NULL, 0, TYPE_STRING, "^(Accept|Reject|Defer)$", -1, "Defer", 0, OPT_MILTER, "Action to be performed on error conditions (this includes failure to\nallocate data structures, no scanners available, network timeouts, unknown\nscanner replies and the like.\nThe following actions are available:\nAccept: the message is accepted for delievery;\nReject: immediately refuse delievery (a 5xx error is returned to the peer);\nDefer: return a temporary failure message (4xx) to the peer.", "Defer" },
485
505
 
486
 
    { "RejectMsg", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "This option allows to set a specific rejection reason for infected messages\nand it's therefore only useful together with \"OnInfected Reject\"\nThe string \"%v\", if present, will be replaced with the virus name.", "MTA specific" },
 
506
    { "RejectMsg", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "This option allows you to set a specific rejection reason for infected messages\nand it's therefore only useful together with \"OnInfected Reject\"\nThe string \"%v\", if present, will be replaced with the virus name.", "MTA specific" },
487
507
 
488
508
    { "AddHeader", NULL, 0, TYPE_STRING, "^(No|Replace|Yes|Add)$", -1, "no", 0, OPT_MILTER, "If this option is set to \"Replace\" (or \"Yes\"), an \"X-Virus-Scanned\" and an\n\"X-Virus-Status\" headers will be attached to each processed message, possibly\nreplacing existing headers.\nIf it is set to Add, the X-Virus headers are added possibly on top of the\nexisting ones.\nNote that while \"Replace\" can potentially break DKIM signatures, \"Add\" may\nconfuse procmail and similar filters.", "Replace" },
489
509
 
490
 
    { "ReportHostname", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "When AddHeader is in use, this option allows to arbitrary set the reported\nhostname. This may be desirable in order to avoid leaking internal names.\nIf unset the real machine name is used.", "my.mail.server.name" },
 
510
    { "ReportHostname", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "When AddHeader is in use, this option allows you to set the reported\nhostname. This may be desirable in order to avoid leaking internal names.\nIf unset the real machine name is used.", "my.mail.server.name" },
491
511
 
492
512
    { "VirusAction", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "Execute a command when an infected message is processed.\nThe following parameters are passed to the invoked program in this order:\nvirus name, queue id, sender, destination, subject, message id, message date.\nNote #1: this requires MTA macroes to be available (see LogInfected below)\nNote #2: the process is invoked in the context of clamav-milter\nNote #3: clamav-milter will wait for the process to exit. Be quick or fork to\navoid unnecessary delays in email delievery", "/usr/local/bin/my_infected_message_handler" },
493
513
 
497
517
 
498
518
    { "SkipAuthenticated", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "Messages from authenticated SMTP users matching this extended POSIX\nregular expression (egrep-like) will not be scanned.\nAs an alternative, a file containing a plain (not regex) list of names (one\nper line) can be specified using the prefix \"file:\".\ne.g. SkipAuthenticated file:/etc/good_guys\n\nNote: this is the AUTH login name!", "SkipAuthenticated ^(tom|dick|henry)$" },
499
519
 
500
 
    { "LogInfected", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "This option allows to tune what is logged when a message is infected.\nPossible values are Off (the default - nothing is logged),\nBasic (minimal info logged), Full (verbose info logged)\nNote:\nFor this to work properly in sendmail, make sure the msg_id, mail_addr,\nrcpt_addr and i macroes are available in eom. In other words add a line like:\nMilter.macros.eom={msg_id}, {mail_addr}, {rcpt_addr}, i\nto your .cf file. Alternatively use the macro:\ndefine(`confMILTER_MACROS_EOM', `{msg_id}, {mail_addr}, {rcpt_addr}, i')\nPostfix should be working fine with the default settings.", "Basic" },
 
520
    { "LogInfected", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "This option allows you to tune what is logged when a message is infected.\nPossible values are Off (the default - nothing is logged),\nBasic (minimal info logged), Full (verbose info logged)\nNote:\nFor this to work properly in sendmail, make sure the msg_id, mail_addr,\nrcpt_addr and i macroes are available in eom. In other words add a line like:\nMilter.macros.eom={msg_id}, {mail_addr}, {rcpt_addr}, i\nto your .cf file. Alternatively use the macro:\ndefine(`confMILTER_MACROS_EOM', `{msg_id}, {mail_addr}, {rcpt_addr}, i')\nPostfix should be working fine with the default settings.", "Basic" },
501
521
 
502
 
    { "LogClean", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "This option allows to tune what is logged when no threat is found in a scanned message.\nSee LogInfected for possible values and caveats.\nUseful in debugging but drastically increases the log size.", "Basic" },
 
522
    { "LogClean", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "This option allows you to tune what is logged when no threat is found in a scanned message.\nSee LogInfected for possible values and caveats.\nUseful in debugging but drastically increases the log size.", "Basic" },
503
523
 
504
524
    { "SupportMultipleRecipients", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_MILTER, "This option affects the behaviour of LogInfected, LogClean and VirusAction\nwhen a message with multiple recipients is scanned:\nIf SupportMultipleRecipients is off (the default)\nthen one single log entry is generated for the message and, in case the\nmessage is determined to be malicious, the command indicated by VirusAction\nis executed just once. In both cases only the last recipient is reported.\nIf SupportMultipleRecipients is on:\nthen one line is logged for each recipient and the command indicated\nby VirusAction is also executed once for each recipient.\n\nNote: although it's probably a good idea to enable this option, the default value\nis currently set to off for legacy reasons.", "yes" },
505
525
 
1124
1144
 
1125
1145
    return opts;
1126
1146
}
 
1147
 
 
1148
struct optstruct *optadditem(const char *name, const char *arg, int verbose, int toolmask, int ignore,
 
1149
                            struct optstruct *oldopts)
 
1150
{
 
1151
        int i, err = 0, sc = 0, lc=0, line = 0, ret;
 
1152
        struct optstruct *opts = NULL, *opts_last = NULL, *opt;
 
1153
        char *buff;
 
1154
        regex_t regex;
 
1155
        long long numarg, lnumarg;
 
1156
        int regflags = REG_EXTENDED | REG_NOSUB;
 
1157
    const struct clam_option *optentry = NULL;
 
1158
    
 
1159
    if(oldopts)
 
1160
        opts = oldopts;
 
1161
    
 
1162
    
 
1163
    for(i = 0; ; i++) {
 
1164
        optentry = &clam_options[i];
 
1165
        if(!optentry->name && !optentry->longopt)
 
1166
            break;
 
1167
        
 
1168
        if(((optentry->owner & toolmask) && ((optentry->owner & toolmask) != OPT_DEPRECATED)) || (ignore && (optentry->owner & ignore))) {
 
1169
            if(!oldopts && optadd(&opts, &opts_last, optentry->name, optentry->longopt, optentry->strarg, optentry->numarg, optentry->flags, i) < 0) {
 
1170
                fprintf(stderr, "ERROR: optparse: Can't register new option (not enough memory)\n");
 
1171
                optfree(opts);
 
1172
                return NULL;
 
1173
            }
 
1174
            
 
1175
        }
 
1176
    }
 
1177
    
 
1178
    if(MAX(sc, lc) > MAXCMDOPTS) {
 
1179
            fprintf(stderr, "ERROR: optparse: (short|long)opts[] is too small\n");
 
1180
            optfree(opts);
 
1181
            return NULL;
 
1182
        }
 
1183
    
 
1184
    while(1) {
 
1185
        if(!name) {
 
1186
            fprintf(stderr, "ERROR: Problem parsing options (name == NULL)\n");
 
1187
            err = 1;
 
1188
            break;
 
1189
        }
 
1190
        
 
1191
        opt = optget_i(opts, name);
 
1192
        if(!opt) {
 
1193
            if(verbose)
 
1194
                fprintf(stderr, "ERROR: Parse error at line %d: Unknown option %s\n", line, name);
 
1195
            err = 1;
 
1196
            break;
 
1197
        }
 
1198
        optentry = &clam_options[opt->idx];
 
1199
        
 
1200
        if(ignore && (optentry->owner & ignore) && !(optentry->owner & toolmask)) {
 
1201
            if(verbose)
 
1202
                fprintf(stderr, "WARNING: Ignoring unsupported option %s at line %u\n", opt->name, line);
 
1203
            continue;
 
1204
        }
 
1205
        
 
1206
        if(optentry->owner & OPT_DEPRECATED) {
 
1207
            if(toolmask & OPT_DEPRECATED) {
 
1208
                if(optaddarg(opts, name, "foo", 1) < 0) {
 
1209
                    fprintf(stderr, "ERROR: Can't register argument for option %s\n", name);
 
1210
                    err = 1;
 
1211
                    break;
 
1212
                }
 
1213
            } else {
 
1214
                if(verbose)
 
1215
                    fprintf(stderr, "WARNING: Ignoring deprecated option %s at line %u\n", opt->name, line);
 
1216
            }
 
1217
            continue;
 
1218
        }
 
1219
        
 
1220
        if(optentry->regex) {
 
1221
            if(!(optentry->flags & FLAG_REG_CASE))
 
1222
                regflags |= REG_ICASE;
 
1223
            
 
1224
            if(cli_regcomp(&regex, optentry->regex, regflags)) {
 
1225
                fprintf(stderr, "ERROR: optparse: Can't compile regular expression %s for option %s\n", optentry->regex, name);
 
1226
                err = 1;
 
1227
                break;
 
1228
            }
 
1229
            ret = cli_regexec(&regex, arg, 0, NULL, 0);
 
1230
            cli_regfree(&regex);
 
1231
            if(ret == REG_NOMATCH) {
 
1232
                fprintf(stderr, "ERROR: Incorrect argument format for option %s\n", name);
 
1233
                err = 1;
 
1234
                break;
 
1235
            }
 
1236
        }
 
1237
        
 
1238
        numarg = -1;
 
1239
        switch(optentry->argtype) {
 
1240
            case TYPE_STRING:
 
1241
                if(!arg)
 
1242
                    arg = optentry->strarg;
 
1243
                
 
1244
                break;
 
1245
                
 
1246
            case TYPE_NUMBER:
 
1247
                if (arg)
 
1248
                    numarg = atoi(arg);
 
1249
                else
 
1250
                    numarg = 0;
 
1251
                arg = NULL;
 
1252
                break;
 
1253
                
 
1254
            case TYPE_SIZE:
 
1255
                errno = 0;
 
1256
                if(arg)
 
1257
                    lnumarg = strtoul(arg, &buff, 0);
 
1258
                else {
 
1259
                    numarg = 0;
 
1260
                    break;
 
1261
                }
 
1262
                if(errno != ERANGE) {
 
1263
                    switch(*buff) {
 
1264
                        case 'M':
 
1265
                        case 'm':
 
1266
                            if(lnumarg <= UINT_MAX/(1024*1024)) lnumarg *= 1024*1024;
 
1267
                            else errno = ERANGE;
 
1268
                            break;
 
1269
                        case 'K':
 
1270
                        case 'k':
 
1271
                            if(lnumarg <= UINT_MAX/1024) lnumarg *= 1024;
 
1272
                            else errno = ERANGE;
 
1273
                            break;
 
1274
                        case '\0':
 
1275
                            break;
 
1276
                        default:
 
1277
                            fprintf(stderr, "ERROR: Can't parse numerical argument for option %s\n", name);
 
1278
                            err = 1;
 
1279
                    }
 
1280
                }
 
1281
                
 
1282
                arg = NULL;
 
1283
                if(err) break;
 
1284
                if(errno == ERANGE) {
 
1285
                    fprintf(stderr, "WARNING: Numerical value for option %s too high, resetting to 4G\n", name);
 
1286
                    lnumarg = UINT_MAX;
 
1287
                }
 
1288
                
 
1289
                numarg = lnumarg ? lnumarg : UINT_MAX;
 
1290
                break;
 
1291
                
 
1292
            case TYPE_BOOL:
 
1293
                if(!strcasecmp(arg, "yes") || !strcmp(arg, "1") || !strcasecmp(arg, "true"))
 
1294
                    numarg = 1;
 
1295
                else
 
1296
                    numarg = 0;
 
1297
                
 
1298
                arg = NULL;
 
1299
                break;
 
1300
        }
 
1301
        
 
1302
        if(err)
 
1303
            break;
 
1304
        
 
1305
        if(optaddarg(opts, name, arg, numarg) < 0) {
 
1306
            fprintf(stderr, "ERROR: Can't register argument for option --%s\n", optentry->longopt);
 
1307
            err = 1;
 
1308
        }
 
1309
        break;
 
1310
    }
 
1311
    
 
1312
    if(err) {
 
1313
        optfree(opts);
 
1314
        return NULL;
 
1315
    }
 
1316
      
 
1317
    return opts;
 
1318
}