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 /miscutils | |
| 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
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/crond.c | 83 |
1 files changed, 34 insertions, 49 deletions
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) |
