/* * Configuration */ void getconf(void) { FILE *f1; char line[STRLEN]; /* Configure defaults */ io_config(); /* Determine dot file name */ getdotfile(); /* Load dot file when available */ if (p.dotfile[0] && (f1 = fopen(p.dotfile, "rb")) != NULL) { while (fgets(line, STRLEN, f1) != NULL) { /* Remove CRLF */ rmcrlf(line, STRLEN); if (mystrcasestr(line, "DEVICE=") == line) { strncpy(p.device, &line[7], STRLEN); } #ifdef TTY else if (mystrcasestr(line, "BAUDRATE=") == line) { p.baudrate = strtoul(&line[9], NULL, 0); } #endif else if (mystrcasestr(line, "SLEEP=") == line) { p.sleep_low = strtoul(&line[6], NULL, 0); p.sleep_high = p.sleep_low; } else if (mystrcasestr(line, "SLEEP_LOW=") == line) { p.sleep_low = strtoul(&line[10], NULL, 0); } else if (mystrcasestr(line, "SLEEP_HIGH=") == line) { p.sleep_high = strtoul(&line[11], NULL, 0); } else if (mystrcasestr(line, "BITRULES=") == line) { p.bitrules = strtoul(&line[9], NULL, 0); } else if (mystrcasestr(line, "BUSY=") == line) { p.busy = strtoul(&line[5], NULL, 0); } #if defined(RPI) || defined(BITBANG) || defined(FTDI) || defined(BPI) else if (mystrcasestr(line, "VPP=") == line) { p.vpp = strtoul(&line[4], NULL, 0); } else if (mystrcasestr(line, "PGM=") == line) { p.pgm = strtoul(&line[4], NULL, 0); } else if (mystrcasestr(line, "PGC=") == line) { p.pgc = strtoul(&line[4], NULL, 0); } else if (mystrcasestr(line, "PGD=") == line) { p.pgdi = strtoul(&line[4], NULL, 0); p.pgdo = p.pgdi; } else if (mystrcasestr(line, "PGDO=") == line) { p.pgdo = strtoul(&line[5], NULL, 0); } else if (mystrcasestr(line, "PGDI=") == line) { p.pgdi = strtoul(&line[5], NULL, 0); } #endif /* RPI || BITBANG || FTDI || BPI */ #if defined(FTDI) else if (mystrcasestr(line, "USB_SERIAL=") == line) { strncpy(p.usb_serial, &line[11], STRLEN); } #endif /* FTDI*/ #ifdef MCP23017 else if (mystrcasestr(line, "MCP=") == line) { p.mcp = strtoul(&line[4], NULL, 0); } #endif /* MCP23017 */ else if (mystrcasestr(line, "FWSLEEP=") == line) { p.fwsleep = strtoul(&line[8], NULL, 0); } else if (mystrcasestr(line, "DEBUG=") == line) { p.debug = strtoul(&line[6], NULL, 0); } else if (mystrcasestr(line, "ETC=") == line) { strncpy(p.etc, &line[4], STRLEN); } } fclose(f1); } else { /* We are using the defaults */ snprintf(p.dotfile, STRLEN, "Using defaults (override in %s)", DOTFILENAME); } }
/* * Get line * * Reads input line and updates the byte count and address fields. * * The record type field (*tt) is also returned as: * * TT_EOF EOF record * TT_DATA Data record * ~TT_DATA Not a data record (255) */ char * inhx32_fgets(char *line, FILE *fp, uint8_t *bb, uint16_t *aaaa, uint8_t *tt, uint16_t *extended_addr) { size_t len; uint8_t cc, _tt; uint16_t i; *bb = 0; *aaaa = 0; *tt = ~TT_DATA; /* Not a data record (255) */ /* Get line */ if (fgets(line, STRLEN, fp) == NULL) return NULL; /* EOF */ /* Validate line prefix */ if (line[0] != ':') return line; /* Remove CRLF */ rmcrlf(line, STRLEN); /* Validate line length */ len = strlen(line); if ((len & 1) == 0 || len < 11) return line; /* Validate checksum */ cc = 0; for (i = 1; line[i]; i += 2) cc += hex2byte(&line[i]); if (cc != 0) return line; /* Determine number of bytes in this line */ *bb = hex2byte(&line[BB]); #if 0 /* Validate number of bytes */ if (*bb > PIC_BYTLEN) return line; #endif /* Validate line length */ if (len != (2 * *bb + 11)) return line; /* Determine address for this line */ *aaaa = (hex2byte(&line[AAAA]) << 8) | hex2byte(&line[AAAA + 2]); /* Determine record type */ _tt = hex2byte(&line[TT]); /* Process data record */ if (_tt == TT_DATA) { /* Validate line length */ if (*bb == 0) return line; /* Not a data record */ /* Validate alignment */ if (p.pic && (*bb % p.pic->align)) { #if 0 printf("%s: information: unaligned input ignored\n", __func__); #endif return line; /* Not a data record */ } } /* Process extended address record */ else if (_tt == TT_EXTENDED_LINEAR_ADDRESS) { /* Validate extended address */ if (*aaaa != 0 || *bb != 2) return line; /* Not a data record */ /* Determine extended address */ *extended_addr = (hex2byte(&line[HHHH]) << 8) | hex2byte(&line[HHHH + 2]); return line; /* Not a data record */ } /* Ignore other records */ else { return line; /* Not a data record */ } /* Return data record */ *tt = TT_DATA; return line; }
int read_config(char *file, srv_t * srv) { FILE *fp; char s[LINEBUF], *cp, *sp, pluginname[256]; char section = 0, *dbname = 0, *dbload = 0; unsigned int n = 0; long lval; int i; plugin_t *plugins, *pl = 0; dback_t *dbp = 0; const conf_com_t *ccp; spocp_result_t r; /* * should never be necessary if (!srv->root) srv->root = ruleset_new(0); */ if (!srv->root->db) srv->root->db = db_new(); plugins = srv->plugin; if ((fp = fopen(file, "r")) == NULL) { traceLog(LOG_ERR, "Could not find or open the configuration file \"%s\"", file); return 0; } while (fgets(s, LINEBUF, fp)) { n++; rmcrlf(s); if (*s == 0 || *s == '#') continue; /* * New section */ if (*s == '[') { cp = find_balancing(s + 1, '[', ']'); if (cp == 0) { traceLog(LOG_ERR, err_msg, n, "Section specification"); return 0; } *cp = 0; sp = s + 1; if (strcasecmp(sp, "server") == 0) section = SYSTEM; else if (strcasecmp(sp, "dback") == 0) section = DBACK; else { section = PLUGIN; strlcpy(pluginname, sp, sizeof( pluginname)); pl = 0; } continue; } /* * Within a section The directives are of the form: * key *SP * "=" *SP val *(*SP val) * val = 1*nonspacechar / '"' char '"' */ rm_lt_sp(s, 1); /* remove leading and trailing blanks */ /* * empty line or comment */ if (*s == 0 || *s == '#') continue; cp = strchr(s, '='); if (cp == 0) { traceLog(LOG_ERR, err_msg, n, "syntax error"); continue; } sp = cp; for (*cp++ = '\0'; *cp && (*cp == ' ' || *cp == '\t'); cp++) *cp = '\0'; for (sp--; sp >= s && (*sp == ' ' || *sp == '\t'); sp--) *sp = '\0'; /* * no key, not good */ if (*s == '\0') continue; switch (section) { case SYSTEM: for (i = 1; keyword[i]; i++) if (strcasecmp(keyword[i], s) == 0) break; if (keyword[i] == 0) { #ifdef HAVE_SASL if((strncmp("sasl_", s, 5) == 0)) add_overflow_directive(s, cp); else #endif traceLog(LOG_ERR, err_msg, n, "Unknown keyword"); continue; } switch (i) { case RULEFILE: if (srv->rulefile) free(srv->rulefile); srv->rulefile = Strdup(cp); break; case CERTIFICATE: if (srv->certificateFile) free(srv->certificateFile); srv->certificateFile = Strdup(cp); break; case PRIVATEKEY: if (srv->privateKey) free(srv->privateKey); srv->privateKey = Strdup(cp); break; case CALIST: if (srv->caList) free(srv->caList); srv->caList = Strdup(cp); break; case DHFILE: if (srv->dhFile) free(srv->dhFile); srv->dhFile = Strdup(cp); break; case ENTROPYFILE: if (srv->SslEntropyFile) free(srv->SslEntropyFile); srv->SslEntropyFile = Strdup(cp); break; case PASSWD: if (srv->passwd) free(srv->passwd); srv->passwd = Strdup(cp); break; case LOGGING: if (srv->logfile) free(srv->logfile); srv->logfile = Strdup(cp); break; case TIMEOUT: if (numstr(cp, &lval) == SPOCP_SUCCESS) { if (lval >= 0 && lval <= YEAR) srv->timeout = (unsigned int) lval; else { traceLog(LOG_ERR, err_msg, n, "Value out of range"); srv->timeout = DEFAULT_TIMEOUT; } } else { traceLog(LOG_ERR, err_msg, n, "Non numeric value"); srv->timeout = DEFAULT_TIMEOUT; } break; case UNIXDOMAINSOCKET: if (srv->uds) free(srv->uds); srv->uds = Strdup(cp); break; case PORT: if (numstr(cp, &lval) == SPOCP_SUCCESS) { if (lval > 0L && lval < 65536) { srv->port = (unsigned int) lval; } else { traceLog(LOG_ERR, err_msg, n, "Number out of range"); srv->port = DEFAULT_PORT; } } else { traceLog(LOG_ERR, err_msg, n, "Non numeric value"); } break; case NTHREADS: if (numstr(cp, &lval) == SPOCP_SUCCESS) { if (lval <= 0) { traceLog(LOG_ERR, err_msg, n, "Value out of range"); return 0; } else { int level = (int) lval; srv->threads = level; } } else { traceLog(LOG_ERR, err_msg, n, "Non numeric specification"); return 0; } break; case SSLVERIFYDEPTH: if (numstr(cp, &lval) == SPOCP_SUCCESS) { if (lval > 0L) { srv->sslverifydepth = (unsigned int) lval; } else { traceLog(LOG_ERR, err_msg, n, "number out of range"); srv->sslverifydepth = 0; } } else { traceLog(LOG_ERR, err_msg, n, "Non numeric value"); } break; case PIDFILE: if (srv->pidfile) Free(srv->pidfile); srv->pidfile = Strdup(cp); break; case MAXCONN: if (numstr(cp, &lval) == SPOCP_SUCCESS) { if (lval > 0L) { srv->nconn = (unsigned int) lval; } else { traceLog(LOG_ERR, err_msg, n, "Number out of range"); srv->sslverifydepth = 0; } } else { traceLog(LOG_ERR, err_msg, n, "Non numeric value"); } break; #ifdef HAVE_SSL case CLIENTCERT: if (strcasecmp(cp, "none") == 0) srv->clientcert = NONE; else if (strcasecmp(cp, "demand") == 0) srv->clientcert = DEMAND; else if (strcasecmp(cp, "hard") == 0) srv->clientcert = HARD; break; #endif case NAME: if (srv->name) Free(srv->name); srv->name = Strdup(cp); break; } break; case PLUGIN: if (pl == 0) { if (strcmp(s, "load") != 0) { traceLog(LOG_ERR, err_msg, n, "First directive in plugin sector has to be \"load\""); section = 0; } if ((pl = plugin_load(plugins, pluginname, cp)) == 0) section = 0; else { /* * The last one is placed last */ for (; pl->next; pl = pl->next); } if (plugins == 0) plugins = pl; } else { if (strcmp(s, "poolsize") == 0) { if (numstr(cp, &lval) == SPOCP_SUCCESS) { if (lval <= 0) { traceLog(LOG_ERR, err_msg, n, "Value out of range"); } else { int level = (int) lval; if (pl->dyn == 0) pl->dyn = pdyn_new (level); if (pl->dyn->size == 0) pl->dyn->size = level; } } else { traceLog(LOG_ERR, err_msg, n, "Non numeric specification"); } } else if (strcmp(s, "cachetime") == 0) { if (plugin_add_cachedef(pl, cp) == FALSE ) traceLog(LOG_ERR, err_msg, n, "Cachetime def"); } else if (pl->ccmds == 0) { /* No * directives * allowed */ traceLog(LOG_ERR, err_msg, n, "Directive where there should not be one"); } else { for (ccp = pl->ccmds; ccp; ccp++) { int np=0, j; char **arr; arr = strchop(cp,&np); for (j=0; j<np; j++) traceLog(LOG_ERR, "%s:%s", cp, arr[j]); if (strcmp(ccp->name, s) == 0) { r = ccp->func(&pl-> conf, ccp-> cmd_data, np, arr); if (r != SPOCP_SUCCESS) { traceLog (LOG_ERR, err_msg, n, ccp-> errmsg); } charmatrix_free( arr ); break; } } if (ccp == 0) { traceLog(LOG_ERR,err_msg, n, "Unknown directive"); } } } break; case DBACK: if (dbp == 0) { if (strcmp(s, "name") == 0) { dbname = Strdup(cp); if (dbname && dbload) { dbp = dback_load(dbname, dbload); free(dbname); free(dbload); } } else if (strcmp(s, "load") == 0) { dbload = Strdup(cp); if (dbname && dbload) { dbp = dback_load(dbname, dbload); free(dbname); free(dbload); } } else traceLog(LOG_ERR,err_msg, n, "Unknown directive"); } else { for (ccp = dbp->ccmds; ccp && *ccp->name; ccp++) { if (strcmp(ccp->name, s) == 0) { r = ccp->func(&dbp->conf, ccp->cmd_data, 1, &cp); if (r != SPOCP_SUCCESS) { traceLog(LOG_ERR,err_msg, n, ccp->errmsg); } break; } } if (ccp == 0) { traceLog(LOG_ERR,err_msg, n, "Unknown directive"); } } break; } } fclose(fp); if (srv->pidfile == 0) srv->pidfile = Strdup("spocd.pid"); if (srv->timeout == 0) srv->timeout = DEFAULT_TIMEOUT; if (srv->threads == 0) srv->threads = DEFAULT_NTHREADS; if (srv->sslverifydepth == 0) srv->sslverifydepth = DEFAULT_SSL_DEPTH; srv->plugin = plugins; srv->dback = dbp; return 1; }