int main(int argc, char **argv) { char c; char *flags=0; optind = 0; while ((c = getopt(argc, argv, "vi:x:Mp:")) !=EOF) { switch (c) { case 'i': cfile = optarg; insert = 1; break; case 'x': extract = 1; cfile = optarg; break; case 'M': makemagic = 1; break; case 'v': view = 1; break; case 'p': setflags = 1; flags = optarg; break; default: usage(); } } dexefile = argv[optind]; if (!dexefile) usage(); if ((insert || extract) && !cfile) usage(); if (insert) { putconf(); if (setflags) changeflags(flags); } else if (view) viewconf(); else if (setflags) changeflags(flags); else if (extract) getconf(); else usage(); return 0; }
int main(int argc, char *argv[]) { int opt; int opt_list = 0; char *conf_file = CONF_FILE; // parse arguments while ((opt = getopt(argc, argv, "c:l")) != -1) { switch (opt) { case 'c': conf_file = optarg; break; case 'l': opt_list = 1; break; } } if (optind >= argc) { fprintf(stderr, "ERROR: no hostname given\n"); exit(1); } // open config file char data[DATA_SIZE]; FILE *f = fopen(conf_file, "r"); if (f == NULL) { fprintf(stderr, "ERROR: config file %s does not exist\n", conf_file); exit(1); } // store default configuration putconf("alias_last -last"); putconf("alias_text unavailable"); putconf("data_port 4411"); putconf("data_timeout 2"); putconf("relay_port 22"); // store config settings while (fgets(data, DATA_SIZE, f) != NULL) { if (strlen(data) == DATA_SIZE - 1) { fprintf(stderr, "ERROR: config entry \"%s\" too long\n", data); exit(1); } if (data[strlen(data) - 1] == '\n') data[strlen(data) - 1] = 0; if (data[strlen(data) - 1] == '\r') data[strlen(data) - 1] = 0; putconf(data); } fclose(f); // check required config settings for (int i = 0; i < sizeof(conf_req) / sizeof(char *); i++) { char *tmp = getconf(conf_req[i]); if (tmp == NULL) { fprintf(stderr, "ERROR: config parameter %s is not defined\n", conf_req[i]); exit(1); } } // copy argument char arg[strlen(argv[optind]) + 1]; strcpy(arg, argv[optind]); // chop off domain char *alias_domain = getconf("alias_domain"); char *tmp = strstr(arg, alias_domain); if (tmp == arg + strlen(arg) - strlen(alias_domain)) tmp[0] = 0; // chop off last int last = 0; char *alias_last = getconf("alias_last"); tmp = strstr(arg, alias_last); if (tmp == arg + strlen(arg) - strlen(alias_last)) { tmp[0] = 0; last = 1; } // find default hosts for given alias char hosts_alias[strlen(arg) + 7]; sprintf(hosts_alias, "hosts_%s", arg); char *defaults = getconf(hosts_alias); if (defaults != NULL) { // given host matches defined alias, so load balance // construct balancing request char sdata[DATA_SIZE]; snprintf(sdata, DATA_SIZE, "%s%s %d", arg, last ? getconf("alias_last") : "", getuid()); // concatenate optional arguments to request for (int i = optind + 1; i < argc; i++) { if (strlen(argv[i]) + 2 > DATA_SIZE - strlen(sdata)) { fprintf(stderr, "ERROR: excessive argument length\n"); exit(1); } strncat(sdata, argv[i], DATA_SIZE - strlen(sdata) - 2); } strcat(sdata, "\n"); // retrieve least loaded hosts from data server or time out signal(SIGALRM, timeout); char *host = strdup(getconf("data_host")); for (host = strtok(host, " "); host; host = strtok(NULL, " ")) { // resolve host name outside alarm to avoid reentrancy issues struct addrinfo *ainfo = resolve(host); alarm(igetconf("data_timeout")); if (sigsetjmp(env, 1) != SIGALRM && !getdata(sdata, data, ainfo)) break; // loop to try alternate data servers on failure alarm(0); } alarm(0); if (host == NULL) { // copy default data on failed retrieval for strtok strncpy(data, defaults, DATA_SIZE - 1); data[DATA_SIZE - 1] = 0; } if (strspn(data, " ") == strlen(data)) { // data is empty so no hosts available fprintf(stderr, "ERROR: all hosts for alias %s are %s\n", arg, getconf("alias_text")); exit(1); } // count number of hosts in data host = data; long n = 1; while ((host = strchr(host + 1, ' ')) != NULL) n++; // pick random host from data srand(time(NULL)); n = rand() % n; for (host = strtok(data, " "); n-- > 0; host = strtok(NULL, " ")); if (opt_list) { // print chosen host printf("%s\n", host); exit(0); } else { // connect to chosen host execl(getconf("relay_path"), getconf("relay_path"), host, getconf("relay_port"), NULL); // does not return } } // given host does not match alias, so pass through untouched if (opt_list) { // print given host printf("%s\n", argv[optind]); } else { // connect to given host execl(getconf("relay_path"), getconf("relay_path"), argv[optind], getconf("relay_port"), NULL); // does not return } }