]> arthur.barton.de Git - netatalk.git/blob - libatalk/dsi/dsi_write.c
implemented config.h
[netatalk.git] / libatalk / dsi / dsi_write.c
1 /*
2  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
3  * All rights reserved. See COPYRIGHT.
4  *
5  * 7 Oct 1997 added checks for 0 data.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 /* this streams writes */
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <sys/time.h>
18 #include <fcntl.h>
19 #include <string.h>
20
21 #include <atalk/dsi.h>
22 #include <netatalk/endian.h>
23
24 #ifndef MIN
25 #define MIN(a,b)     ((a) < (b) ? (a) : (b))
26 #endif
27
28 /* initialize relevant things for dsi_write. this returns the amount
29  * of data in the data buffer. the interface has been reworked to allow
30  * for arbitrary buffers. */
31 size_t dsi_writeinit(DSI *dsi, void *buf, const size_t buflen)
32 {
33   const struct itimerval none = {{0, 0}, {0, 0}};
34   size_t len, header;
35
36   /* figure out how much data we have. do a couple checks for 0 
37    * data */
38   header = ntohl(dsi->header.dsi_code);
39   dsi->datasize = header ? ntohl(dsi->header.dsi_len) - header : 0;
40   if (dsi->datasize > 0) {
41     len = MIN(sizeof(dsi->commands) - header, dsi->datasize);
42     
43     /* write last part of command buffer into buf */
44     memcpy(buf, dsi->commands + header, len);
45     
46     /* recalculate remaining data */
47     dsi->datasize -= len;
48   } else
49     len = 0;
50
51   /* deal with signals. i'm doing it this way to ensure that we don't
52    * get confused if a writeflush on zero remaining data is, for some
53    * reason, needed. */
54   sigprocmask(SIG_BLOCK, &dsi->sigblockset, NULL);
55   setitimer(ITIMER_REAL, &none, &dsi->savetimer);
56   return len;
57 }
58
59 /* fill up buf and then return. this should be called repeatedly
60  * until all the data has been read. i block alarm processing 
61  * during the transfer to avoid sending unnecessary tickles. */
62 size_t dsi_write(DSI *dsi, void *buf, const size_t buflen)
63 {
64   size_t length;
65
66   if (((length = MIN(buflen, dsi->datasize)) > 0) &&
67       ((length = dsi_stream_read(dsi, buf, length)) > 0)) {
68     dsi->datasize -= length;
69     return length;
70   }
71
72   setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
73   sigprocmask(SIG_UNBLOCK, &dsi->sigblockset, NULL);
74   return 0;
75 }
76
77 /* flush any unread buffers. */
78 void dsi_writeflush(DSI *dsi)
79 {
80   size_t length;
81
82   while (dsi->datasize > 0) { 
83     length = dsi_stream_read(dsi, dsi->data,
84                              MIN(sizeof(dsi->data), dsi->datasize));
85     if (length > 0)
86       dsi->datasize -= length;
87     else
88       break;
89   }
90
91   setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
92   sigprocmask(SIG_UNBLOCK, &dsi->sigblockset, NULL);
93 }