/* ARISA - Line Driven Socket Functions * Copyright (C) 2004 Carl Ritson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "arisa.h" #include #include #include "line-drive.h" linebuf_t *alloc_linebuf(size_t msgsize) { linebuf_t *lb = xalloc(sizeof(linebuf_t)); if(msgsize < 64) msgsize = 64; lb->msgsize = msgsize; lb->bufsize = lb->msgsize + 2; lb->buffer = xalloc(lb->bufsize); lb->pos = 0; lb->used = 0; return lb; } void free_linebuf(linebuf_t *lb) { xfree(lb->buffer); xfree(lb); } void clear_linebuf(linebuf_t *lb) { lb->buffer[0] = '\0'; lb->pos = 0; lb->used = 0; } int linebuf_inuse(linebuf_t *lb) { if(lb->pos != 0 || lb->used != 0) return 1; else return 0; } size_t copy_linebuf(linebuf_t *lb, char *dst, size_t dstsize) { size_t len = IMIN(lb->used, dstsize - 1); if(len <= 0) return 0; xstrncpy(dst,lb->buffer,len + 1); return len; } void load_linebuf(linebuf_t *lb, char *src) { size_t len; len = IMIN( snprintf(lb->buffer,lb->msgsize,"%s",src), lb->msgsize - 1 ); lb->used = len; lb->pos = len; } char *dup_linebuf(linebuf_t *lb) { char *line = NULL; if(lb->used > 0) { line = xalloc(lb->used + 1); copy_linebuf(lb,line,lb->used + 1); } return line; } int recv_line(int sok, linebuf_t *lb) { int i,ret; lb->used = 0; ret = recv(sok,lb->buffer + lb->pos, (lb->msgsize - lb->pos),MSG_PEEK); if(ret <= 0) return -1; for(i = 0; i < (ret + lb->pos); ++i) { if(lb->buffer[i] == '\n') { ret = recv(sok,lb->buffer + lb->pos, (i+1) - lb->pos,0); if(ret <= 0) return -1; lb->buffer[i] = '\0'; lb->used = i; lb->pos = 0; if(i != 0) { if(lb->buffer[i-1] == '\r') { lb->buffer[i-1] = '\0'; lb->used--; } } return 1; } } ret = recv(sok,lb->buffer + lb->pos,ret,0); if(ret <= 0) return -1; lb->pos += ret; if(lb->pos >= lb->msgsize) lb->pos = 0; return 0; } int send_line(int sok, linebuf_t *lb) { int ret; if(lb->used == 0) return 1; lb->pos = 0; ret = send(sok,lb->buffer,lb->used,0); if(ret <= 0) return -1; lb->used -= ret; if(lb->used > 0) { memmove(lb->buffer, lb->buffer + ret, lb->used + 1); return 0; } else return 1; }