1/* 2 * $Id: dsi_read.c,v 1.7 2009-10-25 06:13:11 didg Exp $ 3 * 4 * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) 5 * All rights reserved. See COPYRIGHT. 6 */ 7 8#ifdef HAVE_CONFIG_H 9#include "config.h" 10#endif /* HAVE_CONFIG_H */ 11 12#include <stdio.h> 13#include <string.h> 14#ifdef HAVE_UNISTD_H 15#include <unistd.h> 16#endif /* HAVE_UNISTD_H */ 17#include <signal.h> 18#include <sys/types.h> 19#include <sys/time.h> 20#ifdef HAVE_SYS_FILIO_H 21#include <sys/filio.h> 22#endif 23 24#include <atalk/dsi.h> 25#include <atalk/util.h> 26#include <atalk/logger.h> 27 28/* streaming i/o for afp_read. this is all from the perspective of the 29 * client. it basically does the reverse of dsi_write. on first entry, 30 * it will send off the header plus whatever is in its command 31 * buffer. it returns the amount of stuff still to be read 32 * (constrained by the buffer size). */ 33ssize_t dsi_readinit(DSI *dsi, void *buf, const size_t buflen, 34 const size_t size, const int err) 35{ 36 LOG(log_maxdebug, logtype_dsi, "dsi_readinit: sending %zd bytes from buffer, total size: %zd", 37 buflen, size); 38 39 dsi->flags |= DSI_NOREPLY; /* we will handle our own replies */ 40 dsi->header.dsi_flags = DSIFL_REPLY; 41 dsi->header.dsi_len = htonl(size); 42 dsi->header.dsi_code = htonl(err); 43 44 dsi->in_write++; 45 if (dsi_stream_send(dsi, buf, buflen)) { 46 dsi->datasize = size - buflen; 47 LOG(log_maxdebug, logtype_dsi, "dsi_readinit: remaining data for sendfile: %zd", dsi->datasize); 48 return MIN(dsi->datasize, buflen); 49 } 50 51 return -1; /* error */ 52} 53 54void dsi_readdone(DSI *dsi) 55{ 56 dsi->in_write--; 57} 58 59/* send off the data */ 60ssize_t dsi_read(DSI *dsi, void *buf, const size_t buflen) 61{ 62 size_t len; 63 64 len = dsi_stream_write(dsi, buf, buflen, 0); 65 66 if (len == buflen) { 67 dsi->datasize -= len; 68 return MIN(dsi->datasize, buflen); 69 } 70 71 return -1; 72} 73