int parse_switches(int argc, char **argv, int *piBr, int *pbForce, int *pbPrintVersion, int *pbKeepLabel, int *pbWritePartitionInfo, int *piHeads) { int bHelp = 0; int i; *piBr = NO_WRITING; *pbForce = 0; *pbPrintVersion = 0; *pbKeepLabel = 1; *pbWritePartitionInfo = 0; *piHeads = -1; if(argc < 2) return 1; /* Don't parse the device */ argc--; if(( ! strcmp("-h", argv[argc])) || ( ! strcmp("--help", argv[argc]))) bHelp = 1; else if(( ! strcmp("-v", argv[argc])) || ( ! strcmp("--version", argv[argc]))) *pbPrintVersion = 1; /* Don't parse the name of the program */ while(--argc) { if( ! strcmp("--fat12w7", argv[argc])) *piBr = FAT12W7_BR; if( ! strcmp("--fat12", argv[argc])) *piBr = FAT12_BR; else if( ! strcmp("--fat32w7", argv[argc])) *piBr = FAT32W7_BR; else if( ! strcmp("--fat32nt", argv[argc])) *piBr = FAT32NT_BR; else if( ! strcmp("--fat32pe", argv[argc])) *piBr = FAT32PE_BR; else if( ! strcmp("--fat32", argv[argc])) *piBr = FAT32_BR; else if( ! strcmp("--fat32free", argv[argc])) *piBr = FAT32FD_BR; else if( ! strcmp("--fat16free", argv[argc])) *piBr = FAT16FD_BR; else if( ! strcmp("--fat16", argv[argc])) *piBr = FAT16_BR; else if( ! strcmp("--ntfs", argv[argc])) *piBr = NTFS_BR; else if( ! strcmp("--force", argv[argc])) *pbForce = 1; else if( ! strcmp("--wipelabel", argv[argc])) *pbKeepLabel = 0; else if( ! strcmp("--partition", argv[argc])) *pbWritePartitionInfo = 1; else if( ! strcmp("--mbr7fat", argv[argc])) *piBr = MBR_WIN7FAT; else if( ! strcmp("--mbr7", argv[argc])) *piBr = MBR_WIN7; else if( ! strcmp("--mbrvista", argv[argc])) *piBr = MBR_VISTA; else if( ! strcmp("--mbr", argv[argc])) *piBr = MBR_2000; else if( ! strcmp("--mbr95b", argv[argc])) *piBr = MBR_95B; else if( ! strcmp("--mbrdos", argv[argc])) *piBr = MBR_DOS; else if( ! strcmp("--mbrsyslinux", argv[argc])) *piBr = MBR_SYSLINUX; else if( ! strcmp("--mbrgptsyslinux", argv[argc])) *piBr = MBR_GPT_SYSLINUX; else if( ! strcmp("--mbrzero", argv[argc])) *piBr = MBR_ZERO; else if( ! strcmp("--write", argv[argc])) *piBr = AUTO_BR; else if( ! strcmp("--version", argv[argc])) *pbPrintVersion = 1; else if( (argv[argc][0] == '-') && (argv[argc][1] != '-') && !argv[argc][2]) { for(i=1; argv[argc][i]; i++) { switch(argv[argc][i]) { case '0': *piBr = FAT12W7_BR; break; case '1': *piBr = FAT12_BR; break; case 'b': *piBr = FAT32NT_BR; case '2': *piBr = FAT32NT_BR; break; case 'e': *piBr = FAT32PE_BR; break; case '3': *piBr = FAT32_BR; break; case '4': *piBr = FAT32FD_BR; break; case '5': *piBr = FAT16FD_BR; break; case '6': *piBr = FAT16_BR; break; case 'n': *piBr = NTFS_BR; break; case 'f': *pbForce = 1; break; case 'l': *pbKeepLabel = 0; break; case 'p': *pbWritePartitionInfo = 1; break; case '8': *piBr = MBR_WIN7FAT; break; case '7': *piBr = MBR_WIN7; break; case 'i': *piBr = MBR_VISTA; break; case 'm': *piBr = MBR_2000; break; case '9': *piBr = MBR_95B; break; case 'd': *piBr = MBR_DOS; break; case 's': *piBr = MBR_SYSLINUX; break; case 't': *piBr = MBR_GPT_SYSLINUX; break; case 'z': *piBr = MBR_ZERO; break; case 'w': *piBr = AUTO_BR; break; case 'v': *pbPrintVersion = 1; break; default: bHelp=1; break; } } } else if((!strcmp("--heads", argv[argc-1]) || !strcmp("-H", argv[argc-1])) && isnumberstr(argv[argc])) *piHeads = atoi(argv[argc--]); else bHelp = 1; } return bHelp; } /* parse_switches */
/* * 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); }