#include "sock_conn.h" /*mvar things*/ //shitty macro #define MVAR_ALLOC_STRC(VNAME,VTYPE,VRET)\ VTYPE *VNAME;\ VNAME=malloc(sizeof(VTYPE));\ if ((VNAME)==NULL){\ VRET\ }\ memset(VNAME,0,sizeof(VTYPE)); #define MVAR_ALLOC_ARR(VNAME,VTYPE,VSZ,VRET)\ VTYPE *VNAME;\ VNAME=malloc(sizeof(VTYPE)*(VSZ));\ if ((VNAME)==NULL){\ VRET\ }\ memset(VNAME,0,sizeof(VTYPE)*(VSZ)); irc_buf* irc_buf_create() { MVAR_ALLOC_STRC(ret,irc_buf,{ return NULL; }); ret->out_size = 0; ret->max_out_size = IRC_BUF_OUT_SIZE; ret->buf_out = malloc(ret->max_out_size); if (ret->buf_out == NULL) { free(ret); PERM(); return NULL; } memset(ret->buf_out, 0, ret->max_out_size); ret->in_size = 0; ret->max_in_size = IRC_BUF_IN_SIZE; ret->buf_in = malloc(ret->max_in_size); if (ret->buf_in == NULL) { free(ret->buf_out); free(ret); return NULL; } memset(ret->buf_in, 0, ret->max_in_size); ret->ready = 0; return ret; } //cpy bytes from input to output int __irc_buf_drain_io(irc_buf *ib) { int cnt=0; int i; int j; //out buffer is allready full if (ib->out_size-1 == ib->max_out_size) { PRINT("Out buffer is full\n"); return -1; } //check if buffer is complete buffer if (ib->ready == 1) //its marked as complete { PRINT("Buffear allready ready\n"); return 0; } //in case if its not marked, -1 becouse its index in array if ((ib->out_size >= 2) &&(ib->buf_out[ib->out_size-1]=='\n') &&(ib->buf_out[ib->out_size-2]=='\r')) { PRINT("Buffer is ready\n"); return 0; } //BUG //here is hope that server will send 512/1024 bytes that will be terminated with "\r\n" //but this could be false hope if someone gona abuse it, buffer will fill up and will //not be able to give back new lines //FIX //just add more logic pal to handle this "special" case //lets from in buffer put as much as possible to out buffer i = ib->in_size-1; j = ib->out_size; PRINT("in_size=%d out_size=%d\n",ib->in_size, ib->out_size); cnt = 0; while ((jmax_out_size)&&(i>=0)) //buffers ar full or empty { //if (ib->out_size >= 2) if (j >= 3) //be carefull with this line { if (((ib->buf_out[j-3]=='\r')&&(ib->buf_out[j-2]=='\n')))//bufferunderflow { PRINT("READY\n"); ib->ready = 1; //PNL(); break; } } ib->buf_out[j] = ib->buf_in[i]; i--; j++; cnt++; } //update PRINT("Copied %d bytes\n", cnt); ib->in_size = i+1; //i can end up as -1 ib->out_size = j; // PRINT("in_size=%d out_size=%d\n",ib->in_size, ib->out_size); //if out buffer full and its doesnt have proper ending if (ib->out_size >= 2) if ((ib->buf_out[ib->out_size-1]=='\n')&&(ib->buf_out[ib->out_size-2]=='\r')) { PRINT("READY\n"); ib->ready = 1; return cnt; } PRINT("%d\n",cnt); return cnt; } //return amount not written bytes int irc_buf_puts(irc_buf *ib, char *in_buf, int sz) { int i,j; int cnt; int ret = -1; int fret = -1; if (ib == NULL) { PERM(); return -1; } if (in_buf == NULL) { PERM(); return -1; } if (sz<0) { PERM(); return -1; } cnt = 0; for ( i=0, j=ib->in_size,cnt=0; (imax_in_size); i++, j++,cnt++) { //PRINT("%d %d\n",i,j); ib->buf_in[j] = in_buf[sz-i-1]; } ib->in_size = j; fret = __irc_buf_drain_io(ib); if (fret == 0) { printf("Cant do it pal\n"); } //printf("%d %d\n",sz,cnt); ret = fret; return ret; } int irc_buf_putc(irc_buf *ib, char c) { printf("Not implemtented\n"); return -1; } //return size of output buffer int irc_buf_sz(irc_buf *ib) { if (ib == NULL) return -1; return ib->out_size; } int irc_buf_ready(irc_buf *ib) { if (ib == NULL) { return -1; } return ib->ready; } //unset ready and return line char *irc_buf_line(irc_buf *ib) { char *ret = NULL; if (ib == NULL) { PERM(); return NULL; } if (ib->ready == 0) { PERM(); return NULL; } ret = alloc_new_str_s(ib->buf_out, ib->out_size); if (ret == NULL) { PERM(); return NULL; } ib->ready = 0; ib->out_size = 0; return ret; } int irc_buf_destroy(irc_buf *ib) { if (ib == NULL) { return -1; } free(ib->buf_in); free(ib->buf_out); free(ib); return 0; } /* connect to hostname:port return fd>0 if connection succesful */ int irc_connect( char *hostname, char *port ) { int fd=0; int fret=-1; struct addrinfo serv, *res; if (hostname == NULL) { PERM(); return -1; } if (port == NULL) { PERM(); return -1; } memset(&serv, 0, sizeof(serv)); serv.ai_family = AF_INET; serv.ai_socktype = SOCK_STREAM; if (0 != getaddrinfo(hostname, port, &serv, &res)) { PERM(); perror("Couldnt get addr info"); return -1; } fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); fret = connect(fd, res->ai_addr, res->ai_addrlen); if (fret!=0) { PERM(); return -1; } //? //freeaddrinfo(&serv); return fd; }