// Execute a CGI script in a users public_html/cgi-bin directory // // (C) M.A.Smith University of Brighton // // Permission is granted to use this code // provided this declaration and copyright notice remains intact. // // 1 April 1996 //#include "t99_type.h" // Updated for latest C++ 01-08-03 #include #include #include #include #include #include #include #include // fork exec #include // wait #include // kill #include "parse.h" #include "parse.cpp" #include "mas_cvo.cpp" void cgi_var_output(); void execute( char file[], char user[], char *argv[], char *env[] ); char* map_uname( char *path ); // Parameters to the run program // passed in the QUERY_STRING environment variable // // file=mame - Names the file to be run // user=name - The user // Remember all files name must be absolute or relative to the // directory in which the CGI script is run // ~user/public_html/cgi-bin int main(int argc, char* argv[], char *env[] ) { char *query_str = getenv("QUERY_STRING"); Parse list( query_str == 0 ? (char*)"user=mas&file=cgi&other=123" : query_str ); execute( list.get_item_n( "file"), list.get_item_n( "user" ), argv, env ); return 0; } void cgi_error( char mes[], char mes1[] ="", char mes2[]="" ) { html("Content-type: text/html"); html(""); html(""); html(""); html("Error"); html(""); html(""); html("

Error calling CGI script

"); html("

"); html_( mes ); html_( mes1 ); html( mes2 ); html("

"); cgi_var_output(); html(""); html(""); } void execute( char file[], char user[], char *argv[], char *env[] ) { const int RUN_FOR = 20; char prog[255]; prog[0] = '\0'; strcat( prog, "~" ); strcat( prog, user ); strcat( prog, "/public_html/" ); char *path = map_uname( prog ); chdir( path ); // ~user/public_html/ pid_t pid = fork(); if ( pid == 0 ) { strcat( path, "cgi-bin/" ); strcat( path, file ); alarm( RUN_FOR ); execve( path, argv, env ); // prog cgi_error( "File not readable [", path, "]" ); } else { close(0); close(1); close(2); pid_t pid2 = fork(); if ( pid2 == 0 ) { sleep( RUN_FOR + 2 ); kill( pid, 9 ); // Hand of GOD } else { // Just die } } } char* map_uname( char *path ) { #ifndef NO_MAP if ( path[0] == '~' ) { char uname[255]; // Holds user name char *rest = &path[1]; // omit ~ char *p = &uname[0]; // user while ( *rest != '/' && *rest != '\0' ) { *p++ = *rest++; } *p = '\0'; // Terminator char *root = uname; // If fails passwd *pw = getpwnam( uname ); // Structure about user if ( pw != NULL ) { root = pw->pw_dir; // Users home directory } int len_root = strlen(root); int len_path = len_root + strlen(rest); char *new_path = new char[len_path+1]; // Dynamic string strcpy( &new_path[0], root ); // abs user path strcpy( &new_path[len_root], rest ); // remainder return new_path; } else { return path; } #endif return path; }