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