diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-16 22:12:18 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-16 22:12:18 +0000 |
| commit | c01340fe26b76e172805ff641ad9af6bc45cdc91 (patch) | |
| tree | 1b3b57ef2fd7441bb91410b89f763056279baddf | |
| parent | 38e54f1c1384e76adafb4e611a6bd456e4351d42 (diff) | |
| download | busybox-w32-c01340fe26b76e172805ff641ad9af6bc45cdc91.tar.gz busybox-w32-c01340fe26b76e172805ff641ad9af6bc45cdc91.tar.bz2 busybox-w32-c01340fe26b76e172805ff641ad9af6bc45cdc91.zip | |
update of config file parser from Vladimir
| -rw-r--r-- | include/libbb.h | 20 | ||||
| -rw-r--r-- | libbb/parse_config.c | 106 | ||||
| -rw-r--r-- | miscutils/crond.c | 83 | ||||
| -rw-r--r-- | networking/nameif.c | 20 |
4 files changed, 52 insertions, 177 deletions
diff --git a/include/libbb.h b/include/libbb.h index 3a7c2eee9..c124b1a5e 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -985,30 +985,20 @@ extern int set_loop(char **devname, const char *file, unsigned long long offset) | |||
| 985 | char *bb_askpass(int timeout, const char * prompt) FAST_FUNC; | 985 | char *bb_askpass(int timeout, const char * prompt) FAST_FUNC; |
| 986 | int bb_ask_confirmation(void) FAST_FUNC; | 986 | int bb_ask_confirmation(void) FAST_FUNC; |
| 987 | 987 | ||
| 988 | extern int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC; | 988 | int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC; |
| 989 | 989 | ||
| 990 | /* | 990 | /* |
| 991 | * Uniform config file parser helpers | 991 | * Uniform config file parser helpers |
| 992 | */ | 992 | */ |
| 993 | #define PARSER_STDIO_BASED 1 | ||
| 994 | #if !PARSER_STDIO_BASED | ||
| 995 | typedef struct parser_t { | ||
| 996 | char *data; | ||
| 997 | char *line; | ||
| 998 | int lineno; | ||
| 999 | } parser_t; | ||
| 1000 | extern char* config_open(parser_t *parser, const char *filename) FAST_FUNC; | ||
| 1001 | #else | ||
| 1002 | typedef struct parser_t { | 993 | typedef struct parser_t { |
| 1003 | FILE *fp; | 994 | FILE *fp; |
| 1004 | char *line; | 995 | char *line, *data; |
| 1005 | int lineno; | 996 | int lineno; |
| 1006 | } parser_t; | 997 | } parser_t; |
| 1007 | extern FILE* config_open(parser_t *parser, const char *filename) FAST_FUNC; | 998 | FILE* config_open(parser_t *parser, const char *filename) FAST_FUNC; |
| 1008 | #endif | ||
| 1009 | /* TODO: add define magic to collapse ntokens/mintokens/comment into one int param */ | 999 | /* TODO: add define magic to collapse ntokens/mintokens/comment into one int param */ |
| 1010 | extern char* config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment) FAST_FUNC; | 1000 | int config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment) FAST_FUNC; |
| 1011 | extern void config_close(parser_t *parser) FAST_FUNC; | 1001 | void config_close(parser_t *parser) FAST_FUNC; |
| 1012 | 1002 | ||
| 1013 | /* Concatenate path and filename to new allocated buffer. | 1003 | /* Concatenate path and filename to new allocated buffer. |
| 1014 | * Add "/" only as needed (no duplicate "//" are produced). | 1004 | * Add "/" only as needed (no duplicate "//" are produced). |
diff --git a/libbb/parse_config.c b/libbb/parse_config.c index 6612db367..e63204b09 100644 --- a/libbb/parse_config.c +++ b/libbb/parse_config.c | |||
| @@ -31,101 +31,6 @@ Typical usage: | |||
| 31 | 31 | ||
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | #if !PARSER_STDIO_BASED | ||
| 35 | |||
| 36 | char* FAST_FUNC config_open(parser_t *parser, const char *filename) | ||
| 37 | { | ||
| 38 | // empty file configures nothing! | ||
| 39 | char *data = xmalloc_open_read_close(filename, NULL); | ||
| 40 | if (!data) | ||
| 41 | return data; | ||
| 42 | |||
| 43 | // convert 0x5c 0x0a (backslashes at the very end of line) to 0x20 0x20 (spaces) | ||
| 44 | for (char *s = data; (s = strchr(s, '\\')) != NULL; ++s) | ||
| 45 | if ('\n' == s[1]) { | ||
| 46 | s[0] = s[1] = ' '; | ||
| 47 | } | ||
| 48 | |||
| 49 | // init parser | ||
| 50 | parser->line = parser->data = data; | ||
| 51 | parser->lineno = 0; | ||
| 52 | |||
| 53 | return data; | ||
| 54 | } | ||
| 55 | |||
| 56 | void FAST_FUNC config_close(parser_t *parser) | ||
| 57 | { | ||
| 58 | // for now just free config data | ||
| 59 | free(parser->data); | ||
| 60 | } | ||
| 61 | |||
| 62 | char* FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment) | ||
| 63 | { | ||
| 64 | char *ret, *line; | ||
| 65 | int noreduce = (ntokens<0); // do not treat subsequent delimiters as one delimiter | ||
| 66 | if (ntokens < 0) | ||
| 67 | ntokens = -ntokens; | ||
| 68 | ret = line = parser->line; | ||
| 69 | // nullify tokens | ||
| 70 | memset(tokens, 0, sizeof(void *) * ntokens); | ||
| 71 | // now split to lines | ||
| 72 | while (*line) { | ||
| 73 | int token_num = 0; | ||
| 74 | // limit the line | ||
| 75 | char *ptr = strchrnul(line, '\n'); | ||
| 76 | *ptr++ = '\0'; | ||
| 77 | // line number | ||
| 78 | parser->lineno++; | ||
| 79 | // comments mean EOLs | ||
| 80 | if (comment) | ||
| 81 | *strchrnul(line, comment) = '\0'; | ||
| 82 | // skip leading delimiters | ||
| 83 | while (*line && strchr(delims, *line)) | ||
| 84 | line++; | ||
| 85 | // skip empty lines | ||
| 86 | if (*line) { | ||
| 87 | char *s; | ||
| 88 | // now split line to tokens | ||
| 89 | s = line; | ||
| 90 | while (s) { | ||
| 91 | char *p; | ||
| 92 | // get next token | ||
| 93 | if (token_num+1 >= ntokens) | ||
| 94 | break; | ||
| 95 | p = s; | ||
| 96 | while (*p && !strchr(delims, *p)) | ||
| 97 | p++; | ||
| 98 | if (!*p) | ||
| 99 | break; | ||
| 100 | *p++ = '\0'; | ||
| 101 | // pin token | ||
| 102 | if (noreduce || *s) { | ||
| 103 | tokens[token_num++] = s; | ||
| 104 | //bb_error_msg("L[%d] T[%s]", token_num, s); | ||
| 105 | } | ||
| 106 | s = p; | ||
| 107 | } | ||
| 108 | // non-empty remainder is also a token. So if ntokens == 0, we just return the whole line | ||
| 109 | if (s && (noreduce || *s)) | ||
| 110 | tokens[token_num++] = s; | ||
| 111 | // sanity check: have we got all required tokens? | ||
| 112 | if (token_num < mintokens) | ||
| 113 | bb_error_msg_and_die("bad line %u, %d tokens found, %d needed", parser->lineno, token_num, mintokens); | ||
| 114 | // advance data for the next call | ||
| 115 | line = ptr; | ||
| 116 | break; | ||
| 117 | } | ||
| 118 | // line didn't contain any token -> try next line | ||
| 119 | ret = line = ptr; | ||
| 120 | } | ||
| 121 | parser->line = line; | ||
| 122 | |||
| 123 | // return current line. caller must check *ret to determine whether to continue | ||
| 124 | return ret; | ||
| 125 | } | ||
| 126 | |||
| 127 | #else // stdio-based | ||
| 128 | |||
| 129 | FILE* FAST_FUNC config_open(parser_t *parser, const char *filename) | 34 | FILE* FAST_FUNC config_open(parser_t *parser, const char *filename) |
| 130 | { | 35 | { |
| 131 | // empty file configures nothing! | 36 | // empty file configures nothing! |
| @@ -142,10 +47,12 @@ FILE* FAST_FUNC config_open(parser_t *parser, const char *filename) | |||
| 142 | 47 | ||
| 143 | void FAST_FUNC config_close(parser_t *parser) | 48 | void FAST_FUNC config_close(parser_t *parser) |
| 144 | { | 49 | { |
| 50 | free(parser->line); | ||
| 51 | free(parser->data); | ||
| 145 | fclose(parser->fp); | 52 | fclose(parser->fp); |
| 146 | } | 53 | } |
| 147 | 54 | ||
| 148 | char* FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment) | 55 | int FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment) |
| 149 | { | 56 | { |
| 150 | char *line, *q; | 57 | char *line, *q; |
| 151 | int token_num, len; | 58 | int token_num, len; |
| @@ -160,6 +67,8 @@ char* FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mi | |||
| 160 | // free used line | 67 | // free used line |
| 161 | free(parser->line); | 68 | free(parser->line); |
| 162 | parser->line = NULL; | 69 | parser->line = NULL; |
| 70 | free(parser->data); | ||
| 71 | parser->data = NULL; | ||
| 163 | 72 | ||
| 164 | while (1) { | 73 | while (1) { |
| 165 | int n; | 74 | int n; |
| @@ -211,6 +120,7 @@ char* FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mi | |||
| 211 | 120 | ||
| 212 | // store line | 121 | // store line |
| 213 | parser->line = line = xrealloc(line, len + 1); | 122 | parser->line = line = xrealloc(line, len + 1); |
| 123 | parser->data = xstrdup(line); | ||
| 214 | 124 | ||
| 215 | // now split line to tokens | 125 | // now split line to tokens |
| 216 | //TODO: discard consecutive delimiters? | 126 | //TODO: discard consecutive delimiters? |
| @@ -241,7 +151,5 @@ char* FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mi | |||
| 241 | bb_error_msg_and_die("bad line %u: %d tokens found, %d needed", | 151 | bb_error_msg_and_die("bad line %u: %d tokens found, %d needed", |
| 242 | parser->lineno, token_num, mintokens); | 152 | parser->lineno, token_num, mintokens); |
| 243 | 153 | ||
| 244 | return parser->line; // maybe token_num instead? | 154 | return token_num; |
| 245 | } | 155 | } |
| 246 | |||
| 247 | #endif | ||
diff --git a/miscutils/crond.c b/miscutils/crond.c index e48abf9f8..af37bb15b 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c | |||
| @@ -304,7 +304,7 @@ static const char MonAry[] ALIGN1 = | |||
| 304 | /* "Jan""Feb""Mar""Apr""May""Jun""Jul""Aug""Sep""Oct""Nov""Dec" */ | 304 | /* "Jan""Feb""Mar""Apr""May""Jun""Jul""Aug""Sep""Oct""Nov""Dec" */ |
| 305 | ; | 305 | ; |
| 306 | 306 | ||
| 307 | static char *ParseField(char *user, char *ary, int modvalue, int off, | 307 | static void ParseField(char *user, char *ary, int modvalue, int off, |
| 308 | const char *names, char *ptr) | 308 | const char *names, char *ptr) |
| 309 | /* 'names' is a pointer to a set of 3-char abbreviations */ | 309 | /* 'names' is a pointer to a set of 3-char abbreviations */ |
| 310 | { | 310 | { |
| @@ -312,11 +312,11 @@ static char *ParseField(char *user, char *ary, int modvalue, int off, | |||
| 312 | int n1 = -1; | 312 | int n1 = -1; |
| 313 | int n2 = -1; | 313 | int n2 = -1; |
| 314 | 314 | ||
| 315 | if (base == NULL) { | 315 | // this can't happen due to config_read() |
| 316 | return NULL; | 316 | /*if (base == NULL) |
| 317 | } | 317 | return;*/ |
| 318 | 318 | ||
| 319 | while (!isspace(*ptr)) { | 319 | while (1) { |
| 320 | int skip = 0; | 320 | int skip = 0; |
| 321 | 321 | ||
| 322 | /* Handle numeric digit or symbol or '*' */ | 322 | /* Handle numeric digit or symbol or '*' */ |
| @@ -352,8 +352,7 @@ static char *ParseField(char *user, char *ary, int modvalue, int off, | |||
| 352 | 352 | ||
| 353 | /* handle optional range '-' */ | 353 | /* handle optional range '-' */ |
| 354 | if (skip == 0) { | 354 | if (skip == 0) { |
| 355 | crondlog(WARN9 "user %s: parse error at %s", user, base); | 355 | goto err; |
| 356 | return NULL; | ||
| 357 | } | 356 | } |
| 358 | if (*ptr == '-' && n2 < 0) { | 357 | if (*ptr == '-' && n2 < 0) { |
| 359 | ++ptr; | 358 | ++ptr; |
| @@ -388,8 +387,7 @@ static char *ParseField(char *user, char *ary, int modvalue, int off, | |||
| 388 | s0 = skip; | 387 | s0 = skip; |
| 389 | } | 388 | } |
| 390 | if (--failsafe == 0) { | 389 | if (--failsafe == 0) { |
| 391 | crondlog(WARN9 "user %s: parse error at %s", user, base); | 390 | goto err; |
| 392 | return NULL; | ||
| 393 | } | 391 | } |
| 394 | } while (n1 != n2); | 392 | } while (n1 != n2); |
| 395 | 393 | ||
| @@ -402,9 +400,10 @@ static char *ParseField(char *user, char *ary, int modvalue, int off, | |||
| 402 | n2 = -1; | 400 | n2 = -1; |
| 403 | } | 401 | } |
| 404 | 402 | ||
| 405 | if (!isspace(*ptr)) { | 403 | if (*ptr) { |
| 404 | err: | ||
| 406 | crondlog(WARN9 "user %s: parse error at %s", user, base); | 405 | crondlog(WARN9 "user %s: parse error at %s", user, base); |
| 407 | return NULL; | 406 | return; |
| 408 | } | 407 | } |
| 409 | 408 | ||
| 410 | if (DebugOpt && (LogLevel <= 5)) { /* like LVL5 */ | 409 | if (DebugOpt && (LogLevel <= 5)) { /* like LVL5 */ |
| @@ -414,7 +413,6 @@ static char *ParseField(char *user, char *ary, int modvalue, int off, | |||
| 414 | fprintf(stderr, "%d", (unsigned char)ary[i]); | 413 | fprintf(stderr, "%d", (unsigned char)ary[i]); |
| 415 | fputc('\n', stderr); | 414 | fputc('\n', stderr); |
| 416 | } | 415 | } |
| 417 | return skip_whitespace(ptr); | ||
| 418 | } | 416 | } |
| 419 | 417 | ||
| 420 | static void FixDayDow(CronLine *line) | 418 | static void FixDayDow(CronLine *line) |
| @@ -445,11 +443,10 @@ static void FixDayDow(CronLine *line) | |||
| 445 | 443 | ||
| 446 | static void SynchronizeFile(const char *fileName) | 444 | static void SynchronizeFile(const char *fileName) |
| 447 | { | 445 | { |
| 448 | FILE *fi; | 446 | struct parser_t parser; |
| 449 | struct stat sbuf; | 447 | struct stat sbuf; |
| 450 | int maxEntries; | ||
| 451 | int maxLines; | 448 | int maxLines; |
| 452 | char buf[1024]; | 449 | char *tokens[6]; |
| 453 | #if ENABLE_FEATURE_CROND_CALL_SENDMAIL | 450 | #if ENABLE_FEATURE_CROND_CALL_SENDMAIL |
| 454 | char *mailTo = NULL; | 451 | char *mailTo = NULL; |
| 455 | #endif | 452 | #endif |
| @@ -458,57 +455,44 @@ static void SynchronizeFile(const char *fileName) | |||
| 458 | return; | 455 | return; |
| 459 | 456 | ||
| 460 | DeleteFile(fileName); | 457 | DeleteFile(fileName); |
| 461 | fi = fopen(fileName, "r"); | 458 | if (!config_open(&parser, fileName)) |
| 462 | if (!fi) | ||
| 463 | return; | 459 | return; |
| 464 | 460 | ||
| 465 | maxEntries = MAXLINES; | 461 | maxLines = (strcmp(fileName, "root") == 0) ? 65535 : MAXLINES; |
| 466 | if (strcmp(fileName, "root") == 0) { | ||
| 467 | maxEntries = 65535; | ||
| 468 | } | ||
| 469 | maxLines = maxEntries * 10; | ||
| 470 | 462 | ||
| 471 | if (fstat(fileno(fi), &sbuf) == 0 && sbuf.st_uid == DaemonUid) { | 463 | if (fstat(fileno(parser.fp), &sbuf) == 0 && sbuf.st_uid == DaemonUid) { |
| 472 | CronFile *file = xzalloc(sizeof(CronFile)); | 464 | CronFile *file = xzalloc(sizeof(CronFile)); |
| 473 | CronLine **pline; | 465 | CronLine **pline; |
| 466 | int n; | ||
| 474 | 467 | ||
| 475 | file->cf_User = xstrdup(fileName); | 468 | file->cf_User = xstrdup(fileName); |
| 476 | pline = &file->cf_LineBase; | 469 | pline = &file->cf_LineBase; |
| 477 | 470 | ||
| 478 | while (fgets(buf, sizeof(buf), fi) != NULL && --maxLines) { | 471 | while (--maxLines && (n=config_read(&parser, tokens, 6, 0, " \t", '#')) > 0) { |
| 479 | CronLine *line; | 472 | CronLine *line; |
| 480 | char *ptr; | ||
| 481 | 473 | ||
| 482 | trim(buf); | ||
| 483 | if (buf[0] == '\0' || buf[0] == '#') { | ||
| 484 | continue; | ||
| 485 | } | ||
| 486 | if (--maxEntries == 0) { | ||
| 487 | break; | ||
| 488 | } | ||
| 489 | if (DebugOpt) { | 474 | if (DebugOpt) { |
| 490 | crondlog(LVL5 "user:%s entry:%s", fileName, buf); | 475 | crondlog(LVL5 "user:%s entry:%s", fileName, parser.data); |
| 491 | } | 476 | } |
| 477 | |||
| 492 | /* check if line is setting MAILTO= */ | 478 | /* check if line is setting MAILTO= */ |
| 493 | if (0 == strncmp("MAILTO=", buf, 7)) { | 479 | if (0 == strncmp(tokens[0], "MAILTO=", 7)) { |
| 494 | #if ENABLE_FEATURE_CROND_CALL_SENDMAIL | 480 | #if ENABLE_FEATURE_CROND_CALL_SENDMAIL |
| 495 | free(mailTo); | 481 | free(mailTo); |
| 496 | mailTo = (buf[7]) ? xstrdup(buf+7) : NULL; | 482 | mailTo = (tokens[0][7]) ? xstrdup(&tokens[0][7]) : NULL; |
| 497 | #endif /* otherwise just ignore such lines */ | 483 | #endif /* otherwise just ignore such lines */ |
| 498 | continue; | 484 | continue; |
| 499 | } | 485 | } |
| 486 | /* check if a minimum of tokens is specified */ | ||
| 487 | if (n < 5) | ||
| 488 | continue; | ||
| 500 | *pline = line = xzalloc(sizeof(CronLine)); | 489 | *pline = line = xzalloc(sizeof(CronLine)); |
| 501 | /* parse date ranges */ | 490 | /* parse date ranges */ |
| 502 | ptr = ParseField(file->cf_User, line->cl_Mins, 60, 0, NULL, buf); | 491 | ParseField(file->cf_User, line->cl_Mins, 60, 0, NULL, tokens[0]); |
| 503 | ptr = ParseField(file->cf_User, line->cl_Hrs, 24, 0, NULL, ptr); | 492 | ParseField(file->cf_User, line->cl_Hrs, 24, 0, NULL, tokens[1]); |
| 504 | ptr = ParseField(file->cf_User, line->cl_Days, 32, 0, NULL, ptr); | 493 | ParseField(file->cf_User, line->cl_Days, 32, 0, NULL, tokens[2]); |
| 505 | ptr = ParseField(file->cf_User, line->cl_Mons, 12, -1, MonAry, ptr); | 494 | ParseField(file->cf_User, line->cl_Mons, 12, -1, MonAry, tokens[3]); |
| 506 | ptr = ParseField(file->cf_User, line->cl_Dow, 7, 0, DowAry, ptr); | 495 | ParseField(file->cf_User, line->cl_Dow, 7, 0, DowAry, tokens[4]); |
| 507 | /* check failure */ | ||
| 508 | if (ptr == NULL) { | ||
| 509 | free(line); | ||
| 510 | continue; | ||
| 511 | } | ||
| 512 | /* | 496 | /* |
| 513 | * fix days and dow - if one is not "*" and the other | 497 | * fix days and dow - if one is not "*" and the other |
| 514 | * is "*", the other is set to 0, and vise-versa | 498 | * is "*", the other is set to 0, and vise-versa |
| @@ -519,22 +503,23 @@ static void SynchronizeFile(const char *fileName) | |||
| 519 | line->cl_MailTo = xstrdup(mailTo); | 503 | line->cl_MailTo = xstrdup(mailTo); |
| 520 | #endif | 504 | #endif |
| 521 | /* copy command */ | 505 | /* copy command */ |
| 522 | line->cl_Shell = xstrdup(ptr); | 506 | line->cl_Shell = xstrdup(tokens[5]); |
| 523 | if (DebugOpt) { | 507 | if (DebugOpt) { |
| 524 | crondlog(LVL5 " command:%s", ptr); | 508 | crondlog(LVL5 " command:%s", tokens[5]); |
| 525 | } | 509 | } |
| 526 | pline = &line->cl_Next; | 510 | pline = &line->cl_Next; |
| 511 | //bb_error_msg("M[%s]F[%s][%s][%s][%s][%s][%s]", mailTo, tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]); | ||
| 527 | } | 512 | } |
| 528 | *pline = NULL; | 513 | *pline = NULL; |
| 529 | 514 | ||
| 530 | file->cf_Next = FileBase; | 515 | file->cf_Next = FileBase; |
| 531 | FileBase = file; | 516 | FileBase = file; |
| 532 | 517 | ||
| 533 | if (maxLines == 0 || maxEntries == 0) { | 518 | if (maxLines == 0) { |
| 534 | crondlog(WARN9 "user %s: too many lines", fileName); | 519 | crondlog(WARN9 "user %s: too many lines", fileName); |
| 535 | } | 520 | } |
| 536 | } | 521 | } |
| 537 | fclose(fi); | 522 | config_close(&parser); |
| 538 | } | 523 | } |
| 539 | 524 | ||
| 540 | static void CheckUpdates(void) | 525 | static void CheckUpdates(void) |
diff --git a/networking/nameif.c b/networking/nameif.c index f3d333baf..506f4fa1c 100644 --- a/networking/nameif.c +++ b/networking/nameif.c | |||
| @@ -160,21 +160,13 @@ int nameif_main(int argc, char **argv) | |||
| 160 | prepend_new_eth_table(&clist, ifname, *argv++); | 160 | prepend_new_eth_table(&clist, ifname, *argv++); |
| 161 | } | 161 | } |
| 162 | } else { | 162 | } else { |
| 163 | ifh = xfopen(fname, "r"); | 163 | struct parser_t parser; |
| 164 | while ((line = xmalloc_fgets(ifh)) != NULL) { | 164 | if (config_open(&parser, fname)) { |
| 165 | char *next; | 165 | char *tokens[2]; |
| 166 | 166 | while (config_read(&parser, tokens, 2, 2, " \t", '#')) | |
| 167 | line_ptr = skip_whitespace(line); | 167 | prepend_new_eth_table(&clist, tokens[0], tokens[1]); |
| 168 | if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) | 168 | config_close(&parser); |
| 169 | goto read_next_line; | ||
| 170 | next = skip_non_whitespace(line_ptr); | ||
| 171 | if (*next) | ||
| 172 | *next++ = '\0'; | ||
| 173 | prepend_new_eth_table(&clist, line_ptr, next); | ||
| 174 | read_next_line: | ||
| 175 | free(line); | ||
| 176 | } | 169 | } |
| 177 | fclose(ifh); | ||
| 178 | } | 170 | } |
| 179 | 171 | ||
| 180 | ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0); | 172 | ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0); |
