/********************************************************************** * * cgiargs.cpp -- * Copyright (C) 1999 The New Zealand Digital Library Project * * A component of the Greenstone digital library software * from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************/ #include "cgiargs.h" #include "gsdlunicode.h" void cgiarg_t::clear () { value.clear(); source = program_arg; fileupload.clear(); } cgiarg_t &cgiarg_t::operator=(const cgiarg_t &x) { value=x.value; source=x.source; return *this; } bool operator==(const cgiarg_t &x, const cgiarg_t &y) { return ((x.value == y.value) && (x.source == y.source)); } bool operator<(const cgiarg_t &x, const cgiarg_t &y) { return ((x.value < y.value) || ((x.value == y.value) && (x.source == y.source))); } void fileupload_t::clear() { name.clear(); type.clear(); size = 0; tmp_name.clear(); } ostream &operator<<(ostream &outs, const fileupload_t &fu) { utf8outconvertclass text_t2utf8; outs << "*** fileupload\n"; outs << text_t2utf8 << "name=" << fu.name << ", type="<< fu.type<<", size="<getint(); } fileupload_t *cgiargsclass::getargfile (const text_t &key) { iterator here = args.find (key); if (here == args.end()) return NULL; return &((*here).second.fileupload); } // stream operators to print cgi arguments for debugging purposes ostream &operator<<(ostream &outs, const cgiargsclass &args) { utf8outconvertclass text_t2utf8; cgiargsclass::const_iterator here = args.begin (); cgiargsclass::const_iterator end = args.end (); outs << "*** cgiargsclass\n"; while (here != end) { outs << text_t2utf8 << " \"" << (*here).first << "\"=\"" << (*here).second.value << "\"\n"; ++here; } outs << "\n"; return outs; } cgiarginfo::cgiarginfo () { multiplechar = false; multiplevalue = false; fileupload = false; defaultstatus = weak; argdefault.clear(); savedarginfo = can; } bool operator==(const cgiarginfo &x, const cgiarginfo &y) { return ((x.shortname == y.shortname) && (x.longname == y.longname) && (x.multiplechar == y.multiplechar) && (x.multiplevalue == y.multiplevalue) && (x.fileupload == y.fileupload) && (x.defaultstatus == y.defaultstatus) && (x.argdefault == y.argdefault) && (x.savedarginfo == y.savedarginfo)); } bool operator<(const cgiarginfo &x, const cgiarginfo &y) { return ((x.shortname < y.shortname) || ((x.shortname == y.shortname) && ((x.longname < y.longname) || ((x.longname == y.longname) && ((x.multiplevalue < y.multiplevalue) || ((x.multiplevalue == y.multiplevalue) && ((x.fileupload == y.fileupload) && ((x.fileupload < y.fileupload) || ((x.multiplechar < y.multiplechar) || ((x.multiplechar == y.multiplechar) && ((x.defaultstatus < y.defaultstatus) || ((x.defaultstatus == y.defaultstatus) && ((x.argdefault < y.argdefault) || ((x.argdefault == y.argdefault) && ((x.savedarginfo < y.savedarginfo)))))))))))))))); } // constructor cgiargsinfoclass::cgiargsinfoclass () { } // addarginfo will combine the information with the present // information. If name clashes were detected then the information // will be written to logout (or stderr) and addarginfo will return false. No // processing with the arguments should be done if this happens // as the results will be meaningless. bool cgiargsinfoclass::addarginfo (ostream *logout, cgiarginfo &info) { // if info.fileupload is set certain other fields are implicitly // overridden if (info.fileupload) { info.multiplechar = false; info.defaultstatus = cgiarginfo::weak; info.argdefault = ""; info.savedarginfo = cgiarginfo::mustnot; } cgiarginfo *orginfo = getarginfo (info.shortname); if (orginfo == NULL) { argsinfo[info.shortname] = info; return true; // no clashes } if (orginfo->longname != info.longname) { outconvertclass text_t2ascii; if (logout != NULL) { (*logout) << text_t2ascii << "Error: cgi argument name clash for argument \"" << info.shortname << "\".\nOne long name was\n \"" << orginfo->longname << "\"\nand the other was\n \"" << info.longname << "\".\n\n"; } else { cerr << text_t2ascii << "Error: cgi argument name clash for argument \"" << info.shortname << "\".\nOne long name was\n \"" << orginfo->longname << "\"\nand the other was\n \"" << info.longname << "\".\n\n"; } return false; // found a clash } if (orginfo->multiplevalue != info.multiplevalue) { outconvertclass text_t2ascii; if (logout != NULL) { (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname << "\" was given as being a single value option\n" << "and a multiple value option.\n\n"; } else { cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname << "\" was given as being a single value option\n" << "and a multiple value option.\n\n"; } return false; // found a clash } if (orginfo->fileupload != info.fileupload) { outconvertclass text_t2ascii; if (logout != NULL) { (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname << "\" was given as being a file upload argument\n" << "and a non file upload argument.\n\n"; } else { cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname << "\" was given as being a file upload argument\n" << "and a non file upload argument.\n\n"; } return false; // found a clash } if (orginfo->multiplechar != info.multiplechar) { outconvertclass text_t2ascii; if (logout != NULL) { (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname << "\" was given as being a single character option\n" << "and a multiple character option.\n\n"; } else { cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname << "\" was given as being a single character option\n" << "and a multiple character option.\n\n"; } return false; // found a clash } if (!info.multiplechar && info.argdefault.size() > 1) { outconvertclass text_t2ascii; if (logout != NULL) { (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname << "\" was defined as being a single character option\n" << "but a multiple character default was given.\n\n"; } else { cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname << "\" was defined as being a single character option\n" << "but a multiple character default was given.\n\n"; } return false; // found a problem } // make sure there is no clashes in the savedarginfo if ((orginfo->savedarginfo==cgiarginfo::mustnot && info.savedarginfo==cgiarginfo::must) || (orginfo->savedarginfo==cgiarginfo::must && info.savedarginfo==cgiarginfo::mustnot)) { outconvertclass text_t2ascii; if (logout != NULL) { (*logout) << text_t2ascii << "Error: it was specified that cgi argument \"" << info.shortname << "\" should be saved in the state\n" << "information and that it should not be save in the state information.\n\n"; } else { cerr << text_t2ascii << "Error: it was specified that cgi argument \"" << info.shortname << "\" should be saved in the state\n" << "information and that it should not be save in the state information.\n\n"; } return false; // found a clash } // the only time orginfo->savedarginfo can change is when it is set // to "can" if (orginfo->savedarginfo == cgiarginfo::can) orginfo->savedarginfo = info.savedarginfo; if (orginfo->defaultstatus > info.defaultstatus) { return true; } orginfo->defaultstatus = info.defaultstatus; orginfo->argdefault = info.argdefault; return true; } bool cgiargsinfoclass::addarginfo (ostream *logout, cgiargsinfoclass &info) { iterator here = info.begin (); iterator end = info.end (); while (here != end) { if (!addarginfo (NULL, (*here).second)) { cerr << "returning false\n"; return false; } ++here; } return true; // made it, no clashes } bool cgiargsinfoclass::addarginfo (ostream *logout, const text_t& argshortname, const text_tmap& mapinfo) { cgiarginfo *arginfo = getarginfo (argshortname); if (arginfo == NULL) { arginfo = &(argsinfo[argshortname]); arginfo->shortname = argshortname; arginfo->defaultstatus = cgiarginfo::config; } text_tmap::const_iterator thisInfo = mapinfo.begin(); text_tmap::const_iterator endInfo = mapinfo.end(); while (thisInfo != endInfo) { if (thisInfo->first == "longname") arginfo->longname = thisInfo->second; else if (thisInfo->first == "multiplechar") arginfo->multiplechar = (thisInfo->second == "true"); else if (thisInfo->first == "defaultstatus") { if (thisInfo->second == "none") arginfo->defaultstatus = cgiarginfo::none; else if (thisInfo->second == "weak") arginfo->defaultstatus = cgiarginfo::weak; else if (thisInfo->second == "good") arginfo->defaultstatus = cgiarginfo::good; else if (thisInfo->second == "config") arginfo->defaultstatus = cgiarginfo::config; else if (thisInfo->second == "imperative") arginfo->defaultstatus = cgiarginfo::imperative; } else if (thisInfo->first == "argdefault") { arginfo->argdefault = thisInfo->second; } else if (thisInfo->first == "savedarginfo") { if (thisInfo->second == "mustnot") arginfo->savedarginfo = cgiarginfo::mustnot; else if (thisInfo->second == "can") arginfo->savedarginfo = cgiarginfo::can; else if (thisInfo->second == "must") arginfo->savedarginfo = cgiarginfo::must; } else if (logout != NULL) { (*logout) << ("Invalid argument for cgiarg for " + argshortname + " (" + thisInfo->first + ")\n"); } ++thisInfo; } return true; } bool cgiargsinfoclass::addarginfo (ostream *logout, confcgiarg_tmap& info) { confcgiarg_tmap::const_iterator thisArg = info.begin(); confcgiarg_tmap::const_iterator endArg = info.end(); while (thisArg != endArg) { if (!addarginfo(logout, thisArg->first, thisArg->second)) return false; ++thisArg; } return true; } cgiarginfo *cgiargsinfoclass::getarginfo (const text_t &key) { iterator here = argsinfo.find (key); if (here == argsinfo.end()) return NULL; return &((*here).second); } const cgiarginfo *cgiargsinfoclass::getarginfo (const text_t &key) const { const_iterator here = argsinfo.find (key); if (here == argsinfo.end()) return NULL; return &((*here).second); } // stream operators to print cgiarginfo for debugging purposes ostream &operator<<(ostream &outs, const cgiargsinfoclass &argsinfo) { utf8outconvertclass text_t2utf8; cgiargsinfoclass::const_iterator here = argsinfo.begin (); cgiargsinfoclass::const_iterator end = argsinfo.end (); outs << "*** cgiargsinfoclass\n"; while (here != end) { outs << text_t2utf8 << (*here).first << ", "; ++here; } outs << "\n"; return outs; }