#include "super.h" #include "struct.h" #define LL() fprintf(stderr, "[%s, line %i]: ", __FILE__, __LINE__) extern void parse(option *, const char *); extern void link_config(config *); extern void show_config(config *); extern void lc(char *); extern int aa(struct s_array *, const char *); extern void ai(struct s_array *); extern void ad(struct s_array *); extern void ap(struct s_array *); extern void ac(struct s_array *); config *c_top; void parse(option * o, const char *file) { FILE *f = fopen(file, "r"); unsigned int line_number; int i; char line[BUFSIZ]; char *arg, *cmt, *opt; config *scan; if (f == (FILE *) 0) { LL(); fprintf(stderr, "%s: %s (%i)\n", file, strerror(errno), errno); exit(EXIT_FAILURE); } for (line_number = 1; fgets(line, BUFSIZ - 1, f); line_number++) { config *new; opt = line; while (isspace(*opt)) opt++; for (i = strlen(opt) - 1; i >= 0 && isspace(opt[i]); i--) opt[i] = '\0'; if (opt[0] == '\0' || opt[0] == '#') continue; cmt = strchr(line, '#'); if (cmt != (char *) 0) *cmt++ = '\0'; while (isspace(*opt)) opt++; for (i = strlen(opt) - 1; i >= 0 && isspace(opt[i]); i--) opt[i] = '\0'; arg = strchr(line, '='); if (arg == (char *) 0) { LL(); fprintf(stderr, "[%s, line %i]: No '=' found.\n", file, line_number); exit(EXIT_FAILURE); } *arg++ = '\0'; while (isspace(*arg)) arg++; lc(opt); for (i = strlen(opt) - 1; i >= 0 && isspace(opt[i]); i--) opt[i] = '\0'; new = (config *) malloc(sizeof(config)); if (new == (config *) 0) { LL(); fprintf(stderr, "malloc(sizeof(%i)) failed: %s (%i)\n", sizeof(config), strerror(errno), errno); exit(EXIT_FAILURE); } strncpy(new->key, opt, BUFSIZ - 1); strncpy(new->val, arg, BUFSIZ - 1); strncpy(new->file, file, BUFSIZ - 1); new->line_number = line_number; link_config(new); } fclose(f); ai(&o->argallow); /* verification */ for (scan = c_top; scan; scan = scan->next) { if (!strcmp(scan->key, "logdir")) { struct stat logdir_stat; if ((stat(scan->val, &logdir_stat)) == -1) { fprintf(stderr, "[%s, line %i]: logdir '%s': %s (%i)\n", scan->file, scan->line_number, scan->val, strerror(errno), errno); exit(EXIT_FAILURE); } if (!(logdir_stat.st_mode & S_IFDIR)) { fprintf(stderr, "[%s, line %i]: logdir '%s' is not a directory.\n", scan->file, scan->line_number, scan->val); exit(EXIT_FAILURE); } strncpy(o->logdir, scan->val, BUFSIZ - 1); } else if (!strcmp(scan->key, "default shell")) { struct stat defshell_stat; #ifdef HAVE_GETUSERSHELL char *shell; int found = FALSE; setusershell(); while ((shell = (char *) getusershell()) != (char *) 0) if (!strcmp(shell, scan->val)) found = TRUE; endusershell(); if (found == FALSE) { fprintf(stderr, "[%s, line %i]: default shell '%s' is not in /etc/shells.\n", scan->file, scan->line_number, scan->val); exit(EXIT_FAILURE); } #endif /* HAVE_GETUSERSHELL */ if ((stat(scan->val, &defshell_stat)) == -1) { fprintf(stderr, "[%s, line %i]: default shell '%s': %s (%i)\n", scan->file, scan->line_number, scan->val, strerror(errno), errno); exit(EXIT_FAILURE); } strncpy(o->defshell, scan->val, BUFSIZ - 1); } else if (!strcmp(scan->key, "delimiter")) { if (strlen(scan->val) > 1) { fprintf(stderr, "[%s, line %i]: delimiter must be _one_ non-alpha-numeric character. (i.e. : _ + ')\n", scan->file, scan->line_number); exit(EXIT_FAILURE); } o->fdl = (char) *(scan->val); if (!ispunct(o->fdl)) { fprintf(stderr, "[%s, line %i]: delimiter must be punctuation character.\n", scan->file, scan->line_number); exit(EXIT_FAILURE); } } else if (!strcmp(scan->key, "-c arg allow")) aa(&o->argallow, scan->val); else if (!strcmp(scan->key, "syslog.priority")) { int found = FALSE; #ifdef LOG_EMERG if (!strcmp(scan->val, "LOG_EMERG")) { o->priority = LOG_EMERG; found = TRUE; } #endif /* LOG_EMERG */ #ifdef LOG_ALERT if (!strcmp(scan->val, "LOG_ALERT")) { o->priority = LOG_ALERT; found = TRUE; } #endif /* LOG_ALERT */ #ifdef LOG_CRIT if (!strcmp(scan->val, "LOG_CRIT")) { o->priority = LOG_CRIT; found = TRUE; } #endif /* LOG_CRIT */ #ifdef LOG_ERR if (!strcmp(scan->val, "LOG_ERR")) { o->priority = LOG_ERR; found = TRUE; } #endif /* LOG_ERR */ #ifdef LOG_WARNING if (!strcmp(scan->val, "LOG_WARNING")) { o->priority = LOG_WARNING; found = TRUE; } #endif /* LOG_WARNING */ #ifdef LOG_NOTICE if (!strcmp(scan->val, "LOG_NOTICE")) { o->priority = LOG_NOTICE; found = TRUE; } #endif /* LOG_NOTICE */ #ifdef LOG_INFO if (!strcmp(scan->val, "LOG_INFO")) { o->priority = LOG_INFO; found = TRUE; } #endif /* LOG_INFO */ #ifdef LOG_DEBUG if (!strcmp(scan->val, "LOG_DEBUG")) { o->priority = LOG_DEBUG; found = TRUE; } #endif /* LOG_DEBUG */ if (found == FALSE) { fprintf(stderr, "[%s, line %i]: syslog.priority: level '%s' is unknown.\n", scan->file, scan->line_number, scan->val); fputs("The following values are acceptable:\n", stderr); #ifdef LOG_EMERG fputs("LOG_EMERG\n", stderr); #endif /* LOG_EMERG */ #ifdef LOG_ALERT fputs("LOG_ALERT\n", stderr); #endif /* LOG_ALERT */ #ifdef LOG_CRIT fputs("LOG_CRIT\n", stderr); #endif /* LOG_CRIT */ #ifdef LOG_ERR fputs("LOG_ERR\n", stderr); #endif /* LOG_ERR */ #ifdef LOG_WARNING fputs("LOG_WARNING\n", stderr); #endif /* LOG_WARNING */ #ifdef LOG_NOTICE fputs("LOG_NOTICE\n", stderr); #endif /* LOG_NOTICE */ #ifdef LOG_INFO fputs("LOG_INFO\n", stderr); #endif /* LOG_INFO */ #ifdef LOG_DEBUG fputs("LOG_DEBUG\n", stderr); #endif /* LOG_DEBUG */ exit(EXIT_FAILURE); } } /* if(!strcmp(scan->key, "syslog.priority")) */ else if (!strcmp(scan->key, "syslog.facility")) { int found = FALSE; #ifdef LOG_AUTH if (!strcmp(scan->val, "LOG_AUTH")) { o->facility = LOG_AUTH; found = TRUE; } #endif /* LOG_AUTH */ #ifdef LOG_AUTHPRIV if (!strcmp(scan->val, "LOG_AUTHPRIV")) { o->facility = LOG_AUTHPRIV; found = TRUE; } #endif /* LOG_AUTHPRIV */ #ifdef LOG_CRON if (!strcmp(scan->val, "LOG_CRON")) { o->facility = LOG_CRON; found = TRUE; } #endif /* LOG_CRON */ #ifdef LOG_DAEMON if (!strcmp(scan->val, "LOG_DAEMON")) { o->facility = LOG_DAEMON; found = TRUE; } #endif /* LOG_DAEMON */ #ifdef LOG_FTP if (!strcmp(scan->val, "LOG_FTP")) { o->facility = LOG_FTP; found = TRUE; } #endif /* LOG_FTP */ #ifdef LOG_KERN if (!strcmp(scan->val, "LOG_KERN")) { o->facility = LOG_KERN; found = TRUE; } #endif /* LOG_KERN */ #ifdef LOG_LOCAL0 if (!strcmp(scan->val, "LOG_LOCAL0")) { o->facility = LOG_LOCAL0; found = TRUE; } #endif /* LOG_LOCAL0 */ #ifdef LOG_LOCAL1 if (!strcmp(scan->val, "LOG_LOCAL1")) { o->facility = LOG_LOCAL1; found = TRUE; } #endif /* LOG_LOCAL1 */ #ifdef LOG_LOCAL2 if (!strcmp(scan->val, "LOG_LOCAL2")) { o->facility = LOG_LOCAL2; found = TRUE; } #endif /* LOG_LOCAL2 */ #ifdef LOG_LOCAL3 if (!strcmp(scan->val, "LOG_LOCAL3")) { o->facility = LOG_LOCAL3; found = TRUE; } #endif /* LOG_LOCAL3 */ #ifdef LOG_LOCAL4 if (!strcmp(scan->val, "LOG_LOCAL4")) { o->facility = LOG_LOCAL4; found = TRUE; } #endif /* LOG_LOCAL4 */ #ifdef LOG_LOCAL5 if (!strcmp(scan->val, "LOG_LOCAL5")) { o->facility = LOG_LOCAL5; found = TRUE; } #endif /* LOG_LOCAL5 */ #ifdef LOG_LOCAL6 if (!strcmp(scan->val, "LOG_LOCAL6")) { o->facility = LOG_LOCAL6; found = TRUE; } #endif /* LOG_LOCAL6 */ #ifdef LOG_LOCAL7 if (!strcmp(scan->val, "LOG_LOCAL7")) { o->facility = LOG_LOCAL7; found = TRUE; } #endif /* LOG_LOCAL7 */ #ifdef LOG_LPR if (!strcmp(scan->val, "LOG_LPR")) { o->facility = LOG_LPR; found = TRUE; } #endif /* LOG_LPR */ #ifdef LOG_MAIL if (!strcmp(scan->val, "LOG_MAIL")) { o->facility = LOG_MAIL; found = TRUE; } #endif /* LOG_MAIL */ #ifdef LOG_NEWS if (!strcmp(scan->val, "LOG_NEWS")) { o->facility = LOG_NEWS; found = TRUE; } #endif /* LOG_NEWS */ #ifdef LOG_SYSLOG if (!strcmp(scan->val, "LOG_SYSLOG")) { o->facility = LOG_SYSLOG; found = TRUE; } #endif /* LOG_SYSLOG */ #ifdef LOG_USER if (!strcmp(scan->val, "LOG_USER")) { o->facility = LOG_USER; found = TRUE; } #endif /* LOG_USER */ #ifdef LOG_UUCP if (!strcmp(scan->val, "LOG_UUCP")) { o->facility = LOG_UUCP; found = TRUE; } #endif /* LOG_UUCP */ if (found == FALSE) { fprintf(stderr, "[%s, line %i]: syslog.facility: level '%s' is unknown.\n", scan->file, scan->line_number, scan->val); fputs("The following values are acceptable:\n", stderr); #ifdef LOG_AUTH fputs("LOG_AUTH\n", stderr); #endif /* LOG_AUTH */ #ifdef LOG_AUTHPRIV fputs("LOG_AUTHPRIV\n", stderr); #endif /* LOG_AUTHPRIV */ #ifdef LOG_CRON fputs("LOG_CRON\n", stderr); #endif /* LOG_CRON */ #ifdef LOG_DAEMON fputs("LOG_DAEMON\n", stderr); #endif /* LOG_DAEMON */ #ifdef LOG_FTP fputs("LOG_FTP\n", stderr); #endif /* LOG_FTP */ #ifdef LOG_KERN fputs("LOG_KERN\n", stderr); #endif /* LOG_KERN */ #ifdef LOG_LOCAL0 fputs("LOG_LOCAL0\n", stderr); #endif /* LOG_LOCAL0 */ #ifdef LOG_LOCAL1 fputs("LOG_LOCAL1\n", stderr); #endif /* LOG_LOCAL1 */ #ifdef LOG_LOCAL2 fputs("LOG_LOCAL2\n", stderr); #endif /* LOG_LOCAL2 */ #ifdef LOG_LOCAL3 fputs("LOG_LOCAL3\n", stderr); #endif /* LOG_LOCAL3 */ #ifdef LOG_LOCAL4 fputs("LOG_LOCAL4\n", stderr); #endif /* LOG_LOCAL4 */ #ifdef LOG_LOCAL5 fputs("LOG_LOCAL5\n", stderr); #endif /* LOG_LOCAL5 */ #ifdef LOG_LOCAL6 fputs("LOG_LOCAL6\n", stderr); #endif /* LOG_LOCAL6 */ #ifdef LOG_LOCAL7 fputs("LOG_LOCAL7\n", stderr); #endif /* LOG_LOCAL7 */ #ifdef LOG_LPR fputs("LOG_LPR\n", stderr); #endif /* LOG_LPR */ #ifdef LOG_MAIL fputs("LOG_MAIL\n", stderr); #endif /* LOG_MAIL */ #ifdef LOG_NEWS fputs("LOG_NEWS\n", stderr); #endif /* LOG_NEWS */ #ifdef LOG_SYSLOG fputs("LOG_SYSLOG\n", stderr); #endif /* LOG_SYSLOG */ #ifdef LOG_USER fputs("LOG_USER\n", stderr); #endif /* LOG_USER */ #ifdef LOG_UUCP fputs("LOG_UUCP\n", stderr); #endif /* LOG_UUCP */ exit(EXIT_FAILURE); } } /* if(!strcmp(scan->key, "syslog.facility")) */ else { fprintf(stderr, "[%s, line %i]: unknown configuration option '%s'\n", scan->file, scan->line_number, scan->key); exit(EXIT_FAILURE); } } /* for(scan = c_top; scan; scan = scan->next) */ } void link_config(config * c) { c->next = c_top; if (c_top) c_top->prev = c; c_top = c; } void show_config(config * top) { config *scan; for (scan = top; scan; scan = scan->next) { fprintf(stderr, "[%s, line %i]\n", scan->file, scan->line_number); fprintf(stderr, " key = %s\n", scan->key); fprintf(stderr, " val = %s\n", scan->val); } }