librsync  2.0.2
netint.c
Go to the documentation of this file.
1 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  *
3  * librsync -- library for network deltas
4  *
5  * Copyright (C) 1999, 2000, 2001 by Martin Pool <mbp@sourcefrog.net>
6  * Copyright (C) 1999 by Andrew Tridgell <tridge@samba.org>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23  /*=
24  | Ummm, well, OK. The network's the
25  | network, the computer's the
26  | computer. Sorry for the confusion.
27  | -- Sun Microsystems
28  */
29 
30 /** \file netint.c Network-byte-order output to the tube.
31  *
32  * All the `suck' routines return a result code. The most common values are
33  * RS_DONE if they have enough data, or RS_BLOCKED if there is not enough input
34  * to proceed.
35  *
36  * All the netint operations are done in a fairly simpleminded way, since we
37  * don't want to rely on stdint types that may not be available on some
38  * platforms.
39  *
40  * \todo If we don't have <stdint.h> (or perhaps even if we do), determine
41  * endianness and integer size by hand and use that to do our own conversion
42  * routines. We possibly need this anyhow to do 64-bit integers, since there
43  * seems to be no ntohs() analog. */
44 
45 #include "config.h"
46 
47 #include <assert.h>
48 #include <sys/types.h>
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <string.h>
52 
53 #include "librsync.h"
54 
55 #include "job.h"
56 #include "netint.h"
57 #include "trace.h"
58 #include "stream.h"
59 
60 #define RS_MAX_INT_BYTES 8
61 
62 /** Write a single byte to a stream output. */
63 rs_result rs_squirt_byte(rs_job_t *job, unsigned char d)
64 {
65  rs_tube_write(job, &d, 1);
66  return RS_DONE;
67 }
68 
69 /** Write a variable-length integer to a stream.
70  *
71  * \param job Job of data.
72  *
73  * \param d Datum to write out.
74  *
75  * \param len Length of integer, in bytes. */
76 rs_result rs_squirt_netint(rs_job_t *job, rs_long_t d, int len)
77 {
78  unsigned char buf[RS_MAX_INT_BYTES];
79  int i;
80 
81  if (len <= 0 || len > RS_MAX_INT_BYTES) {
82  rs_error("Illegal integer length %d", len);
83  return RS_INTERNAL_ERROR;
84  }
85 
86  /* Fill the output buffer with a bigendian representation of the number. */
87  for (i = len - 1; i >= 0; i--) {
88  buf[i] = d; /* truncated */
89  d >>= 8;
90  }
91 
92  rs_tube_write(job, buf, len);
93 
94  return RS_DONE;
95 }
96 
97 rs_result rs_squirt_n4(rs_job_t *job, int val)
98 {
99  return rs_squirt_netint(job, val, 4);
100 }
101 
102 rs_result rs_suck_netint(rs_job_t *job, rs_long_t *v, int len)
103 {
104  unsigned char *buf;
105  int i;
106  rs_result result;
107 
108  if (len <= 0 || len > RS_MAX_INT_BYTES) {
109  rs_error("Illegal integer length %d", len);
110  return RS_INTERNAL_ERROR;
111  }
112 
113  if ((result = rs_scoop_read(job, len, (void **)&buf)) != RS_DONE)
114  return result;
115 
116  *v = 0;
117 
118  for (i = 0; i < len; i++) {
119  *v = *v << 8 | buf[i];
120  }
121 
122  return RS_DONE;
123 }
124 
125 rs_result rs_suck_byte(rs_job_t *job, unsigned char *v)
126 {
127  void *inb;
128  rs_result result;
129 
130  if ((result = rs_scoop_read(job, 1, &inb)) == RS_DONE)
131  *v = *((unsigned char *)inb);
132 
133  return result;
134 }
135 
136 rs_result rs_suck_n4(rs_job_t *job, int *v)
137 {
138  rs_result result;
139  rs_long_t d;
140 
141  result = rs_suck_netint(job, &d, 4);
142  *v = d;
143  return result;
144 }
145 
146 int rs_int_len(rs_long_t val)
147 {
148  if (!(val & ~(rs_long_t)0xff))
149  return 1;
150  else if (!(val & ~(rs_long_t)0xffff))
151  return 2;
152  else if (!(val & ~(rs_long_t)0xffffffff))
153  return 4;
154  else if (!(val & ~(rs_long_t)0xffffffffffffffff))
155  return 8;
156  else {
157  rs_fatal("can't encode integer " FMT_LONG " yet", val);
158  return -1;
159  }
160 }
logging functions.
rs_result rs_squirt_netint(rs_job_t *job, rs_long_t d, int len)
Write a variable-length integer to a stream.
Definition: netint.c:76
Public header for librsync.
rs_result
Return codes from nonblocking rsync operations.
Definition: librsync.h:161
rs_result rs_scoop_read(rs_job_t *job, size_t len, void **ptr)
Read LEN bytes if possible, and remove them from the input scoop.
Definition: scoop.c:190
Probably a library bug.
Definition: librsync.h:180
rs_result rs_squirt_byte(rs_job_t *job, unsigned char d)
Write a single byte to a stream output.
Definition: netint.c:63
Completed successfully.
Definition: librsync.h:162
void rs_tube_write(rs_job_t *job, const void *buf, size_t len)
Push some data into the tube for storage.
Definition: tube.c:211
of this structure are private.
Definition: job.h:26