table::~table() { clear_table(); clear_header(); clear_status(); endwin(); }
// display a "WAIT" message static void _near _fastcall list_wait( LPTSTR pszPrompt ) { // clear the header line clear_header(); // display "WAIT" in blinking chars WriteStrAtt( 0, (( nScreenColumns / 2 ) - ( strlen( pszPrompt ) / 2 )), ( nInverse | 0x80 ), pszPrompt ); }
static void show_404(int sock) //404错误处理 { clear_header(sock); char* msg="HTTP/1.0 404 Not Found\r\n"; send(sock,msg,strlen(msg),0); //发送状态行 send(sock,"\r\n",strlen("\r\n"),0); //发送空行 struct stat st; stat("wwwroot/404.html",&st); int fd=open("wwwroot/404.html",O_RDONLY); sendfile(sock,fd,NULL,st.st_size); close(fd); }
void echo_html(int client,char* path,size_t size) { clear_header(client);//将缓冲区的内容清空,包含请求行,消息报头 int fd=open(path,O_RDONLY,0); if(fd<0) { return_error_client(); return; } else { char buf[1024]; memset(buf,'\0',sizeof(buf)); sprintf(buf,"HTTP/1.0 200 OK\r\n\r\n"); send(client,buf,strlen(buf),0); sendfile(client,fd,NULL,size); } close(fd); }
} //--------------------------------------------------------------------------// inline void Catalog::connects(){ // при выборе группы из каталога - установить фильтр по группам QObject::connect(this->groups, SIGNAL(itemActivated(QTreeWidgetItem*, int)), SLOT(change_group(QTreeWidgetItem*, int))); // при нажатии кнопки сброса фильтра по группам - сбросить его QObject::connect(this->reset_groups, SIGNAL(clicked()), SIGNAL(hide_catalog())); // при выборе группы из каталога - установить заголовок каталога QObject::connect(this->groups, SIGNAL(itemActivated(QTreeWidgetItem*, int)), SLOT(change_header(QTreeWidgetItem*,int))); // при сбросе фильтра по группам - установить заголовок каталога по умолчанию QObject::connect(this->reset_groups, SIGNAL(clicked()), SLOT(clear_header())); } //--------------------------------------------------------------------------// //--------------------------- ФУНКЦИИ --------------------------------------// //--------------------------------------------------------------------------// bool Catalog::addGroups(){ return add_groups(this->groups); } //--------------------------------------------------------------------------// //--------------------------- СЛОТЫ ----------------------------------------// //--------------------------------------------------------------------------// void Catalog::move_button(){
static void * accept_request(void *arg) { int sock = (int)arg; char buf[_SIZE_]; char method[_SIZE_/10]; char url[_SIZE_]; char path[_SIZE_]; memset(buf, '\0', sizeof(buf)); memset(buf, '\0', sizeof(method)); memset(buf, '\0', sizeof(url)); memset(buf, '\0', sizeof(path)); int cgi = 0; int ret = -1; char *query_string = NULL; // 数据参数 int len = sizeof(buf) / sizeof(buf[0]); #ifdef _DEBUG_ do { // http 请求 报文 按行存储 ret = get_line(sock, buf, len); printf("%s", buf); fflush(stdout); } while (ret > 0 && strcmp(buf, "\n") != 0); #endif ret = get_line(sock, buf, len); // 获取请求行 printf("line: %s\n", buf); if (ret < 0) { echo_errno(sock); return (void*)1; } // GET / HTTP/1.0 int i = 0; // method index int j = 0; // buf index // 请求行 包括 【方法(GET/POST)】【url】【HTTP/1.0(1.1)】 // 获取方法 GET/POST while ((i < sizeof(method) - 1) && (j < sizeof(buf)) && (!isspace(buf[j]))) { method[i] = buf[j]; ++i; ++j; } method[i] = '\0'; // strcasecmp 忽略大小写的比较 if (strcasecmp(method, "GET") != 0 && strcasecmp(method, "POST") != 0) { echo_errno(sock); return (void*)2; } // 跳过空格 while (j < sizeof(buf) && isspace(buf[j])) { j++; } i = 0; // 获取url url是除了域名 端口号之后的 /。。。 while ((i < sizeof(url) - 1) && (j < sizeof(buf)) && (!isspace(buf[j]))) { url[i++] = buf[j++]; } url[i] = '\0'; //GET 所传递的参数 在URL中, 从server的QUERY_STRING 中获取 //POST 所传递的参数 在 数据包中 从server环境变量中CONTENT_LENGTH 环境变量中获取参数 数据的长度 if (strcasecmp(method, "POST") == 0) { cgi = 1; } if (strcasecmp(method, "GET") == 0) { query_string = url; // 路径和数据参数 以?分隔 如 http:// baidu.com /s ? k = v while (*query_string != '\0' && *query_string != '?') { ++query_string; } if(*query_string == '?') // GET 带参数 需要进一步处理参数 { cgi = 1; *query_string++ = '\0'; } } // 没指定具体网页 加默认网页 和 根文件夹(安全考虑) sprintf(path, "httpdoc%s", url); if (path[strlen(path) - 1] == '/') { strcat(path, "index.html"); } // method , query_string, cgi, path struct stat st; if (stat(path, &st) < 0) // 测文件在不在 { echo_errno(sock); return (void*)3; } else { if (S_ISDIR(st.st_mode))// 测是不是 文件夹 { strcat(path, "/index.html"); } else if( (st.st_mode & S_IXUSR) ||\ (st.st_mode & S_IXGRP) ||\ (st.st_mode & S_IXOTH)) // 查看cgi执行权限 { cgi = 1; } else {} if (cgi) { exec_cgi(sock, method, path, query_string); } else { clear_header(sock); // echo_www(sock, path, st.st_size); } } }
static void exec_cgi(int sock, const char *method, const char *path, const char *query_string ) { char buf[_SIZE_]; int content_length = -1;// 内容长度 方便获取内容 int ret = -1; int cgi_input[2]; int cgi_output[2]; char method_env[_SIZE_]; char query_string_env[_SIZE_]; char content_length_env[_SIZE_]; printf("[exec_cgi ]method : %s \n", method); if (strcasecmp(method, "GET") == 0) { clear_header(sock); } else // POST { do { ret = get_line(sock, buf, sizeof(buf)); if (strncasecmp(buf, "Content-Length: ", 16) == 0) { content_length = atoi(&buf[16]); // break 不用 break 即把参数Content-Length获取 又把 空行删除 } }while ((ret > 0) && strcmp(buf, "\n") != 0); if (content_length == -1) { echo_errno(sock); return; } } sprintf(buf, "HTTP/1.0 200 OK\r\n\r\n"); send(sock, buf, strlen(buf), 0); // 创建 父子进程之间的 通信管道 cgi_input子进程的读 cgi_output子进程的写 if (pipe(cgi_input) < 0) { echo_errno(sock); return; } if (pipe(cgi_output) < 0) { echo_errno(sock); return; } pid_t id = fork(); if (id < 0) { echo_errno(sock); return ; } if (id == 0)// child { close(cgi_input[1]); close(cgi_output[0]); // //////////////// // 重定向 管道到 标准输入 和 输出 这样以后 printf()直接打到管道 dup2(cgi_input[0], 0); dup2(cgi_output[1], 1); sprintf(method_env, "REQUEST_METHOD=%s", method); putenv(method_env);// 注册环境变量 这样 execl 执行二进制程序时时 获取这些参数方便getenv // GET 要得 参数 在请求字段 中 环境变量注册 quer_string_env // post 要的参数在 内容中 所以要知道 内容什么时候截至(内容长度)所以 只要知道content_length_env 就可以了 if (strcasecmp(method, "GET") == 0) { sprintf(query_string_env, "QUERY_STRING=%s", query_string); putenv(query_string_env); } else // post { sprintf(content_length_env, "CONTENT_LENGTH=%d", content_length); putenv(content_length_env); printf("%d-----------env\n", content_length); } // 执行 二进制 程序 execl(path,path,NULL); exit(1); } else // father { close(cgi_input[0]); close(cgi_output[1]); char c = '\0'; int i = 0; printf("%s --fmethod\n", method); if (strcasecmp(method, "POST") == 0) { printf("--father here %d\n", content_length); for (; i < content_length; i++) { recv(sock, &c, 1, 0); printf("--%c ", c); fflush(stdout); write(cgi_input[1], &c, 1);// 给子进程 发过去 } } printf("\n"); int ret = 0; while ((ret = read(cgi_output[0], &c, 1)) > 0)// 子进程退出 文件符号关闭 read读完文件结尾 返回0 { send(sock, &c, 1, 0);// 父进程 负责向sock发送子进程的数据 } waitpid(id, NULL, 0); close(sock); } }
/** * Send an edcl packet and fragment it if max_packet_size < data_size */ static int send_fragmented(void) { unsigned int nb_ack_packet = 0; unsigned int address_offset = 0; unsigned int nb_sent_packet = 0; unsigned int local_data_size = config.data_size; edcl_packet_t* packet = NULL; /* Allocating the packet of the packet */ packet = calloc(1, min(local_data_size, MAX_DATA_SIZE) + sizeof (edcl_header_t)); if (packet == NULL) goto error_malloc; do { /* Filling up the edcl header */ clear_header(packet->header); set_operation(packet->header, WRITE_OP); set_sequence(packet->header, config.sequence_number); set_address(packet->header, config.memory_address + address_offset); set_length(packet->header, min(local_data_size, MAX_DATA_SIZE)); if (config.verbose) fprintf(stderr, " [%d] Trying to write at 0x%08x.", config.sequence_number, config.memory_address + address_offset); /* Copying the data in the packet */ memcpy(packet->data, config.data_c + address_offset, min(local_data_size, MAX_DATA_SIZE)); /* Sending the packet to the ethernet IP */ if (sendto(config.socket, packet, min(local_data_size, MAX_DATA_SIZE) + sizeof (edcl_header_t), 0, config.serv_info->ai_addr, config.serv_info->ai_addrlen) == -1) goto error_send; /* Waiting for the aknowledgment */ if (recvfrom(config.socket, packet, sizeof (edcl_header_t) + min(local_data_size, MAX_DATA_SIZE), 0, NULL, 0) == -1) goto error_recvfrom; /* We've been aknowledge, keep sending */ if (get_ack(packet->header)) { if (config.verbose) fprintf(stderr, "\t[OK]\n"); address_offset += min(local_data_size, MAX_DATA_SIZE); local_data_size -= min(local_data_size, MAX_DATA_SIZE); ++config.sequence_number; ++nb_ack_packet; } /* The sequence number was wrong, fix it */ else { if (config.verbose) fprintf(stderr, "\t[Failed]\n Wrong sequence number (%d) should be: %d. Fixed.\n", config.sequence_number, get_sequence(packet->header)); config.sequence_number = get_sequence(packet->header); } ++nb_sent_packet; } while (local_data_size > 0); if (config.verbose) { fprintf(stderr, "The datas have been fragmented in %d packets.\n", nb_ack_packet); fprintf(stderr, "\t %d packets have been sent (%d have been lost).\n", nb_sent_packet, nb_sent_packet - nb_ack_packet); } /* Releasing ressources */ free(packet); return (0); error_recvfrom: error_send: if (config.verbose) fprintf(stderr, "Error while sending the packet.\n"); free(packet); return (errno); error_malloc: if (config.verbose) fprintf(stderr, "Unable to allocate the packet.\n"); return (errno); }
int handler_msg(int sock) //浏览器请求处理函数 { char buf[SIZE]; int count=get_line(sock,buf); int ret=0; char method[32]; char url[SIZE]; char *query_string=NULL; int i=0; int j=0; int cgi=0; //获取请求方法和请求路径 while(j<count) { if(isspace(buf[j])) { break; } method[i]=buf[j]; i++; j++; } method[i]='\0'; while(isspace(buf[j])&&j<SIZE) //过滤空格 { j++; } if(strcasecmp(method,"POST")&&strcasecmp(method,"GET")) { printf_log("method failed",FATAL); echo_error(sock,405); ret=5; goto end; } if(strcasecmp(method,"POST")==0) { cgi=1; } i=0; while(j<count) { if(isspace(buf[j])) { break; } if(buf[j]=='?') { query_string=&url[i]; query_string++; url[i]='\0'; } else url[i]=buf[j]; j++; i++; } url[i]='\0'; if(strcasecmp(method,"GET")==0&&query_string!=NULL) { cgi=1; } //找到请求的资源路径 char path[SIZE]; sprintf(path,"wwwroot%s",url); if(path[strlen(path)-1]=='/') //判断浏览器请求的是不是目录 { strcat(path,"index.html"); //如果请求的是目录,则就把该目录下的首页返回回去 } struct stat st; if(stat(path,&st)<0) //获取客户端请求的资源的相关属性 { printf_log("stat path faile\n",FATAL); echo_error(sock,404); ret=6; goto end; } else { if(S_ISDIR(st.st_mode)) { strcat(path,"/index.html"); } if(st.st_mode & (S_IXUSR | S_IXOTH | S_IXGRP)) { cgi=1; } } if(cgi) //请求的是可执行程序或者带参数用cgi程序处理 { ret=excu_cgi(sock,method,path,query_string); //处理CGI模式的请求 } else { clear_header(sock); ret=echo_www(sock,path,st.st_size); //如果是GET方法,而且没有参数,请求的也不是可执行程序,则直接返回资源 } end: close(sock); return ret; }
static int excu_cgi(int sock,const char* method,\ const char* path,const char* query_string) //处理CGI模式的请求 { char line[SIZE]; int ret=0; int content_len=-1; if(strcasecmp(method,"GET")==0) //如果是GET方法的CGI { //清空消息报头 clear_header(sock); } else //POST方法的CGI { //获取post方法的参数大小 do { ret=get_line(sock,line); if(strncmp(line,"Content-Length: ",16)==0) //post的消息体记录正文长度的字段 { content_len=atoi(line+16); //求出正文的长度 } }while(ret!=1&&(strcmp(line,"\n")!=0)); } //将method、query_string、content_len导出为环境变量 char method_env[SIZE/8]; char query_string_env[SIZE/8]; char content_len_env[SIZE/8]; sprintf(method_env,"METHOD=%s",method); putenv(method_env); sprintf(query_string_env,"QUERY_STRING=%s",query_string); putenv(query_string_env); sprintf(content_len_env,"CONTENT_LEN=%d",content_len); putenv(content_len_env); int input[2]; //站在CGI程序的角度,创建两个管道 int output[2]; pipe(input); pipe(output); pid_t id=fork(); if(id<0) { printf_log("fork failed",FATAL); echo_error(sock,500); return 9; } else if(id==0) //子进程 { close(input[1]); //关闭input的写端 close(output[0]); //关闭output的读端 //将文件描述符重定向到标准输入标准输出 dup2(input[0],0); dup2(output[1],1); execl(path,path,NULL); //替换CGI程序 exit(1); } else //father { close(input[0]); //关闭input的读端 close(output[1]); //关闭output的写端 char ch='\0'; if(strcasecmp(method,"POST")==0) //如果是post方法,则父进程需要给子进程发送参数 { int i=0; for( i=0;i<content_len;i++) { recv(sock,&ch,1,0); //从sock里面一次读一个字符,总共读conten_len个字符 write(input[1],&ch,1); } } char* msg="HTTP/1.0 200 OK\r\n\r\n"; send(sock,msg,strlen(msg),0); //接收子进程的返回结果 while(read(output[0],&ch,1)) //如果CGI程序结束,写端关闭,则读端返回0 { send(sock,&ch,1,0); } waitpid(id,NULL,0); //回收子进程 } return 0; }
void exe_cgi(int client,const char*path,const char*method,const char*query_string) { int num=0; char buf[1024]; int content_length=-1; int cgi_input[2]={0}; int cgi_output[2]={0}; pid_t pid; if(strcasecmp(method,"GET")==0)//如果是get方法,信息都存储在query_string中,因此直接清空client { clear_header(client); } else//否则就是POST方法,需要cgi执行 { do { memset(buf,'\0',sizeof(buf)); num=get_line(client,buf,sizeof(buf)); if(strncasecmp(buf,"Content-Length:",15)==0) { content_length=atoi(&buf[16]);//在消息报头中得到消息正文的长度 } }while(num>0 && strcmp(buf,"\n")!=0); if(content_length==-1)//content_length如果还是-1,则说明请求格式有问题 { return_error_client(); return; } } sprintf(buf,"HTTP/1.0 200 OK\r\n\r\n");//该请求被受理返回状态行信息 send(client,buf,strlen(buf),0); if(pipe(cgi_input)<0) { return_error_client(); return; } //创建两个管道 if(pipe(cgi_output)<0) { close(cgi_input[0]); close(cgi_input[1]); return_error_client(); return; } if((pid=fork())<0) { close(cgi_input[0]); close(cgi_input[1]); close(cgi_output[0]); close(cgi_output[1]); return_error_client(); return; } else if(pid==0)//子进程 { //设置三个数组存放环境变量 char meth_env[1024]; char query_env[1024]; char content_len_env[1024]; memset(meth_env,'\0',sizeof(meth_env)); memset(query_env,'\0',sizeof(query_env)); memset(content_len_env,'\0',sizeof(content_len_env)); close(cgi_input[1]);//cgi脚本从cgi_input读取数据 close(cgi_output[0]);//cgi脚本从cgi_output输出数据 dup2(cgi_output[1],1);//cgi脚本的标准输出变成cgi_output管道 dup2(cgi_input[0],0);//cgi脚本的标准输入变成cgi_input sprintf(meth_env,"REQUEST_METHOD=%s",method); putenv(meth_env);//设置环境变量 if(strcasecmp(method,"GET")==0)//GET方法进入cgi,说明client肯定有参数传入 { sprintf(query_env,"QUERY_STRING=%s",query_string); putenv(query_env);//将参数导出为环境变量,供cgi脚本使用 } else//POST方法 { sprintf(content_len_env,"CONTENT_LENGTH=%d",content_length); putenv(content_len_env); } execl(path,path,NULL); exit(1); } else//父进程 { int i=0; char c; close(cgi_input[0]); close(cgi_output[1]); if(strcasecmp(method,"POST")==0) { for(;i<content_length;i++) { recv(client,&c,1,0); write(cgi_input[1],&c,1); } } while(read(cgi_output[0],&c,1)>0) { send(client,&c,1,0); } close(cgi_input[0]); close(cgi_output[1]); waitpid(pid,NULL,0); } }
void* accept_request(void* arg) { pthread_detach(pthread_self()); int sock = (int)arg; char buf[_SIZE_]; char method[_SIZE_]; char url[_SIZE_]; char path[_SIZE_]; memset(buf, '\0', sizeof(buf)); memset(method, '\0', sizeof(method)); memset(url, '\0', sizeof(url)); memset(path, '\0', sizeof(path)); int cgi = 0; int ret = -1; char* query_string = NULL; #ifdef _DEBUG_ do{ ret = get_line(sock, buf, sizeof(buf)); printf("%s", buf); fflush(stdout); } while((ret > 0) && (strcmp(buf, "\n") != 0)); #endif ret = get_line(sock, buf, sizeof(buf)); if(ret < 0) { echo_errno(sock); return (void *)1; } //GET /HTTP/1.1 int i = 0; // method index int j = 0; // buf index while( (i < sizeof(method)-1) && (j < sizeof(buf)) && (!isspace(buf[j]))) { method[i] = buf[j]; i++, j++; } method[i] = '\0'; while( isspace(buf[j]) ) { j++; } if(strcasecmp(method, "GET") != 0 && strcasecmp(method, "POST") != 0) { echo_errno(sock); return (void*)2; } if(strcasecmp(method, "POST") == 0) { cgi = 1; } i = 0; // url index while( (i<sizeof(url)-1) && (j < sizeof(buf)) && (!isspace(buf[j]))) { url[i] = buf[j]; i++, j++; } if(strcasecmp(method, "GET") == 0) { query_string = url; while(*query_string != '\0' && *query_string != '?' ) { query_string++; } if(*query_string == '?') { cgi = 1; *query_string = '\0'; query_string++; } } // / /aa/bb/cc sprintf(path, "htdoc%s", url); // htdoc/ if(path[strlen(path) - 1] == '/') { strcat(path, "index.html"); } printf("method: %s\n", method); printf("path: %s\n", path); printf("query_string: %s\n", query_string); struct stat st; if(stat(path, &st) < 0) { echo_errno(sock); return (void*)3; } else { if(S_ISDIR(st.st_mode)) { strcpy(path, "htdoc/index.html"); } else if( (st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) { cgi = 1; } else {} if(cgi) { exec_cgi(sock, path, method, query_string); } else { clear_header(sock); echo_html(sock, path, st.st_size); } } close(sock); return (void*)0; }
void exec_cgi(int sock, const char* path, const char* method, const char* query_string) { print_debug("enter cgi\n"); char buf[_SIZE_]; int numchars = 0; int content_length = -1; // pipe int cgi_input[2] = {0, 0}; int cgi_output[2] = {0, 0}; //child proc pid_t id; print_debug(method); if(strcasecmp(method, "GET") == 0) // GET { clear_header(sock); } else // POST { do{ memset(buf, '\0', sizeof(buf)); numchars = get_line(sock, buf, sizeof(buf)); if(strncasecmp(buf, "Content-Length:", strlen("Content-Length:")) == 0) { content_length = atoi(&buf[16]); } }while(numchars > 0 && strcmp(buf, "\n") != 0); if(content_length == -1) { return; } } memset(buf, '\0', sizeof(buf)); strcpy(buf, HTTP_VERSION); strcat(buf, " 200 OK\r\n\r\n"); send(sock, buf, strlen(buf), 0); if(pipe(cgi_input) == -1) // pipe error { return; } if(pipe(cgi_output) == -1) // { close(cgi_input[0]); close(cgi_input[1]); return; } if((id = fork()) < 0) // fork error { close(cgi_input[0]); close(cgi_input[1]); close(cgi_output[0]); close(cgi_output[1]); return; } else if( id == 0 ) // child { char query_env[_SIZE_/10]; char method_env[_SIZE_]; char content_len_env[_SIZE_]; memset(method_env, '\0', sizeof(method_env)); memset(query_env, '\0', sizeof(query_env)); memset(content_len_env, '\0', sizeof(content_len_env)); close(cgi_input[1]); close(cgi_output[0]); dup2(cgi_input[0], 0); dup2(cgi_output[1], 1); sprintf(method_env, "REQUEST_METHOD=%s", method); putenv(method_env); if(strcasecmp("GET", method) == 0) // GET { sprintf(query_env, "QUERY_STRING=%s", query_string); putenv(query_env); } else { sprintf(content_len_env, "CONTENT_LENGTH=%d", content_length); putenv(content_len_env); } execl(path, path, NULL); exit(1); } else // father { close(cgi_input[0]); close(cgi_output[1]); int i = 0; char c = '\0'; if(strcasecmp("POST", method) == 0) { for(; i < content_length; i++) { recv(sock, &c, 1, 0); write(cgi_input[1], &c, 1); } } while( read(cgi_output[0], &c, 1) > 0) { send(sock, &c, 1, 0); } close(cgi_input[1]); close(cgi_output[0]); waitpid(id, NULL, 0); } }
static int _fastcall _list( LPTSTR pszFileName ) { register int c, i; TCHAR szDescription[512], szHeader[132], szLine[32]; long lTemp, lRow; POPWINDOWPTR wn = NULL; FILESEARCH dir; // get default normal and inverse attributes if ( gpIniptr->ListColor != 0 ) { SetScrColor( nScreenRows, nScreenColumns, gpIniptr->ListColor ); } // set colors GetAtt( (unsigned int *)&nNormal, (unsigned int *)&nInverse ); if ( gpIniptr->ListStatusColor != 0 ) nInverse = gpIniptr->ListStatusColor; // flip the first line to inverse video clear_header(); // open the file & initialize buffers if ( ListOpenFile( pszFileName )) return ERROR_EXIT; // kludge for empty files or pipes if ( LFile.lSize == 0L ) LFile.lSize = 1L; for ( ; ; ) { // display header if ( fDirtyHeader ) { clear_header(); sprintf( szHeader, LIST_HEADER, fname_part(LFile.szName), gchVerticalBar, gchVerticalBar, gchVerticalBar ); WriteStrAtt( 0, 0, nInverse, szHeader ); fDirtyHeader = 0; } // display location within file // (don't use color_printf() so we won't have // problems with windowed sessions) i = sprintf( szHeader, LIST_LINE, LFile.nListHorizOffset, LFile.lCurrentLine + gpIniptr->ListRowStart, (int)((( LFile.lViewPtr + 1 ) * 100 ) / LFile.lSize )); WriteStrAtt( 0, ( nScreenColumns - i ), nInverse, szHeader ); SetCurPos( 0, 0 ); if ( lListFlags & LIST_SEARCH ) { lListFlags &= ~LIST_SEARCH; fSearchFlags = 0; if ( lListFlags & LIST_REVERSE ) { c = LIST_FIND_CHAR_REVERSE; fSearchFlags |= FFIND_REVERSE_SEARCH; // goto the last row while ( ListMoveLine( 1 ) != 0 ) ; } else c = LIST_FIND_CHAR; if ( lListFlags & LIST_NOWILDCARDS ) fSearchFlags |= FFIND_NOWILDCARDS; bListSkipLine = 0; goto FindNext; } // get the key from the BIOS, because // STDIN might be redirected if ((( c = cvtkey( GetKeystroke( EDIT_NO_ECHO | EDIT_BIOS_KEY | EDIT_UC_SHIFT), MAP_GEN | MAP_LIST)) == (TCHAR)ESC )) break; switch ( c ) { case CTRLC: return CTRLC; case CUR_LEFT: case CTL_LEFT: if (( lListFlags & LIST_WRAP ) || ( LFile.nListHorizOffset == 0 )) goto bad_key; if (( LFile.nListHorizOffset -= (( c == CUR_LEFT ) ? 8 : 40 )) < 0 ) LFile.nListHorizOffset = 0; break; case CUR_RIGHT: case CTL_RIGHT: if (( lListFlags & LIST_WRAP ) || ( LFile.nListHorizOffset >= MAXLISTLINE + 1 )) goto bad_key; if ((LFile.nListHorizOffset += ((c == CUR_RIGHT) ? 8 : 40 )) > MAXLISTLINE + 1 ) LFile.nListHorizOffset = MAXLISTLINE+1; break; case CUR_UP: if ( ListMoveLine( -1 ) == 0 ) goto bad_key; Scroll(1, 0, nScreenRows, nScreenColumns, -1, nNormal); DisplayLine( 1, LFile.lViewPtr ); continue; case CUR_DOWN: if ( ListMoveLine( 1 ) == 0 ) goto bad_key; Scroll( 1, 0, nScreenRows, nScreenColumns, 1, nNormal ); // display last line lTemp = LFile.lViewPtr; lRow = (nScreenRows - 1); lTemp += MoveViewPtr( lTemp, &lRow ); if ( lRow == ( nScreenRows - 1 )) DisplayLine( nScreenRows, lTemp ); continue; case HOME: ListHome(); break; case END: // goto the last row list_wait( LIST_WAIT ); while ( ListMoveLine( 1 ) != 0 ) ; case PgUp: // already at TOF? if ( LFile.lViewPtr == 0L ) goto bad_key; for ( i = 1; (( i < nScreenRows ) && ( ListMoveLine( -1 ) != 0 )); i++ ) ; break; case PgDn: case SPACE: if ( ListMoveLine( nScreenRows - 1 ) == 0 ) goto bad_key; break; case F1: // help // don't allow a ^X exit from HELP _help( gpInternalName, HELP_NX ); continue; case TAB: // change tab size // disable ^C / ^BREAK handling HoldSignals(); wn = wOpen( 2, 5, 4, strlen( LIST_TABSIZE ) + 10, nInverse, LIST_TABSIZE_TITLE, NULL ); wn->nAttrib = nNormal; wClear(); wWriteListStr( 0, 1, wn, LIST_TABSIZE ); egets( szLine, 2, (EDIT_DIALOG | EDIT_BIOS_KEY | EDIT_NO_CRLF | EDIT_DIGITS)); wRemove( wn ); if (( i = atoi( szLine )) > 0 ) TABSIZE = i; // enable ^C / ^BREAK handling EnableSignals(); break; case DEL: // delete this file if (( lListFlags & LIST_STDIN ) == 0 ) { // disable ^C / ^BREAK handling HoldSignals(); wn = wOpen( 2, 5, 4, strlen( LIST_DELETE ) + 10, nInverse, LIST_DELETE_TITLE, NULL ); wn->nAttrib = nNormal; wClear(); wWriteListStr( 0, 1, wn, LIST_DELETE ); i = GetKeystroke( EDIT_ECHO | EDIT_BIOS_KEY | EDIT_UC_SHIFT ); wRemove( wn ); // enable ^C / ^BREAK handling EnableSignals(); if ( i == (TCHAR)YES_CHAR ) { if ( LFile.hHandle > 0 ) _close( LFile.hHandle ); LFile.hHandle = -1; remove( pszFileName ); return 0; } } break; case INS: // save to a file ListSaveFile(); break; case LIST_INFO_CHAR: { unsigned int uSize = 1024; TCHAR _far *lpszText, _far *lpszArg; int fFSType, fSFN = 1; TCHAR szBuf[16]; DOSFILEDATE laDir, crDir; // disable ^C / ^BREAK handling HoldSignals(); memset( &dir, '\0', sizeof(FILESEARCH) ); if (( lListFlags & LIST_STDIN ) == 0 ) { if ( find_file( FIND_FIRST, LFile.szName, 0x07 | FIND_CLOSE | FIND_EXACTLY, &dir, NULL ) == NULL ) { honk(); continue; } } // display info on the current file i = (( lListFlags & LIST_STDIN ) ? 5 : 10 ); if (( fFSType = ifs_type( LFile.szName )) != FAT ) i = 11; wn = wOpen( 2, 1, i, 77, nInverse, gpInternalName, NULL ); wn->nAttrib = nNormal; wClear(); i = 0; if ( lListFlags & LIST_STDIN ) wWriteStrAtt( 0, 1, nNormal, LIST_INFO_PIPE ); else { szDescription[0] = _TEXT('\0'); process_descriptions( LFile.szName, szDescription, DESCRIPTION_READ ); lpszText = lpszArg = (TCHAR _far *)AllocMem( &uSize ); strcpy(szBuf, FormatDate( dir.fd.file_date.months, dir.fd.file_date.days, dir.fd.file_date.years + 80, 0 )); if (fFSType != FAT) { FileTimeToDOSTime( &(dir.ftLastAccessTime), &( laDir.ft.wr_time), &( laDir.fd.wr_date) ); FileTimeToDOSTime( &(dir.ftCreationTime), &(crDir.ft.wr_time), &(crDir.fd.wr_date) ); strcpy( szLine, FormatDate( laDir.fd.file_date.months, laDir.fd.file_date.days, laDir.fd.file_date.years + 80, 0 )); sprintf_far( lpszText, LIST_INFO_LFN, LFile.szName, szDescription, dir.ulSize, szBuf, dir.ft.file_time.hours, gaCountryInfo.szTimeSeparator[0],dir.ft.file_time.minutes, szLine, laDir.ft.file_time.hours, gaCountryInfo.szTimeSeparator[0], laDir.ft.file_time.minutes, FormatDate( crDir.fd.file_date.months, crDir.fd.file_date.days, crDir.fd.file_date.years + 80, 0 ), crDir.ft.file_time.hours, gaCountryInfo.szTimeSeparator[0], crDir.ft.file_time.minutes); } else { sprintf_far( lpszText, LIST_INFO_FAT, LFile.szName, szDescription, dir.ulSize, szBuf, dir.ft.file_time.hours, gaCountryInfo.szTimeSeparator[0],dir.ft.file_time.minutes ); } // print the text for ( ; ( *lpszArg != _TEXT('\0') ); i++ ) { sscanf_far( lpszArg, _TEXT("%[^\n]%*c%n"), szHeader, &uSize ); // allow for long filenames ... if (( i == 0 ) && ( strlen( szHeader ) > 73 )) { c = szHeader[73]; szHeader[73] = _TEXT('\0'); wWriteStrAtt( i++, 1, nNormal, szHeader ); szHeader[73] = (TCHAR)c; wWriteStrAtt( i, 15, nNormal, szHeader+73 ); fSFN = 0; } else wWriteStrAtt( i, 1, nNormal, szHeader ); lpszArg += uSize; } FreeMem( lpszText ); } wWriteListStr( i+fSFN, 1, wn, PAUSE_PROMPT ); GetKeystroke( EDIT_NO_ECHO | EDIT_BIOS_KEY ); wRemove( wn ); // enable ^C / ^BREAK handling EnableSignals(); continue; } case LIST_GOTO_CHAR: // goto the specified line / hex offset // disable ^C / ^BREAK handling HoldSignals(); wn = wOpen( 2, 5, 4, strlen( LIST_GOTO_OFFSET ) + 20, nInverse, LIST_GOTO_TITLE, NULL ); wn->nAttrib = nNormal; wClear(); wWriteListStr( 0, 1, wn, (( lListFlags & LIST_HEX) ? LIST_GOTO_OFFSET : LIST_GOTO)); i = egets( szLine, 10, (EDIT_DIALOG | EDIT_BIOS_KEY | EDIT_NO_CRLF)); wRemove( wn ); // enable ^C / ^BREAK handling EnableSignals(); if ( i == 0 ) break; list_wait( LIST_WAIT ); // if in hex mode, jump to offset if ( lListFlags & LIST_HEX ) { strupr( szLine ); sscanf( szLine, _TEXT("%lx"), &lRow ); lRow = lRow / 0x10; } else if ( sscanf( szLine, FMT_LONG, &lRow ) == 0 ) continue; lRow -= gpIniptr->ListRowStart; if ( lRow >= 0 ) { LFile.lViewPtr = MoveViewPtr( 0L, &lRow ); LFile.lCurrentLine = lRow; } else { LFile.lViewPtr += MoveViewPtr( LFile.lViewPtr, &lRow ); LFile.lCurrentLine += lRow; } break; case LIST_HIBIT_CHAR: // toggle high bit filter lListFlags ^= LIST_HIBIT; break; case LIST_WRAP_CHAR: // toggle line wrap lListFlags ^= LIST_WRAP; nRightMargin = (( lListFlags & LIST_WRAP ) ? GetScrCols() : MAXLISTLINE ); // recalculate current line list_wait( LIST_WAIT ); // get start of line LFile.nListHorizOffset = 0; // line number probably changed, so recompute everything LFile.lCurrentLine = ComputeLines( 0L, LFile.lViewPtr ); LFile.lViewPtr = MoveViewPtr( 0L, &(LFile.lCurrentLine )); break; case LIST_HEX_CHAR: // toggle hex display lListFlags ^= LIST_HEX; // if hex, reset to previous 16-byte // boundary if ( lListFlags & LIST_HEX ) { LFile.lViewPtr -= ( LFile.lViewPtr % 16 ); } else { // if not hex, reset to start of line ListMoveLine( 1 ); ListMoveLine( -1 ); } // recalculate current line list_wait( LIST_WAIT ); LFile.lCurrentLine = ComputeLines( 0L, LFile.lViewPtr ); break; case LIST_FIND_CHAR: case LIST_FIND_CHAR_REVERSE: // find first matching string bListSkipLine = 0; //lint -fallthrough case LIST_FIND_NEXT_CHAR: case LIST_FIND_NEXT_CHAR_REVERSE: // find next matching string if (( c == LIST_FIND_CHAR ) || ( c == LIST_FIND_CHAR_REVERSE )) { // disable ^C / ^BREAK handling HoldSignals(); fSearchFlags = 0; wn = wOpen( 2, 1, 4, 75, nInverse, (( c == LIST_FIND_NEXT_CHAR_REVERSE ) ? LIST_FIND_TITLE_REVERSE : LIST_FIND_TITLE ), NULL ); wn->nAttrib = nNormal; wClear(); if ( lListFlags & LIST_HEX ) { wWriteListStr( 0, 1, wn, LIST_FIND_HEX ); if ( GetKeystroke( EDIT_ECHO | EDIT_BIOS_KEY | EDIT_UC_SHIFT ) == YES_CHAR ) fSearchFlags |= FFIND_HEX_SEARCH; wClear(); } wWriteListStr( 0, 1, wn, LIST_FIND ); egets( szListFindWhat, 64, (EDIT_DIALOG | EDIT_BIOS_KEY | EDIT_NO_CRLF)); wRemove( wn ); // enable ^C / ^BREAK handling EnableSignals(); } else { FindNext: // a "Next" has to be from current position fSearchFlags &= ~FFIND_TOPSEARCH; } if ( szListFindWhat[0] == _TEXT('\0') ) continue; sprintf( szDescription, LIST_FIND_WAIT, szListFindWhat ); list_wait( szDescription ); // save start position lTemp = LFile.lViewPtr; lRow = LFile.lCurrentLine; if (( c == LIST_FIND_CHAR_REVERSE ) || ( c == LIST_FIND_NEXT_CHAR_REVERSE )) { // start on the previous line fSearchFlags |= FFIND_REVERSE_SEARCH; } else { fSearchFlags &= ~FFIND_REVERSE_SEARCH; // skip the first line (except on /T"xxx") if ( bListSkipLine ) ListMoveLine( 1 ); } bListSkipLine = 1; if ( SearchFile( fSearchFlags ) != 1 ) { ListSetCurrent( lTemp ); LFile.lViewPtr = lTemp; LFile.lCurrentLine = lRow; } else LFile.fDisplaySearch = (( fSearchFlags & FFIND_CHECK_CASE ) ? 2 : 1 ); break; case LIST_PRINT_CHAR: // print the file ListPrintFile(); continue; case LIST_CONTINUE_CHAR: case CTL_PgDn: return 0; case LIST_PREVIOUS_CHAR: case CTL_PgUp: // previous file if ( nCurrent > 0 ) { nCurrent--; return 0; } //lint -fallthrough default: bad_key: honk(); continue; } // rewrite the display ListUpdateScreen(); } return 0; }
static void* accept_request(void *arg) //static { int sock = (int)arg; char buf[SIZE]; int len = sizeof(buf)/sizeof(*buf); char method[SIZE/10]; char url[SIZE]; char path[SIZE]; int ret = -1; int i = 0; int j = 0; char *query_string = NULL; //aim at val(can shu) int cgi = 0; #ifdef _DEBUG_ // do // { // ret = get_line(sock, buf, len); // printf("%s", buf); // fflush(stdout); // }while(ret > 0 && (strcmp(buf, "\n") != 0) ); #endif memset(buf, '\0', sizeof(buf)); memset(method, '\0', sizeof(method)); memset(url, '\0', sizeof(url)); memset(path, '\0', sizeof(buf)); //Request Line ret = get_line(sock, buf, len); if(ret <= 0) { echo_errno(sock); return (void*)1; } i = 0; //method index j = 0; //buf index while((i < (sizeof(method)/sizeof(*method) - 1)) && (j < sizeof(buf)/sizeof(*buf) - 1) && (!isspace(buf[j]) ) ) { method[i] = buf[j]; ++i; ++j; } method[i] = '\0'; if((strcasecmp(method, "GET") != 0) && (strcasecmp(method, "POST")) ) { //echo_errno(sock); return (void*)2; } //URL while(isspace(buf[j])) //Remove Space { ++j; } i = 0; while( ( i < sizeof(url)/sizeof(*url)-1 ) && (j < sizeof(buf)/sizeof(*buf)) && (!isspace(buf[j])) ) { url[i] = buf[j]; ++i; ++j; } url[i] = '\0'; if( strcasecmp(method, "POST") == 0 ) { cgi = 1; sprintf(path, "%s", url+1); } if( strcasecmp(method, "GET") == 0 ) { query_string = url; while( *query_string != '\0' && *query_string != '?' ) { query_string++; } if(*query_string == '?') { cgi = 1; *query_string = '\0'; ++query_string; } } if( strcasecmp(method, "GET") == 0 ) { sprintf(path, "htdoc%s", url); if( path[strlen(path)-1] == '/' ) { strcat(path, "index.html"); } } struct stat st; if( stat(path, &st) < 0 ) { //echo_errno(); //404 return (void*)3; } else //case : DIR { if( S_ISDIR(st.st_mode) ) { strcat(path, "index.html"); } else if( (st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) //bin(binary file) { cgi = 1; } else {} //noting to do } printf("!@!#%@^ %s !@%@^%\n", buf); if(cgi) // u+x file { printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!cgi\n"); exe_cgi(sock, method, path, query_string); //cgi mode } else //.jpg .html ... { printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!www\n"); clear_header(sock); //! important! echo_www(sock, path, st.st_size); } close(sock); return 0; }
static void exe_cgi( int sock, const char *method, const char *path, const char *query_string ) { char buf[SIZE]; int content_length = -1; //pipe named by child side int cgi_input[2]; int cgi_output[2]; char method_env[SIZE]; char query_string_env[SIZE]; char content_length_env[SIZE]; char tmpc; memset(buf, '\0', sizeof(buf)); // ! ! ! ! ! M U S T I N I T A R R A Y ! ! ! memset(method_env, '\0', sizeof(method_env)); memset(query_string_env, '\0', sizeof(query_string)); memset(content_length_env, '\0', sizeof(content_length_env)); if(strcasecmp(method, "GET") == 0 ) { clear_header(sock); //"GET" send val by url ,already get } int ret = 0; if(strcasecmp(method, "POST") == 0 ) //different { do { memset(buf, '\0', sizeof(buf)); ret = get_line(sock, buf, sizeof(buf)); if( strncasecmp(buf, "Content-Length: ", 16) == 0) { content_length = atoi(&buf[16]); } }while( (ret > 0) && strcmp(buf, "\n") != 0 ); printf("content_length = %d\n", content_length); if( content_length == -1 ) { echo_errno(sock); return; } } ///////////// (8.11) ///////////////////////////// sprintf(buf, "HTTP/1.0 200 OK\r\n\r\n"); send(sock, buf, strlen(buf), 0); if( pipe(cgi_input) < 0 ) { echo_errno(sock); return; } if( pipe(cgi_output) < 0 ) { echo_errno(sock); return; } pid_t id = fork(); if(id == 0) //child { close(cgi_input[1]); close(cgi_output[0]); dup2(cgi_input[0], 0); dup2(cgi_output[1], 1); sprintf(method_env, "REQUEST_METHOD=%s", method); putenv(method_env); if( strcasecmp(method, "GET") == 0 ) //GET { sprintf(query_string_env, "QUERY_STRING=%s", query_string); putenv(query_string_env); } else //POST { sprintf(content_length_env, "CONTENT_LENGTH=%d", content_length); putenv(content_length_env); } execl(path, path, NULL); //run here , execl wrong exit(1); } else //father { close(cgi_input[0]); close(cgi_output[1]); // dup2(cgi_input[1], 1); // dup2(cgi_output[0], 0); char c = '\0'; int i =0; if( strcasecmp(method, "POST") == 0 ) { for(; i < content_length; ++i) { recv(sock, &c, 1, 0); printf("%c", c); write(cgi_input[1], &c, 1); } } int ret = 0; while( read(cgi_output[0], &c, 1) > 0) { send(sock, &c, 1, 0); } waitpid(id, NULL, 0); } }