📄 readconf.c
字号:
/* libdrcom - Library for communicating with DrCOM 2133 Broadband Access Server Copyright (C) 2005 William Poetra Yoga Hadisoeseno <williampoetra@yahoo.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <arpa/inet.h>#include "drcomd.h"#include "daemon_server.h"#include "daemon_kernel.h"#include "utils.h"#define __OPTLEN 256#define __istidy(x) \ ((x >= 'a' && x <= 'z') \ || (x >= 'A' && x <= 'Z') \ || (x >= '0' && x <= '9') \ || (x == '_' || x == '=' || x == '.' || x == ',' || x == ':' || x == '/'))/* Some kind of checklist: + 0 means option was never encountered in the config file + 1 means option found, value specified and valid + 2 means option found, value specified and invalid + 3 means option found, but no value specified + 4 means option found more than once*/struct _opt_checklist{ u_int8_t username; u_int8_t password; u_int8_t dev; u_int8_t mac; u_int8_t mac0; u_int8_t nic[4]; u_int8_t dnsp; u_int8_t dnss; u_int8_t dhcp; u_int8_t hostip; u_int8_t servip; u_int8_t hostport; u_int8_t servport; u_int8_t hostname; u_int8_t winver; u_int8_t winbuild; u_int8_t servicepack;};int __stripcomments(char *);int __tidyup(char *);int __optname(char *, char *);int __optval(char *, char *);int __parseopt(struct drcom_conf *, char *, struct _opt_checklist *opts);int __fillopts(struct drcom_conf *, struct drcom_info *, struct drcom_host *, struct _opt_checklist *);void init_conf(struct drcom_conf *conf);int get_except(struct drcom_conf *conf, char *buf);/* _readconf A routine for parsing the config file.*/int _readconf(struct drcom_conf *conf, struct drcom_info *info, struct drcom_host *host){ FILE *dotconf; char buf[__OPTLEN], *s; struct _opt_checklist opts; int lineno = 0, r = 0; memset(&opts, 0, sizeof(opts)); init_conf(conf); dotconf = fopen(DRCOM_CONF, "r"); if (!dotconf) return -1; while (1) { s = fgets(buf, __OPTLEN, dotconf); if (s == NULL) break; r = __parseopt(conf, buf, &opts); ++lineno; if (r < 0 || r > 1) { fprintf(stderr, "Error processing config file at line %d.\n", lineno); break; } } /* Even if there was an error, we should close the file first */ fclose(dotconf); if (r < 0 || r > 1) return -1; r = __fillopts(conf, info, host, &opts); if (r) {fprintf(stderr, "fillopts failed\n");goto out;} r = add_except(conf, conf->dnsp, 0xffffffff); if (r) goto out; r = add_except(conf, conf->dnss, 0xffffffff);out: if (r) { fprintf(stderr, "Error digesting configuration!\n"); return -1; } return 0;}int __stripcomments(char *buf){ char *c; c = strchr(buf, '#'); if (c != NULL) *c = '\0'; return (c - buf + 1);}int __tidyup(char *buf){ int i, len, tidylen, inquote; len = strlen(buf); tidylen = 0; inquote = 0; for (i = 0; i < len; ++i) { if (__istidy(buf[i]) || (inquote && (buf[i] != '"'))) { buf[tidylen] = buf[i]; ++tidylen; } else if (buf[i] == '"') { inquote = (inquote) ? 0 : 1; } } buf[tidylen] = '\0'; return tidylen;}int __optname(char *buf, char *optname){ char *t; int len; memset(optname, 0, 256); t = strchr(buf, '='); if (t != NULL) { len = t - buf; strncpy(optname, buf, len); } else { len = -1; optname[0] = '\0'; } return len;}int __optval(char *buf, char *optval){ char *t; int len; memset(optval, 0, 256); t = strchr(buf, '='); if (t != NULL) { len = strlen(buf) - (t - buf + 1); strncpy(optval, t + 1, len); } else { len = -1; optval[0] = '\0'; } return len;}void init_conf(struct drcom_conf *conf){ memset(conf, 0, sizeof(struct drcom_conf));}int add_except(struct drcom_conf *conf, u_int32_t ip, u_int32_t mask){ static unsigned int bufsize = 0; int i; if (conf->except == NULL){ bufsize = 32*sizeof(struct e_address); conf->except_count = 0; conf->except = (struct e_address *)malloc(bufsize); if (conf->except == NULL){ return -1; } } for(i=0; i<conf->except_count; i++) { struct e_address *p = conf->except + i; if ((p->addr & p->mask) == (ip & mask)) return 0; } if (bufsize == conf->except_count*sizeof(struct e_address)) { bufsize *= 2; conf->except = (struct e_address *)realloc(conf->except, bufsize); if (conf->except == NULL){ return -1; } } conf->except[conf->except_count].addr = ip; conf->except[conf->except_count].mask = mask; conf->except_count++; return 0;}int get_except(struct drcom_conf *conf, char *buf){ struct in_addr ip, mask; char *t, *p, *m; p = buf; while (*p != '\0') { t = strchr(p, ','); if (t == NULL) t = p+strlen(p); else { *t = '\0'; t++; } m = strchr(p, '/'); if (m == NULL) return -1; *m = '\0'; m++; if (!inet_pton(AF_INET, p, &ip) || !inet_pton(AF_INET, m, &mask)) return -1; if (add_except(conf, ip.s_addr, mask.s_addr)!=0) return -1; p = t; } return 0;}int __parseopt(struct drcom_conf *conf, char *buf, struct _opt_checklist *opts){/* define them here because they are __parseopt()-specific */#define __optprefix(y, n) \ (strncmp(optname, y, n) == 0)#define __isopt(y, n) \ (strncmp(optname, y, n) == 0 && optname_len == n) int len, optname_len, optval_len, r; long int l; unsigned int _mac[6]; char optname[256], optval[256]; struct in_addr ip = {0}; len = strlen(buf); if (len > 256) { len = 256; buf[len] = '\0'; } len = __stripcomments(buf); if (len == 0) goto skip; len = __tidyup(buf); if (len == 0) goto skip; optname_len = __optname(buf, optname); if (optname_len < 0) goto err; optval_len = __optval(buf, optval); if (optval_len < 0) goto err; if (optname_len == 0) { goto err; } else if (__isopt("username", 8)) { if (opts->username != 0) { opts->username = 4; goto ok; } if (optval_len == 0) { opts->username = 3; goto ok; } memset(conf->username, 0, 36); strncpy(conf->username, optval, 36); opts->username = 1; goto ok; } else if (__isopt("password", 8)) { if (opts->password != 0) { opts->password = 4; goto ok; } if (optval_len == 0) { opts->password = 3; goto ok; } memset(conf->password, 0, 16); strncpy(conf->password, optval, 16); opts->password = 1; goto ok; } else if (__isopt("except", 6)) { if (optval_len == 0) goto ok; else { int r = get_except(conf, optval); if (r==0) goto ok; else{ fprintf(stderr, "except list error\n"); goto err; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -