- FILE *f;
- char *cp;
- char line[1024];
- char cmd[1024];
- char path[256];
- int linenum;
- int num_cmds = 64;
- int cur_cmd = 0;
- double est;
- entropy_source_t *entcmd;
-
- f = fopen(cmdfilename, "r");
- if (!f) {
- fatal("couldn't read entropy commands file %.100s: %.100s",
- cmdfilename, strerror(errno));
- }
-
- entcmd = (entropy_source_t *)xmalloc(num_cmds * sizeof(entropy_source_t));
- memset(entcmd, '\0', num_cmds * sizeof(entropy_source_t));
-
- /* Read in file */
- linenum = 0;
- while (fgets(line, sizeof(line), f)) {
- int arg;
- char *argv;
-
- linenum++;
-
- /* skip leading whitespace, test for blank line or comment */
- cp = line + strspn(line, WHITESPACE);
- if ((*cp == 0) || (*cp == '#'))
- continue; /* done with this line */
-
- /* First non-whitespace char should be double quote delimiting */
- /* commandline */
- if (*cp != '"') {
- error("bad entropy command, %.100s line %d", cmdfilename,
- linenum);
- continue;
- }
-
- /* first token, command args (incl. argv[0]) in double quotes */
- cp = strtok(cp, "\"");
- if (cp == NULL) {
- error("missing or bad command string, %.100s line %d -- ignored",
- cmdfilename, linenum);
- continue;
- }
- strlcpy(cmd, cp, sizeof(cmd));
-
- /* second token, full command path */
- if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
- error("missing command path, %.100s line %d -- ignored",
- cmdfilename, linenum);
- continue;
- }
-
- /* did configure mark this as dead? */
- if (strncmp("undef", cp, 5) == 0)
- continue;
-
- strlcpy(path, cp, sizeof(path));
-
- /* third token, entropy rate estimate for this command */
- if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
- error("missing entropy estimate, %.100s line %d -- ignored",
- cmdfilename, linenum);
- continue;
- }
- est = strtod(cp, &argv);
-
- /* end of line */
- if ((cp = strtok(NULL, WHITESPACE)) != NULL) {
- error("garbage at end of line %d in %.100s -- ignored", linenum,
- cmdfilename);
- continue;
- }
-
- /* save the command for debug messages */
- entcmd[cur_cmd].cmdstring = xstrdup(cmd);
-
- /* split the command args */
- cp = strtok(cmd, WHITESPACE);
- arg = 0;
- argv = NULL;
- do {
- char *s = (char*)xmalloc(strlen(cp) + 1);
- strncpy(s, cp, strlen(cp) + 1);
- entcmd[cur_cmd].args[arg] = s;
- arg++;
- } while ((arg < 5) && (cp = strtok(NULL, WHITESPACE)));
-
- if (strtok(NULL, WHITESPACE))
- error("ignored extra command elements (max 5), %.100s line %d",
- cmdfilename, linenum);
-
- /* Copy the command path and rate estimate */
- entcmd[cur_cmd].path = xstrdup(path);
- entcmd[cur_cmd].rate = est;
-
- /* Initialise other values */
- entcmd[cur_cmd].sticky_badness = 1;
-
- cur_cmd++;
-
- /* If we've filled the array, reallocate it twice the size */
- /* Do this now because even if this we're on the last command,
- we need another slot to mark the last entry */
- if (cur_cmd == num_cmds) {
- num_cmds *= 2;
- entcmd = xrealloc(entcmd, num_cmds * sizeof(entropy_source_t));
- }
- }
-
- /* zero the last entry */
- memset(&entcmd[cur_cmd], '\0', sizeof(entropy_source_t));
-
- /* trim to size */
- entropy_sources = xrealloc(entcmd, (cur_cmd+1) * sizeof(entropy_source_t));
-
- debug("loaded %d entropy commands from %.100s", cur_cmd, cmdfilename);
-
- return (cur_cmd >= MIN_ENTROPY_SOURCES);