?»??»?/* vi: set sw=4 ts=4: */ /* ------------------------------------------------------------ */ /* rct - a light weight web configuration tools */ /* Copyright (c) 2001 Redsonic Inc. All rights reserved. */ /* v1.0.0 1/17/2002 */ /* ------------------------------------------------------------ */ #include "version.h" #include "port.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "dispatch.h" #include "Config.h" /* #include "lingualen.h" */ /* #include "lingualgb.h" */ /* #include "lingualb5.h" */ /* #include "lingualjp.h" */ #ifdef RCT_USER_DEFINE_UI char* get_session_val(const char* name); int put_session_val(const char* name, const char* value); #endif #ifdef RELEASE #define DEFAULT_HTTP_PORT 80 #define DEFAULT_USER "root" #else #define DEFAULT_HTTP_PORT 8080 #define DEFAULT_USER "root" #endif #define MAXI_PAIRS 100 #ifndef __USE_XOPEN #define __USE_XOPEN #endif #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif /* A multi-family sockaddr. */ typedef union { struct sockaddr sa; struct sockaddr_in sa_in; #ifdef HAVE_SOCKADDR_IN6 struct sockaddr_in6 sa_in6; #endif /* HAVE_SOCKADDR_IN6 */ #ifdef HAVE_SOCKADDR_STORAGE struct sockaddr_storage sa_stor; #endif /* HAVE_SOCKADDR_STORAGE */ } usockaddr; char* incoming_ip; /* Where the request comes. Only single connection permit.*/ extern char* redusername; extern char* redpassword; #ifdef RCT_PROFILE_TWO_ACCOUNTS extern char* redusername_2; extern char* redpassword_2; extern char* redacceright; #endif extern char* redaccessip; extern char* redlanguage; static char* argv0; static int debug; int port; static int do_chroot; int debug_flag=0; static char* user; static char* cgi_pattern; static char* hostname; static char hostname_buf[500]; NEW_MODULE user_defined_module[10] = {{NULL,NULL,NULL},{NULL,NULL,NULL}, {NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}, {NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}; /*static u_int hostaddr; */ static char* logfile; static char* pidfile; static char* charset = "iso-8859-1"; static FILE* logfp; static int listen4_fd, listen6_fd; /* Request variables. */ int conn_fd; usockaddr client_addr; static char* request; static int request_size, request_len, request_idx; int method; char* path; char* file; char* installed_modules; struct stat sb; char* query; char* protocol; int status; long bytes; char* req_hostname; char* authorization; long content_length; char* content_type; char* cookie; char* host; char* referer; char* useragent; char* remoteuser; char* CONFIG_SESSION; char* WIZARD_SESSION; int which_tab=1; /* Forwards. */ extern int save_to_flash(void); static void usage( void ); static int initialize_listen_socket( usockaddr* usaP ); static void handle_request( void ); static void de_dotdot( char* file ); static void do_file( void ); static void do_main( void ); static void interpose_input(void); static void add_to_postdat( char* str, int len ); static void auth_check(); static void send_authenticate( char* realm ); void send_redirect( char* url); void send_error( int s, char* title, char* extra_header, char* text ); static void send_error_body( int s, char* title, char* text ); static void send_error_tail( void ); void add_headers( int s, char* title, char* extra_header, char* mime_type, long b, time_t mod ); static void start_request( void ); static void add_to_request( char* str, int len ); static char* get_request_line( void ); static void start_response( void ); void add_to_response( char* str, int len ); void send_response( void ); static int my_read( char* buf, int size ); static int my_write( char* buf, int size ); static void make_log_entry( void ); static char* get_method_str( int m ); static char* get_mime_type( char* name ); static void handle_sigterm( int sig ); static void handle_sigchld( int sig ); static void lookup_hostname( usockaddr* usa4P, size_t sa4_len, int* gotv4P, usockaddr* usa6P, size_t sa6_len, int* gotv6P ); char* ntoa( usockaddr* usaP ); static size_t sockaddr_len( usockaddr* usaP ); static int b64_decode( const char* str, unsigned char* space, int size ); static void check_new_module(void); static void add_new_module(char *module_name, char *link_url, char *image_name); #define SESSION_LIVE_TIME 120 void noaction(int sig); int cur_pid=0; /* Here are some html functions */ /* void send_page( char* title); */ /* static int page_template(int section); */ void home_page(void); void handler_errmesg(void); //static void profile_html(char* in_name,char* out_mesg); void inner_errmesg(char* mesg); //#define exit(x) int main( int argc, char** argv ) { int argn; uid_t uid; usockaddr host_addr4; usockaddr host_addr6; int gotv4, gotv6; fd_set afdset; int maxfd; usockaddr usa; int sz, r; int trackmore=0; char *tbuf; struct stat sbuf; /* Parse args. */ argv0 = argv[0]; //debug = 0; debug = 1; port = -1; do_chroot = 0; cgi_pattern = (char*) 0; user = DEFAULT_USER; hostname = (char*)0; logfile = (char*) 0; // pidfile = (char*) 0; pidfile = (char*) "/var/run/rct.pid"; logfp = (FILE*) 0; argn = 1; incoming_ip = (char*) 0; installed_modules = (char*) 0; while ( argn < argc && (argv[argn][0] == '-' || trackmore==1)) { if ( strcmp( argv[argn], "-p" ) == 0 && argn + 1 < argc ) { ++argn; port = atoi( argv[argn] ); trackmore = 0; } else if ( strcmp( argv[argn], "-d" ) == 0) { debug_flag= 1; trackmore = 0; } else if ( strcmp( argv[argn], "-l" ) == 0 && argn + 1 < argc ) { ++argn; logfile = argv[argn]; trackmore = 0; } else if ( strcmp( argv[argn], "-m" ) == 0 && argn + 1 < argc ) { ++argn; trackmore = 1; // printf(" %s ",argv[argn]); if(installed_modules==NULL) { installed_modules = (char*)malloc(strlen(argv[argn])+3); (void)strcpy(installed_modules,":"); (void)strcat(installed_modules,argv[argn]); (void)strcat(installed_modules,":"); } else { tbuf = installed_modules; installed_modules = (char*)malloc(strlen(argv[argn])+strlen(tbuf)+4); (void)strcpy(installed_modules,tbuf); (void)strcat(installed_modules,":"); (void)strcat(installed_modules,argv[argn]); (void)strcat(installed_modules,":"); free(tbuf); } } else if(trackmore==1) { tbuf = installed_modules; installed_modules = (char*)malloc(strlen(argv[argn])+strlen(tbuf)+4); (void)strcpy(installed_modules,tbuf); (void)strcat(installed_modules,":"); (void)strcat(installed_modules,argv[argn]); (void)strcat(installed_modules,":"); free(tbuf); } else usage(); ++argn; } if ( argn != argc ) usage(); if ( port == -1 ) { port = DEFAULT_HTTP_PORT; } if ( logfile != (char*) 0 ) { /* Open the log file. */ logfp = fopen( logfile, "a" ); if ( logfp == (FILE*) 0 ) { perror( logfile ); exit( 1 ); } } /* Create the session directory if it does not exsist. */ stat("session",&sbuf); if ( !S_ISDIR(sbuf.st_mode) ) { #ifdef DEBUG (void) fprintf(stderr,"Missing \"session\" directory. Creating ...\n"); #endif mkdir("session",0755); } /* Remove all the session data file */ system("rm -f session/*"); /* check if user defined module */ check_new_module(); textdomain(PACKAGE); // setlocale(LC_ALL,""); /* Look up hostname. */ lookup_hostname( &host_addr4, sizeof(host_addr4), &gotv4, &host_addr6, sizeof(host_addr6), &gotv6 ); if ( hostname == (char*) 0 ) { (void) gethostname( hostname_buf, sizeof(hostname_buf) ); hostname = hostname_buf; } if ( ! ( gotv4 || gotv6 ) ) { #ifdef DEBUG (void) fprintf( stderr, "can't find any valid address\n" ); #endif exit( 1 ); } /* Initialize listen sockets. Try v6 first because of a Linux peculiarity; ** unlike other systems, it has magical v6 sockets that also listen for v4, ** but if you bind a v4 socket first then the v6 bind fails. */ if ( gotv6 ) listen6_fd = initialize_listen_socket( &host_addr6 ); else listen6_fd = -1; if ( gotv4 ) listen4_fd = initialize_listen_socket( &host_addr4 ); else listen4_fd = -1; /* If we didn't get any valid sockets, fail. */ if ( listen4_fd == -1 && listen6_fd == -1 ) { #ifdef DEBUG (void) fprintf( stderr, "can't bind to any address\n" ); #endif exit( 1 ); } if ( ! debug ) { /* Make ourselves a daemon. */ #ifdef HAVE_DAEMON if ( daemon( 1, 1 ) < 0 ) { perror( "daemon" ); exit( 1 ); } #else switch ( fork() ) { case 0: break; case -1: perror( "fork" ); exit( 1 ); default: exit( 0 ); } #ifdef HAVE_SETSID (void) setsid(); #endif #endif } else { /* Even if we don't daemonize, we still want to disown our parent ** process. */ #ifdef HAVE_SETSID (void) setsid(); #endif /* HAVE_SETSID */ } if ( pidfile != (char*) 0 ) { /* Write the PID file. */ FILE* pidfp = fopen( pidfile, "w" ); if ( pidfp == (FILE*) 0 ) { perror( pidfile ); exit( 1 ); } (void) fprintf( pidfp, "%d\n", (int) getpid() ); (void) fclose( pidfp ); } /* Read zone info now, in case we chroot(). */ tzset(); /* If we're root, start becoming someone else. */ if ( getuid() == 0 ) { struct passwd* pwd; FILE *fp = fopen("/etc/passwd","r"); pwd = fgetpwent(fp); if ( pwd == (struct passwd*) 0 ) { (void) fprintf( stderr, "%s: unknown user - '%s'\n", argv0, user ); exit( 1 ); } /* Set aux groups to null. */ if ( setgroups( 0, (const gid_t*) 0 ) < 0 ) { perror( "setgroups" ); exit( 1 ); } /* Set primary group. */ if ( setgid( pwd->pw_gid ) < 0 ) { perror( "setgid" ); exit( 1 ); } /* Try setting aux groups correctly - not critical if this fails. */ if ( initgroups( user, pwd->pw_gid ) < 0 ) perror( "initgroups" ); #ifdef HAVE_SETLOGIN /* Set login name. */ (void) setlogin( user ); #endif /* HAVE_SETLOGIN */ /* Save the new uid for setting after we chroot(). */ uid = pwd->pw_uid; } /* Chroot if requested. */ if ( do_chroot ) { char cwd[1000]; (void) getcwd( cwd, sizeof(cwd) - 1 ); if ( chroot( cwd ) < 0 ) { perror( "chroot" ); exit( 1 ); } /* Always chdir to / after a chroot. */ if ( chdir( "/" ) < 0 ) { perror( "chroot chdir" ); exit( 1 ); } } /* If we're root, become someone else. */ if ( getuid() == 0 ) { /* Set uid. */ if ( setuid( uid ) < 0 ) { perror( "setuid" ); exit( 1 ); } /* Check for unnecessary security exposure. */ #ifdef DEBUG if (!do_chroot ) (void) fprintf( stderr,"%s: started as root without requesting chroot(), warning only\n", argv0 ); #endif } /* Catch various termination signals. */ (void) signal( SIGTERM, handle_sigterm ); (void) signal( SIGINT, handle_sigterm ); (void) signal( SIGHUP, handle_sigterm ); (void) signal( SIGUSR1, handle_sigterm ); /* Catch defunct children. */ //(void) signal( SIGCHLD, handle_sigchld ); /* And get EPIPE instead of SIGPIPE. */ (void) signal( SIGPIPE, SIG_IGN ); (void) signal( SIGUSR1, SIG_IGN ); (void) signal( SIGUSR2, SIG_IGN ); /* Main loop. */ for (;;) { /* Possibly do a select() on the possible two listen fds. */ /* struct sockaddr_in addr; int len=sizeof(addr); conn_fd = accept( listen4_fd, &addr,&len ); incoming_ip = ntoa(&addr); */ struct sockaddr_in addr; int len=sizeof(usa); conn_fd = accept( listen4_fd,(struct sockaddr_in *)&usa,&len ); incoming_ip = ntoa(&usa); if (conn_fd < 0) { perror("accept1"); continue; } r = fork(); if ( r < 0 ) { perror( "fork" ); exit( 1 ); } else if ( r == 0 ) { handle_request(); exit(0); } (void) close( conn_fd ); alarm(SESSION_LIVE_TIME); cur_pid=r; signal(SIGALRM, noaction); wait(&r); //wait4(r,&len,0,NULL); alarm(0); } } static void usage( void ) { #ifdef DEBUG (void) fprintf( stderr, "usage: %s [-p port] [-l logfile] [-m module ...]\n", argv0 ); /* (void) fprintf(stderr,"Installed Moduels: %s\n",installed_modules); */ #endif exit( 1 ); } static int initialize_listen_socket( usockaddr* usaP ) { int listen_fd; int i; listen_fd = socket( usaP->sa.sa_family, SOCK_STREAM, 0 ); if ( listen_fd < 0 ) { perror( "socket" ); return -1; } (void) fcntl( listen_fd, F_SETFD, 1 ); i = 1; if ( setsockopt( listen_fd, SOL_SOCKET, SO_REUSEADDR, (char*) &i, sizeof(i) ) < 0 ) { perror( "setsockopt" ); return -1; } if ( bind( listen_fd, &usaP->sa, sockaddr_len( usaP ) ) < 0 ) { perror( "bind" ); return -1; } if ( listen( listen_fd, 1024 ) < 0 ) { perror( "listen" ); return -1; } return listen_fd; } /* This runs in a child process, and exits when done, so cleanup is not needed. */ static void handle_request( void ) { char* method_str; char* line; char* cp; char buf[40]; /* Initialize the request variables. */ remoteuser = (char*) 0; method = -1; path = (char*) 0; file = (char*) 0; query = (char*) 0; protocol = "HTTP/1.0"; status = 0; bytes = -1; req_hostname = (char*) 0; authorization = (char*) 0; content_type = (char*) 0; content_length = -1; cookie = (char*) 0; host = (char*) 0; referer = ""; useragent = ""; /* Multilingual */ get_rct_config(); if(!redlanguage) redlanguage="iso-8859-1"; if(strcmp(redlanguage, "iso-8559-1")==0) // setlocale(LC_ALL,"ISO-8859-1"); // setlocale(LC_ALL,"en_US"); // setlocale(LC_ALL,"C"); setenv("LC_ALL", "C", 1); else if(strcmp(redlanguage, "gb2312")==0) // setlocale(LC_ALL, "zh_CN.GB2312"); setenv("LC_ALL", "zh_CN.GB2312", 1); else if(strcmp(redlanguage, "big5")==0) // setlocale(LC_ALL, "zh_TW.Big5"); setenv("LC_ALL", "zh_TW.Big5", 1); /* if(setenv("LC_ALL", "zh_TW.Big5", 1)==0) { printf("Set zh_TW.Big Successful\n"); } else { printf("Set zh_TW.Big Fail\n"); } */ else // setlocale(LC_ALL, "ISO-8859-1"); // setlocale(LC_ALL, "en_US"); // setlocale(LC_ALL,"C"); setenv("LC_ALL", "C", 1); textdomain(PACKAGE); /* Read in the request. */ start_request(); start_response(); for (;;) { char buf[1024]; int r = my_read( buf, sizeof(buf) ); if ( r <= 0 ) break; add_to_request( buf, r ); if ( strstr( request, "\r\n\r\n" ) != (char*) 0 || strstr( request, "\n\n" ) != (char*) 0 ) break; } /* Parse the first line of the request. */ method_str = get_request_line(); path = strpbrk( method_str, " \t\n\r" ); if ( path == (char*) 0 ) send_error( 400, _("Bad Request"), (char*) 0, _("Can't parse request.") ); *path++ = '\0'; #ifdef DEBUG if(path&&strncmp(path,"/image/",7)) { fprintf(stderr, "\n\n========== < enter rct handler request > ==========\n"); // (void) fprintf( stderr, "method=%s\npath=%s\n", method_str,path); fflush(stderr); } #endif path += strspn( path, " \t\n\r" ); protocol = strpbrk( path, " \t\n\r" ); if ( protocol == (char*) 0 ) send_error( 400, _("Bad Request"), (char*) 0, _("Can't parse request.") ); *protocol++ = '\0'; query = strchr( path, '?' ); /* if ( query == (char*) 0 ) */ /* query = ""; */ /* else */ /* *query++ = '\0'; */ if (query != (char*) 0 ) *query++ = '\0'; #ifdef DEBUG if(query) { (void) fprintf( stderr, "query=%s\n", query); fflush(stderr); } #endif /* Parse the rest of the request headers. */ while ( ( line = get_request_line() ) != (char*) 0 ) { #ifdef DEBUG if(path && strncmp(path,"/image/",7)) { (void) fprintf( stderr, "%s\n", line); fflush(stderr); } #endif if ( line[0] == '\0' ) break; else if ( strncasecmp( line, "Authorization:", 14 ) == 0 ) { cp = &line[14]; cp += strspn( cp, " \t" ); authorization = cp; } else if ( strncasecmp( line, "Content-Length:", 15 ) == 0 ) { cp = &line[15]; cp += strspn( cp, " \t" ); content_length = atol( cp ); } else if ( strncasecmp( line, "Content-Type:", 13 ) == 0 ) { cp = &line[13]; cp += strspn( cp, " \t" ); content_type = cp; } else if ( strncasecmp( line, "Cookie:", 7 ) == 0 ) { cp = &line[7]; cp += strspn( cp, " \t" ); cookie = cp; } else if ( strncasecmp( line, "Host:", 5 ) == 0 ) { cp = &line[5]; cp += strspn( cp, " \t" ); host = cp; } else if ( strncasecmp( line, "Referer:", 8 ) == 0 ) { cp = &line[8]; cp += strspn( cp, " \t" ); referer = cp; } else if ( strncasecmp( line, "User-Agent:", 11 ) == 0 ) { cp = &line[11]; cp += strspn( cp, " \t" ); useragent = cp; } } if ( strcasecmp( method_str, get_method_str( METHOD_GET ) ) == 0 ) method = METHOD_GET; else if ( strcasecmp( method_str, get_method_str( METHOD_HEAD ) ) == 0 ) method = METHOD_HEAD; else if ( strcasecmp( method_str, get_method_str( METHOD_POST ) ) == 0 ) method = METHOD_POST; else send_error( 501, _("Not Implemented"), (char*) 0, _("That method is not implemented.") ); CONFIG_SESSION = get_session_file(incoming_ip, 0); WIZARD_SESSION = get_session_file(incoming_ip, 1); strdecode( path, path ); if ( path[0] != '/' ) send_error( 400, _("Bad Request"), (char*) 0, _("Bad filename.") ); file = &(path[1]); if ( file[0] == '\0' ) file = "./"; de_dotdot( file ); if ( file[0] == '/' || ( file[0] == '.' && file[1] == '.' && ( file[2] == '\0' || file[2] == '/' ) ) ) send_error( 400, _("Bad Request"), (char*) 0, _("Illegal filename.") ); #ifdef RCT_USER_DEFINE_UI if (strncmp(file, "rct/help", 8)==0) referer = get_session_val("HELP_REFERER"); if (file == "./") { put_session_val("HELP_REFERER", path); sprintf(buf, "html/%s/index.htm", redlanguage); send_redirect(buf); } else if (strncmp(file, "home", 4)==0) { if (check_status()==0) { path = "/"; put_session_val("HELP_REFERER", path); if((stat(RCT_CONFIG,&sb)<0)&&strncmp(file, "rct_wizard", 10)) which_tab=0; else auth_check(); home_page(); } } else if ((strncmp(file, "html/", 5)==0) || strncmp(file, "css/", 4)==0|| (strncmp(file, "image/", 6)==0)) #else if (strncmp(file, "image/", 6)==0) #endif { if ( stat( file, &sb ) < 0 ) send_error( 404, _("Not Found"), (char*) 0, _("File not found.") ); if ( ! S_ISDIR( sb.st_mode ) ) do_file(); } else { #ifdef RCT_USER_DEFINE_UI if (strncmp(file, "rct/help", 8) !=0) put_session_val("HELP_REFERER", path); #endif #ifdef DEBUG if(method ==METHOD_GET) fprintf(stderr, "request: /%s from %s method: GET\n", file, ntoa(&client_addr)); else if(method ==METHOD_POST) fprintf(stderr, "request: /%s from %s method: POST\n", file, ntoa(&client_addr)); fflush(stderr); #endif if((stat(RCT_CONFIG,&sb)<0)&&strncmp(file, "rct_wizard", 10)) { which_tab=0; if (check_status()) { home_page(); } } else { if (check_status()) { do_main(); } } } } #ifdef RCT_USER_DEFINE_UI int put_session_val(name, value) const char* name; const char* value; { FILE *fp,*fd; char ftmp[30], fname[30]; char buf[1024], c; int i,j,k,len, n; char* et; if(name==NULL) return 1; (void) strcpy(fname,"session/t"); (void) strcat(fname,incoming_ip); if(stat(fname,&sb)==0) { len = strlen(name); et = (char*)malloc(len+2); (void) strcpy(et,name); (void) strcat(et,"="); (void) strcpy(ftmp,"/tmp/"); (void) strcat(ftmp,incoming_ip); if ((fp = fopen(fname, "r")) == NULL) return 1; if ((fd = fopen(ftmp, "w")) == NULL) { if (fp) fclose(fp); return 1; } i = j = k = 0; while (!feof(fp)) { c = fgetc(fp); if((i == 0)&& (!isspace(c))) { buf[i++] = c; } else if((i>0)&&(c == '\n')) { buf[i]='\0'; if((strncmp(trim(buf),et,len) == 0)&&(buf[len]=='=')) { k=1; if(!strcmp(fname, CONFIG)) (!value)?fprintf(fd,"%s=\'\'\n",name):fprintf(fd,"%s=\'%s\'\n",name,value); else (!value)?fprintf(fd,"%s=\n",name):fprintf(fd,"%s=%s\n",name,value); } else { fprintf(fd,"%s\n",buf); } i = 0; } else buf[i++] = c; } if(k==0) (!value)?fprintf(fd,"%s=\n",name):fprintf(fd,"%s=%s\n",name,value); fclose(fp); fclose(fd); free(et); /* copy file back */ if ((fd = fopen(fname, "w")) == NULL) return 1; if ((fp = fopen(ftmp, "r")) == NULL) { if (fd) fclose(fd); return 1; } (void)flock(fileno(fd),LOCK_EX); while (!feof(fp)) { c = fgetc(fp); if(c != EOF) fputc(c,fd); } (void)flock(fileno(fd),LOCK_UN); fclose(fp); fclose(fd); unlink(ftmp); /* remove temp file */ } else { if ((fp = fopen(fname, "w")) == NULL) return (1); else { (void)flock(fileno(fp),LOCK_EX); (!value) ? fprintf(fp,"%s=\n",name) : fprintf(fp,"%s=%s\n",name,value); (void)flock(fileno(fp),LOCK_UN); fclose(fp); return 0; } } return 0; } char* get_session_val(name) const char* name; { FILE *fp; char buf[120], *key, *value, *value2,c, *v2, *ref; int i=0; const char delimiters[] = "=\r\n\t"; char fname[30]; if(name==NULL) return NULL; (void) strcpy(fname,"session/t"); (void) strcat(fname,incoming_ip); if ((fp = fopen(fname, "r")) == NULL) return NULL; while (!feof(fp)) { c = fgetc(fp); if((i == 0)&& (!isspace(c))) { buf[i++] = c; } else if((i>0)&&(c == '\n')) { buf[i]='\0'; v2 = strtok(buf, delimiters); key = (char*)trim(v2); value = strtok(NULL, delimiters); if((key!=NULL)&&(key[0]!='#')) { if(value !=NULL) { if ((value2 = strdup(value)) == NULL) malloc_error(); } else value2 = NULL; if (!strcmp(key, name)) ref= value2; } i = 0; } else buf[i++] = c; } fclose(fp); return ref; } #endif static void de_dotdot( char* file ) { char* cp; char* cp2; int l; /* Elide any xxx/../ sequences. */ while ( ( cp = strstr( file, "/../" ) ) != (char*) 0 ) { for ( cp2 = cp - 1; cp2 >= file && *cp2 != '/'; --cp2 ) continue; if ( cp2 < file ) break; (void) strcpy( cp2, cp + 3 ); } /* Also elide any xxx/.. at the end. */ while ( ( l = strlen( file ) ) > 3 && strcmp( ( cp = file + l - 3 ), "/.." ) == 0 ) { for ( cp2 = cp - 1; cp2 >= file && *cp2 != '/'; --cp2 ) continue; if ( cp2 < file ) break; *cp2 = '\0'; } } char* response; int response_size, response_len; char* bodycode; int bodycode_size, bodycode_len; char* htitle; int htitle_size, htitle_len; char* hdescr; int hdescr_size, hdescr_len; char* postdat; int postdat_size, postdat_len; int use_form=0; int overwrite_form_end=0; static void do_file( void ) { char* type; char fixed_type[500]; char* cp; int fd; void* ptr; fd = open( file, O_RDONLY ); if ( fd < 0 ) send_error( 403, _("Forbidden"), (char*) 0, _("File is protected.") ); type = get_mime_type( file ); (void) snprintf( fixed_type, sizeof(fixed_type), type, (charset == NULL) ? "iso-8859-1" : charset ); /* send_authenticate( "/" ); */ add_headers( 200, "Ok", (char*) 0, fixed_type, -1, -1 ); send_response(); if ( method == METHOD_HEAD ) return; #ifdef HAVE_MMAP if ( sb.st_size > 0 ) /* avoid zero-length mmap */ { ptr = mmap( 0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0 ); if ( ptr != (void*) -1 ) { (void) my_write( ptr, sb.st_size ); (void) munmap( ptr, sb.st_size ); } } #else ptr = (char *) malloc(1024*10); if (ptr) { while(1) { int len = read(fd,ptr,10*1024); if (len <= 0) break; my_write(ptr,len); } free(ptr); } #endif (void) close( fd ); } static void do_main( void ) { char** argp; char** envp; FILE *fpro; int parse_headers; char* binary; char* directory; char* uname; char* pa; char* pa1; char* save; char slogoff[50]; char* s="conf/"; bodycode=(char*) 0; hdescr=(char*) 0; htitle==(char*) 0; if ( method != METHOD_GET && method != METHOD_POST ) send_error( 501, _("Not Implemented"), (char*) 0, _("That method is not implemented.") ); if (method == METHOD_POST) /* get the post data */ { interpose_input(); #ifdef DEBUG fprintf(stderr,"postdata length=%d\n",postdat_len); //,postdat_size,strlen(postdat)); if((postdat)&&(postdat_len>0)&&(postdat_len !=strlen(postdat))) fprintf(stderr,"The post content has binary data. One or more files are in binary format.\n"); // fprintf(stderr,"POST DATA:\n%s\n",postdat); fflush(stderr); #endif } if ((strncmp(file, "rct_wizard",10) == 0)&&(stat(RCT_CONFIG,&sb)!=0)) { rct_wizard1(); //home_page(); } else { /* auth checking first */ auth_check(); //get_config('C'); //if (access_check( ntoa(&client_addr))) //inner_errmesg(_("Access denied. Your IP Address is unauthorized. See your Systems Administrator.")); dispatcher(); } } /* This routine is used only for POST requests. It reads the post data ** from the request for the handlers. */ static void interpose_input() { int c, r; char buf[10240]; c = request_len - request_idx; if ( c > 0 ) { /* if ( write( wfd, &(request[request_idx]), c ) != c ) */ /* return; */ add_to_postdat(&(request[request_idx]), c); } while ( c < content_length ) { r = my_read( buf, MIN( sizeof(buf), content_length - c ) ); if ( r == 0 ) sleep( 1 ); else if ( r < 0 ) { if ( errno == EAGAIN ) sleep( 1 ); else return; } else { /* if ( write( wfd, buf, r ) != r ) */ /* return; */ add_to_postdat(buf,r); c += r; } } } static void auth_check() { char authpath[10000]; struct stat sb; char authinfo[500]; char* authpass; char* dirname="/"; int l; FILE* fp; char *cps,*key, *value, *value2; /* #ifdef DEBUG */ /* (void) fprintf( stderr, "Authorization: %s\n", authorization); */ /* #endif */ /* Does this request contain authorization info? */ if ( authorization == (char*) 0 ) /* Nope, return a 401 Unauthorized. */ send_authenticate( dirname ); /* Basic authorization info? */ if ( strncmp( authorization, "Basic ", 6 ) != 0 ) send_authenticate( dirname ); /* Decode it. */ l = b64_decode( &(authorization[6]), authinfo, sizeof(authinfo) ); authinfo[l] = '\0'; /* Split into user and password. */ authpass = strchr( authinfo, ':' ); if ( authpass == (char*) 0 ) /* No colon? Bogus auth info. */ send_authenticate( dirname ); *authpass++ = '\0'; #ifdef DEBUG // fprintf(stderr, "Enter auth_check(): client IP=%s\n", ntoa(&client_addr)); // fflush(stderr); #endif //if (access_check( ntoa(&client_addr))) if (access_check(incoming_ip)) inner_errmesg(_("Access denied. Your IP Address is unauthorized.")); else { cps = (char*) crypt(&authpass[0], &authinfo[0]); #ifdef RCT_PROFILE_TWO_ACCOUNTS if ((strcmp(cps,redpassword)==0) && (strcmp(authinfo,redusername)==0)) { redacceright = "W"; return; } if ( redpassword_2 && redusername_2 && (strcmp(cps,redpassword_2)==0) && (strcmp(authinfo,redusername_2)==0) && (method==METHOD_GET)) { redacceright = "R"; return; } #else // Single user if ((strcmp(cps,redpassword)==0) && (strcmp(authinfo,redusername)==0)) return; #endif send_authenticate( dirname ); } } void send_redirect( char* url) { char header[10000]; //fprintf(stderr,"%s\n",url); (void) snprintf( header, sizeof(header), "location: %s", url ); send_error( 301, _("Redirect"), header, _("Page Redirect") ); } static void send_authenticate( char* realm ) { char header[10000]; (void) snprintf( header, sizeof(header), "WWW-Authenticate: Basic realm=\"%s\"", realm ); send_error( 401, _("Unauthorized"), header, _("Authorization required.") ); } void send_error( int s, char* title, char* extra_header, char* text ) { add_headers( s, title, extra_header, "text/html", -1, -1 ); send_error_body( s, title, text ); send_error_tail(); send_response(); exit( 1 ); } static void send_error_body( int s, char* title, char* text ) { char buf[10000]; int buflen; /* Send built-in error page. */ buflen = snprintf(buf, sizeof(buf), "%d %s\n

