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