Back to index

avfs  1.0.1
send.c
Go to the documentation of this file.
00001 /*
00002     AVFS: A Virtual File System Library
00003     Copyright (C) 1998-2001  Miklos Szeredi <miklos@szeredi.hu>
00004 
00005     This program can be distributed either under the terms of the GNU
00006     GPL or under the terms of the GNU LGPL.  See the files COPYING and
00007     COPYING.LIB.
00008 */
00009 
00010 #include "send.h"
00011 
00012 #include <stdlib.h>
00013 #include <unistd.h>
00014 
00015 #define BUFLEN 1024
00016 struct buffer {
00017     int fd;
00018     char buf[BUFLEN];
00019     unsigned int ptr;
00020     unsigned int len;
00021     int error;
00022 };
00023 
00024 static int sock_write(int sock, const char *msg, unsigned int len)
00025 {
00026     int res;
00027 
00028     while(len > 0) {
00029         res = write(sock, msg, len);
00030         if(res == -1)
00031             return -1;
00032 
00033         len -= res;
00034         msg += res;
00035     }
00036 
00037     return 0;
00038 }
00039 
00040 static void init_buffer(struct buffer *buf, int fd)
00041 {
00042     buf->fd = fd;
00043     buf->ptr = 0;
00044     buf->len = 0;
00045     buf->error = 0;
00046 }
00047 
00048 
00049 static void read_buffer(struct buffer *buf, char *msg, unsigned int len)
00050 {
00051     int res;
00052 
00053     while(len > 0) {
00054         if(buf->error != 0)
00055             return;
00056 
00057         if(buf->len == 0 && len > BUFLEN) {
00058             res = read(buf->fd, msg, len);
00059             if(res <= 0) {
00060                 buf->error = -1;
00061                 return;
00062             }
00063             
00064             len -= res;
00065             msg += res;
00066         }
00067         else if(len <= buf->len) {
00068             memcpy(msg, buf->buf + buf->ptr, len);
00069             buf->len -= len;
00070             buf->ptr += len;
00071             return;
00072         }
00073         else {
00074             memcpy(msg, buf->buf + buf->ptr, buf->len);
00075             msg += buf->len;
00076             len -= buf->len;
00077             buf->ptr = 0;
00078 
00079             res = read(buf->fd, buf->buf, BUFLEN);
00080             if(res <= 0)
00081                 buf->error = -1;
00082             else
00083                 buf->len = res;
00084         }
00085     }
00086 }
00087 
00088 static void write_buffer(struct buffer *buf, const char *msg, unsigned int len)
00089 {
00090     unsigned int rem;
00091 
00092     while(len > 0) {
00093         if(buf->error != 0)
00094             return;
00095 
00096         if(buf->ptr == 0 && len > BUFLEN) {
00097             buf->error = sock_write(buf->fd, msg, len);
00098             return;
00099         }
00100 
00101         rem = BUFLEN - buf->ptr;
00102         if(len < rem) {
00103             memcpy(buf->buf + buf->ptr, msg, len);
00104             buf->ptr += len;
00105             return;
00106         }
00107         
00108         memcpy(buf->buf + buf->ptr, msg, rem);
00109         len -= rem;
00110         msg += rem;
00111         buf->error = sock_write(buf->fd, buf->buf, BUFLEN);
00112         buf->ptr = 0;
00113     }
00114 }
00115 
00116 static void flush_buffer(struct buffer *buf)
00117 {
00118     if(buf->error != 0)
00119         return;
00120     
00121     buf->error = sock_write(buf->fd, buf->buf, buf->ptr);
00122 }
00123 
00124 int __av_read_message(int sock, struct avfs_in_message *msg)
00125 {
00126     unsigned int lengths[MAXSEG];
00127     struct buffer buf;
00128     int i;
00129 
00130     init_buffer(&buf, sock);
00131     read_buffer(&buf, (void *) lengths, sizeof(int) * MAXSEG);
00132 
00133     for(i = 0; i < MAXSEG; i++) {
00134         msg->seg[i].len = lengths[i];
00135         if(lengths[i] != 0) {
00136             if(msg->seg[i].buf == NULL)
00137                 msg->seg[i].buf = malloc(lengths[i]);
00138             
00139             read_buffer(&buf, msg->seg[i].buf, msg->seg[i].len);
00140         }
00141     }
00142     
00143     return buf.error;
00144 }
00145 
00146 
00147 int __av_write_message(int sock, struct avfs_out_message *msg)
00148 {
00149     int i;
00150     unsigned int lengths[MAXSEG];
00151     struct buffer buf;
00152 
00153     for(i = 0; i < MAXSEG; i++) {
00154         if(i < msg->num)
00155             lengths[i] = msg->seg[i].len;
00156         else
00157             lengths[i] = 0;
00158     }
00159 
00160     init_buffer(&buf, sock);
00161 
00162     write_buffer(&buf, (void *) lengths, sizeof(int) * MAXSEG);
00163     
00164     for(i = 0; i < msg->num; i++)
00165         write_buffer(&buf, msg->seg[i].buf, msg->seg[i].len);
00166 
00167     flush_buffer(&buf);
00168 
00169     return buf.error;
00170 }
00171