//***************************************************************************** // Simple ReadParse.cc for CGI-Programming. // Distribute freely for non-commercial use. // // E-Mail: Gottfried.Rudorfer@wu-wien.ac.at // // Bugfixes: // 01/98 integrated CERT security fix. // // (c) 1999 by Gottfried Rudorfer // All rights reserved. //***************************************************************************** // Documentation: ************************************************************* // 1. Evaluates the strings passed by the GET and POST method. Uses a STL-Map. // An Example: This code expands Key1=Value1&Key3&Key2=Value2 pairs or singles // into the map "in". /* #include using namespace std; #include "ReadParse.h" int main() { ReadParse mycgi; mycgi.PrintHeader(); map::iterator pos; for(pos=mycgi.in.begin(); pos != mycgi.in.end(); ++pos) { cout << "Name: " << pos->first << "," << "Value: " << pos->second << "
" << endl; cout << "
\n"; } } */ // 2. The method EvalFile(string) opens the file named in string // and parses the contents of that file for $vars. If such a string is // found, it is replaced with the value behind the key stored in the map "in". // You may have more than one variable substiution i.e.: // //***************************************************************************** #include"ReadParse.h" ReadParse::ReadParse() { _env_string = _html_string = NULL; _has_parsed = 0; Parse(); } ReadParse::~ReadParse() { if (_html_string) delete _html_string; if (_env_string) delete _env_string; } void ReadParse::PrintHeader() { cout << "Content-type: text/html\n" << endl; } int ReadParse::strnicmp(const char *s1, const char *s2, const int count) { char a='\0', b='\0'; for(int n=0; n=0;j--) { c=*++strptr; //skip % if ((c >= '0') && (c <= '9')) { value+=w[j]*(c-'0'); } else if ((c >= 'a') && (c <= 'f')) { value+=w[j]*(10+(c-'a')); } else if ((c >= 'A') && (c <= 'F')) { value+=w[j]*(10+c-'A'); } else return 0; } thechar=value; return 1; } void ReadParse::Parse() { int html_length; set_new_handler(CgiNoSpace); char *sg = NULL, *sp = NULL; if(_has_parsed) { cerr << "Don't Call ReadParse twice !!!!\n"; return; } _has_parsed=1; Mygetenv("QUERY_STRING"); if (_env_string) { int l = strlen(_env_string); sg=new char[l+2]; strcpy(sg,_env_string); } Mygetenv("CONTENT_LENGTH"); if (_env_string) { int l = atoi(_env_string); if (l > 0) { sp=new char[l+2]; cin.get(sp,l+1); } } if(!sg && !sp) { cerr << "ReadParse: Hey boy ... we understand METHOD GET & POST\n"; cerr << "ReadParse: Define at least the environment variable QUERY_STRING\n"; exit(1); } html_length = 0; if (sg) html_length += strlen(sg); if (sp) html_length += strlen(sp); if(sg && sp) html_length++; // '&' _html_string = new char [html_length+2]; _html_string[0] = '\0'; if (sg) { strcat(_html_string, sg); delete sg; } if (sp) { if (_html_string[0] != '\0') strcat(_html_string, "&"); strcat(_html_string, sp); delete sp; } int rows=html_length+1, cols=2, html_bufcount[] = {0,0}, readparse_flag=0; char *ptr, *html_arr=new char[rows*cols], c; html_length=strlen(_html_string); ptr=_html_string; while (true) { switch(*ptr) { case '=': readparse_flag=1; break; case '&': case '\0': *(html_arr+html_bufcount[0])='\0'; *(html_arr+rows+html_bufcount[1])='\0'; in[(string)CertFix(html_arr)] = (string)CertFix(html_arr+rows); if (*ptr == '\0') return; readparse_flag=0; html_bufcount[0] = 0; html_bufcount[1] = 0; break; case '%': if (strlen(ptr) >=3) { if (HexToChar(ptr, c)) { *(html_arr+readparse_flag*rows+html_bufcount[readparse_flag]++)=c; ptr+=2; break; } } case '+': *ptr=' '; default: *(html_arr+readparse_flag*rows+html_bufcount[readparse_flag]++) = *ptr; break; } ptr++; } delete html_arr; } string ReadParse::Line(const string& text, const string::size_type pos) { string::size_type nl_pos, cpos = 0; unsigned int line=1; char buf[10]; while((cpos < pos) && (cpos != string::npos)) { nl_pos = text.find_first_of("\n", cpos); if (nl_pos == string::npos) break; if (nl_pos < pos) { line++; cpos = nl_pos + 1; } else break; } sprintf(buf, "%d", line); return string(buf); } string ReadParse::EvalString(const string text) { string::size_type dollar, space; const string trennzeichen(" \t\n"); string neu=""; unsigned int numsub; for (string::size_type cpos=0; cpos != string::npos; ) { dollar = text.find_first_of("$", cpos); numsub = 1; if (dollar != string::npos) { neu += text.substr(cpos, dollar-cpos); space=text.find_first_of(trennzeichen,dollar); while(text.at(dollar+numsub) == '$') numsub++; string name=text.substr(dollar+numsub,space-dollar-numsub); if (space != string::npos) cpos = space + 1; else cpos = space; string subs=""; bool ok = false; for(unsigned int j = 0; j < numsub; j++) { subs += name + " -> "; if ((in.find(name) != in.end()) && (name.length() > 0)) { name = in[name]; ok = true; } else { neu += " Fehler: Variable \'" + name + "\' wurde nicht in der Zeile " + Line(text, dollar) + " gefunden! Die Ableitung ist: " + subs + "."; ok = false; break; } } if (ok) neu += name; } else { neu += text.substr(cpos, dollar-cpos); cpos = dollar; } } return neu; } string ReadParse::EvalFile(const string file) { ifstream in; string r="", s; in.open(file.c_str(), ios::in); if (!in) { cout << "Fehler beim Lesen der Datei \"" << file << "\"" << endl; } else { while(getline(in, s)) r += s + '\n'; in.close(); } return EvalString(r); }