/** * Replace marker text. * * Replace all occurrances of the marker text with the substitution text. * The result is stored in an automatically freed temporary buffer. * * @param src_str The source string * @param str_len The length of the string * @param match the SCM-ized marker string * @param repl the SCM-ized replacement string * @param ppz_res pointer to the result pointer * @param res_len pointer to result length */ static void do_substitution( char const * src_str, ssize_t str_len, SCM match, SCM repl, char ** ppz_res, ssize_t * res_len) { char * pzMatch = ag_scm2zchars(match, "match text"); char * rep_str = ag_scm2zchars(repl, "repl text"); int mark_len = (int)AG_SCM_STRLEN(match); int repl_len = (int)AG_SCM_STRLEN(repl); { int ct = sub_count(src_str, pzMatch); if (ct == 0) return; /* No substitutions -- no work. */ str_len += (repl_len - mark_len) * ct; } { char * dest = scribble_get(str_len + 1); *ppz_res = dest; *res_len = str_len; for (;;) { char const * next = strstr(src_str, pzMatch); size_t len; if (next == NULL) break; len = (size_t)(next - src_str); if (len != 0) { memcpy(dest, src_str, len); dest += len; } memcpy(dest, rep_str, (size_t)repl_len); dest += repl_len; src_str = next + mark_len; } strcpy(dest, src_str); } }
void AntiSem::sub_locked(T cur,F Release,ulen dcount) { Log("#; (#;) -= #; by #;",name,count,dcount,GetTaskName(cur)); sub_count(dcount); if( count<=level ) { event(AntiSemEvent::Release); Release(list,Release_Ok,name); } else { event(AntiSemEvent::Sub); } }
/* * @brief listen每次accept一个连接,则创建一个线程收取文件,线程的call_back函数即为handler,参数是accept的fd * @param int fd */ int handler(int fd) { char buffer[NET_BUFFER_LEN], encrypt_buffer[NET_BUFFER_LEN]; char *buf_ptr; int recv_len = 0; int send_len = 0; int total_recv_len = 0; int total_send_len = 0; int prefix_len = SYMBOL_LEN + COMMAND_LEN + DATA_LEN + FILL_LEN; int payload_len = 0; int fill_len = 0; int data_len = 0; int continue_flag = 1; q_node_t *node; pthread_detach(pthread_self()); add_count(); node = get_recv_node(); //while recv_len == -1看起来很奇怪,似乎将while变成if更加合理 //但是如果在recv时候被信号中断等待过程,则需要重新recv 使用while可以在recv到数据或者0的时候立即 //退出并进一步判断,在recv返回-1的时候判断errno选择是退出还是继续recv while ((recv_len = recv(fd, (void*)buffer, sizeof(buffer), 0)) == -1) { if (errno == EINTR) continue; else { write_log("Handler,recv:%s\n", strerror(errno)); goto ret; //or just break, and recv_len = -1,program will goto ret at the if condition down there } } if (recv_len == 0) { write_log("Recv 0:client_closed %s\n", strerror(errno)); goto ret; } total_recv_len = recv_len; if (recv_len < prefix_len) { //刚开始收数据时,缓冲区是空的,而本fd连头部信息都没有收完全. write_log("Bad connection,recv command error![recv_len=%u,prefixlen=%u]\n", recv_len,prefix_len); goto ret; } while (continue_flag) { while (total_recv_len < prefix_len) { while ((recv_len = recv(fd, (void*)(buffer+total_recv_len), sizeof(buffer) - total_recv_len, 0)) == -1) { if (errno == EINTR) continue; else { write_log("Recv error:%s\n", strerror(errno)); goto ret; } } total_recv_len += recv_len; if (recv_len == 0) { write_log("recv 0:%s\n", strerror(errno)); goto ret; } } //暂时只解析头部 #ifdef ENCODE_ des_decrypt_n(des_pass_phrase, (const void*)buffer , (void*)encrypt_buffer, prefix_len/ALIGN_LEN); //32BYTE/8BYTE memcpy(buffer,encrypt_buffer,prefix_len); #endif payload_len = *(int*)(buffer + SYMBOL_LEN + COMMAND_LEN); fill_len = *(int*)(buffer + SYMBOL_LEN + COMMAND_LEN + DATA_LEN); data_len = prefix_len + payload_len + fill_len + DATA_END_LEN; if (data_len > sizeof(buffer)) { write_log("data_len[%u] > buffer size[%lu]!!!\ please enlarge your buffer size\n", data_len, sizeof(buffer)); goto ret; } if ((total_recv_len - prefix_len) < (payload_len + fill_len + DATA_END_LEN)) { while ((recv_len = recv(fd, (void*)buffer+total_recv_len, (sizeof(buffer) - total_recv_len), 0)) < (data_len - total_recv_len)) { if (recv_len == -1) { if (errno == EINTR) continue; write_log("Handler,recv:%s\n", strerror(errno)); goto ret; } else if (recv_len == 0) { write_log("Handler,recv 0 :%s\n", strerror(errno)); goto ret; } else total_recv_len += recv_len; } total_recv_len += recv_len; } if (memcmp(SYMBOL, buffer, SYMBOL_LEN) != 0) { write_log("Bad connection, bad symbol![%s]\n", buffer); goto ret; } if (memcmp(C_GET_LOAD, buffer + SYMBOL_LEN, COMMAND_LEN) == 0) { buf_ptr = buffer; memcpy(buf_ptr, SYMBOL, SYMBOL_LEN); //packet symbol buf_ptr += SYMBOL_LEN; memcpy(buf_ptr, C_SHOW_LOAD, COMMAND_LEN); //ask server's load command buf_ptr += COMMAND_LEN; data_len = sizeof(float); fill_len = ALIGN_LEN - sizeof(float); memcpy(buf_ptr, &data_len, DATA_LEN ); buf_ptr += DATA_LEN; memcpy(buf_ptr, &fill_len, FILL_LEN ); buf_ptr += FILL_LEN; //================getload============ FILE *result; char result_buf[TEXT_LINE_LEN]; result = popen("awk 'BEGIN{\"uptime\"|getline; print $11;}'","r"); fread(result_buf,sizeof(char),sizeof(result_buf),result); pclose(result); float server_load = atof(result_buf); //============================ memcpy(buf_ptr, &server_load, data_len); buf_ptr += data_len; memset(buf_ptr, 0x0, fill_len); buf_ptr += fill_len; memcpy(buf_ptr,DATA_END,DATA_END_LEN); buf_ptr += DATA_END_LEN; #ifdef ENCODE_ des_encrypt_n(des_pass_phrase, (const void*)buffer , (void*)encrypt_buffer, (buf_ptr - buffer)/ALIGN_LEN); //32BYTE/8BYTE memcpy(buffer, encrypt_buffer, sizeof(buffer)); #endif //sent to client send_len = 0; total_send_len = 0; data_len = buf_ptr - buffer; while ((send_len = send(fd, buffer+total_send_len, (data_len-total_send_len), 0) ) < (data_len - total_send_len) ) { if (send_len == -1) { if (errno == EINTR) continue; write_log("Send load: send error:%s\n", strerror(errno)); goto ret; } else total_send_len += send_len; } total_send_len += send_len; goto ret; } if (memcmp(C_SEND_DATA, buffer + SYMBOL_LEN, COMMAND_LEN) == 0) { //解析数据体 #ifdef ENCODE_ des_decrypt_n(des_pass_phrase, (const void*)(buffer+prefix_len), (void*)encrypt_buffer, (data_len - prefix_len)/ALIGN_LEN); //32BYTE/8BYTE memcpy(buffer + prefix_len, encrypt_buffer, data_len - prefix_len); #endif buf_ptr = buffer + prefix_len; store_result_t *t1; store_result_t *tmp; int effctive_size = sizeof(store_result_t) - sizeof((store_result_t*)0); //=========================================== while ((buf_ptr - (buffer + prefix_len)) < payload_len) { t1 = (store_result_t*)buf_ptr; //将这批数据挂在recvlink上 tmp = get_mem(); memcpy(tmp, t1, effctive_size); tmp->next = NULL; buf_ptr += effctive_size; if (node->recv_link == NULL) node->recv_link = tmp; else { tmp->next = node->recv_link; node->recv_link = tmp; } file_recv_node_len[node->number]++ ; } //============================================ buf_ptr += fill_len;//跳到后续数据标识符 //若为其他(应该是"DATA_END") 则可以退出,若为CONTINU,则继续接收 uint32_t packet_len = prefix_len + payload_len + fill_len + DATA_END_LEN; //printf("\t\t%u,%u\n",total_recv_len,packet_len); if (memcmp(buf_ptr, CONTINUE, DATA_END_LEN) == 0) { //有后续数据 buf_ptr += DATA_END_LEN; if ((buf_ptr - buffer) == sizeof(buffer)) { //buffer收满了,则重新收 recv_len = 0; total_recv_len =0; continue_flag = 1; } else if (total_recv_len == packet_len) { //如果接收到了一个完整的数据分段,则重新接收 recv_len = 0; total_recv_len = 0; continue_flag = 1; } else { //如果缓冲区中有后续包的分段,则前移动,因为这些数据没有解密,所以直接移动 memcpy(encrypt_buffer, buf_ptr, total_recv_len - packet_len); memcpy(buffer, encrypt_buffer, total_recv_len - packet_len); recv_len = total_recv_len - packet_len; total_recv_len = recv_len; continue_flag = 1; } } else continue_flag = 0; //no more data transmitted }//send data }//while continue //store_data int status = write_file(node->recv_link, file_recv_node_len[node->number]); if(status == 0) { //echo DATA__OK to client; buf_ptr = buffer; memcpy(buf_ptr, SYMBOL, SYMBOL_LEN); //packet symbol buf_ptr += SYMBOL_LEN; memcpy(buf_ptr, C_DATA_OK, COMMAND_LEN); //ask server's load command buf_ptr += COMMAND_LEN; memset(buf_ptr, 0x0, DATA_LEN + FILL_LEN); buf_ptr += (DATA_LEN + FILL_LEN); memcpy(buf_ptr,DATA_END,DATA_END_LEN); buf_ptr += DATA_END_LEN; #ifdef ENCODE_ des_encrypt_n(des_pass_phrase, (const void*)buffer , (void*)encrypt_buffer, (buf_ptr - buffer)/ALIGN_LEN); //32BYTE/8BYTE memcpy(buffer,encrypt_buffer,sizeof(buffer)); #endif //sent to client send_len = 0; total_send_len = 0; data_len = buf_ptr - buffer; while ((send_len = send(fd, buffer+total_send_len, (data_len-total_send_len), 0)) < (data_len - total_send_len)) { if (send_len == -1) { if (errno == EINTR) continue; write_log("Send load: send error:%s\n", strerror(errno)); goto ret; } else total_send_len += send_len; } total_send_len += send_len; } ret: recycle_recv_node(node); sub_count(); pthread_mutex_lock(&thread_count_mutex); pthread_cond_signal(&thread_count_cond); pthread_mutex_unlock(&thread_count_mutex); close(fd); pthread_exit(0); return 0; }