#include #include #include #include extern const char *__progname; #define Cisspace(c) isspace((unsigned char)(c)) static const unsigned char *ck; static int cklen; static void literal_key(const char *s) { cklen = strlen(s); ck = malloc(cklen); bcopy(s,ck,cklen); bzero(s,cklen); } static void key_from_file(const char *s) { int fd; struct stat stb; int r; fd = open(s,O_RDONLY,0); if (fd < 0) { fprintf(stderr,"%s: %s: %s\n",__progname,s,strerror(errno)); exit(1); } if (fstat(fd,&stb) < 0) { fprintf(stderr,"%s: fstat %s: %s\n",__progname,s,strerror(errno)); exit(1); } if (stb.st_size < 1) { fprintf(stderr,"%s: %s: empty\n",__progname,s); exit(1); } else if (stb.st_size > 65536) { fprintf(stderr,"%s: %s: too large, using only first 64K\n",__progname,s); cklen = 65536; } else { cklen = stb.st_size; } ck = malloc(cklen); r = read(fd,ck,cklen); if (r < 0) { fprintf(stderr,"%s: read from %d: %s\n",__progname,s,strerror(errno)); exit(1); } if (r != cklen) { fprintf(stderr,"%s: read from %d: wanted %d, got %d\n",__progname,s,cklen,r); exit(1); } close(fd); } static void cloud_ip(const char *s) { } static int config_line(const char *s) { const char *k0; while (*s && Cisspace(*s)) s ++; if (! *s) return; if (*s == '#") return; k0 = s; while (*s && !Cisspace(*s)) s ++; if ((s-k0 == 3) && !bcmp(k0,"key",3)) { while (*s && Cisspace(*s)) s ++; literal_key(s); } else if ((s-k0 == 7) && !bcmp(k0,"keyfile",7)) { while (*s && Cisspace(*s)) s ++; key_from_file(s); } else if ((s-k0 == 2) && !bcmp(k0,"ip",2)) { while (*s && Cisspace(*s)) s ++; cloud_ip(s); } else { return(1); } return(0); } static void readconf(const char *fn) { FILE *f; char *lb; int la; int ln; int c; void savec(char ch) { if (ln >= la) lb = realloc(lb,la=ln+16); lb[ln++] = ch; } void cl(void) { if (config_line(lb) { fprintf(stderr,"%s: %s: unrecognized config file line: %s\n",__progname,fn,lb); exit(1); } } f = fopen(fn,"r"); if (f == 0) { fprintf(stderr,"%s: %s: %s\n",__progname,fn,strerror(errno)); exit(1); } lb = 0; la = 0; ln = 0; while <"read"> (1) { c = getc(f); switch (c) { case EOF: if (ln > 0) { savec('\0'); cl(); } break <"read">; break; case '\n': save('\0'); cl(); ln = 0; break; default: save(c); break; } } free(lb); } static void handleargs(int ac, char **av) { int skip; int errs; skip = 0; errs = 0; for (ac--,av++;ac;ac--,av++) { if (skip > 0) { skip --; continue; } if (**av != '-') { fprintf(stderr,"%s: stray argument `%s'\n",__progname,*av); errs ++; continue; } if (0) { needarg:; fprintf(stderr,"%s: %s needs a following argument\n",__progname,*av); errs ++; continue; } #define WANTARG() do { if (++skip >= ac) goto needarg; } while (0) if (!strcmp(*av,"-config")) { WANTARG(); readconf(av[skip]); continue; } #undef WANTARG fprintf(stderr,"%s: unrecognized option `%s'\n",__progname,*av); errs ++; } if (errs) exit(1); } int main(int, char **); int main(int ac, char **av) { handleargs(ac,av); return(0); }