%d %s

\n", s, title, s, title ); add_to_response( buf, buflen ); buflen = snprintf( buf, sizeof(buf), "%s\n", text ); add_to_response( buf, buflen ); } static void send_error_tail( void ) { char buf[500]; int buflen; if ( match( "**MSIE**", useragent ) ) { int n; buflen = snprintf( buf, sizeof(buf), "\n" ); add_to_response( buf, buflen ); } buflen = snprintf( buf, sizeof(buf), "
\n
%s
\n\n", SERVER_URL, SERVER_SOFTWARE ); add_to_response( buf, buflen ); } void add_headers( int s, char* title, char* extra_header, char* mime_type, long b, time_t mod ) { time_t now; char timebuf[100]; char buf[10000]; int buflen; const char* rfc1123_fmt = "%a, %d %b %Y %H:%M:%S GMT"; status = s; bytes = b; make_log_entry(); buflen = snprintf( buf, sizeof(buf), "%s %d %s\r\n", protocol, status, title ); add_to_response( buf, buflen ); buflen = snprintf( buf, sizeof(buf), "Server: %s\r\n", SERVER_SOFTWARE ); add_to_response( buf, buflen ); now = time( (time_t*) 0 ); (void) strftime( timebuf, sizeof(timebuf), rfc1123_fmt, gmtime( &now ) ); buflen = snprintf( buf, sizeof(buf), "Date: %s\r\n", timebuf ); add_to_response( buf, buflen ); if ( extra_header != (char*) 0 ) { buflen = snprintf( buf, sizeof(buf), "%s\r\n", extra_header ); add_to_response( buf, buflen ); } if ( mime_type != (char*) 0 ) { buflen = snprintf( buf, sizeof(buf), "Content-type: %s\r\n", mime_type ); add_to_response( buf, buflen ); } if ( bytes >= 0 ) { buflen = snprintf( buf, sizeof(buf), "Content-length: %ld\r\n", bytes ); add_to_response( buf, buflen ); } if ( mod != (time_t) -1 ) { (void) strftime( timebuf, sizeof(timebuf), rfc1123_fmt, gmtime( &mod ) ); buflen = snprintf( buf, sizeof(buf), "Last-modified: %s\r\n", timebuf ); add_to_response( buf, buflen ); } buflen = snprintf( buf, sizeof(buf), "Connection: close\r\n\r\n" ); add_to_response( buf, buflen ); } static void start_request( void ) { request_size = 0; request_idx = 0; } static void add_to_request( char* str, int len ) { add_to_buf( &request, &request_size, &request_len, str, len ); } static char* get_request_line( void ) { int i; char c; for ( i = request_idx; request_idx < request_len; ++request_idx ) { c = request[request_idx]; if ( c == '\n' || c == '\r' ) { request[request_idx] = '\0'; ++request_idx; if ( c == '\r' && request_idx < request_len && request[request_idx] == '\n' ) { request[request_idx] = '\0'; ++request_idx; } return &(request[i]); } } return (char*) 0; } static void add_to_postdat( char* str, int len ) { add_to_buf( &postdat, &postdat_size, &postdat_len, str, len ); } static void start_response( void ) { response_size = 0; bodycode_size = 0; postdat_size = 0; hdescr_size = 0; htitle_size = 0; } void add_to_response( char* str, int len ) { add_to_buf( &response, &response_size, &response_len, str, len ); } void send_response( void ) { (void) my_write( response, response_len ); response[0]='\0'; response_len=0; } void send_additional_response( void ) { (void) my_write( response, response_len ); } static int my_read( char* buf, int size ) { return read( conn_fd, buf, size ); } static int my_write( char* buf, int size ) { return write( conn_fd, buf, size ); } static void make_log_entry( void ) { char* ru; char url[500]; char bytes_str[40]; time_t now; struct tm* t; const char* cernfmt_nozone = "%d/%b/%Y:%H:%M:%S"; char date_nozone[100]; int zone; char sign; char date[100]; if ( logfp == (FILE*) 0 ) return; /* Format the user. */ if ( remoteuser != (char*) 0 ) ru = remoteuser; else ru = "-"; now = time( (time_t*) 0 ); (void) snprintf( url, sizeof(url), "%s", path ); /* Format the bytes. */ if ( bytes >= 0 ) (void) snprintf( bytes_str, sizeof(bytes_str), "%ld", bytes ); else (void) strcpy( bytes_str, "-" ); /* Format the time, forcing a numeric timezone (some log analyzers ** are stoooopid about this). */ t = localtime( &now ); (void) strftime( date_nozone, sizeof(date_nozone), cernfmt_nozone, t ); #ifdef HAVE_TM_GMTOFF zone = t->tm_gmtoff / 60L; #else // zone = - ( timezone / 60L ); zone = 0; /* Probably have to add something about daylight time here. */ #endif if ( zone >= 0 ) sign = '+'; else { sign = '-'; zone = -zone; } zone = ( zone / 60 ) * 100 + zone % 60; (void) snprintf( date, sizeof(date), "%s %c%04d", date_nozone, sign, zone ); /* And write the log entry. */ (void) fprintf( logfp, "%.80s - %.80s [%s] \"%.80s %.200s %.80s\" %d %s \"%.200s\" \"%.80s\"\n", ntoa( &client_addr ), ru, date, get_method_str( method ), url, protocol, status, bytes_str, referer, useragent ); (void) fflush( logfp ); } static char* get_method_str( int m ) { switch ( m ) { case METHOD_GET: return "GET"; case METHOD_HEAD: return "HEAD"; case METHOD_POST: return "POST"; default: return (char*) 0; } } static char* get_mime_type( char* name ) { struct { char* ext; char* type; } table[] = {{ ".html", "text/html; charset=%s" }, { ".htm", "text/html; charset=%s" }, { ".txt", "text/plain; charset=%s" }, { ".css", "text/plain; charset=%s" }, { ".gif", "image/gif" }, { ".jpg", "image/jpeg" }, { ".gz", "application/x-tar-gz" }, { ".tgz", "application/x-tar-gz" } }; int fl = strlen( name ); int i; for ( i = 0; i < sizeof(table) / sizeof(*table); ++i ) { int el = strlen( table[i].ext ); if ( strcasecmp( &(name[fl - el]), table[i].ext ) == 0 ) return table[i].type; } return "text/plain; charset=%s"; } void noaction(int sig) { if (cur_pid) kill(cur_pid, SIGTERM); } static void handle_sigterm( int sig ) { #ifdef DEBUG (void) fprintf( stderr, "%s: exiting due to signal %d\n", argv0, sig ); #endif exit( 1 ); } static void handle_sigchld( int sig ) { pid_t pid; int status; return; /* Reap defunct children until there aren't any more. */ for (;;) { //#ifdef HAVE_WAITPID // pid = waitpid( (pid_t) -1, &status, WNOHANG ); //#else /* HAVE_WAITPID */ pid = wait3( &status, WNOHANG, (struct rusage*) 0 ); //#endif /* HAVE_WAITPID */ if ( (int) pid == 0 ) /* none left */ break; if ( (int) pid < 0 ) { perror("pid<0"); if ( errno == EINTR ) /* because of ptrace */ continue; /* ECHILD shouldn't happen with the WNOHANG option, ** but with some kernels it does anyway. Ignore it. */ if ( errno != ECHILD ) perror( "child wait" ); break; } } } static void lookup_hostname( usockaddr* usa4P, size_t sa4_len, int* gotv4P, usockaddr* usa6P, size_t sa6_len, int* gotv6P ) { #if defined(HAVE_GETADDRINFO) && defined(HAVE_GAI_STRERROR) struct addrinfo hints; struct addrinfo* ai; struct addrinfo* ai2; struct addrinfo* aiv4; struct addrinfo* aiv6; int gaierr; char strport[10]; memset( &hints, 0, sizeof(hints) ); hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; (void) snprintf( strport, sizeof(strport), "%d", port ); if ( (gaierr = getaddrinfo( hostname, strport, &hints, &ai )) != 0 ) { #ifdef DEBUG (void) fprintf( stderr, "getaddrinfo %.80s - %s\n", hostname, gai_strerror( gaierr ) ); #endif exit( 1 ); } /* Find the first IPv4 and IPv6 entries. */ aiv4 = (struct addrinfo*) 0; aiv6 = (struct addrinfo*) 0; for ( ai2 = ai; ai2 != (struct addrinfo*) 0; ai2 = ai2->ai_next ) { switch ( ai2->ai_family ) { case AF_INET: if ( aiv4 == (struct addrinfo*) 0 ) aiv4 = ai2; break; #if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) case AF_INET6: if ( aiv6 == (struct addrinfo*) 0 ) aiv6 = ai2; break; #endif /* AF_INET6 && HAVE_SOCKADDR_IN6 */ } } if ( aiv4 == (struct addrinfo*) 0 ) *gotv4P = 0; else { if ( sa4_len < aiv4->ai_addrlen ) { #ifdef DEBUG (void) fprintf( stderr, "%.80s - sockaddr too small (%d < %d)\n", hostname, sa4_len, aiv4->ai_addrlen ); #endif exit( 1 ); } memset( usa4P, 0, sa4_len ); memcpy( usa4P, aiv4->ai_addr, aiv4->ai_addrlen ); *gotv4P = 1; } if ( aiv6 == (struct addrinfo*) 0 ) *gotv6P = 0; else { if ( sa6_len < aiv6->ai_addrlen ) { #ifdef DEBUG (void) fprintf( stderr, "%.80s - sockaddr too small (%d < %d)\n", hostname, sa6_len, aiv6->ai_addrlen ); #endif exit( 1 ); } memset( usa6P, 0, sa6_len ); memcpy( usa6P, aiv6->ai_addr, aiv6->ai_addrlen ); *gotv6P = 1; } freeaddrinfo( ai ); #else /* HAVE_GETADDRINFO && HAVE_GAI_STRERROR */ struct hostent* he; *gotv6P = 0; memset( usa4P, 0, sa4_len ); usa4P->sa.sa_family = AF_INET; if ( hostname == (char*) 0 ) usa4P->sa_in.sin_addr.s_addr = htonl( INADDR_ANY ); else { usa4P->sa_in.sin_addr.s_addr = inet_addr( hostname ); if ( (int) usa4P->sa_in.sin_addr.s_addr == -1 ) { he = gethostbyname( hostname ); if ( he == (struct hostent*) 0 ) { #ifdef DEBUG #ifdef HAVE_HSTRERROR (void) fprintf( stderr, "gethostbyname %.80s - %s\n", hostname, hstrerror( h_errno ) ); #else /* HAVE_HSTRERROR */ (void) fprintf( stderr, "gethostbyname %.80s failed\n", hostname ); #endif /* HAVE_HSTRERROR */ #endif exit( 1 ); } if ( he->h_addrtype != AF_INET ) { #ifdef DEBUG (void) fprintf( stderr, "%.80s - non-IP network address\n", hostname ); #endif exit( 1 ); } (void) memcpy( &usa4P->sa_in.sin_addr.s_addr, he->h_addr, he->h_length ); } } usa4P->sa_in.sin_port = htons( port ); *gotv4P = 1; #endif /* HAVE_GETADDRINFO && HAVE_GAI_STRERROR */ } char* ntoa( usockaddr* usaP ) { #ifdef HAVE_GETNAMEINFO static char str[200]; if ( getnameinfo( &usaP->sa, sockaddr_len( usaP ), str, sizeof(str), 0, 0, NI_NUMERICHOST ) != 0 ) { str[0] = '?'; str[1] = '\0'; } return str; #else /* HAVE_GETNAMEINFO */ return inet_ntoa( usaP->sa_in.sin_addr ); #endif /* HAVE_GETNAMEINFO */ } static size_t sockaddr_len( usockaddr* usaP ) { switch ( usaP->sa.sa_family ) { case AF_INET: return sizeof(struct sockaddr_in); #if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) case AF_INET6: return sizeof(struct sockaddr_in6); #endif /* AF_INET6 && HAVE_SOCKADDR_IN6 */ default: #ifdef DEBUG (void) fprintf(stderr, "unknown sockaddr family - %d\n", usaP->sa.sa_family ); #endif exit( 1 ); } } /* Base-64 decoding. This represents binary data as printable ASCII ** characters. Three 8-bit binary bytes are turned into four 6-bit ** values, like so: ** ** [11111111] [22222222] [33333333] ** ** [111111] [112222] [222233] [333333] ** ** Then the 6-bit values are represented using the characters "A-Za-z0-9+/". */ static int b64_decode_table[256] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 00-0F */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 10-1F */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, /* 20-2F */ 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, /* 30-3F */ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, /* 40-4F */ 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, /* 50-5F */ -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, /* 60-6F */ 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, /* 70-7F */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 80-8F */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 90-9F */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* A0-AF */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* B0-BF */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* C0-CF */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* D0-DF */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* E0-EF */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 /* F0-FF */ }; /* Do base-64 decoding on a string. Ignore any non-base64 bytes. ** Return the actual number of bytes generated. The decoded size will ** be at most 3/4 the size of the encoded, and may be smaller if there ** are padding characters (blanks, newlines). */ static int b64_decode( const char* str, unsigned char* space, int size ) { const char* cp; int space_idx, phase; int d, prev_d; unsigned char c; space_idx = 0; phase = 0; for ( cp = str; *cp != '\0'; ++cp ) { d = b64_decode_table[*cp]; if ( d != -1 ) { switch ( phase ) { case 0: ++phase; break; case 1: c = ( ( prev_d << 2 ) | ( ( d & 0x30 ) >> 4 ) ); if ( space_idx < size ) space[space_idx++] = c; ++phase; break; case 2: c = ( ( ( prev_d & 0xf ) << 4 ) | ( ( d & 0x3c ) >> 2 ) ); if ( space_idx < size ) space[space_idx++] = c; ++phase; break; case 3: c = ( ( ( prev_d & 0x03 ) << 6 ) | d ); if ( space_idx < size ) space[space_idx++] = c; phase = 0; break; } prev_d = d; } } return space_idx; } void home_page(void) { struct stat sb1; int j=0; char firmware_version[80]; FILE *fp; if ( (fp=fopen("/rct/version","r")) == NULL){ strcpy(firmware_version,"unknown!"); printf("not found.\n"); } else { fgets(firmware_version,80,fp); fclose(fp); } get_config('C'); if(stat(RCT_CONFIG, &sb1 ) < 0 ) { j=1; which_tab=0; add_html("
\n

Welcome

\n"); add_html("

"); add_html(_("Thank you for choosing Wireless Wizard. This powerful network tool will enable you to securely connect multiple computers to the internet through a single connection through an intuitive and easy to use web-based menu system.")); add_html("

\n"); } else { add_html("

"); add_html(_("Welcome Back")); add_html("

\n"); add_html("

"); add_html(_("Wireless Wizard is now up and running. The category tabs are now enabled. You may now set up additional services, or make modifications to current settings by clicking one of the category tabs.")); add_html("

\n"); } add_html("

"); add_html(_("This edition includes the following features.")); add_html("

\n"); add_html(""); add_html("\n"); add_html("\n"); add_html("\n"); add_html("\n"); add_html("\n"); add_html("
"); add_html(_("Networking:")); add_html("

"); add_html(_("Configure basic network connection options")); add_html("

"); add_html(_("Security:")); add_html("

"); add_html(_("Manage the network security features")); add_html("

"); add_html(_("Intranet:")); add_html("

"); add_html(_("Provide the intranet services")); add_html("

"); add_html(_("Administration:")); add_html(""); add_html(_("Access Wireless Wizard's administrative services")); add_html("
"); add_html(_("Wizard:")); add_html(""); add_html(_("Offer a step by step, easy to follow setup process")); add_html("
"); add_html(_("Firmware Version:")); add_html(""); add_html(firmware_version); add_html("
"); if(!j) { add_html("\n

 

"); add_html(_("You may start the basic setup by clicking Configuration Wizard button below.")); add_html("

\n"); #ifndef RCT_PROFILE_TWO_ACCOUNTS // Single user add_html("      
\n"); #else // Two Accounts if(!strcmp(redacceright,"W")) { add_html("      
\n"); } else if(!strcmp(redacceright,"R")) { add_html("      \n\n"); } #endif }else{ add_html("\n

 

"); add_html(_("Please click the button below to start the wizard that will guide you through the setup steps to get Wireless Wizard up and running.")); add_html("

     
\n"); } send_page(_("Home Page")); } void handler_errmesg(void) { add_handler_title(_("Invalid Request!")); add_html("
"); add_table_begin(1); add_td(0,"500",_("The handler")); add_html(" \"/"); add_html(file); add_html("\" "); add_html(_("does not exist")); add_html(".\n"); close_td(3); send_page(_("Handler Error!")); } void inner_errmesg(char* mesg) { add_handler_title(_("Internal Error!")); add_handler_descr(mesg); send_page(_("Internal Error!")); } void malloc_error(void) { inner_errmesg(_("Out of memory!")); } void check_new_module(void) { int i=0; struct stat sb; FILE *fp; char buf[1024], *key, *value, *value2,c,*v2; const char delimiters[] = ",\r\n\t"; if(stat(IP_CONFIG, &sb)==0 ) { if ((fp = fopen(USER_MODULE_FILE, "r")) == NULL) return; while (!feof(fp)) { c = fgetc(fp); if((i == 0)&&(!isspace(c))) { buf[i++] = c; } else if((i>0)&&(c == '\n')) { buf[i]='\0'; key = trim(strtok(buf, delimiters)); value = trim(strtok(NULL, delimiters)); value2 = trim(strtok(NULL, delimiters)); if((key!=NULL)&&(key[0]!='#')&&(value2!=NULL)) { add_new_module(key,value,value2); } i = 0; } else buf[i++] = c; } fclose(fp); } return; } static void add_new_module(char *module_name, char *link_url, char *image_name) { int i=0,j=0; if((!module_name)||(!image_name)) return; for(i=0;i<10;i++) { if(user_defined_module[i].module_name ==NULL) { j=1; break; } } if(j==0) return; else { user_defined_module[i].module_name= (char*) malloc(strlen(module_name)+1); (void)strcpy(user_defined_module[i].module_name,module_name); user_defined_module[i].image_name= (char*) malloc(strlen(image_name)+1); (void)strcpy(user_defined_module[i].image_name,image_name); if(link_url !=NULL) { user_defined_module[i].link_url= (char*) malloc(strlen(link_url)+1); (void)strcpy(user_defined_module[i].link_url,link_url); } } return; } /* Description: If the file /tmp/restarting exists, it means that the system is in initialization phase. In this situration, we won't let user do anything except reboot. Return Value: 0 : The system is in initializtion state. 1 : The system is in ready state. */ int check_status() { struct stat st; if (stat("/tmp/zz_restarting",&st)!=0) return 1; // The system/verify_restart is the only one which can be accessed in // initialization state. If you want to open more links, add them here. if (strcmp(file,"system/verify_restart")==0) { return 1; } /*this won't work coz system/verify_restart should be used with METHOD_POST*/ //add_handler_descr(_("The system is not ready yet. Please wait for 15 seconds. Otherwise, you can click this link to reboot the system if you suspect this gateway is out of control.")); /*-- using software reboot ---*/ //add_handler_descr( // "
"); /*-- using hardtware reboot ---*/ add_handler_descr( ""); add_handler_descr(_("The system is not ready yet. Please wait for 15 seconds. Otherwise, you can click this link to reboot the system if you suspect this gateway is out of control.")); add_handler_descr(""); add_html(""); send_page("System busy"); return 0; } /** * Free the request buffer. After release this buffer, you should not * use any POST variables anymore. * PS: This function is usually used when you want to release memory for * other processes. */ void free_request_buffer() { if (request) free(request); request = NULL; request_size=0; } my_system(char *cmd) { int pid; if ((pid=fork())==0) { setsid(); close(conn_fd); system(cmd); exit(0); } wait(&pid); }