/****************************************************************************** * $Id: lstringhack.c,v 1.10 2005/09/25 11:55:53 gareuselesinge Exp $ * This file is part of FreePOPs (http://www.freepops.org) * * This file is distributed under the terms of GNU GPL license. * ******************************************************************************/ /****************************************************************************** * File description: * some hacks * Notes: * * Authors: * Name ******************************************************************************/ #include #include #if defined(BEOS) # include #endif #ifdef __sun # include #endif #include "lstringhack.h" #include "regularexp.h" #include "win32_compatibility.h" #include "log.h" #define LOG_ZONE "STRINGHACK" struct strhack_t { int header_done; long int current_lines; char last3[4]; char last4[4]; // char* to_free_top; // char* to_free_dot; }; struct strhack_t* new_str_hack() { struct strhack_t* tmp; tmp = malloc(sizeof(struct strhack_t)); MALLOC_CHECK(tmp); tmp->header_done = 0; tmp->current_lines = 0; memset(tmp->last3,'\0',4); memset(tmp->last4,'\0',4); //tmp->to_free_top = NULL; //tmp->to_free_dot = NULL; return tmp ; } void delete_str_hack(struct strhack_t* x) { //free(x->to_free_top); //free(x->to_free_dot); free(x); } /*! gets a string, plus a static buffer char last [4] * and return a buffer with all the \n\r.\n replaced * with \n\r..\n even if fragmented between two subsequest * calls. buff must be dynamic memory, and the result should be free * by the client, while buff is eventually freed by this function. * */ char * dothack(struct strhack_t*a,const char *buff) { char defrag[7]; int p; int n; char* rc; char* last = a->last4; if(buff == NULL) return NULL; //buff = strdup(buff); memset(defrag,'\0',7); strcpy(defrag,last); strncpy(&defrag[strlen(last)],buff,3); defrag[strlen(last)+3]='\0'; p = regfind_start(defrag,"\r\n\\.\r"); if(p != -1) { //fragmented! char* idx; int d; //printf("!!FRAG ->%s<-!!\n",defrag); idx = index(defrag,'.'); if(idx == NULL) { //printf("!!ERROR\n"); ERROR_PRINT("not a '.'\n"); } d = idx - defrag; //printf("!!d=%d\n",d); switch(d) { case 0: case 1: case 5: //printf("!!skip\n"); break; case 2: case 3: case 4: { char * rc = calloc(strlen(buff)+ 2,sizeof(char)); memcpy(rc,&("\n.."[4-d]),d); strcpy(&rc[d-1],&buff[d-2]); //free(buff); buff = (const char*)rc; /* if (a->to_free_dot != NULL) free(a->to_free_dot); a->to_free_dot = buff; */ } break; default: //printf("!!ERROR\n"); ERROR_PRINT("not in case!\n"); break; } } n = regfind_count(buff,"\r\n\\.\r",1); //printf("!!%d!!\n",n); if(n>0) { int i,o; int len = strlen(buff); //int n1=n; //DELETE ME!!!! rc = calloc(len + 1 + n,sizeof(char)); for(i=0,o=0;n>0;i++,o++) { //printf("!!comparing %s!!\n",&buff[i]); if(!strncmp(&buff[i],"\r\n.\r",4)) { memcpy(&rc[o],"\r\n..\r",5); o+=5-2; i+=4-2; n--; //printf("!!GOT!!\n"); } else { rc[o] = buff[i]; } } if( i < len) { //printf("i=%d, o=%d, len_buff=%d, lenrc=%d\n", // i,o, strlen(&buff[i]), len + 1 + n1); strcpy(&rc[o],&buff[i]); } //free(buff); // this if should be always true /* if (a->to_free_dot != NULL) free(a->to_free_dot); a->to_free_dot = rc; */ } else { rc = (char *)buff; } memcpy(last,&rc[strlen(rc) - 3],4); return rc; } // returned value is tmp char *tophack(struct strhack_t *a,const char* tmp,int lines) { char* buff = NULL; if(!a->header_done) { regmatch_t pm; char defrag[7]; // build the defrag memset(defrag,'\0',7); strncat(defrag, a->last3,3); strncat(defrag,tmp,3); //DBG("DEFRAG='%s'\n",defrag); //search first here pm = regfind(defrag,"\r\n\r\n"); if(pm.begin == -1) { //not fragmented :) //DBG("NOT FRAGMENTED!!\n"); //search for the end of header pm = regfind(tmp,"\r\n\r\n"); if( pm.begin != -1) { a->header_done = 1; a->current_lines = regfind_count(&tmp[pm.end],"\r\n",0); } } else { //DBG("!! FRAGMENTED !!\n"); // the end of the header tag is fragmented a->header_done = 1; a->current_lines = regfind_count(tmp,"\r\n",0); // if ..R|NRN or .RN|RN. current_lines-- pm = regfind(defrag,"..\r\n\r\n"); if(pm.begin != -1) a->current_lines--; pm = regfind(defrag,".\r\n\r\n."); if(pm.begin != -1) a->current_lines--; } //save last3 snprintf(a->last3, 4,"%s",&tmp[strlen(tmp)-3]); } else { a->current_lines += regfind_count(tmp,"\r\n",0); } /* have we received more than needed? */ if (a->current_lines > lines || (lines == 0 && a->header_done)) { int i; int l,l_old; /* if (a->to_free_top != NULL) free(a->to_free_top); */ buff = strdup(tmp); /*a->to_free_top = tmp;*/ //DBG("cutting %ld\n",a->current_lines - lines); l = l_old = strlen(buff) - 2; if(lines == 0) i = -1; // we have t oremove the blank line! else i = 0; //return back from the end of while( i <= a->current_lines - lines && l >= 0) { if(!strncmp(&buff[l],"\r\n",2)) { i++; l--; //skip 2 == strlen("\r\n") //DBG("CUT %d\n$\n%s\n$\n",i,&buff[l]); } l--; } if(l>=0) l+=2; // fix it putting a \0 if(l>=0) { //DBG("(%d)cutting from here:\n$\n%s\n$\n",l,&tmp[l]); if(l_old - l >= 3) { buff[l+2]='\0'; buff[l+1]='\n'; buff[l+0]='\r'; } else if(l_old - l >= 1) { buff[l]='\0'; } } } else buff= (char *)tmp; return buff; } int check_stop(struct strhack_t *a,int lines) { if (a->current_lines > lines || (lines == 0 && a->header_done)) return 1; else return 0; } int current_lines(struct strhack_t *a) { return a->current_lines; }