/* options.c Parses command line options and provides options control panel with an interactive Web interface for the Web server (webserver.c). -------------------------------------------------------------------------------- gSOAP XML Web services tools Copyright (C) 2001-2004, Robert van Engelen, Genivia, Inc. All Rights Reserved. This software is released under one of the following two licenses: GPL or Genivia's license for commercial use. -------------------------------------------------------------------------------- GPL license. 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 Author contact information: engelen@genivia.com / engelen@acm.org -------------------------------------------------------------------------------- A commercial use license is available from Genivia, Inc., contact@genivia.com -------------------------------------------------------------------------------- */ #define SOAP_NOGLOBAL #define SOAP_FMAC3 static #include "optC.c" #include "options.h" #include "httpget.h" #ifdef WIN32 #define OPTION_CHAR '/' #else #define OPTION_CHAR '-' #endif struct option *copy_options(const struct option *options); int parse_options(int argc, char **argv, struct option *options); void query_options(struct soap *soap, struct option *options); int load_options(const char *file, const char *name, struct option *options); int save_options(const char *file, const char *name, struct option *options); int html_options(struct soap *soap, struct option *options); int html_form_options(struct soap *soap, struct option *options); static int set_option(const char *key, const char *val, struct option *options); static int set_selection(const char *val, struct option *p); static int find_selection(const char *value, const char *selections); static void print_usage(int argc, char **argv, struct option *options); struct option *copy_options(const struct option *options) { struct option *p; int n; for (n = 0; options[n].name; n++) ; p = (struct option*)malloc((n + 1) * sizeof(struct option)); if (p) { for (n = 0; options[n].name; n++) { p[n].name = options[n].name; p[n].selections = options[n].selections; p[n].selected = options[n].selected; if (options[n].value) { p[n].value = (char*)malloc(strlen(options[n].value) + 1); strcpy(p[n].value, options[n].value); } else p[n].value = NULL; } p[n].name = NULL; p[n].selections = NULL; p[n].selected = 0; p[n].value = NULL; } return p; } void free_options(struct option *options) { if (options) { struct option *p; for (p = options; p->name; p++ ) { if (p->value) free(p->value); } free(options); } } int parse_options(int argc, char **argv, struct option *options) { int i; for (i = 1; i < argc; i++) { const char *key, *val; key = argv[i]; if (*key == OPTION_CHAR) { int flag = 1; while (flag && *++key) { if (*key == '?' || !strcmp(key, "help")) { print_usage(argc, argv, options); return 1; } if (i < argc) val = argv[i + 1]; else val = NULL; switch (set_option(key, val, options)) { case 2: i++; case 1: flag = 0; case 0: break; case -1: fprintf(stderr, "%s: missing argument value for option %c%s\n", argv[0], OPTION_CHAR, key); print_usage(argc, argv, options); return 1; case -2: fprintf(stderr, "%s: unknown option %c%s\n", argv[0], OPTION_CHAR, key); print_usage(argc, argv, options); return 1; } } } else if (set_option(NULL, key, options) < 0) fprintf(stderr, "%s: invalid argument %s\n", argv[0], key); } return 0; } void query_options(struct soap *soap, struct option *options) { char *s = query(soap); /* get arguments from query string */ while (s) { char *key = query_key(soap, &s); /* decode next query string key */ char *val = query_val(soap, &s); /* decode next query string value */ if (key) set_option(key, val, options); } } int load_options(const char *file, const char *name, struct option *options) { struct soap soap; soap_init(&soap); if (file) { soap.recvfd = open(file, O_RDONLY); if (soap.recvfd < 0) { soap_done(&soap); return EOF; } } if (!soap_begin_recv(&soap) && !soap_element_begin_in(&soap, name, 1, NULL)) { struct t__Option t; while (soap_in_t__Option(&soap, "option", &t, NULL)) if (set_option(t.key, t.val, options) < 0) ; /* error, just ignore for now */ if (!soap_element_end_in(&soap, name)) soap_end_recv(&soap); } if (file) close(soap.recvfd); soap_end(&soap); soap_done(&soap); return soap.error; } int save_options(const char *file, const char *name, struct option *options) { struct soap soap; soap_init1(&soap, SOAP_XML_TREE); soap.namespaces = NULL; soap.encodingStyle = NULL; if (file) { soap.sendfd = open(file, O_CREAT | O_RDWR, 0644); if (soap.sendfd < 0) { soap_done(&soap); return EOF; } } if (!soap_begin_send(&soap) && !soap_element_begin_out(&soap, name, 0, NULL)) { struct option *p; struct t__Option t; for (p = options; p->name; p++) { t.val = NULL; if (!p->name[0]) { if (!p->value) continue; t.key = NULL; t.val = p->value; } else if (p->name[1] == '.') t.key = (char*)p->name + 2; else t.key = (char*)p->name; if (p->selections && strchr(p->selections, ' ')) { const char *s = p->selections - 1; char *r; int i; for (i = p->selected; i > 0; i--) { s = strchr(s + 1, ' '); if (!s) break; } if (s) { t.val = soap_strdup(&soap, s + 1); r = strchr(t.val, ' '); if (r) *r = '\0'; } } else if (p->value) t.val = p->value; else if (!p->selected) continue; if (soap_out_t__Option(&soap, "option", 0, &t, NULL)) break; } if (!soap_element_end_out(&soap, name)) soap_end_send(&soap); } if (file) close(soap.sendfd); soap_end(&soap); soap_done(&soap); return soap.error; } int html_options(struct soap *soap, struct option *options) { struct option *p; soap_send(soap, "
"); if (!n[0]) { if (s) soap_send(soap, s); soap_send(soap, " | "); if (p->value) soap_send(soap, p->value); soap_send(soap, " | "); } else if (!s) { soap_send(soap, n); soap_send(soap, "![]() | on | "); else soap_send(soap, "'>off | "); } else if (strchr(s, ' ')) { soap_send(soap, n); soap_send(soap, ""); for (i = 0; ; i++) { t = strchr(s, ' '); if (i == 0) soap_send(soap, ""); else soap_send(soap, " | ||||||||
");
if (i == p->selected)
soap_send(soap, "![]() | ");
else
{ soap_send(soap, "");
soap_send(soap, "![]() | "); } if (t) soap_send_raw(soap, s, t - s); else soap_send(soap, s); soap_send(soap, " | "); if (!t) break; soap_send(soap, ""); } soap_send(soap, " | \n"); // | |||||||||