$treeview $search $mathjax $extrastylesheet
librsync
2.0.2
$projectbrief
|
$projectbrief
|
$searchbox |
00001 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 * 00003 * librsync -- library for network deltas 00004 * 00005 * Copyright (C) 1999, 2000, 2001 by Martin Pool <mbp@sourcefrog.net> 00006 * Copyright (C) 1999 by Andrew Tridgell <tridge@samba.org> 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation; either version 2.1 of 00011 * the License, or (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00021 */ 00022 00023 /*= 00024 | Ummm, well, OK. The network's the 00025 | network, the computer's the 00026 | computer. Sorry for the confusion. 00027 | -- Sun Microsystems 00028 */ 00029 00030 /** \file netint.c Network-byte-order output to the tube. 00031 * 00032 * All the `suck' routines return a result code. The most common values are 00033 * RS_DONE if they have enough data, or RS_BLOCKED if there is not enough input 00034 * to proceed. 00035 * 00036 * All the netint operations are done in a fairly simpleminded way, since we 00037 * don't want to rely on stdint types that may not be available on some 00038 * platforms. 00039 * 00040 * \todo If we don't have <stdint.h> (or perhaps even if we do), determine 00041 * endianness and integer size by hand and use that to do our own conversion 00042 * routines. We possibly need this anyhow to do 64-bit integers, since there 00043 * seems to be no ntohs() analog. */ 00044 00045 #include "config.h" 00046 00047 #include <assert.h> 00048 #include <sys/types.h> 00049 #include <stdlib.h> 00050 #include <stdio.h> 00051 #include <string.h> 00052 00053 #include "librsync.h" 00054 00055 #include "job.h" 00056 #include "netint.h" 00057 #include "trace.h" 00058 #include "stream.h" 00059 00060 #define RS_MAX_INT_BYTES 8 00061 00062 /** Write a single byte to a stream output. */ 00063 rs_result rs_squirt_byte(rs_job_t *job, unsigned char d) 00064 { 00065 rs_tube_write(job, &d, 1); 00066 return RS_DONE; 00067 } 00068 00069 /** Write a variable-length integer to a stream. 00070 * 00071 * \param job Job of data. 00072 * 00073 * \param d Datum to write out. 00074 * 00075 * \param len Length of integer, in bytes. */ 00076 rs_result rs_squirt_netint(rs_job_t *job, rs_long_t d, int len) 00077 { 00078 unsigned char buf[RS_MAX_INT_BYTES]; 00079 int i; 00080 00081 if (len <= 0 || len > RS_MAX_INT_BYTES) { 00082 rs_error("Illegal integer length %d", len); 00083 return RS_INTERNAL_ERROR; 00084 } 00085 00086 /* Fill the output buffer with a bigendian representation of the number. */ 00087 for (i = len - 1; i >= 0; i--) { 00088 buf[i] = d; /* truncated */ 00089 d >>= 8; 00090 } 00091 00092 rs_tube_write(job, buf, len); 00093 00094 return RS_DONE; 00095 } 00096 00097 rs_result rs_squirt_n4(rs_job_t *job, int val) 00098 { 00099 return rs_squirt_netint(job, val, 4); 00100 } 00101 00102 rs_result rs_suck_netint(rs_job_t *job, rs_long_t *v, int len) 00103 { 00104 unsigned char *buf; 00105 int i; 00106 rs_result result; 00107 00108 if (len <= 0 || len > RS_MAX_INT_BYTES) { 00109 rs_error("Illegal integer length %d", len); 00110 return RS_INTERNAL_ERROR; 00111 } 00112 00113 if ((result = rs_scoop_read(job, len, (void **)&buf)) != RS_DONE) 00114 return result; 00115 00116 *v = 0; 00117 00118 for (i = 0; i < len; i++) { 00119 *v = *v << 8 | buf[i]; 00120 } 00121 00122 return RS_DONE; 00123 } 00124 00125 rs_result rs_suck_byte(rs_job_t *job, unsigned char *v) 00126 { 00127 void *inb; 00128 rs_result result; 00129 00130 if ((result = rs_scoop_read(job, 1, &inb)) == RS_DONE) 00131 *v = *((unsigned char *)inb); 00132 00133 return result; 00134 } 00135 00136 rs_result rs_suck_n4(rs_job_t *job, int *v) 00137 { 00138 rs_result result; 00139 rs_long_t d; 00140 00141 result = rs_suck_netint(job, &d, 4); 00142 *v = d; 00143 return result; 00144 } 00145 00146 int rs_int_len(rs_long_t val) 00147 { 00148 if (!(val & ~(rs_long_t)0xff)) 00149 return 1; 00150 else if (!(val & ~(rs_long_t)0xffff)) 00151 return 2; 00152 else if (!(val & ~(rs_long_t)0xffffffff)) 00153 return 4; 00154 else if (!(val & ~(rs_long_t)0xffffffffffffffff)) 00155 return 8; 00156 else { 00157 rs_fatal("can't encode integer " FMT_LONG " yet", val); 00158 return -1; 00159 } 00160 }