]> arthur.barton.de Git - netatalk.git/blob - libatalk/dsi/dsi_read.c
Initial revision
[netatalk.git] / libatalk / dsi / dsi_read.c
1 /*
2  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
3  * All rights reserved. See COPYRIGHT.
4  */
5
6 #include <stdio.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <signal.h>
10 #include <sys/types.h>
11 #include <sys/time.h>
12
13 #include <atalk/dsi.h>
14
15 #ifndef min
16 #define min(a,b)   ((a) < (b) ? (a) : (b))
17 #endif
18
19 /* streaming i/o for afp_read. this is all from the perspective of the
20  * client. it basically does the reverse of dsi_write. on first entry,
21  * it will send off the header plus whatever is in its command
22  * buffer. it returns the amount of stuff still to be read
23  * (constrained by the buffer size). */
24 ssize_t dsi_readinit(DSI *dsi, void *buf, const size_t buflen,
25                     const size_t size, const int err)
26 {
27   const struct itimerval none = {{0, 0}, {0, 0}};
28
29   dsi->noreply = 1; /* we will handle our own replies */
30   dsi->header.dsi_flags = DSIFL_REPLY;
31   /*dsi->header.dsi_command = DSIFUNC_CMD;*/
32   dsi->header.dsi_len = htonl(size);
33   dsi->header.dsi_code = htonl(err);
34
35   sigprocmask(SIG_BLOCK, &dsi->sigblockset, NULL);
36   setitimer(ITIMER_REAL, &none, &dsi->savetimer);
37   if (dsi_stream_send(dsi, buf, buflen)) {
38     dsi->datasize = size - buflen;
39     return min(dsi->datasize, buflen);
40   }
41
42   return -1; /* error */
43 }
44
45 void dsi_readdone(DSI *dsi)
46 {
47   setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
48   sigprocmask(SIG_UNBLOCK, &dsi->sigblockset, NULL);
49 }
50
51 /* send off the data */
52 ssize_t dsi_read(DSI *dsi, void *buf, const size_t buflen)
53 {
54   size_t len = dsi_stream_write(dsi, buf, buflen);
55
56   if (len == buflen) {
57     dsi->datasize -= len;
58     return min(dsi->datasize, buflen);
59   }
60
61   return -1;
62 }