]> arthur.barton.de Git - netatalk.git/blob - libatalk/dsi/dsi_read.c
92dd7eef8dff11b7a4d29fbe46549ad433b31012
[netatalk.git] / libatalk / dsi / dsi_read.c
1 /*
2  * $Id: dsi_read.c,v 1.4 2005-04-28 20:50:02 bfernhomberg 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 <sys/ioctl.h> 
26
27 #ifndef min
28 #define min(a,b)   ((a) < (b) ? (a) : (b))
29 #endif /* ! min */
30
31 /* streaming i/o for afp_read. this is all from the perspective of the
32  * client. it basically does the reverse of dsi_write. on first entry,
33  * it will send off the header plus whatever is in its command
34  * buffer. it returns the amount of stuff still to be read
35  * (constrained by the buffer size). */
36 ssize_t dsi_readinit(DSI *dsi, void *buf, const size_t buflen,
37                     const size_t size, const int err)
38 {
39 #ifdef TIMER_ON_WRITE
40   const struct itimerval none = {{0, 0}, {0, 0}};
41 #endif
42
43   dsi->noreply = 1; /* we will handle our own replies */
44   dsi->header.dsi_flags = DSIFL_REPLY;
45   /*dsi->header.dsi_command = DSIFUNC_CMD;*/
46   dsi->header.dsi_len = htonl(size);
47   dsi->header.dsi_code = htonl(err);
48
49   sigprocmask(SIG_BLOCK, &dsi->sigblockset, &dsi->oldset);
50   dsi->sigblocked = 1;
51 #ifdef TIMER_ON_WRITE
52   setitimer(ITIMER_REAL, &none, &dsi->savetimer);
53 #endif  
54   if (dsi_stream_send(dsi, buf, buflen)) {
55     dsi->datasize = size - buflen;
56     return min(dsi->datasize, buflen);
57   }
58
59   return -1; /* error */
60 }
61
62 void dsi_readdone(DSI *dsi)
63 {
64 #ifdef TIMER_ON_WRITE
65   setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
66 #endif
67   sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
68   dsi->sigblocked = 0;
69 }
70
71 /* */
72 int dsi_block(DSI *dsi, const int mode)
73 {
74 #if 0
75     dsi->noblocking = mode;
76     return 0;
77 #else
78     int adr = mode;
79     int ret;
80     
81     ret = ioctl(dsi->socket, FIONBIO, &adr);
82     if (!ret) {
83         dsi->noblocking = mode;
84     }
85     return ret;
86 #endif    
87 }
88
89 /* send off the data */
90 ssize_t dsi_read(DSI *dsi, void *buf, const size_t buflen)
91 {
92   size_t len;
93   int delay = (dsi->datasize != buflen)?1:0;
94   
95   len  = dsi_stream_write(dsi, buf, buflen, delay);
96
97   if (len == buflen) {
98     dsi->datasize -= len;
99     return min(dsi->datasize, buflen);
100   }
101
102   return -1;
103 }