diff options
Diffstat (limited to 'sock_conn.c')
-rw-r--r-- | sock_conn.c | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/sock_conn.c b/sock_conn.c new file mode 100644 index 0000000..a57ca7b --- /dev/null +++ b/sock_conn.c @@ -0,0 +1,248 @@ +#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); + 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); + 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 ret=-1; + int cnt=0; + int i; + int j; + + //out buffer is allready full + if (ib->out_size-1 == ib->max_out_size) + { + printf("Out buffer is full\n"); + return -1; + } + + //check if buffer is complete buffer + if ((ib->ready == 1) //its marked as complete + || + //in case if its not marked, -1 becouse its index in array + ((ib->out_size >= 2) + &&(ib->buf_out[ib->out_size-1]=='\n') + &&(ib->buf_out[ib->out_size-2]=='\r'))) + { + printf("Buffer is ready\n"); + return 0; + } + + //lets from in buffer put as much as possible to out buffer + i = ib->in_size-1; + j = ib->out_size; + //PRINT("%d %d\n",i,j); + cnt = 0; + while ((j<ib->max_out_size)&&(i>=0)) //buffers ar full or empty + { + if (ib->out_size >= 2) + if (((ib->buf_out[j-2]=='\r')&&(ib->buf_out[j-1]=='\n')))//bufferunderflow + { + 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; // + //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')) + { + ib->ready = 1; + return 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; + (i<sz)&&(j<ib->max_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 = cnt; + + 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; + + struct addrinfo serv, *res; + + memset(&serv, 0, sizeof(serv)); + serv.ai_family = AF_INET; + serv.ai_socktype = SOCK_STREAM; + getaddrinfo(hostname, port, &serv, &res); + fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + connect(fd, res->ai_addr, res->ai_addrlen); + + //? + //freeaddrinfo(&serv); + + return fd; +} + + + |