void LuaParser::getTop(bool& output) const { if (lua_isnil(this->L, -1)) { throw missing_field() << info_what("Missing field"); } else if (!lua_isboolean(this->L, -1)) { throw type_error() << info_what("Field is not a boolean"); } else { output = lua_toboolean(this->L, -1); } }
void LuaParser::getTop(std::string& output) const { if (lua_isnil(this->L, -1)) { throw missing_field() << info_what("Missing field"); } else if (!lua_isstring(this->L, -1)) { throw type_error() << info_what("Field is not a string"); } else { output = lua_tostring(this->L, -1); } }
void LuaParser::getTop(double& output) const { if (lua_isnil(this->L, -1)) { throw missing_field() << info_what("Missing field"); } else if (!lua_isnumber(this->L, -1)) { throw type_error() << info_what("Field is not a number"); } else { output = lua_tonumber(this->L, -1); } }
/* * Parse a configuration file and return a linked list of all the logs * to process */ struct conf_entry * parse_file(int *nentries) { char line[BUFSIZ], *parse, *q, *errline, *group, *tmp, *ep; struct conf_entry *working = NULL, *first = NULL; struct passwd *pwd; struct group *grp; struct stat sb; int lineno; FILE *f; long l; if (strcmp(conf, "-") == 0) f = stdin; else if ((f = fopen(conf, "r")) == NULL) err(1, "can't open %s", conf); *nentries = 0; for (lineno = 1; fgets(line, sizeof(line), f); lineno++) { tmp = sob(line); if (*tmp == '\0' || *tmp == '#') continue; errline = strdup(tmp); if (errline == NULL) err(1, "strdup"); (*nentries)++; if (!first) { working = malloc(sizeof(struct conf_entry)); if (working == NULL) err(1, "malloc"); first = working; } else { working->next = malloc(sizeof(struct conf_entry)); if (working->next == NULL) err(1, "malloc"); working = working->next; } q = parse = missing_field(sob(line), errline, lineno); *(parse = son(line)) = '\0'; working->log = strdup(q); if (working->log == NULL) err(1, "strdup"); if ((working->logbase = strrchr(working->log, '/')) != NULL) working->logbase++; q = parse = missing_field(sob(++parse), errline, lineno); *(parse = son(parse)) = '\0'; if ((group = strchr(q, ':')) != NULL || (group = strrchr(q, '.')) != NULL) { *group++ = '\0'; if (*q) { if (!(isnumberstr(q))) { if ((pwd = getpwnam(q)) == NULL) errx(1, "%s:%d: unknown user: %s", conf, lineno, q); working->uid = pwd->pw_uid; } else working->uid = atoi(q); } else working->uid = (uid_t)-1; q = group; if (*q) { if (!(isnumberstr(q))) { if ((grp = getgrnam(q)) == NULL) errx(1, "%s:%d: unknown group: %s", conf, lineno, q); working->gid = grp->gr_gid; } else working->gid = atoi(q); } else working->gid = (gid_t)-1; q = parse = missing_field(sob(++parse), errline, lineno); *(parse = son(parse)) = '\0'; } else { working->uid = (uid_t)-1; working->gid = (gid_t)-1; } l = strtol(q, &ep, 8); if (*ep != '\0' || l < 0 || l > ALLPERMS) errx(1, "%s:%d: bad permissions: %s", conf, lineno, q); working->permissions = (mode_t)l; q = parse = missing_field(sob(++parse), errline, lineno); *(parse = son(parse)) = '\0'; l = strtol(q, &ep, 10); if (*ep != '\0' || l < 0 || l >= INT_MAX) errx(1, "%s:%d: bad number: %s", conf, lineno, q); working->numlogs = (int)l; q = parse = missing_field(sob(++parse), errline, lineno); *(parse = son(parse)) = '\0'; if (isdigit(*q)) working->size = atoi(q) * 1024; else working->size = -1; working->flags = 0; q = parse = missing_field(sob(++parse), errline, lineno); *(parse = son(parse)) = '\0'; l = strtol(q, &ep, 10); if (l < 0 || l >= INT_MAX) errx(1, "%s:%d: interval out of range: %s", conf, lineno, q); working->hours = (int)l; switch (*ep) { case '\0': break; case '@': working->trim_at = parse8601(ep + 1); if (working->trim_at == (time_t) - 1) errx(1, "%s:%d: bad time: %s", conf, lineno, q); working->flags |= CE_TRIMAT; break; case '$': working->trim_at = parseDWM(ep + 1); if (working->trim_at == (time_t) - 1) errx(1, "%s:%d: bad time: %s", conf, lineno, q); working->flags |= CE_TRIMAT; break; case '*': if (q == ep) break; /* FALLTHROUGH */ default: errx(1, "%s:%d: bad interval/at: %s", conf, lineno, q); break; } q = sob(++parse); /* Optional field */ if (*q == 'Z' || *q == 'z' || *q == 'B' || *q == 'b' || *q == 'M' || *q == 'm') { *(parse = son(q)) = '\0'; while (*q) { switch (*q) { case 'Z': case 'z': working->flags |= CE_COMPACT; break; case 'B': case 'b': working->flags |= CE_BINARY; break; case 'M': case 'm': working->flags |= CE_MONITOR; break; case 'F': case 'f': working->flags |= CE_FOLLOW; break; default: errx(1, "%s:%d: illegal flag: `%c'", conf, lineno, *q); break; } q++; } } else parse--; /* no flags so undo */ working->pidfile = PIDFILE; working->signal = SIGHUP; working->runcmd = NULL; working->whom = NULL; for (;;) { q = parse = sob(++parse); /* Optional field */ if (q == NULL || *q == '\0') break; if (*q == '/') { *(parse = son(parse)) = '\0'; if (strlen(q) >= MAXPATHLEN) errx(1, "%s:%d: pathname too long: %s", conf, lineno, q); working->pidfile = strdup(q); if (working->pidfile == NULL) err(1, "strdup"); } else if (*q == '"' && (tmp = strchr(q + 1, '"'))) { *(parse = tmp) = '\0'; if (*++q != '\0') { working->runcmd = strdup(q); if (working->runcmd == NULL) err(1, "strdup"); } working->pidfile = NULL; working->signal = -1; } else if (strncmp(q, "SIG", 3) == 0) { int i; *(parse = son(parse)) = '\0'; for (i = 1; i < NSIG; i++) { if (!strcmp(sys_signame[i], q + 3)) { working->signal = i; break; } } if (i == NSIG) errx(1, "%s:%d: unknown signal: %s", conf, lineno, q); } else if (working->flags & CE_MONITOR) { *(parse = son(parse)) = '\0'; working->whom = strdup(q); if (working->whom == NULL) err(1, "strdup"); } else errx(1, "%s:%d: unrecognized field: %s", conf, lineno, q); } free(errline); if ((working->flags & CE_MONITOR) && working->whom == NULL) errx(1, "%s:%d: missing monitor notification field", conf, lineno); /* If there is an arcdir, set working->backdir. */ if (arcdir != NULL && working->logbase != NULL) { if (*arcdir == '/') { /* Fully qualified arcdir */ working->backdir = arcdir; } else { /* arcdir is relative to log's parent dir */ *(working->logbase - 1) = '\0'; if ((asprintf(&working->backdir, "%s/%s", working->log, arcdir)) == -1) err(1, "malloc"); *(working->logbase - 1) = '/'; } /* Ignore arcdir if it doesn't exist. */ if (stat(working->backdir, &sb) != 0 || !S_ISDIR(sb.st_mode)) { if (working->backdir != arcdir) free(working->backdir); working->backdir = NULL; } } else working->backdir = NULL; /* Make sure we can't oflow MAXPATHLEN */ if (working->backdir != NULL) { if (snprintf(line, sizeof(line), "%s/%s.%d%s", working->backdir, working->logbase, working->numlogs, COMPRESS_POSTFIX) >= MAXPATHLEN) errx(1, "%s:%d: pathname too long: %s", conf, lineno, q); } else { if (snprintf(line, sizeof(line), "%s.%d%s", working->log, working->numlogs, COMPRESS_POSTFIX) >= MAXPATHLEN) errx(1, "%s:%d: pathname too long: %s", conf, lineno, working->log); } } if (working) working->next = NULL; (void)fclose(f); return (first); }