1/*
2 * $Id: dsi_write.c,v 1.5 2009-10-20 04:31:41 didg Exp $
3 *
4 * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
5 * All rights reserved. See COPYRIGHT.
6 *
7 * 7 Oct 1997 added checks for 0 data.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif /* HAVE_CONFIG_H */
13
14/* this streams writes */
15#include <stdio.h>
16#ifdef HAVE_UNISTD_H
17#include <unistd.h>
18#endif /* HAVE_UNISTD_H */
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <sys/time.h>
22#ifdef HAVE_FCNTL_H
23#include <fcntl.h>
24#endif /* HAVE_FCNTL_H */
25#include <string.h>
26
27#include <atalk/dsi.h>
28#include <netatalk/endian.h>
29
30#ifndef MIN
31#define MIN(a,b)     ((a) < (b) ? (a) : (b))
32#endif /* ! MIN */
33
34/* initialize relevant things for dsi_write. this returns the amount
35 * of data in the data buffer. the interface has been reworked to allow
36 * for arbitrary buffers. */
37size_t dsi_writeinit(DSI *dsi, void *buf, const size_t buflen _U_)
38{
39  size_t len, header;
40
41  /* figure out how much data we have. do a couple checks for 0
42   * data */
43  header = ntohl(dsi->header.dsi_code);
44  dsi->datasize = header ? ntohl(dsi->header.dsi_len) - header : 0;
45  if (dsi->datasize > 0) {
46    len = MIN(sizeof(dsi->commands) - header, dsi->datasize);
47
48    /* write last part of command buffer into buf */
49    memcpy(buf, dsi->commands + header, len);
50
51    /* recalculate remaining data */
52    dsi->datasize -= len;
53  } else
54    len = 0;
55
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. */
62size_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  return 0;
72}
73
74/* flush any unread buffers. */
75void dsi_writeflush(DSI *dsi)
76{
77  size_t length;
78
79  while (dsi->datasize > 0) {
80    length = dsi_stream_read(dsi, dsi->data,
81			     MIN(sizeof(dsi->data), dsi->datasize));
82    if (length > 0)
83      dsi->datasize -= length;
84    else
85      break;
86  }
87}
88