Filewatcher File Search
FTP Search
  
Directory 
  
Content Search 
   
pkg://rsync-2.5.7-1.src.rpm:614564/rsync-2.5.7.tar.gz  info  downloads

rsync-2.5.7/0040755000111500011410000000000007763533656012714 5ustar  rsync-bugsrsyncrsync-2.5.7/doc/0040755000111500011150000000000007763533641014412 5ustar  rsync-bugsrsync-bugsrsync-2.5.7/doc/.cvsignore0100644000111500011150000000002307447511163016374 0ustar  rsync-bugsrsync-bugsrsync.pdf
rsync.ps
rsync-2.5.7/doc/README-SGML0100644000111500011150000000124007442774776016036 0ustar  rsync-bugsrsync-bugsHandling the rsync SGML documentation

rsync documentation is now primarily in Docbook format.  Docbook is an
SGML/XML documentation format that is becoming standard on free
operating systems.  It's also used for Samba documentation.

The SGML files are source code that can be translated into various
useful output formats, primarily PDF, HTML, Postscript and plain text.  

To do this transformation on Debian, you should install the
docbook-utils package.  Having done that, you can say 

  docbook2pdf rsync.sgml

and so on.

On other systems you probably need James Clark's "sp" and "JadeTeX"
packages.  Work it out for yourself and send a note to the mailing
list.

rsync-2.5.7/doc/profile.txt0100644000111500011150000000361707436476451016621 0ustar  rsync-bugsrsync-bugsNotes on rsync profiling

strlcpy is hot:

                0.00    0.00       1/7735635     push_dir [68]
                0.00    0.00       1/7735635     pop_dir [71]
                0.00    0.00       1/7735635     send_file_list [15]
                0.01    0.00   18857/7735635     send_files [4]
                0.04    0.00  129260/7735635     send_file_entry [18]
                0.04    0.00  129260/7735635     make_file [20]
                0.04    0.00  141666/7735635     send_directory <cycle 1> [36]
                2.29    0.00 7316589/7735635     f_name [13]
[14]    11.7    2.42    0.00 7735635         strlcpy [14]


Here's the top few functions:

 46.23      9.57     9.57 13160929     0.00     0.00  mdfour64
 14.78     12.63     3.06 13160929     0.00     0.00  copy64
 11.69     15.05     2.42  7735635     0.00     0.00  strlcpy
 10.05     17.13     2.08    41438     0.05     0.38  sum_update
  4.11     17.98     0.85 13159996     0.00     0.00  mdfour_update
  1.50     18.29     0.31                             file_compare
  1.45     18.59     0.30   129261     0.00     0.01  send_file_entry
  1.23     18.84     0.26  2557585     0.00     0.00  f_name
  1.11     19.07     0.23  1483750     0.00     0.00  u_strcmp
  1.11     19.30     0.23   118129     0.00     0.00  writefd_unbuffered
  0.92     19.50     0.19  1085011     0.00     0.00  writefd
  0.43     19.59     0.09   156987     0.00     0.00  read_timeout
  0.43     19.68     0.09   129261     0.00     0.00  clean_fname
  0.39     19.75     0.08    32887     0.00     0.38  matched
  0.34     19.82     0.07        1    70.00 16293.92  send_files
  0.29     19.89     0.06   129260     0.00     0.00  make_file
  0.29     19.95     0.06    75430     0.00     0.00  read_unbuffered



mdfour could perhaps be made faster:

/* NOTE: This code makes no attempt to be fast!  */

There might be an optimized version somewhere that we can borrow.
rsync-2.5.7/doc/rsync.sgml0100644000111500011150000002710307446544364016436 0ustar  rsync-bugsrsync-bugs<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
<book id="rsync">
  <bookinfo>
    <title>rsync</title>
    <copyright>
      <year>1996 -- 2002</year>
      <holder>Martin Pool</holder>
      <holder>Andrew Tridgell</holder>
    </copyright>
    <author>
      <firstname>Martin</firstname>
      <surname>Pool</surname>
    </author>
  </bookinfo>

  <chapter>
    <title>Introduction</title>

    <para>rsync is a flexible program for efficiently copying files or
      directory trees.

    <para>rsync has many options to select which files will be copied
      and how they are to be transferred.  It may be used as an
      alternative to ftp, http, scp or rcp.

    <para>The rsync remote-update protocol allows rsync to transfer just
      the differences between two sets of files across the network link,
      using an efficient checksum-search algorithm described in the
      technical report that accompanies this package.</para>

    <para>Some of the additional features of rsync are:</para>

    <itemizedlist>
      
      <listitem>
	<para>support for copying links, devices, owners, groups and
	  permissions
	</para>
      </listitem>
      
      <listitem>
	<para>
	  exclude and exclude-from options similar to GNU tar
	</para>
      </listitem>

      <listitem>
	<para>
	  a CVS exclude mode for ignoring the same files that CVS would ignore
      </listitem>

      <listitem>
	<para>
	  can use any transparent remote shell, including rsh or ssh
      </listitem>

      <listitem>
	<para>
	  does not require root privileges
      </listitem>

      <listitem>
	<para>
	  pipelining of file transfers to minimize latency costs
      </listitem>
		
      <listitem>
	<para>
	  support for anonymous or authenticated rsync servers (ideal for
	  mirroring)
	</para>
      </listitem>
    </itemizedlist>
  </chapter>



  <chapter>
    <title>Using rsync</title>
    <section>
      <title>
	Introductory example
      </title>
      
      <para>
	Probably the most common case of rsync usage is to copy files
	to or from a remote machine using
	<application>ssh</application> as a network transport.  In
	this situation rsync is a good alternative to
	<application>scp</application>.
      </para>

      <para>
	The most commonly used arguments for rsync are
      </para>

      <variablelist>
	<varlistentry>
	  <term><option>-v</option></term>
	  <listitem>
	    <para>Be verbose.  Primarily, display the name of each file as it is copied.</para>
	  </listitem>
	</varlistentry>


	<varlistentry>
	  <term><option>-a</option></term>
	  <listitem>
	    <para>
	      Reproduce the structure and attributes of the origin files as exactly
	      as possible: this includes copying subdirectories, symlinks, special
	      files, ownership and permissions.  (@xref{Attributes to
	      copy}.)
	    </para>
	  </listitem>
	</varlistentry>
      </variablelist>


	
      <para><option>-v </option>
      
      <para><option>-z</option>
	Compress network traffic, using a modified version of the
	@command{zlib} library.</para>
      
      <para><option>-P</option>
	Display a progress indicator while files are transferred.  This should
	normally be ommitted if rsync is not run on a terminal.
      </para>
    </section>




    <section>
      <title>Local and remote</title>
      
      <para>There are six different ways of using rsync. They
      are:</para>

      

      <!-- one of (CALLOUTLIST GLOSSLIST ITEMIZEDLIST ORDEREDLIST SEGMENTEDLIST SIMPLELIST VARIABLELIST CAUTION IMPORTANT NOTE TIP WARNING LITERALLAYOUT PROGRAMLISTING PROGRAMLISTINGCO SCREEN SCREENCO SCREENSHOT SYNOPSIS CMDSYNOPSIS FUNCSYNOPSIS CLASSSYNOPSIS FIELDSYNOPSIS CONSTRUCTORSYNOPSIS DESTRUCTORSYNOPSIS METHODSYNOPSIS FORMALPARA PARA SIMPARA ADDRESS BLOCKQUOTE GRAPHIC GRAPHICCO MEDIAOBJECT MEDIAOBJECTCO INFORMALEQUATION INFORMALEXAMPLE INFORMALFIGURE INFORMALTABLE EQUATION EXAMPLE FIGURE TABLE MSGSET PROCEDURE SIDEBAR QANDASET ANCHOR BRIDGEHEAD REMARK HIGHLIGHTS ABSTRACT AUTHORBLURB EPIGRAPH INDEXTERM REFENTRY SECTION) -->
      <orderedlist>
	<listitem>
	  <para>
	    for copying local files. This is invoked when neither
	    source nor destination path contains a @code{:} separator

	<listitem>
	  <para>
	    for copying from the local machine to a remote machine using
	    a remote shell program as the transport (such as rsh or
	    ssh). This is invoked when the destination path contains a
	    single @code{:} separator.

	<listitem>
	  <para>
	    for copying from a remote machine to the local machine
	    using a remote shell program. This is invoked when the source
	    contains a @code{:} separator.

	<listitem>
	  <para>
	    for copying from a remote rsync server to the local
	    machine. This is invoked when the source path contains a @code{::}
	    separator or a @code{rsync://} URL.

	<listitem>
	  <para>
	    for copying from the local machine to a remote rsync
	    server. This is invoked when the destination path contains a @code{::}
	    separator.

	<listitem>
	  <para>
	    for listing files on a remote machine. This is done the
	    same way as rsync transfers except that you leave off the
	    local destination.  

	</listitem>
      </orderedlist>
	  <para>
Note that in all cases (other than listing) at least one of the source
and destination paths must be local.

	  <para>
Any one invocation of rsync makes a copy in a single direction.  rsync
currently has no equivalent of @command{ftp}'s interactive mode.

@cindex @sc{nfs}
@cindex network filesystems
@cindex remote filesystems

	  <para>
rsync's network protocol is generally faster at copying files than
network filesystems such as @sc{nfs} or @sc{cifs}.  It is better to
run rsync on the file server either as a daemon or over ssh than
running rsync giving the network directory.
      </para>
    </section>
  </chapter>



  <chapter>
    <title>Frequently asked questions</title>

    
    <!-- one of (CALLOUTLIST GLOSSLIST ITEMIZEDLIST ORDEREDLIST SEGMENTEDLIST SIMPLELIST VARIABLELIST CAUTION IMPORTANT NOTE TIP WARNING LITERALLAYOUT PROGRAMLISTING PROGRAMLISTINGCO SCREEN SCREENCO SCREENSHOT SYNOPSIS CMDSYNOPSIS FUNCSYNOPSIS CLASSSYNOPSIS FIELDSYNOPSIS CONSTRUCTORSYNOPSIS DESTRUCTORSYNOPSIS METHODSYNOPSIS FORMALPARA PARA SIMPARA ADDRESS BLOCKQUOTE GRAPHIC GRAPHICCO MEDIAOBJECT MEDIAOBJECTCO INFORMALEQUATION INFORMALEXAMPLE INFORMALFIGURE INFORMALTABLE EQUATION EXAMPLE FIGURE TABLE MSGSET PROCEDURE SIDEBAR QANDASET ANCHOR BRIDGEHEAD REMARK HIGHLIGHTS ABSTRACT AUTHORBLURB EPIGRAPH INDEXTERM SECTION SIMPLESECT REFENTRY SECT1) -->
    <qandaset>
      <!-- one of (QANDADIV QANDAENTRY) -->

      <qandaentry>
	<question>
	  <!-- one of (CALLOUTLIST GLOSSLIST ITEMIZEDLIST ORDEREDLIST
	  SEGMENTEDLIST SIMPLELIST VARIABLELIST CAUTION IMPORTANT NOTE
	  TIP WARNING LITERALLAYOUT PROGRAMLISTING PROGRAMLISTINGCO
	  SCREEN SCREENCO SCREENSHOT SYNOPSIS CMDSYNOPSIS FUNCSYNOPSIS
	  CLASSSYNOPSIS FIELDSYNOPSIS CONSTRUCTORSYNOPSIS
	  DESTRUCTORSYNOPSIS METHODSYNOPSIS FORMALPARA PARA SIMPARA
	  ADDRESS BLOCKQUOTE GRAPHIC GRAPHICCO MEDIAOBJECT
	  MEDIAOBJECTCO INFORMALEQUATION INFORMALEXAMPLE
	  INFORMALFIGURE INFORMALTABLE EQUATION EXAMPLE FIGURE TABLE
	  PROCEDURE ANCHOR BRIDGEHEAD REMARK HIGHLIGHTS INDEXTERM) -->
	  <para>Are there mailing lists for rsync?
	</question>

	<answer>
	  <para>Yes, and you can subscribe and unsubscribe through a
	  web interface at
	    <ulink
	      url="http://lists.samba.org/">http://lists.samba.org/</ulink>
	  </para>

	  <para>
	    If you are having trouble with the mailing list, please
	    send mail to the administrator
	    
	    <email>rsync-admin@lists.samba.org</email>

	    not to the list itself.
	  </para>

	  <para>
	    The mailing list archives are searchable.  Use 
	    <ulink url="http://google.com/">Google</ulink> and prepend
	    the search with <userinput>site:lists.samba.org
	    rsync</userinput>, plus relevant keywords.
	  </para>
	</answer>
      </qandaentry>


      <qandaentry>
	<question>
	  <para>
	    Why is rsync so much bigger when I build it with
	    <command>gcc</command>?
	  </para>
	</question>
	<answer>
	  <para>
	    On gcc, rsync builds by default with debug symbols
	    included.  If you strip both executables, they should end
	    up about the same size.  (Use <command>make
	    install-strip</command>.)
	  </para>
	</answer>
      </qandaentry>

      
      <qandaentry>
	<question>
	  <para>Is rsync useful for a single large file like an ISO image?</para>
	</question>
	<answer>
	  <para>
	    Yes, but note the following:

	  <para>
   Background: A common use of rsync is to update a file (or set of files) in one location from a more
   correct or up-to-date copy in another location, taking advantage of portions of the files that are
   identical to speed up the process. (Note that rsync will transfer a file in its entirety if no copy
   exists at the destination.)

	  <para>
   (This discussion is written in terms of updating a local copy of a file from a correct file in a
   remote location, although rsync can work in either direction.)

	  <para>
   The file to be updated (the local file) must be in a destination directory that has enough space for
   two copies of the file. (In addition, keep an extra copy of the file to be updated in a different
   location for safety -- see the discussion (below) about rsync's behavior when the rsync process is
   interrupted before completion.)

	  <para>
   The local file must have the same name as the remote file being sync'd to (I think?). If you are
   trying to upgrade an iso from, for example, beta1 to beta2, rename the local file to the same name
   as the beta2 file. *(This is a useful thing to do -- only the changed portions will be
   transmitted.)*

	  <para>
   The extra copy of the local file kept in a different location is because of rsync's behavior if
   interrupted before completion:

	  <para>
   * If you specify the --partial option and rsync is interrupted, rsync will save the partially
   rsync'd file and throw away the original local copy. (The partially rsync'd file is correct but
   truncated.) If rsync is restarted, it will not have a local copy of the file to check for duplicate
   blocks beyond the section of the file that has already been rsync'd, thus the remainder of the rsync
   process will be a "pure transfer" of the file rather than taking advantage of the rsync algorithm.

	  <para>
   * If you don't specify the --partial option and rsync is interrupted, rsync will throw away the
   partially rsync'd file, and, when rsync is restarted starts the rsync process over from the
   beginning.

	  <para>
   Which of these is most desirable depends on the degree of commonality between the local and remote
   copies of the file *and how much progress was made before the interruption*.

	  <para>
   The ideal approach after an interruption would be to create a new file by taking the original file
   and deleting a portion equal in size to the portion already rsync'd and then appending *the
   remaining* portion to the portion of the file that has already been rsync'd. (There has been some
   discussion about creating an option to do this automatically.)

   The --compare-dest option is useful when transferring multiple files, but is of no benefit in
   transferring a single file. (AFAIK)

   *Other potentially useful information can be found at:
   -[3]http://twiki.org/cgi-bin/view/Wikilearn/RsyncingALargeFile

   This answer, formatted with "real" bullets, can be found at:
   -[4]http://twiki.org/cgi-bin/view/Wikilearn/RsyncingALargeFileFAQ*

	  </para>
	</answer>
      </qandaentry>
    </qandaset>
  </chapter>


  <appendix>
    <title>Other Resources</title>
    
    <para><ulink url="http://www.ccp14.ac.uk/ccp14admin/rsync/"></ulink></para>
  </appendix>
</book>rsync-2.5.7/lib/0040755000111500011410000000000007763533616013456 5ustar  rsync-bugsrsyncrsync-2.5.7/lib/getaddrinfo.c0100644000111500011150000003455307763533616017056 0ustar  rsync-bugsrsync-bugs/*
 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 *
 * Changes Copyright (C) 2001 by Martin Pool <mbp@samba.org>
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
 *
 * Issues to be discussed:
 * - Thread safe-ness must be checked.
 * - Return values.  There are nonstandard return values defined and used
 *   in the source code.  This is because RFC2133 is silent about which error
 *   code must be returned for which situation.
 * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag.
 */

#include <rsync.h>

#if defined(__KAME__) && defined(INET6)
# define FAITH
#endif

#define SUCCESS 0
#define ANY 0
#define YES 1
#define NO  0

#ifdef FAITH
static int translate = NO;
static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT;
#endif /* FAITH */

/* Amdahl's UTS 2.1.2 defines NO_ADDRESS instead of NO_DATA. */

#ifndef NO_DATA
#ifdef NO_ADDRESS
#define NO_DATA NO_ADDRESS
#endif
#endif /* ndef NO_DATA */

static const char in_addrany[] = { 0, 0, 0, 0 };
static const char in6_addrany[] = {
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static const char in_loopback[] = { 127, 0, 0, 1 }; 
static const char in6_loopback[] = {
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
};

struct sockinet {
	u_char	si_len;
	u_char	si_family;
	u_short	si_port;
};

static struct afd {
	int a_af;
	int a_addrlen;
	int a_socklen;
	int a_off;
	const char *a_addrany;
	const char *a_loopback;	
} afdl [] = {
#ifdef INET6
#define N_INET6 0
	{PF_INET6, sizeof(struct in6_addr),
	 sizeof(struct sockaddr_in6),
	 offsetof(struct sockaddr_in6, sin6_addr),
	 in6_addrany, in6_loopback},
#define N_INET  1
#else
#define N_INET  0
#endif
	{PF_INET, sizeof(struct in_addr),
	 sizeof(struct sockaddr_in),
	 offsetof(struct sockaddr_in, sin_addr),
	 in_addrany, in_loopback},
	{0, 0, 0, 0, NULL, NULL},
};

#ifdef INET6
#define PTON_MAX	16
#else
#define PTON_MAX	4
#endif


static int get_name (const char *, struct afd *,
		     struct addrinfo **, char *, struct addrinfo *,
		     int);
static int get_addr (const char *, int, struct addrinfo **,
			struct addrinfo *, int);
static int str_isnumber (const char *);
	
static char *ai_errlist[] = {
	"success.",
	"address family for hostname not supported.",	/* EAI_ADDRFAMILY */
	"temporary failure in name resolution.",	/* EAI_AGAIN      */
	"invalid value for ai_flags.",		       	/* EAI_BADFLAGS   */
	"non-recoverable failure in name resolution.", 	/* EAI_FAIL       */
	"ai_family not supported.",			/* EAI_FAMILY     */
	"memory allocation failure.", 			/* EAI_MEMORY     */
	"no address associated with hostname.", 	/* EAI_NODATA     */
	"hostname nor servname provided, or not known.",/* EAI_NONAME     */
	"servname not supported for ai_socktype.",	/* EAI_SERVICE    */
	"ai_socktype not supported.", 			/* EAI_SOCKTYPE   */
	"system error returned in errno.", 		/* EAI_SYSTEM     */
	"invalid value for hints.",			/* EAI_BADHINTS	  */
	"resolved protocol is unknown.",		/* EAI_PROTOCOL   */
	"unknown error.", 				/* EAI_MAX        */
};

#define GET_CANONNAME(ai, str) \
if (pai->ai_flags & AI_CANONNAME) {\
	if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\
		strcpy((ai)->ai_canonname, (str));\
	} else {\
		error = EAI_MEMORY;\
		goto free;\
	}\
}


static int get_ai(struct addrinfo ** to_ai,
		   struct addrinfo const * pai,
		   struct afd *afd,
		   const char *addr,
		   short port)
{
	char *p;
	if ((*to_ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) +
					      ((afd)->a_socklen)))
	    == NULL) 
		return 0;
	memcpy(*to_ai, pai, sizeof(struct addrinfo));
	(*to_ai)->ai_addr = (struct sockaddr *)((*to_ai) + 1);
	memset((*to_ai)->ai_addr, 0, (afd)->a_socklen);
	(*to_ai)->ai_addrlen = (afd)->a_socklen;
#if HAVE_SOCKADDR_LEN
	(*to_ai)->ai_addr->sa_len= (afd)->a_socklen;
#endif
	(*to_ai)->ai_addr->sa_family = (*to_ai)->ai_family = (afd)->a_af;
	((struct sockinet *)(*to_ai)->ai_addr)->si_port = port;
	p = (char *)((*to_ai)->ai_addr);
	memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);
	return 1;
}

#define ERR(err) { error = (err); goto bad; }

char *
gai_strerror(ecode)
	int ecode;
{
	if (ecode < 0 || ecode > EAI_MAX)
		ecode = EAI_MAX;
	return ai_errlist[ecode];
}

void
freeaddrinfo(ai)
	struct addrinfo *ai;
{
	struct addrinfo *next;

	do {
		next = ai->ai_next;
		if (ai->ai_canonname)
			free(ai->ai_canonname);
		/* no need to free(ai->ai_addr) */
		free(ai);
	} while ((ai = next) != NULL);
}

static int
str_isnumber(p)
	const char *p;
{
	char *q = (char *)p;
	while (*q) {
		if (! isdigit(*q))
			return NO;
		q++;
	}
	return YES;
}

int
getaddrinfo(hostname, servname, hints, res)
	const char *hostname, *servname;
	const struct addrinfo *hints;
	struct addrinfo **res;
{
	struct addrinfo sentinel;
	struct addrinfo *top = NULL;
	struct addrinfo *cur;
	int i, error = 0;
	char pton[PTON_MAX];
	struct addrinfo ai;
	struct addrinfo *pai;
	u_short port;

#ifdef FAITH
	static int firsttime = 1;

	if (firsttime) {
		/* translator hack */
		{
			char *q = getenv("GAI");
			if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
				translate = YES;
		}
		firsttime = 0;
	}
#endif

	/* initialize file static vars */
	sentinel.ai_next = NULL;
	cur = &sentinel;
	pai = &ai;
	pai->ai_flags = 0;
	pai->ai_family = PF_UNSPEC;
	pai->ai_socktype = ANY;
	pai->ai_protocol = ANY;
	pai->ai_addrlen = 0;
	pai->ai_canonname = NULL;
	pai->ai_addr = NULL;
	pai->ai_next = NULL;
	port = ANY;
	
	if (hostname == NULL && servname == NULL)
		return EAI_NONAME;
	if (hints) {
		/* error check for hints */
		if (hints->ai_addrlen || hints->ai_canonname ||
		    hints->ai_addr || hints->ai_next)
			ERR(EAI_BADHINTS); /* xxx */
		if (hints->ai_flags & ~AI_MASK)
			ERR(EAI_BADFLAGS);
		switch (hints->ai_family) {
		case PF_UNSPEC:
		case PF_INET:
#ifdef INET6
		case PF_INET6:
#endif
			break;
		default:
			ERR(EAI_FAMILY);
		}
		memcpy(pai, hints, sizeof(*pai));
		switch (pai->ai_socktype) {
		case ANY:
			switch (pai->ai_protocol) {
			case ANY:
				break;
			case IPPROTO_UDP:
				pai->ai_socktype = SOCK_DGRAM;
				break;
			case IPPROTO_TCP:
				pai->ai_socktype = SOCK_STREAM;
				break;
			default:
				pai->ai_socktype = SOCK_RAW;
				break;
			}
			break;
		case SOCK_RAW:
			break;
		case SOCK_DGRAM:
			if (pai->ai_protocol != IPPROTO_UDP &&
			    pai->ai_protocol != ANY)
				ERR(EAI_BADHINTS);	/*xxx*/
			pai->ai_protocol = IPPROTO_UDP;
			break;
		case SOCK_STREAM:
			if (pai->ai_protocol != IPPROTO_TCP &&
			    pai->ai_protocol != ANY)
				ERR(EAI_BADHINTS);	/*xxx*/
			pai->ai_protocol = IPPROTO_TCP;
			break;
		default:
			ERR(EAI_SOCKTYPE);
			break;
		}
	}

	/*
	 * service port
	 */
	if (servname) {
		if (str_isnumber(servname)) {
			if (pai->ai_socktype == ANY) {
				/* caller accept *ANY* socktype */
				pai->ai_socktype = SOCK_DGRAM;
				pai->ai_protocol = IPPROTO_UDP;
			}
			port = htons(atoi(servname));
		} else {
			struct servent *sp;
			char *proto;

			proto = NULL;
			switch (pai->ai_socktype) {
			case ANY:
				proto = NULL;
				break;
			case SOCK_DGRAM:
				proto = "udp";
				break;
			case SOCK_STREAM:
				proto = "tcp";
				break;
			default:
				fprintf(stderr, "panic!\n");
				break;
			}
			if ((sp = getservbyname(servname, proto)) == NULL)
				ERR(EAI_SERVICE);
			port = sp->s_port;
			if (pai->ai_socktype == ANY) {
				if (strcmp(sp->s_proto, "udp") == 0) {
					pai->ai_socktype = SOCK_DGRAM;
					pai->ai_protocol = IPPROTO_UDP;
				} else if (strcmp(sp->s_proto, "tcp") == 0) {
					pai->ai_socktype = SOCK_STREAM;
					pai->ai_protocol = IPPROTO_TCP;
				} else
					ERR(EAI_PROTOCOL);	/*xxx*/
			}
		}
	}
	
	/*
	 * hostname == NULL.
	 * passive socket -> anyaddr (0.0.0.0 or ::)
	 * non-passive socket -> localhost (127.0.0.1 or ::1)
	 */
	if (hostname == NULL) {
		struct afd *afd;

		for (afd = &afdl[0]; afd->a_af; afd++) {
			if (!(pai->ai_family == PF_UNSPEC
			   || pai->ai_family == afd->a_af)) {
				continue;
			}

			if (pai->ai_flags & AI_PASSIVE) {
				if (!get_ai(&cur->ai_next, pai, afd, afd->a_addrany, port))
					goto free;
				/* xxx meaningless?
				 * GET_CANONNAME(cur->ai_next, "anyaddr");
				 */
			} else {
				if (!get_ai(&cur->ai_next, pai, afd, afd->a_loopback,
					port))
					goto free;
				/* xxx meaningless?
				 * GET_CANONNAME(cur->ai_next, "localhost");
				 */
			}
			cur = cur->ai_next;
		}
		top = sentinel.ai_next;
		if (top)
			goto good;
		else
			ERR(EAI_FAMILY);
	}
	
	/* hostname as numeric name */
	for (i = 0; afdl[i].a_af; i++) {
		if (inet_pton(afdl[i].a_af, hostname, pton)) {
			u_long v4a;

			switch (afdl[i].a_af) {
			case AF_INET:
				v4a = ((struct in_addr *)pton)->s_addr;
				if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
					pai->ai_flags &= ~AI_CANONNAME;
				v4a >>= IN_CLASSA_NSHIFT;
				if (v4a == 0 || v4a == IN_LOOPBACKNET)
					pai->ai_flags &= ~AI_CANONNAME;
				break;
#ifdef INET6
			case AF_INET6:
			{
				u_char pfx;
				pfx = ((struct in6_addr *)pton)->s6_addr[0];
				if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
					pai->ai_flags &= ~AI_CANONNAME;
				break;
			}
#endif
			}
			
			if (pai->ai_family == afdl[i].a_af ||
			    pai->ai_family == PF_UNSPEC) {
				if (! (pai->ai_flags & AI_CANONNAME)) {
					if (get_ai(&top, pai, &afdl[i], pton, port))
						goto good;
					else
						goto free;
				}
				/*
				 * if AI_CANONNAME and if reverse lookup
				 * fail, return ai anyway to pacify
				 * calling application.
				 *
				 * XXX getaddrinfo() is a name->address
				 * translation function, and it looks strange
				 * that we do addr->name translation here.
				 */
				get_name(pton, &afdl[i], &top, pton, pai, port);
				goto good;
			} else 
				ERR(EAI_FAMILY);	/*xxx*/
		}
	}

	if (pai->ai_flags & AI_NUMERICHOST)
		ERR(EAI_NONAME);

	/* hostname as alphabetical name */
	error = get_addr(hostname, pai->ai_family, &top, pai, port);
	if (error == 0) {
		if (top) {
 good:
			*res = top;
			return SUCCESS;
		} else
			error = EAI_FAIL;
	}
 free:
	if (top)
		freeaddrinfo(top);
 bad:
	*res = NULL;
	return error;
}

static int
get_name(addr, afd, res, numaddr, pai, port0)
	const char *addr;
	struct afd *afd;
	struct addrinfo **res;
	char *numaddr;
	struct addrinfo *pai;
	int port0;
{
	u_short port = port0 & 0xffff;
	struct hostent *hp;
	struct addrinfo *cur;
	int error = 0;
	
#ifdef INET6
	{
		int h_error;
		hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
	}
#else
	hp = gethostbyaddr(addr, afd->a_addrlen, AF_INET);
#endif
	if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
		if (!get_ai(&cur, pai, afd, hp->h_addr_list[0], port))
			goto free;
		GET_CANONNAME(cur, hp->h_name);
	} else {
		if (!get_ai(&cur, pai, afd, numaddr, port))
			goto free;
	}
	
#ifdef INET6
	if (hp)
		freehostent(hp);
#endif
	*res = cur;
	return SUCCESS;
 free:
	if (cur)
		freeaddrinfo(cur);
#ifdef INET6
	if (hp)
		freehostent(hp);
#endif
 /* bad: */
	*res = NULL;
	return error;
}

static int
get_addr(hostname, af, res, pai, port0)
	const char *hostname;
	int af;
	struct addrinfo **res;
	struct addrinfo *pai;
	int port0;
{
	u_short port = port0 & 0xffff;
	struct addrinfo sentinel;
	struct hostent *hp;
	struct addrinfo *top, *cur;
	struct afd *afd;
	int i, error = 0, h_error;
	char *ap;
#ifndef INET6
	extern int h_errno;
#endif

	top = NULL;
	sentinel.ai_next = NULL;
	cur = &sentinel;
#ifdef INET6
	if (af == AF_UNSPEC) {
		hp = getipnodebyname(hostname, AF_INET6,
				AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);
	} else
		hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);
#else
	hp = gethostbyname(hostname);
	h_error = h_errno;
#endif
	if (hp == NULL) {
		switch (h_error) {
		case HOST_NOT_FOUND:
		case NO_DATA:
			error = EAI_NODATA;
			break;
		case TRY_AGAIN:
			error = EAI_AGAIN;
			break;
		case NO_RECOVERY:
		default:
			error = EAI_FAIL;
			break;
		}
		goto bad;
	}

	if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
	    (hp->h_addr_list[0] == NULL))
		ERR(EAI_FAIL);
	
	for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {
		switch (af) {
#ifdef INET6
		case AF_INET6:
			afd = &afdl[N_INET6];
			break;
#endif
#ifndef INET6
		default:	/* AF_UNSPEC */
#endif
		case AF_INET:
			afd = &afdl[N_INET];
			break;
#ifdef INET6
		default:	/* AF_UNSPEC */
			if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
				ap += sizeof(struct in6_addr) -
					sizeof(struct in_addr);
				afd = &afdl[N_INET];
			} else
				afd = &afdl[N_INET6];
			break;
#endif
		}
#ifdef FAITH
		if (translate && afd->a_af == AF_INET) {
			struct in6_addr *in6;

			if (!get_ai(&cur->ai_next, pai, &afdl[N_INET6], ap, port))
				goto free;
			in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;
			memcpy(&in6->s6_addr32[0], &faith_prefix,
			    sizeof(struct in6_addr) - sizeof(struct in_addr));
			memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr));
		} else
#endif /* FAITH */
		if (!get_ai(&cur->ai_next, pai, afd, ap, port))
			goto free;
		if (cur == &sentinel) {
			top = cur->ai_next;
			GET_CANONNAME(top, hp->h_name);
		}
		cur = cur->ai_next;
	}
#ifdef INET6
	freehostent(hp);
#endif
	*res = top;
	return SUCCESS;
 free:
	if (top)
		freeaddrinfo(top);
#ifdef INET6
	if (hp)
		freehostent(hp);
#endif
 bad:
	*res = NULL;
	return error;
}
rsync-2.5.7/lib/addrinfo.h0100644000111500011150000001062007415001662016331 0ustar  rsync-bugsrsync-bugs/*
 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/**
 * @file addrinfo.h
 *
 * Replacement getaddrinfo() for machines that don't have it.  The new
 * getaddrinfo()/getnameinfo() interface is implemented on top of the
 * traditional resolver calls.
 **/

#ifndef HAVE_GETADDRINFO

#ifndef EAI_ADDRFAMILY
/*
 * Error return codes from getaddrinfo()
 */
#define	EAI_ADDRFAMILY	 1	/* address family for hostname not supported */
#define	EAI_AGAIN	 2	/* temporary failure in name resolution */
#define	EAI_BADFLAGS	 3	/* invalid value for ai_flags */
#define	EAI_FAIL	 4	/* non-recoverable failure in name resolution */
#define	EAI_FAMILY	 5	/* ai_family not supported */
#define	EAI_MEMORY	 6	/* memory allocation failure */
#define	EAI_NODATA	 7	/* no address associated with hostname */
#define	EAI_NONAME	 8	/* hostname nor servname provided, or not known */
#define	EAI_SERVICE	 9	/* servname not supported for ai_socktype */
#define	EAI_SOCKTYPE	10	/* ai_socktype not supported */
#define	EAI_SYSTEM	11	/* system error returned in errno */
#define EAI_BADHINTS	12
#define EAI_PROTOCOL	13
#define EAI_MAX		14
#endif /* ndef EAI_ADDRFAMILY */

/*
 * Flag values for getaddrinfo()
 */

#ifndef AI_PASSIVE

#define	AI_PASSIVE	0x00000001 /* get address to use bind() */
#define	AI_CANONNAME	0x00000002 /* fill ai_canonname */
#define	AI_NUMERICHOST	0x00000004 /* prevent name resolution */
/* valid flags for addrinfo */
#define	AI_MASK		(AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)

#define	AI_ALL		0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
#define	AI_V4MAPPED_CFG	0x00000200 /* accept IPv4-mapped if kernel supports */
#define	AI_ADDRCONFIG	0x00000400 /* only if any address is assigned */
#define	AI_V4MAPPED	0x00000800 /* accept IPv4-mapped IPv6 address */
/* special recommended flags for getipnodebyname */
#define	AI_DEFAULT	(AI_V4MAPPED_CFG | AI_ADDRCONFIG)

/*
 * Constants for getnameinfo()
 */
#define	NI_MAXHOST	1025
#define	NI_MAXSERV	32

/*
 * Flag values for getnameinfo()
 */
#define	NI_NOFQDN	0x00000001
#define	NI_NUMERICHOST	0x00000002
#define	NI_NAMEREQD	0x00000004
#define	NI_NUMERICSERV	0x00000008
#define	NI_DGRAM	0x00000010

struct addrinfo {
	int	ai_flags;	/* AI_PASSIVE, AI_CANONNAME */
	int	ai_family;	/* PF_xxx */
	int	ai_socktype;	/* SOCK_xxx */
	int	ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
	size_t	ai_addrlen;	/* length of ai_addr */
	char	*ai_canonname;	/* canonical name for hostname */
	struct sockaddr *ai_addr;	/* binary address */
	struct addrinfo *ai_next;	/* next structure in linked list */
};

extern void freehostent(struct hostent *);
extern char *gai_strerror(int);
#endif /* AI_PASSIVE */
#endif /* HAVE_GETADDRINFO */



#ifndef HAVE_SOCKADDR_STORAGE
struct sockaddr_storage {
#ifdef HAVE_SOCKADDR_LEN
	uchar		ss_len;		/* address length */
	uchar		ss_family;	/* address family */
#else
	unsigned short	ss_family;
#endif
	unsigned char   fill[126];
};
#endif /* ndef HAVE_SOCKADDR_STORAGE */
rsync-2.5.7/lib/compat.c0100644000111500011150000001033407763533616016042 0ustar  rsync-bugsrsync-bugs/* 
   Copyright (C) Andrew Tridgell 1998
   Copyright (C) 2002 by Martin Pool
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/**
 * @file compat.c
 *
 * Reimplementations of standard functions for platforms that don't
 * have them.
 **/



#include "rsync.h"


#ifndef HAVE_STRDUP
 char *strdup(char *s)
{
  int l = strlen(s) + 1;
  char *ret = (char *)malloc(l);
  if (ret)
    strcpy(ret,s);
  return ret;
}
#endif

#ifndef HAVE_GETCWD
 char *getcwd(char *buf, int size)
{
	return getwd(buf);
}
#endif


#ifndef HAVE_WAITPID
 pid_t waitpid(pid_t pid, int *statptr, int options)
{
#ifdef HAVE_WAIT4
	return wait4(pid, statptr, options, NULL);
#else
	/* If wait4 is also not available, try wait3 for SVR3 variants */
	/* Less ideal because can't actually request a specific pid */
	/* At least the WNOHANG option is supported */
	/* Code borrowed from apache fragment written by dwd@bell-labs.com */
	int tmp_pid, dummystat;;
	if (kill(pid, 0) == -1) {
		errno = ECHILD;
		return -1;
	}
	if (statptr == NULL)
		statptr = &dummystat;
	while (((tmp_pid = wait3(statptr, options, 0)) != pid) &&
		    (tmp_pid != -1) && (tmp_pid != 0) && (pid != -1))
	    ;
	return tmp_pid;
#endif
}
#endif


#ifndef HAVE_MEMMOVE
 void *memmove(void *dest, const void *src, size_t n)
{
	bcopy((char *) src, (char *) dest, n);
	return dest;
}
#endif

#ifndef HAVE_STRPBRK
/**
 * Find the first ocurrence in @p s of any character in @p accept.
 *
 * Derived from glibc 
 **/
 char *strpbrk(const char *s, const char *accept)
{
	while (*s != '\0')  {
		const char *a = accept;
		while (*a != '\0') {
			if (*a++ == *s)	return (char *)s;
		}
		++s;
	}

	return NULL;
}
#endif


#ifndef HAVE_STRLCPY
/**
 * Like strncpy but does not 0 fill the buffer and always null 
 * terminates.
 *
 * @param bufsize is the size of the destination buffer.
 *
 * @return index of the terminating byte.
 **/
 size_t strlcpy(char *d, const char *s, size_t bufsize)
{
	size_t len = strlen(s);
	size_t ret = len;
	if (bufsize <= 0) return 0;
	if (len >= bufsize) len = bufsize-1;
	memcpy(d, s, len);
	d[len] = 0;
	return ret;
}
#endif

#ifndef HAVE_STRLCAT
/**
 * Like strncat() but does not 0 fill the buffer and always null 
 * terminates.
 *
 * @param bufsize length of the buffer, which should be one more than
 * the maximum resulting string length.
 **/
 size_t strlcat(char *d, const char *s, size_t bufsize)
{
	size_t len1 = strlen(d);
	size_t len2 = strlen(s);
	size_t ret = len1 + len2;

	if (len1+len2 >= bufsize) {
		len2 = bufsize - (len1+1);
	}
	if (len2 > 0) {
		memcpy(d+len1, s, len2);
		d[len1+len2] = 0;
	}
	return ret;
}
#endif

#ifdef REPLACE_INET_NTOA
 char *rep_inet_ntoa(struct in_addr ip)
{
	unsigned char *p = (unsigned char *)&ip.s_addr;
	static char buf[18];
#if WORDS_BIGENDIAN
	snprintf(buf, 18, "%d.%d.%d.%d", 
		 (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
#else
	snprintf(buf, 18, "%d.%d.%d.%d", 
		 (int)p[3], (int)p[2], (int)p[1], (int)p[0]);
#endif
	return buf;
}
#endif

#ifdef REPLACE_INET_ATON
 int inet_aton(const char *cp, struct in_addr *inp)
{
	unsigned int a1, a2, a3, a4;
	unsigned long ret;

	if (strcmp(cp, "255.255.255.255") == 0) {
		inp->s_addr = (unsigned) -1;
		return 0;
	}

	if (sscanf(cp, "%u.%u.%u.%u", &a1, &a2, &a3, &a4) != 4 ||
	    a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255) {
		return 0;
	}

	ret = (a1 << 24) | (a2 << 16) | (a3 << 8) | a4;

	inp->s_addr = htonl(ret);
	
	if (inp->s_addr == (unsigned) -1) {
		return 0;
	}
	return 1;
}
#endif

/* some systems don't take the 2nd argument */
int sys_gettimeofday(struct timeval *tv)
{
#if HAVE_GETTIMEOFDAY_TZ
	return gettimeofday(tv, NULL);
#else
	return gettimeofday(tv);
#endif
}
rsync-2.5.7/lib/dummy.in0100644000111500011410000000014606506102135015115 0ustar  rsync-bugsrsyncThis is a dummy file to ensure that the lib directory gets created
by configure when a VPATH is used.
rsync-2.5.7/lib/fnmatch.c0100644000111500011410000003065407044550150015227 0ustar  rsync-bugsrsync#include "../rsync.h"
#ifndef HAVE_FNMATCH

/* ----- THE FOLLOWING UP TO 'END' is glibc-2.1.2 posix/fnmatch.c
     except for the parts with '#if 0' */

/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#if 0	/* header files included better by ../rsync.h */

#if HAVE_CONFIG_H
# include <config.h>
#endif

/* Enable GNU extensions in fnmatch.h.  */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE	1
#endif

#include <errno.h>
#include <fnmatch.h>
#include <ctype.h>

#if HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
#endif

#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#endif

#endif /* 0 */
/* For platform which support the ISO C amendement 1 functionality we
   support user defined character classes.  */
#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
# include <wchar.h>
# include <wctype.h>
#endif

/* Comment out all this code if we are using the GNU C Library, and are not
   actually compiling the library itself.  This code is part of the GNU C
   Library, but also included in many other GNU distributions.  Compiling
   and linking in this code is a waste when using the GNU C library
   (especially if it is a shared library).  Rather than having every GNU
   program understand `configure --with-gnu-libc' and omit the object files,
   it is simpler to just do this in the source for each such file.  */

#if 1

# if defined STDC_HEADERS || !defined isascii
#  define ISASCII(c) 1
# else
#  define ISASCII(c) isascii(c)
# endif

#ifdef isblank
# define ISBLANK(c) (ISASCII (c) && isblank (c))
#else
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
#endif
#ifdef isgraph
# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
#else
# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
#endif

#define ISPRINT(c) (ISASCII (c) && isprint (c))
#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
#define ISALNUM(c) (ISASCII (c) && isalnum (c))
#define ISALPHA(c) (ISASCII (c) && isalpha (c))
#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
#define ISLOWER(c) (ISASCII (c) && islower (c))
#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
#define ISSPACE(c) (ISASCII (c) && isspace (c))
#define ISUPPER(c) (ISASCII (c) && isupper (c))
#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))

# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))

# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
/* The GNU C library provides support for user-defined character classes
   and the functions from ISO C amendement 1.  */
#  ifdef CHARCLASS_NAME_MAX
#   define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
#  else
/* This shouldn't happen but some implementation might still have this
   problem.  Use a reasonable default value.  */
#   define CHAR_CLASS_MAX_LENGTH 256
#  endif

#  ifdef _LIBC
#   define IS_CHAR_CLASS(string) __wctype (string)
#  else
#   define IS_CHAR_CLASS(string) wctype (string)
#  endif
# else
#  define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */

#  define IS_CHAR_CLASS(string)						      \
   (STREQ (string, "alpha") || STREQ (string, "upper")			      \
    || STREQ (string, "lower") || STREQ (string, "digit")		      \
    || STREQ (string, "alnum") || STREQ (string, "xdigit")		      \
    || STREQ (string, "space") || STREQ (string, "print")		      \
    || STREQ (string, "punct") || STREQ (string, "graph")		      \
    || STREQ (string, "cntrl") || STREQ (string, "blank"))
# endif

/* Avoid depending on library functions or files
   whose names are inconsistent.  */

# if !defined _LIBC && !defined getenv
extern char *getenv ();
# endif

# ifndef errno
extern int errno;
# endif

/* Match STRING against the filename pattern PATTERN, returning zero if
   it matches, nonzero if not.  */
static int
#ifdef _LIBC
internal_function
#endif
internal_fnmatch (const char *pattern, const char *string,
		  int no_leading_period, int flags)
{
  register const char *p = pattern, *n = string;
  register unsigned char c;

/* Note that this evaluates C many times.  */
# ifdef _LIBC
#  define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
# else
#  define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
# endif

  while ((c = *p++) != '\0')
    {
      c = FOLD (c);

      switch (c)
	{
	case '?':
	  if (*n == '\0')
	    return FNM_NOMATCH;
	  else if (*n == '/' && (flags & FNM_FILE_NAME))
	    return FNM_NOMATCH;
	  else if (*n == '.' && no_leading_period
		   && (n == string
		       || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
	    return FNM_NOMATCH;
	  break;

	case '\\':
	  if (!(flags & FNM_NOESCAPE))
	    {
	      c = *p++;
	      if (c == '\0')
		/* Trailing \ loses.  */
		return FNM_NOMATCH;
	      c = FOLD (c);
	    }
	  if (FOLD ((unsigned char) *n) != c)
	    return FNM_NOMATCH;
	  break;

	case '*':
	  if (*n == '.' && no_leading_period
	      && (n == string
		  || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
	    return FNM_NOMATCH;

	  for (c = *p++; c == '?' || c == '*'; c = *p++)
	    {
	      if (*n == '/' && (flags & FNM_FILE_NAME))
		/* A slash does not match a wildcard under FNM_FILE_NAME.  */
		return FNM_NOMATCH;
	      else if (c == '?')
		{
		  /* A ? needs to match one character.  */
		  if (*n == '\0')
		    /* There isn't another character; no match.  */
		    return FNM_NOMATCH;
		  else
		    /* One character of the string is consumed in matching
		       this ? wildcard, so *??? won't match if there are
		       less than three characters.  */
		    ++n;
		}
	    }

	  if (c == '\0')
	    /* The wildcard(s) is/are the last element of the pattern.
	       If the name is a file name and contains another slash
	       this does mean it cannot match.  */
	    return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
		    ? FNM_NOMATCH : 0);
	  else
	    {
	      const char *endp;

#if 0
	      endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
#else
/* replace call to internal glibc function with equivalent */
	      if (!(flags & FNM_FILE_NAME) || ((endp = strchr(n, '/')) == NULL))
		endp = n + strlen(n);
#endif

	      if (c == '[')
		{
		  int flags2 = ((flags & FNM_FILE_NAME)
				? flags : (flags & ~FNM_PERIOD));

		  for (--p; n < endp; ++n)
		    if (internal_fnmatch (p, n,
					  (no_leading_period
					   && (n == string
					       || (n[-1] == '/'
						   && (flags
						       & FNM_FILE_NAME)))),
					  flags2)
			== 0)
		      return 0;
		}
	      else if (c == '/' && (flags & FNM_FILE_NAME))
		{
		  while (*n != '\0' && *n != '/')
		    ++n;
		  if (*n == '/'
		      && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
					    flags) == 0))
		    return 0;
		}
	      else
		{
		  int flags2 = ((flags & FNM_FILE_NAME)
				? flags : (flags & ~FNM_PERIOD));

		  if (c == '\\' && !(flags & FNM_NOESCAPE))
		    c = *p;
		  c = FOLD (c);
		  for (--p; n < endp; ++n)
		    if (FOLD ((unsigned char) *n) == c
			&& (internal_fnmatch (p, n,
					      (no_leading_period
					       && (n == string
						   || (n[-1] == '/'
						       && (flags
							   & FNM_FILE_NAME)))),
					      flags2) == 0))
		      return 0;
		}
	    }

	  /* If we come here no match is possible with the wildcard.  */
	  return FNM_NOMATCH;

	case '[':
	  {
	    /* Nonzero if the sense of the character class is inverted.  */
	    static int posixly_correct;
	    register int not;
	    char cold;

	    if (posixly_correct == 0)
	      posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;

	    if (*n == '\0')
	      return FNM_NOMATCH;

	    if (*n == '.' && no_leading_period && (n == string
						   || (n[-1] == '/'
						       && (flags
							   & FNM_FILE_NAME))))
	      return FNM_NOMATCH;

	    if (*n == '/' && (flags & FNM_FILE_NAME))
	      /* `/' cannot be matched.  */
	      return FNM_NOMATCH;

	    not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
	    if (not)
	      ++p;

	    c = *p++;
	    for (;;)
	      {
		unsigned char fn = FOLD ((unsigned char) *n);

		if (!(flags & FNM_NOESCAPE) && c == '\\')
		  {
		    if (*p == '\0')
		      return FNM_NOMATCH;
		    c = FOLD ((unsigned char) *p);
		    ++p;

		    if (c == fn)
		      goto matched;
		  }
		else if (c == '[' && *p == ':')
		  {
		    /* Leave room for the null.  */
		    char str[CHAR_CLASS_MAX_LENGTH + 1];
		    size_t c1 = 0;
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
		    wctype_t wt;
# endif
		    const char *startp = p;

		    for (;;)
		      {
			if (c1 == CHAR_CLASS_MAX_LENGTH)
			  /* The name is too long and therefore the pattern
			     is ill-formed.  */
			  return FNM_NOMATCH;

			c = *++p;
			if (c == ':' && p[1] == ']')
			  {
			    p += 2;
			    break;
			  }
			if (c < 'a' || c >= 'z')
			  {
			    /* This cannot possibly be a character class name.
			       Match it as a normal range.  */
			    p = startp;
			    c = '[';
			    goto normal_bracket;
			  }
			str[c1++] = c;
		      }
		    str[c1] = '\0';

# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
		    wt = IS_CHAR_CLASS (str);
		    if (wt == 0)
		      /* Invalid character class name.  */
		      return FNM_NOMATCH;

		    if (__iswctype (__btowc ((unsigned char) *n), wt))
		      goto matched;
# else
		    if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
			|| (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
			|| (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
			|| (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
			|| (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
			|| (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
			|| (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
			|| (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
			|| (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
			|| (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
			|| (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
			|| (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
		      goto matched;
# endif
		  }
		else if (c == '\0')
		  /* [ (unterminated) loses.  */
		  return FNM_NOMATCH;
		else
		  {
		  normal_bracket:
		    if (FOLD (c) == fn)
		      goto matched;

		    cold = c;
		    c = *p++;

		    if (c == '-' && *p != ']')
		      {
			/* It is a range.  */
			unsigned char cend = *p++;
			if (!(flags & FNM_NOESCAPE) && cend == '\\')
			  cend = *p++;
			if (cend == '\0')
			  return FNM_NOMATCH;

			if (cold <= fn && fn <= FOLD (cend))
			  goto matched;

			c = *p++;
		      }
		  }

		if (c == ']')
		  break;
	      }

	    if (!not)
	      return FNM_NOMATCH;
	    break;

	  matched:
	    /* Skip the rest of the [...] that already matched.  */
	    while (c != ']')
	      {
		if (c == '\0')
		  /* [... (unterminated) loses.  */
		  return FNM_NOMATCH;

		c = *p++;
		if (!(flags & FNM_NOESCAPE) && c == '\\')
		  {
		    if (*p == '\0')
		      return FNM_NOMATCH;
		    /* XXX 1003.2d11 is unclear if this is right.  */
		    ++p;
		  }
		else if (c == '[' && *p == ':')
		  {
		    do
		      if (*++p == '\0')
			return FNM_NOMATCH;
		    while (*p != ':' || p[1] == ']');
		    p += 2;
		    c = *p;
		  }
	      }
	    if (not)
	      return FNM_NOMATCH;
	  }
	  break;

	default:
	  if (c != FOLD ((unsigned char) *n))
	    return FNM_NOMATCH;
	}

      ++n;
    }

  if (*n == '\0')
    return 0;

  if ((flags & FNM_LEADING_DIR) && *n == '/')
    /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
    return 0;

  return FNM_NOMATCH;

# undef FOLD
}


int
fnmatch (pattern, string, flags)
     const char *pattern;
     const char *string;
     int flags;
{
  return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
}

#endif	/* _LIBC or not __GNU_LIBRARY__.  */
/* ----- END glibc-2.1.2 posix/fnmatch.c */

#else	/* HAVE_FNMATCH */
void fnmatch_dummy(void) {}
#endif
rsync-2.5.7/lib/fnmatch.h0100644000111500011410000000562507044550150015234 0ustar  rsync-bugsrsync/* Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#ifndef	_FNMATCH_H
#define	_FNMATCH_H	1

#ifdef	__cplusplus
extern "C" {
#endif

#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
# if !defined __GLIBC__ || !defined __P
#  undef	__P
#  define __P(protos)	protos
# endif
#else /* Not C++ or ANSI C.  */
# undef	__P
# define __P(protos)	()
/* We can get away without defining `const' here only because in this file
   it is used only inside the prototype for `fnmatch', which is elided in
   non-ANSI C where `const' is problematical.  */
#endif /* C++ or ANSI C.  */

#ifndef const
# if (defined __STDC__ && __STDC__) || defined __cplusplus
#  define __const	const
# else
#  define __const
# endif
#endif

/* We #undef these before defining them because some losing systems
   (HP-UX A.08.07 for example) define these in <unistd.h>.  */
#undef	FNM_PATHNAME
#undef	FNM_NOESCAPE
#undef	FNM_PERIOD

/* Bits set in the FLAGS argument to `fnmatch'.  */
#define	FNM_PATHNAME	(1 << 0) /* No wildcard can ever match `/'.  */
#define	FNM_NOESCAPE	(1 << 1) /* Backslashes don't quote special chars.  */
#define	FNM_PERIOD	(1 << 2) /* Leading `.' is matched only explicitly.  */

#ifndef FNM_FILE_NAME
# define FNM_FILE_NAME	 FNM_PATHNAME	/* Preferred GNU name.  */
#endif
#ifndef FNM_LEADING_DIR
# define FNM_LEADING_DIR (1 << 3)	/* Ignore `/...' after a match.  */
#endif
#ifndef FNM_CASEFOLD
# define FNM_CASEFOLD	 (1 << 4)	/* Compare without regard to case.  */
#endif

/* Value returned by `fnmatch' if STRING does not match PATTERN.  */
#define	FNM_NOMATCH	1

/* This value is returned if the implementation does not support
   `fnmatch'.  Since this is not the case here it will never be
   returned but the conformance test suites still require the symbol
   to be defined.  */
#ifdef _XOPEN_SOURCE
# define FNM_NOSYS	(-1)
#endif

/* Match STRING against the filename pattern PATTERN,
   returning zero if it matches, FNM_NOMATCH if not.  */
extern int fnmatch __P ((__const char *__pattern, __const char *__string,
			 int __flags));

#ifdef	__cplusplus
}
#endif

#endif /* fnmatch.h */
rsync-2.5.7/lib/getnameinfo.c0100644000111500011150000001221607763533616017054 0ustar  rsync-bugsrsync-bugs/*
 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 *
 * Changes Copyright (C) 2001 by Martin Pool <mbp@samba.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * Issues to be discussed:
 * - Thread safe-ness must be checked
 * - Return values.  There seems to be no standard for return value (RFC2133)
 *   but INRIA implementation returns EAI_xxx defined for getaddrinfo().
 */

#include "rsync.h"

#define SUCCESS 0
#define ANY 0
#define YES 1
#define NO  0

static struct afd {
	int a_af;
	int a_addrlen;
	int a_socklen;
	int a_off;
} afdl [] = {
#ifdef INET6
	{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
		offsetof(struct sockaddr_in6, sin6_addr)},
#endif
	{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
		offsetof(struct sockaddr_in, sin_addr)},
	{0, 0, 0, 0},
};

struct sockinet {
	u_char	si_len;
	u_char	si_family;
	u_short	si_port;
};

#define ENI_NOSOCKET 	0
#define ENI_NOSERVNAME	1
#define ENI_NOHOSTNAME	2
#define ENI_MEMORY	3
#define ENI_SYSTEM	4
#define ENI_FAMILY	5
#define ENI_SALEN	6

int
getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
	const struct sockaddr *sa;
	size_t salen;
	char *host;
	size_t hostlen;
	char *serv;
	size_t servlen;
	int flags;
{
	extern int h_errno;
	struct afd *afd;
	struct servent *sp;
	struct hostent *hp;
	u_short port;
	int family, i;
	char *addr, *p;
	u_long v4a;
#ifdef INET6
	u_char pfx;
#endif
	int h_error;
	char numserv[512];
	char numaddr[512];

	if (sa == NULL)
		return ENI_NOSOCKET;

#ifdef HAVE_SOCKADDR_LEN
	if (sa->sa_len != salen) return ENI_SALEN;
#endif /* HAVE_SOCKADDR_LEN */
	
	family = sa->sa_family;
	for (i = 0; afdl[i].a_af; i++)
		if (afdl[i].a_af == family) {
			afd = &afdl[i];
			goto found;
		}
	return ENI_FAMILY;
	
 found:
	if (salen != afd->a_socklen) return ENI_SALEN;
	
	port = ((struct sockinet *)sa)->si_port; /* network byte order */
	addr = (char *)sa + afd->a_off;

	if (serv == NULL || servlen == 0) {
		/* what we should do? */
	} else if (flags & NI_NUMERICSERV) {
		snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
		if (strlen(numserv) > servlen)
			return ENI_MEMORY;
		strcpy(serv, numserv);
	} else {
		sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
		if (sp) {
			if (strlen(sp->s_name) > servlen)
				return ENI_MEMORY;
			strcpy(serv, sp->s_name);
		} else
			return ENI_NOSERVNAME;
	}

	switch (sa->sa_family) {
	case AF_INET:
		v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
		if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
			flags |= NI_NUMERICHOST;
		v4a >>= IN_CLASSA_NSHIFT;
		if (v4a == 0 || v4a == IN_LOOPBACKNET)
			flags |= NI_NUMERICHOST;			
		break;
#ifdef INET6
	case AF_INET6:
		pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0];
		if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
			flags |= NI_NUMERICHOST;
		break;
#endif
	}
	if (host == NULL || hostlen == 0) {
		/* what should we do? */
	} else if (flags & NI_NUMERICHOST) {
		if (!inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)))
			return ENI_SYSTEM;
		if (strlen(numaddr) > hostlen)
			return ENI_MEMORY;
		strcpy(host, numaddr);
	} else {
#ifdef INET6
		hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
#else
		hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
		h_error = h_errno;
#endif

		if (hp) {
			if (flags & NI_NOFQDN) {
				p = strchr(hp->h_name, '.');
				if (p) *p = '\0';
			}
			if (strlen(hp->h_name) > hostlen) {
#ifdef INET6
				freehostent(hp);
#endif
				return ENI_MEMORY;
			}
			strcpy(host, hp->h_name);
#ifdef INET6
			freehostent(hp);
#endif
		} else {
			if (flags & NI_NAMEREQD)
				return ENI_NOHOSTNAME;
			if (!inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)))
				return ENI_NOHOSTNAME;
			if (strlen(numaddr) > hostlen)
				return ENI_MEMORY;
			strcpy(host, numaddr);
		}
	}
	return SUCCESS;
}
rsync-2.5.7/lib/inet_ntop.c0100644000111500011150000001135107401037005016532 0ustar  rsync-bugsrsync-bugs/*
 * Copyright (C) 1996-2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */


#include "rsync.h"

#define NS_INT16SZ	 2
#define NS_IN6ADDRSZ	16

/*
 * WARNING: Don't even consider trying to compile this on a system where
 * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
 */

static const char *inet_ntop4(const unsigned char *src, char *dst,
			      size_t size);

#ifdef AF_INET6
static const char *inet_ntop6(const unsigned char *src, char *dst,
			      size_t size);
#endif

/* char *
 * isc_net_ntop(af, src, dst, size)
 *	convert a network format address to presentation format.
 * return:
 *	pointer to presentation format address (`dst'), or NULL (see errno).
 * author:
 *	Paul Vixie, 1996.
 */
const char *
inet_ntop(int af, const void *src, char *dst, size_t size)
{
	switch (af) {
	case AF_INET:
		return (inet_ntop4(src, dst, size));
#ifdef AF_INET6
	case AF_INET6:
		return (inet_ntop6(src, dst, size));
#endif
	default:
		errno = EAFNOSUPPORT;
		return (NULL);
	}
	/* NOTREACHED */
}

/* const char *
 * inet_ntop4(src, dst, size)
 *	format an IPv4 address
 * return:
 *	`dst' (as a const)
 * notes:
 *	(1) uses no statics
 *	(2) takes a unsigned char* not an in_addr as input
 * author:
 *	Paul Vixie, 1996.
 */
static const char *
inet_ntop4(const unsigned char *src, char *dst, size_t size)
{
	static const char *fmt = "%u.%u.%u.%u";
	char tmp[sizeof "255.255.255.255"];

	if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size)
	{
		errno = ENOSPC;
		return (NULL);
	}
	strcpy(dst, tmp);

	return (dst);
}

/* const char *
 * isc_inet_ntop6(src, dst, size)
 *	convert IPv6 binary address into presentation (printable) format
 * author:
 *	Paul Vixie, 1996.
 */
#ifdef AF_INET6
static const char *
inet_ntop6(const unsigned char *src, char *dst, size_t size)
{
	/*
	 * Note that int32_t and int16_t need only be "at least" large enough
	 * to contain a value of the specified size.  On some systems, like
	 * Crays, there is no such thing as an integer variable with 16 bits.
	 * Keep this in mind if you think this function should have been coded
	 * to use pointer overlays.  All the world's not a VAX.
	 */
	char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
	struct { int base, len; } best, cur;
	unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
	int i;

	/*
	 * Preprocess:
	 *	Copy the input (bytewise) array into a wordwise array.
	 *	Find the longest run of 0x00's in src[] for :: shorthanding.
	 */
	memset(words, '\0', sizeof words);
	for (i = 0; i < NS_IN6ADDRSZ; i++)
		words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
	best.base = -1;
	cur.base = -1;
	for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
		if (words[i] == 0) {
			if (cur.base == -1)
				cur.base = i, cur.len = 1;
			else
				cur.len++;
		} else {
			if (cur.base != -1) {
				if (best.base == -1 || cur.len > best.len)
					best = cur;
				cur.base = -1;
			}
		}
	}
	if (cur.base != -1) {
		if (best.base == -1 || cur.len > best.len)
			best = cur;
	}
	if (best.base != -1 && best.len < 2)
		best.base = -1;

	/*
	 * Format the result.
	 */
	tp = tmp;
	for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
		/* Are we inside the best run of 0x00's? */
		if (best.base != -1 && i >= best.base &&
		    i < (best.base + best.len)) {
			if (i == best.base)
				*tp++ = ':';
			continue;
		}
		/* Are we following an initial run of 0x00s or any real hex? */
		if (i != 0)
			*tp++ = ':';
		/* Is this address an encapsulated IPv4? */
		if (i == 6 && best.base == 0 &&
		    (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
			if (!inet_ntop4(src+12, tp,
					sizeof tmp - (tp - tmp)))
				return (NULL);
			tp += strlen(tp);
			break;
		}
		tp += sprintf(tp, "%x", words[i]);
	}
	/* Was it a trailing run of 0x00's? */
	if (best.base != -1 && (best.base + best.len) ==
	    (NS_IN6ADDRSZ / NS_INT16SZ))
		*tp++ = ':';
	*tp++ = '\0';

	/*
	 * Check for overflow, copy, and we're done.
	 */
	if ((size_t)(tp - tmp) > size) {
		errno = ENOSPC;
		return (NULL);
	}
	strcpy(dst, tmp);
	return (dst);
}
#endif /* AF_INET6 */
rsync-2.5.7/lib/inet_pton.c0100644000111500011150000001173507763533616016564 0ustar  rsync-bugsrsync-bugs/*
 * Copyright (C) 1996-2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "rsync.h"

#define NS_INT16SZ	 2
#define NS_INADDRSZ	 4
#define NS_IN6ADDRSZ	16

/*
 * WARNING: Don't even consider trying to compile this on a system where
 * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
 */

static int inet_pton4(const char *src, unsigned char *dst);
#ifdef INET6
static int inet_pton6(const char *src, unsigned char *dst);
#endif

/* int
 * inet_pton(af, src, dst)
 *	convert from presentation format (which usually means ASCII printable)
 *	to network format (which is usually some kind of binary format).
 * return:
 *	1 if the address was valid for the specified address family
 *	0 if the address wasn't valid (`dst' is untouched in this case)
 *	-1 if some other error occurred (`dst' is untouched in this case, too)
 * author:
 *	Paul Vixie, 1996.
 */
int
inet_pton(int af,
	  const char *src,
	  void *dst)
{
	switch (af) {
	case AF_INET:
		return (inet_pton4(src, dst));
#ifdef INET6
	case AF_INET6:
		return (inet_pton6(src, dst));
#endif
	default:
		errno = EAFNOSUPPORT;
		return (-1);
	}
	/* NOTREACHED */
}

/* int
 * inet_pton4(src, dst)
 *	like inet_aton() but without all the hexadecimal and shorthand.
 * return:
 *	1 if `src' is a valid dotted quad, else 0.
 * notice:
 *	does not touch `dst' unless it's returning 1.
 * author:
 *	Paul Vixie, 1996.
 */
static int
inet_pton4(src, dst)
	const char *src;
	unsigned char *dst;
{
	static const char digits[] = "0123456789";
	int saw_digit, octets, ch;
	unsigned char tmp[NS_INADDRSZ], *tp;

	saw_digit = 0;
	octets = 0;
	*(tp = tmp) = 0;
	while ((ch = *src++) != '\0') {
		const char *pch;

		if ((pch = strchr(digits, ch)) != NULL) {
			unsigned int new = *tp * 10 + (pch - digits);

			if (new > 255)
				return (0);
			*tp = new;
			if (! saw_digit) {
				if (++octets > 4)
					return (0);
				saw_digit = 1;
			}
		} else if (ch == '.' && saw_digit) {
			if (octets == 4)
				return (0);
			*++tp = 0;
			saw_digit = 0;
		} else
			return (0);
	}
	if (octets < 4)
		return (0);
	memcpy(dst, tmp, NS_INADDRSZ);
	return (1);
}

/* int
 * inet_pton6(src, dst)
 *	convert presentation level address to network order binary form.
 * return:
 *	1 if `src' is a valid [RFC1884 2.2] address, else 0.
 * notice:
 *	(1) does not touch `dst' unless it's returning 1.
 *	(2) :: in a full address is silently ignored.
 * credit:
 *	inspired by Mark Andrews.
 * author:
 *	Paul Vixie, 1996.
 */
#ifdef INET6
static int
inet_pton6(src, dst)
	const char *src;
	unsigned char *dst;
{
	static const char xdigits_l[] = "0123456789abcdef",
			  xdigits_u[] = "0123456789ABCDEF";
	unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
	const char *xdigits, *curtok;
	int ch, saw_xdigit;
	unsigned int val;

	memset((tp = tmp), '\0', NS_IN6ADDRSZ);
	endp = tp + NS_IN6ADDRSZ;
	colonp = NULL;
	/* Leading :: requires some special handling. */
	if (*src == ':')
		if (*++src != ':')
			return (0);
	curtok = src;
	saw_xdigit = 0;
	val = 0;
	while ((ch = *src++) != '\0') {
		const char *pch;

		if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
			pch = strchr((xdigits = xdigits_u), ch);
		if (pch != NULL) {
			val <<= 4;
			val |= (pch - xdigits);
			if (val > 0xffff)
				return (0);
			saw_xdigit = 1;
			continue;
		}
		if (ch == ':') {
			curtok = src;
			if (!saw_xdigit) {
				if (colonp)
					return (0);
				colonp = tp;
				continue;
			}
			if (tp + NS_INT16SZ > endp)
				return (0);
			*tp++ = (unsigned char) (val >> 8) & 0xff;
			*tp++ = (unsigned char) val & 0xff;
			saw_xdigit = 0;
			val = 0;
			continue;
		}
		if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
		    inet_pton4(curtok, tp) > 0) {
			tp += NS_INADDRSZ;
			saw_xdigit = 0;
			break;	/* '\0' was seen by inet_pton4(). */
		}
		return (0);
	}
	if (saw_xdigit) {
		if (tp + NS_INT16SZ > endp)
			return (0);
		*tp++ = (unsigned char) (val >> 8) & 0xff;
		*tp++ = (unsigned char) val & 0xff;
	}
	if (colonp != NULL) {
		/*
		 * Since some memmove()'s erroneously fail to handle
		 * overlapping regions, we'll do the shift by hand.
		 */
		const int n = tp - colonp;
		int i;

		for (i = 1; i <= n; i++) {
			endp[- i] = colonp[n - i];
			colonp[n - i] = 0;
		}
		tp = endp;
	}
	if (tp != endp)
		return (0);
	memcpy(dst, tmp, NS_IN6ADDRSZ);
	return (1);
}
#endif
rsync-2.5.7/lib/mdfour.c0100644000111500011150000001302707401550366016043 0ustar  rsync-bugsrsync-bugs/* 
   Unix SMB/Netbios implementation.
   Version 1.9.
   a implementation of MD4 designed for use in the SMB authentication protocol
   Copyright (C) Andrew Tridgell 1997-1998.
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "rsync.h"

/* NOTE: This code makes no attempt to be fast! 

   It assumes that a int is at least 32 bits long
*/

static struct mdfour *m;

#define MASK32 (0xffffffff)

#define F(X,Y,Z) ((((X)&(Y)) | ((~(X))&(Z))))
#define G(X,Y,Z) ((((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z))))
#define H(X,Y,Z) (((X)^(Y)^(Z)))
#define lshift(x,s) (((((x)<<(s))&MASK32) | (((x)>>(32-(s)))&MASK32)))

#define ROUND1(a,b,c,d,k,s) a = lshift((a + F(b,c,d) + M[k])&MASK32, s)
#define ROUND2(a,b,c,d,k,s) a = lshift((a + G(b,c,d) + M[k] + 0x5A827999)&MASK32,s)
#define ROUND3(a,b,c,d,k,s) a = lshift((a + H(b,c,d) + M[k] + 0x6ED9EBA1)&MASK32,s)

/* this applies md4 to 64 byte chunks */
static void mdfour64(uint32 *M)
{
	uint32 AA, BB, CC, DD;
	uint32 A,B,C,D;

	A = m->A; B = m->B; C = m->C; D = m->D; 
	AA = A; BB = B; CC = C; DD = D;

        ROUND1(A,B,C,D,  0,  3);  ROUND1(D,A,B,C,  1,  7);  
	ROUND1(C,D,A,B,  2, 11);  ROUND1(B,C,D,A,  3, 19);
        ROUND1(A,B,C,D,  4,  3);  ROUND1(D,A,B,C,  5,  7);  
	ROUND1(C,D,A,B,  6, 11);  ROUND1(B,C,D,A,  7, 19);
        ROUND1(A,B,C,D,  8,  3);  ROUND1(D,A,B,C,  9,  7);  
	ROUND1(C,D,A,B, 10, 11);  ROUND1(B,C,D,A, 11, 19);
        ROUND1(A,B,C,D, 12,  3);  ROUND1(D,A,B,C, 13,  7);  
	ROUND1(C,D,A,B, 14, 11);  ROUND1(B,C,D,A, 15, 19);	


        ROUND2(A,B,C,D,  0,  3);  ROUND2(D,A,B,C,  4,  5);  
	ROUND2(C,D,A,B,  8,  9);  ROUND2(B,C,D,A, 12, 13);
        ROUND2(A,B,C,D,  1,  3);  ROUND2(D,A,B,C,  5,  5);  
	ROUND2(C,D,A,B,  9,  9);  ROUND2(B,C,D,A, 13, 13);
        ROUND2(A,B,C,D,  2,  3);  ROUND2(D,A,B,C,  6,  5);  
	ROUND2(C,D,A,B, 10,  9);  ROUND2(B,C,D,A, 14, 13);
        ROUND2(A,B,C,D,  3,  3);  ROUND2(D,A,B,C,  7,  5);  
	ROUND2(C,D,A,B, 11,  9);  ROUND2(B,C,D,A, 15, 13);

	ROUND3(A,B,C,D,  0,  3);  ROUND3(D,A,B,C,  8,  9);  
	ROUND3(C,D,A,B,  4, 11);  ROUND3(B,C,D,A, 12, 15);
        ROUND3(A,B,C,D,  2,  3);  ROUND3(D,A,B,C, 10,  9);  
	ROUND3(C,D,A,B,  6, 11);  ROUND3(B,C,D,A, 14, 15);
        ROUND3(A,B,C,D,  1,  3);  ROUND3(D,A,B,C,  9,  9);  
	ROUND3(C,D,A,B,  5, 11);  ROUND3(B,C,D,A, 13, 15);
        ROUND3(A,B,C,D,  3,  3);  ROUND3(D,A,B,C, 11,  9);  
	ROUND3(C,D,A,B,  7, 11);  ROUND3(B,C,D,A, 15, 15);

	A += AA; B += BB; 
	C += CC; D += DD;
	
	A &= MASK32; B &= MASK32; 
	C &= MASK32; D &= MASK32;

	m->A = A; m->B = B; m->C = C; m->D = D;
}

static void copy64(uint32 *M, unsigned char *in)
{
	int i;

	for (i=0;i<16;i++)
		M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
			(in[i*4+1]<<8) | (in[i*4+0]<<0);
}

static void copy4(unsigned char *out,uint32 x)
{
	out[0] = x&0xFF;
	out[1] = (x>>8)&0xFF;
	out[2] = (x>>16)&0xFF;
	out[3] = (x>>24)&0xFF;
}

void mdfour_begin(struct mdfour *md)
{
	md->A = 0x67452301;
	md->B = 0xefcdab89;
	md->C = 0x98badcfe;
	md->D = 0x10325476;
	md->totalN = 0;
}


static void mdfour_tail(unsigned char *in, int n)
{
	unsigned char buf[128];
	uint32 M[16];
	uint32 b;

	m->totalN += n;

	b = m->totalN * 8;

	memset(buf, 0, 128);
	if (n) memcpy(buf, in, n);
	buf[n] = 0x80;

	if (n <= 55) {
		copy4(buf+56, b);
		copy64(M, buf);
		mdfour64(M);
	} else {
		copy4(buf+120, b); 
		copy64(M, buf);
		mdfour64(M);
		copy64(M, buf+64);
		mdfour64(M);
	}
}

void mdfour_update(struct mdfour *md, unsigned char *in, int n)
{
	uint32 M[16];

	if (n == 0) mdfour_tail(in, n);

	m = md;

	while (n >= 64) {
		copy64(M, in);
		mdfour64(M);
		in += 64;
		n -= 64;
		m->totalN += 64;
	}

	if (n) mdfour_tail(in, n);
}


void mdfour_result(struct mdfour *md, unsigned char *out)
{
	m = md;

	copy4(out, m->A);
	copy4(out+4, m->B);
	copy4(out+8, m->C);
	copy4(out+12, m->D);
}


void mdfour(unsigned char *out, unsigned char *in, int n)
{
	struct mdfour md;
	mdfour_begin(&md);
	mdfour_update(&md, in, n);
	mdfour_result(&md, out);
}

#ifdef TEST_MDFOUR
static void file_checksum1(char *fname)
{
	int fd, i;
	struct mdfour md;
	unsigned char buf[64*1024], sum[16];
	
	fd = open(fname,O_RDONLY);
	if (fd == -1) {
		perror("fname");
		exit(1);
	}
	
	mdfour_begin(&md);

	while (1) {
		int n = read(fd, buf, sizeof(buf));
		if (n <= 0) break;
		mdfour_update(&md, buf, n);
	}

	close(fd);

	mdfour_result(&md, sum);

	for (i=0;i<16;i++)
		printf("%02X", sum[i]);
	printf("\n");
}

#if 0
#include "../md4.h"

static void file_checksum2(char *fname)
{
	int fd, i;
	MDstruct md;
	unsigned char buf[64], sum[16];

	fd = open(fname,O_RDONLY);
	if (fd == -1) {
		perror("fname");
		exit(1);
	}
	
	MDbegin(&md);

	while (1) {
		int n = read(fd, buf, sizeof(buf));
		if (n <= 0) break;
		MDupdate(&md, buf, n*8);
	}

	if (!md.done) {
		MDupdate(&md, buf, 0);
	}

	close(fd);

	memcpy(sum, md.buffer, 16);

	for (i=0;i<16;i++)
		printf("%02X", sum[i]);
	printf("\n");
}
#endif

 int main(int argc, char *argv[])
{
	file_checksum1(argv[1]);
#if 0
	file_checksum2(argv[1]);
#endif
	return 0;
}
#endif
rsync-2.5.7/lib/mdfour.h0100644000111500011410000000221706615773300015111 0ustar  rsync-bugsrsync/* 
   Unix SMB/Netbios implementation.
   Version 1.9.
   a implementation of MD4 designed for use in the SMB authentication protocol
   Copyright (C) Andrew Tridgell 1997-1998.
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

struct mdfour {
	uint32 A, B, C, D;
	uint32 totalN;
};

void mdfour_begin(struct mdfour *md);
void mdfour_update(struct mdfour *md, unsigned char *in, int n);
void mdfour_result(struct mdfour *md, unsigned char *out);
void mdfour(unsigned char *out, unsigned char *in, int n);




rsync-2.5.7/lib/permstring.c0100644000111500011150000000336307763533616016755 0ustar  rsync-bugsrsync-bugs/* 
   Copyright (C) Andrew Tridgell 1996
   Copyright (C) Paul Mackerras 1996
   Copyright (C) 2001 by Martin Pool <mbp@samba.org>
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "rsync.h"

/**
 * Produce a string representation of Unix mode bits like that used by
 * ls(1).
 *
 * @param buf buffer of at least 11 characters
 **/
void permstring(char *perms,
		int mode)
{
	static const char *perm_map = "rwxrwxrwx";
	int i;

	strcpy(perms, "----------");
	
	for (i=0;i<9;i++) {
		if (mode & (1<<i)) perms[9-i] = perm_map[8-i];
	}

	/* Handle setuid/sticky bits.  You might think the indices are
	 * off by one, but remember there's a type char at the
	 * start.  */
	if (mode & S_ISUID)
		perms[3] = (mode & S_IXUSR) ? 's' : 'S';

	if (mode & S_ISGID)
		perms[6] = (mode & S_IXGRP) ? 's' : 'S';
	
#ifdef S_ISVTX
	if (mode & S_ISVTX)
		perms[9] = (mode & S_IXOTH) ? 't' : 'T';
#endif
		
	if (S_ISLNK(mode)) perms[0] = 'l';
	if (S_ISDIR(mode)) perms[0] = 'd';
	if (S_ISBLK(mode)) perms[0] = 'b';
	if (S_ISCHR(mode)) perms[0] = 'c';
	if (S_ISSOCK(mode)) perms[0] = 's';
	if (S_ISFIFO(mode)) perms[0] = 'p';
}

	
rsync-2.5.7/lib/permstring.h0100644000111500011150000000010407400633005016725 0ustar  rsync-bugsrsync-bugs#define PERMSTRING_SIZE 11

void permstring(char *perms, int mode);
rsync-2.5.7/lib/snprintf.c0100644000111500011150000005204007401550366016410 0ustar  rsync-bugsrsync-bugs/*
 * Copyright Patrick Powell 1995
 * This code is based on code written by Patrick Powell (papowell@astart.com)
 * It may be used for any purpose as long as this notice remains intact
 * on all source code distributions
 */

/**************************************************************
 * Original:
 * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
 * A bombproof version of doprnt (dopr) included.
 * Sigh.  This sort of thing is always nasty do deal with.  Note that
 * the version here does not include floating point...
 *
 * snprintf() is used instead of sprintf() as it does limit checks
 * for string length.  This covers a nasty loophole.
 *
 * The other functions are there to prevent NULL pointers from
 * causing nast effects.
 *
 * More Recently:
 *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
 *  This was ugly.  It is still ugly.  I opted out of floating point
 *  numbers, but the formatter understands just about everything
 *  from the normal C string format, at least as far as I can tell from
 *  the Solaris 2.5 printf(3S) man page.
 *
 *  Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
 *    Ok, added some minimal floating point support, which means this
 *    probably requires libm on most operating systems.  Don't yet
 *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
 *    was pretty badly broken, it just wasn't being exercised in ways
 *    which showed it, so that's been fixed.  Also, formated the code
 *    to mutt conventions, and removed dead code left over from the
 *    original.  Also, there is now a builtin-test, just compile with:
 *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
 *    and run snprintf for results.
 * 
 *  Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
 *    The PGP code was using unsigned hexadecimal formats. 
 *    Unfortunately, unsigned formats simply didn't work.
 *
 *  Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
 *    The original code assumed that both snprintf() and vsnprintf() were
 *    missing.  Some systems only have snprintf() but not vsnprintf(), so
 *    the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
 *
 *  Andrew Tridgell (tridge@samba.org) Oct 1998
 *    fixed handling of %.0f
 *    added test for HAVE_LONG_DOUBLE
 *
 * tridge@samba.org, idra@samba.org, April 2001
 *    got rid of fcvt code (twas buggy and made testing harder)
 *    added C99 semantics
 *
 **************************************************************/

#ifndef NO_CONFIG_H /* for some tests */
#include "config.h"
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#include <sys/types.h>
#include <stdarg.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF)
/* only include stdio.h if we are not re-defining snprintf or vsnprintf */
#include <stdio.h>
 /* make the compiler happy with an empty file */
 void dummy_snprintf(void) {} 
#else

#ifdef HAVE_LONG_DOUBLE
#define LDOUBLE long double
#else
#define LDOUBLE double
#endif

#ifdef HAVE_LONG_LONG
#define LLONG long long
#else
#define LLONG long
#endif

static size_t dopr(char *buffer, size_t maxlen, const char *format, 
		   va_list args);
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
		    char *value, int flags, int min, int max);
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
		    long value, int base, int min, int max, int flags);
static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
		   LDOUBLE fvalue, int min, int max, int flags);
static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);

/*
 * dopr(): poor man's version of doprintf
 */

/* format read states */
#define DP_S_DEFAULT 0
#define DP_S_FLAGS   1
#define DP_S_MIN     2
#define DP_S_DOT     3
#define DP_S_MAX     4
#define DP_S_MOD     5
#define DP_S_CONV    6
#define DP_S_DONE    7

/* format flags - Bits */
#define DP_F_MINUS 	(1 << 0)
#define DP_F_PLUS  	(1 << 1)
#define DP_F_SPACE 	(1 << 2)
#define DP_F_NUM   	(1 << 3)
#define DP_F_ZERO  	(1 << 4)
#define DP_F_UP    	(1 << 5)
#define DP_F_UNSIGNED 	(1 << 6)

/* Conversion Flags */
#define DP_C_SHORT   1
#define DP_C_LONG    2
#define DP_C_LDOUBLE 3
#define DP_C_LLONG   4

#define char_to_int(p) ((p)- '0')
#ifndef MAX
#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
#endif

static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args)
{
	char ch;
	LLONG value;
	LDOUBLE fvalue;
	char *strvalue;
	int min;
	int max;
	int state;
	int flags;
	int cflags;
	size_t currlen;
	
	state = DP_S_DEFAULT;
	currlen = flags = cflags = min = 0;
	max = -1;
	ch = *format++;
	
	while (state != DP_S_DONE) {
		if (ch == '\0') 
			state = DP_S_DONE;

		switch(state) {
		case DP_S_DEFAULT:
			if (ch == '%') 
				state = DP_S_FLAGS;
			else 
				dopr_outch (buffer, &currlen, maxlen, ch);
			ch = *format++;
			break;
		case DP_S_FLAGS:
			switch (ch) {
			case '-':
				flags |= DP_F_MINUS;
				ch = *format++;
				break;
			case '+':
				flags |= DP_F_PLUS;
				ch = *format++;
				break;
			case ' ':
				flags |= DP_F_SPACE;
				ch = *format++;
				break;
			case '#':
				flags |= DP_F_NUM;
				ch = *format++;
				break;
			case '0':
				flags |= DP_F_ZERO;
				ch = *format++;
				break;
			default:
				state = DP_S_MIN;
				break;
			}
			break;
		case DP_S_MIN:
			if (isdigit((unsigned char)ch)) {
				min = 10*min + char_to_int (ch);
				ch = *format++;
			} else if (ch == '*') {
				min = va_arg (args, int);
				ch = *format++;
				state = DP_S_DOT;
			} else {
				state = DP_S_DOT;
			}
			break;
		case DP_S_DOT:
			if (ch == '.') {
				state = DP_S_MAX;
				ch = *format++;
			} else { 
				state = DP_S_MOD;
			}
			break;
		case DP_S_MAX:
			if (isdigit((unsigned char)ch)) {
				if (max < 0)
					max = 0;
				max = 10*max + char_to_int (ch);
				ch = *format++;
			} else if (ch == '*') {
				max = va_arg (args, int);
				ch = *format++;
				state = DP_S_MOD;
			} else {
				state = DP_S_MOD;
			}
			break;
		case DP_S_MOD:
			switch (ch) {
			case 'h':
				cflags = DP_C_SHORT;
				ch = *format++;
				break;
			case 'l':
				cflags = DP_C_LONG;
				ch = *format++;
				if (ch == 'l') {	/* It's a long long */
					cflags = DP_C_LLONG;
					ch = *format++;
				}
				break;
			case 'L':
				cflags = DP_C_LDOUBLE;
				ch = *format++;
				break;
			default:
				break;
			}
			state = DP_S_CONV;
			break;
		case DP_S_CONV:
			switch (ch) {
			case 'd':
			case 'i':
				if (cflags == DP_C_SHORT) 
					value = va_arg (args, int);
				else if (cflags == DP_C_LONG)
					value = va_arg (args, long int);
				else if (cflags == DP_C_LLONG)
					value = va_arg (args, LLONG);
				else
					value = va_arg (args, int);
				fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
				break;
			case 'o':
				flags |= DP_F_UNSIGNED;
				if (cflags == DP_C_SHORT)
					value = va_arg (args, unsigned int);
				else if (cflags == DP_C_LONG)
					value = (long)va_arg (args, unsigned long int);
				else if (cflags == DP_C_LLONG)
					value = (long)va_arg (args, unsigned LLONG);
				else
					value = (long)va_arg (args, unsigned int);
				fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
				break;
			case 'u':
				flags |= DP_F_UNSIGNED;
				if (cflags == DP_C_SHORT)
					value = va_arg (args, unsigned int);
				else if (cflags == DP_C_LONG)
					value = (long)va_arg (args, unsigned long int);
				else if (cflags == DP_C_LLONG)
					value = (LLONG)va_arg (args, unsigned LLONG);
				else
					value = (long)va_arg (args, unsigned int);
				fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
				break;
			case 'X':
				flags |= DP_F_UP;
			case 'x':
				flags |= DP_F_UNSIGNED;
				if (cflags == DP_C_SHORT)
					value = va_arg (args, unsigned int);
				else if (cflags == DP_C_LONG)
					value = (long)va_arg (args, unsigned long int);
				else if (cflags == DP_C_LLONG)
					value = (LLONG)va_arg (args, unsigned LLONG);
				else
					value = (long)va_arg (args, unsigned int);
				fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
				break;
			case 'f':
				if (cflags == DP_C_LDOUBLE)
					fvalue = va_arg (args, LDOUBLE);
				else
					fvalue = va_arg (args, double);
				/* um, floating point? */
				fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
				break;
			case 'E':
				flags |= DP_F_UP;
			case 'e':
				if (cflags == DP_C_LDOUBLE)
					fvalue = va_arg (args, LDOUBLE);
				else
					fvalue = va_arg (args, double);
				break;
			case 'G':
				flags |= DP_F_UP;
			case 'g':
				if (cflags == DP_C_LDOUBLE)
					fvalue = va_arg (args, LDOUBLE);
				else
					fvalue = va_arg (args, double);
				break;
			case 'c':
				dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
				break;
			case 's':
				strvalue = va_arg (args, char *);
				if (max == -1) {
					max = strlen(strvalue);
				}
				if (min > 0 && max >= 0 && min > max) max = min;
				fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
				break;
			case 'p':
				strvalue = va_arg (args, void *);
				fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
				break;
			case 'n':
				if (cflags == DP_C_SHORT) {
					short int *num;
					num = va_arg (args, short int *);
					*num = currlen;
				} else if (cflags == DP_C_LONG) {
					long int *num;
					num = va_arg (args, long int *);
					*num = (long int)currlen;
				} else if (cflags == DP_C_LLONG) {
					LLONG *num;
					num = va_arg (args, LLONG *);
					*num = (LLONG)currlen;
				} else {
					int *num;
					num = va_arg (args, int *);
					*num = currlen;
				}
				break;
			case '%':
				dopr_outch (buffer, &currlen, maxlen, ch);
				break;
			case 'w':
				/* not supported yet, treat as next char */
				ch = *format++;
				break;
			default:
				/* Unknown, skip */
				break;
			}
			ch = *format++;
			state = DP_S_DEFAULT;
			flags = cflags = min = 0;
			max = -1;
			break;
		case DP_S_DONE:
			break;
		default:
			/* hmm? */
			break; /* some picky compilers need this */
		}
	}
	if (maxlen != 0) {
		if (currlen < maxlen - 1) 
			buffer[currlen] = '\0';
		else if (maxlen > 0) 
			buffer[maxlen - 1] = '\0';
	}
	
	return currlen;
}

static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
		    char *value, int flags, int min, int max)
{
	int padlen, strln;     /* amount to pad */
	int cnt = 0;

#ifdef DEBUG_SNPRINTF
	printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value);
#endif
	if (value == 0) {
		value = "<NULL>";
	}

	for (strln = 0; value[strln]; ++strln); /* strlen */
	padlen = min - strln;
	if (padlen < 0) 
		padlen = 0;
	if (flags & DP_F_MINUS) 
		padlen = -padlen; /* Left Justify */
	
	while ((padlen > 0) && (cnt < max)) {
		dopr_outch (buffer, currlen, maxlen, ' ');
		--padlen;
		++cnt;
	}
	while (*value && (cnt < max)) {
		dopr_outch (buffer, currlen, maxlen, *value++);
		++cnt;
	}
	while ((padlen < 0) && (cnt < max)) {
		dopr_outch (buffer, currlen, maxlen, ' ');
		++padlen;
		++cnt;
	}
}

/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */

static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
		    long value, int base, int min, int max, int flags)
{
	int signvalue = 0;
	unsigned long uvalue;
	char convert[20];
	int place = 0;
	int spadlen = 0; /* amount to space pad */
	int zpadlen = 0; /* amount to zero pad */
	int caps = 0;
	
	if (max < 0)
		max = 0;
	
	uvalue = value;
	
	if(!(flags & DP_F_UNSIGNED)) {
		if( value < 0 ) {
			signvalue = '-';
			uvalue = -value;
		} else {
			if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
				signvalue = '+';
			else if (flags & DP_F_SPACE)
				signvalue = ' ';
		}
	}
  
	if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */

	do {
		convert[place++] =
			(caps? "0123456789ABCDEF":"0123456789abcdef")
			[uvalue % (unsigned)base  ];
		uvalue = (uvalue / (unsigned)base );
	} while(uvalue && (place < 20));
	if (place == 20) place--;
	convert[place] = 0;

	zpadlen = max - place;
	spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
	if (zpadlen < 0) zpadlen = 0;
	if (spadlen < 0) spadlen = 0;
	if (flags & DP_F_ZERO) {
		zpadlen = MAX(zpadlen, spadlen);
		spadlen = 0;
	}
	if (flags & DP_F_MINUS) 
		spadlen = -spadlen; /* Left Justifty */

#ifdef DEBUG_SNPRINTF
	printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
	       zpadlen, spadlen, min, max, place);
#endif

	/* Spaces */
	while (spadlen > 0) {
		dopr_outch (buffer, currlen, maxlen, ' ');
		--spadlen;
	}

	/* Sign */
	if (signvalue) 
		dopr_outch (buffer, currlen, maxlen, signvalue);

	/* Zeros */
	if (zpadlen > 0) {
		while (zpadlen > 0) {
			dopr_outch (buffer, currlen, maxlen, '0');
			--zpadlen;
		}
	}

	/* Digits */
	while (place > 0) 
		dopr_outch (buffer, currlen, maxlen, convert[--place]);
  
	/* Left Justified spaces */
	while (spadlen < 0) {
		dopr_outch (buffer, currlen, maxlen, ' ');
		++spadlen;
	}
}

static LDOUBLE abs_val(LDOUBLE value)
{
	LDOUBLE result = value;

	if (value < 0)
		result = -value;
	
	return result;
}

static LDOUBLE POW10(int exp)
{
	LDOUBLE result = 1;
	
	while (exp) {
		result *= 10;
		exp--;
	}
  
	return result;
}

static LLONG ROUND(LDOUBLE value)
{
	LLONG intpart;

	intpart = (LLONG)value;
	value = value - intpart;
	if (value >= 0.5) intpart++;
	
	return intpart;
}

/* a replacement for modf that doesn't need the math library. Should
   be portable, but slow */
static double my_modf(double x0, double *iptr)
{
	int i;
	long l;
	double x = x0;
	double f = 1.0;

	for (i=0;i<100;i++) {
		l = (long)x;
		if (l <= (x+1) && l >= (x-1)) break;
		x *= 0.1;
		f *= 10.0;
	}

	if (i == 100) {
		/* yikes! the number is beyond what we can handle. What do we do? */
		(*iptr) = 0;
		return 0;
	}

	if (i != 0) {
		double i2;
		double ret;

		ret = my_modf(x0-l*f, &i2);
		(*iptr) = l*f + i2;
		return ret;
	} 

	(*iptr) = l;
	return x - (*iptr);
}


static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
		   LDOUBLE fvalue, int min, int max, int flags)
{
	int signvalue = 0;
	double ufvalue;
	char iconvert[311];
	char fconvert[311];
	int iplace = 0;
	int fplace = 0;
	int padlen = 0; /* amount to pad */
	int zpadlen = 0; 
	int caps = 0;
	int index;
	double intpart;
	double fracpart;
	double temp;
  
	/* 
	 * AIX manpage says the default is 0, but Solaris says the default
	 * is 6, and sprintf on AIX defaults to 6
	 */
	if (max < 0)
		max = 6;

	ufvalue = abs_val (fvalue);

	if (fvalue < 0) {
		signvalue = '-';
	} else {
		if (flags & DP_F_PLUS) { /* Do a sign (+/i) */
			signvalue = '+';
		} else {
			if (flags & DP_F_SPACE)
				signvalue = ' ';
		}
	}

#if 0
	if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
#endif

#if 0
	 if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */
#endif

	/* 
	 * Sorry, we only support 16 digits past the decimal because of our 
	 * conversion method
	 */
	if (max > 16)
		max = 16;

	/* We "cheat" by converting the fractional part to integer by
	 * multiplying by a factor of 10
	 */

	temp = ufvalue;
	my_modf(temp, &intpart);

	fracpart = ROUND((POW10(max)) * (ufvalue - intpart));
	
	if (fracpart >= POW10(max)) {
		intpart++;
		fracpart -= POW10(max);
	}


	/* Convert integer part */
	do {
		temp = intpart;
		my_modf(intpart*0.1, &intpart);
		temp = temp*0.1;
		index = (int) ((temp -intpart +0.05)* 10.0);
		/* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
		/* printf ("%llf, %f, %x\n", temp, intpart, index); */
		iconvert[iplace++] =
			(caps? "0123456789ABCDEF":"0123456789abcdef")[index];
	} while (intpart && (iplace < 311));
	if (iplace == 311) iplace--;
	iconvert[iplace] = 0;

	/* Convert fractional part */
	if (fracpart)
	{
		do {
			temp = fracpart;
			my_modf(fracpart*0.1, &fracpart);
			temp = temp*0.1;
			index = (int) ((temp -fracpart +0.05)* 10.0);
			/* index = (int) ((((temp/10) -fracpart) +0.05) *10); */
			/* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */
			fconvert[fplace++] =
			(caps? "0123456789ABCDEF":"0123456789abcdef")[index];
		} while(fracpart && (fplace < 311));
		if (fplace == 311) fplace--;
	}
	fconvert[fplace] = 0;
  
	/* -1 for decimal point, another -1 if we are printing a sign */
	padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
	zpadlen = max - fplace;
	if (zpadlen < 0) zpadlen = 0;
	if (padlen < 0) 
		padlen = 0;
	if (flags & DP_F_MINUS) 
		padlen = -padlen; /* Left Justifty */
	
	if ((flags & DP_F_ZERO) && (padlen > 0)) {
		if (signvalue) {
			dopr_outch (buffer, currlen, maxlen, signvalue);
			--padlen;
			signvalue = 0;
		}
		while (padlen > 0) {
			dopr_outch (buffer, currlen, maxlen, '0');
			--padlen;
		}
	}
	while (padlen > 0) {
		dopr_outch (buffer, currlen, maxlen, ' ');
		--padlen;
	}
	if (signvalue) 
		dopr_outch (buffer, currlen, maxlen, signvalue);
	
	while (iplace > 0) 
		dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);

#ifdef DEBUG_SNPRINTF
	printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen);
#endif

	/*
	 * Decimal point.  This should probably use locale to find the correct
	 * char to print out.
	 */
	if (max > 0) {
		dopr_outch (buffer, currlen, maxlen, '.');
		
		while (fplace > 0) 
			dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
	}
	
	while (zpadlen > 0) {
		dopr_outch (buffer, currlen, maxlen, '0');
		--zpadlen;
	}

	while (padlen < 0) {
		dopr_outch (buffer, currlen, maxlen, ' ');
		++padlen;
	}
}

static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
{
	if (*currlen < maxlen) {
		buffer[(*currlen)] = c;
	}
	(*currlen)++;
}

#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
 int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
{
	return dopr(str, count, fmt, args);
}
#endif

#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
 int snprintf(char *str,size_t count,const char *fmt,...)
{
	size_t ret;
	va_list ap;
    
	va_start(ap, fmt);
	ret = vsnprintf(str, count, fmt, ap);
	va_end(ap);
	return ret;
}
#endif

#endif 

#ifndef HAVE_VASPRINTF
 int vasprintf(char **ptr, const char *format, va_list ap)
{
	int ret;
	
	ret = vsnprintf(NULL, 0, format, ap);
	if (ret <= 0) return ret;

	(*ptr) = (char *)malloc(ret+1);
	if (!*ptr) return -1;
	ret = vsnprintf(*ptr, ret+1, format, ap);

	return ret;
}
#endif


#ifndef HAVE_ASPRINTF
 int asprintf(char **ptr, const char *format, ...)
{
	va_list ap;
	int ret;
	
	va_start(ap, format);
	ret = vasprintf(ptr, format, ap);
	va_end(ap);

	return ret;
}
#endif

#ifdef TEST_SNPRINTF

 int sprintf(char *str,const char *fmt,...);

 int main (void)
{
	char buf1[1024];
	char buf2[1024];
	char *fp_fmt[] = {
		"%1.1f",
		"%-1.5f",
		"%1.5f",
		"%123.9f",
		"%10.5f",
		"% 10.5f",
		"%+22.9f",
		"%+4.9f",
		"%01.3f",
		"%4f",
		"%3.1f",
		"%3.2f",
		"%.0f",
		"%f",
		"-16.16f",
		NULL
	};
	double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 
			     0.9996, 1.996, 4.136,  0};
	char *int_fmt[] = {
		"%-1.5d",
		"%1.5d",
		"%123.9d",
		"%5.5d",
		"%10.5d",
		"% 10.5d",
		"%+22.33d",
		"%01.3d",
		"%4d",
		"%d",
		NULL
	};
	long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
	char *str_fmt[] = {
		"10.5s",
		"5.10s",
		"10.1s",
		"0.10s",
		"10.0s",
		"1.10s",
		"%s",
		"%.1s",
		"%.10s",
		"%10s",
		NULL
	};
	char *str_vals[] = {"hello", "a", "", "a longer string", NULL};
	int x, y;
	int fail = 0;
	int num = 0;

	printf ("Testing snprintf format codes against system sprintf...\n");

	for (x = 0; fp_fmt[x] ; x++) {
		for (y = 0; fp_nums[y] != 0 ; y++) {
			int l1 = snprintf(NULL, 0, fp_fmt[x], fp_nums[y]);
			int l2 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]);
			sprintf (buf2, fp_fmt[x], fp_nums[y]);
			if (strcmp (buf1, buf2)) {
				printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", 
				       fp_fmt[x], buf1, buf2);
				fail++;
			}
			if (l1 != l2) {
				printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, fp_fmt[x]);
				fail++;
			}
			num++;
		}
	}

	for (x = 0; int_fmt[x] ; x++) {
		for (y = 0; int_nums[y] != 0 ; y++) {
			int l1 = snprintf(NULL, 0, int_fmt[x], int_nums[y]);
			int l2 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]);
			sprintf (buf2, int_fmt[x], int_nums[y]);
			if (strcmp (buf1, buf2)) {
				printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", 
				       int_fmt[x], buf1, buf2);
				fail++;
			}
			if (l1 != l2) {
				printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, int_fmt[x]);
				fail++;
			}
			num++;
		}
	}

	for (x = 0; str_fmt[x] ; x++) {
		for (y = 0; str_vals[y] != 0 ; y++) {
			int l1 = snprintf(NULL, 0, str_fmt[x], str_vals[y]);
			int l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]);
			sprintf (buf2, str_fmt[x], str_vals[y]);
			if (strcmp (buf1, buf2)) {
				printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", 
				       str_fmt[x], buf1, buf2);
				fail++;
			}
			if (l1 != l2) {
				printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, str_fmt[x]);
				fail++;
			}
			num++;
		}
	}

	printf ("%d tests failed out of %d.\n", fail, num);

	printf("seeing how many digits we support\n");
	{
		double v0 = 0.12345678901234567890123456789012345678901;
		for (x=0; x<100; x++) {
			snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x));
			sprintf(buf2,                "%1.1f", v0*pow(10, x));
			if (strcmp(buf1, buf2)) {
				printf("we seem to support %d digits\n", x-1);
				break;
			}
		}
	}

	return 0;
}
#endif /* SNPRINTF_TEST */
rsync-2.5.7/packaging/0040755000111500011410000000000007763533616014634 5ustar  rsync-bugsrsyncrsync-2.5.7/packaging/lsb/0040755000111500011150000000000007763533616016353 5ustar  rsync-bugsrsync-bugsrsync-2.5.7/packaging/lsb/rsync.spec0100644000111500011150000000515707763533644020373 0ustar  rsync-bugsrsync-bugsSummary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.7
Release: 1
Copyright: GPL
Group: Applications/Networking
Source:	ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.7.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync

%description
rsync is a replacement for rcp that has many more features.

rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.

A technical report describing the rsync algorithm is included with
this package. 

%changelog
* Mon Sept 11 2000 John H Terpstra <jht@turbolinux.com>
  Changed target paths to be Linux Standards Base compliant

* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
  quoted RPM_OPT_FLAGS for the sake of robustness  
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
  reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)

* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
  Upgraded to Rsync 2.0.6
    -new feature anonymous rsync

* Mon Apr  6 1998 Douglas N. Arnold <dna@math.psu.edu>

Upgrade to rsync version 1.7.2.

* Sun Mar  1 1998 Douglas N. Arnold <dna@math.psu.edu>

Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.

* Mon Aug 25 1997 John A. Martin <jam@jamux.com>

Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving 
"Source RPM: rsync-1.6.3-1.src.rpm".

Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.

* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>

rsync-1.6.2-1 packaged.  (This entry by jam to credit Michael for the
previous package(s).)

%prep
%setup

%build
./configure --prefix=/usr --mandir=/usr/share/man
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync

%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,share/man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/share/man/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/share/man/man5

%clean
rm -rf $RPM_BUILD_ROOT

%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/share/man/man1/rsync.1
%attr(-,root,root) /usr/share/man/man5/rsyncd.conf.5
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING
rsync-2.5.7/packaging/redhat/0040755000111500011410000000000007401550371016065 5ustar  rsync-bugsrsyncrsync-2.5.7/packaging/redhat/5.0/0040755000111500011410000000000007763533616016405 5ustar  rsync-bugsrsyncrsync-2.5.7/packaging/redhat/5.0/rsync.spec0100644000111500011150000000470407763533644021361 0ustar  rsync-bugsrsync-bugsSummary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.7
Release: 1
Copyright: GPL
Group: Applications/Networking
Source:	ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.7.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync

%description
rsync is a replacement for rcp that has many more features.

rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.

A technical report describing the rsync algorithm is included with
this package. 

%changelog
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
  quoted RPM_OPT_FLAGS for the sake of robustness  
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
  reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)

* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
  Upgraded to Rsync 2.0.6
    -new feature anonymous rsync

* Mon Apr  6 1998 Douglas N. Arnold <dna@math.psu.edu>

Upgrade to rsync version 1.7.2.

* Sun Mar  1 1998 Douglas N. Arnold <dna@math.psu.edu>

Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.

* Mon Aug 25 1997 John A. Martin <jam@jamux.com>

Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving 
"Source RPM: rsync-1.6.3-1.src.rpm".

Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.

* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>

rsync-1.6.2-1 packaged.  (This entry by jam to credit Michael for the
previous package(s).)

%prep
%setup

%build
./configure --prefix=/usr
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync

%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/man/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/man/man5

%clean
rm -rf $RPM_BUILD_ROOT

%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/man/man1/rsync.1
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING
rsync-2.5.7/packaging/redhat/7.1/0040755000111500011150000000000007763533616017347 5ustar  rsync-bugsrsync-bugsrsync-2.5.7/packaging/redhat/7.1/rsync.spec0100644000111500011150000000471007763533644021361 0ustar  rsync-bugsrsync-bugsSummary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.7
Release: 1
Copyright: GPL
Group: Applications/Networking
Source:	ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.7.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync

%description
rsync is a replacement for rcp that has many more features.

rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.

A technical report describing the rsync algorithm is included with
this package. 

%changelog
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
  quoted RPM_OPT_FLAGS for the sake of robustness  
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
  reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)

* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
  Upgraded to Rsync 2.0.6
    -new feature anonymous rsync

* Mon Apr  6 1998 Douglas N. Arnold <dna@math.psu.edu>

Upgrade to rsync version 1.7.2.

* Sun Mar  1 1998 Douglas N. Arnold <dna@math.psu.edu>

Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.

* Mon Aug 25 1997 John A. Martin <jam@jamux.com>

Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving 
"Source RPM: rsync-1.6.3-1.src.rpm".

Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.

* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>

rsync-1.6.2-1 packaged.  (This entry by jam to credit Michael for the
previous package(s).)

%prep
%setup

%build
./configure --prefix=/usr
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync

%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1* $RPM_BUILD_ROOT/usr/man/man1
install -m644 rsyncd.conf.5* $RPM_BUILD_ROOT/usr/man/man5

%clean
rm -rf $RPM_BUILD_ROOT

%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/man/man1/rsync.1*
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5*
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING
rsync-2.5.7/packaging/solaris/0040755000111500011150000000000007763533616017247 5ustar  rsync-bugsrsync-bugsrsync-2.5.7/packaging/solaris/build_pkg.sh0100644000111500011150000000474707505125477021550 0ustar  rsync-bugsrsync-bugs#!/bin/sh
# Shell script for building Solaris package of rsync
# Author: Jens Apel <jens.apel@web.de>
# License: GPL
#
# BASEDIR is /usr/local and should be the same as the
# --prefix parameter of configure
#
# this script should be copied under
# packaging/solaris/5.8/build_pkg.sh

# Definitions start here
# you can edit this, if you like

# The Package name under which rsync will b installed
PKGNAME=SMBrsync

# Extract common info requires for the 'info' part of the package.
# This should be made generic and generated by the configure script
# but for now it is hard coded
BASEDIR=/usr/local
VERSION="2.5.5"
ARCH=`uname -p`
NAME=rsync

# Definitions end here
# Please do not edit below this line or you know what you do.

## Start by faking root install
echo "Creating install directory (fake $BASEDIR)..."
START=`pwd`
FAKE_ROOT=$START/${PKGNAME}
mkdir $FAKE_ROOT

# copy the binary and the man page to their places
mkdir $FAKE_ROOT/bin
mkdir -p $FAKE_ROOT/doc/rsync
mkdir -p $FAKE_ROOT/man/man1
mkdir -p $FAKE_ROOT/man/man5

cp ../../../rsync $FAKE_ROOT/bin/rsync
cp ../../../rsync.1 $FAKE_ROOT/man/man1/rsync.1
cp ../../../rsyncd.conf.5 $FAKE_ROOT/man/man5/rsyncd.conf.5
cp ../../../README $FAKE_ROOT/doc/rsync/README
cp ../../../COPYING $FAKE_ROOT/doc/rsync/COPYING
cp ../../../tech_report.pdf $FAKE_ROOT/doc/rsync/tech_report.pdf
cp ../../../COPYING $FAKE_ROOT/COPYING

## Build info file
echo "Building pkginfo file..."
cat > $FAKE_ROOT/pkginfo << EOF_INFO
PKG=$PKGNAME
NAME=$NAME
DESC="Program for efficient remote updates of files."
VENDOR="Samba Team URL: http://samba.anu.edu.au/rsync/"
BASEDIR=$BASEDIR
ARCH=$ARCH
VERSION=$VERSION
CATEGORY=application
CLASSES=none
EOF_INFO

## Build prototype file
cat > $FAKE_ROOT/prototype << EOFPROTO
i copyright=COPYING
i pkginfo=pkginfo
d none bin 0755 bin bin
f none bin/rsync 0755 bin bin
d none doc 0755 bin bin
d none doc/$NAME 0755 bin bin
f none doc/$NAME/README 0644 bin bin
f none doc/$NAME/COPYING 0644 bin bin
f none doc/$NAME/tech_report.pdf 0644 bin bin
d none man 0755 bin bin
d none man/man1 0755 bin bin
f none man/man1/rsync.1 0644 bin bin
d none man/man5 0755 bin bin
f none man/man5/rsyncd.conf.5 0644 bin bin
EOFPROTO

## And now build the package.
OUTPUTFILE=$PKGNAME-$VERSION-sol8-$ARCH-local.pkg
echo "Building package.."
echo FAKE_ROOT = $FAKE_ROOT
cd $FAKE_ROOT
pkgmk -d . -r . -f ./prototype -o
pkgtrans -os . $OUTPUTFILE $PKGNAME

mv $OUTPUTFILE ..
cd ..

# Comment this out if you want to see, which file structure has been created
rm -rf $FAKE_ROOT

rsync-2.5.7/authenticate.c0100644000111500011150000001551507763533615016474 0ustar  rsync-bugsrsync-bugs/* -*- c-file-style: "linux"; -*-
   
   Copyright (C) 1998-2000 by Andrew Tridgell 
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/* support rsync authentication */
#include "rsync.h"

/***************************************************************************
encode a buffer using base64 - simple and slow algorithm. null terminates
the result.
  ***************************************************************************/
static void base64_encode(char *buf, int len, char *out)
{
	char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	int bit_offset, byte_offset, idx, i;
	unsigned char *d = (unsigned char *)buf;
	int bytes = (len*8 + 5)/6;

	memset(out, 0, bytes+1);

	for (i=0;i<bytes;i++) {
		byte_offset = (i*6)/8;
		bit_offset = (i*6)%8;
		if (bit_offset < 3) {
			idx = (d[byte_offset] >> (2-bit_offset)) & 0x3F;
		} else {
			idx = (d[byte_offset] << (bit_offset-2)) & 0x3F;
			if (byte_offset+1 < len) {
				idx |= (d[byte_offset+1] >> (8-(bit_offset-2)));
			}
		}
		out[i] = b64[idx];
	}
}

/* create a 16 byte challenge buffer */
static void gen_challenge(char *addr, char *challenge)
{
	char input[32];
	struct timeval tv;

	memset(input, 0, sizeof(input));

	strlcpy((char *)input, addr, 17);
	sys_gettimeofday(&tv);
	SIVAL(input, 16, tv.tv_sec);
	SIVAL(input, 20, tv.tv_usec);
	SIVAL(input, 24, getpid());

	sum_init();
	sum_update(input, sizeof(input));
	sum_end(challenge);
}


/* return the secret for a user from the sercret file. maximum length
   is len. null terminate it */
static int get_secret(int module, char *user, char *secret, int len)
{
	char *fname = lp_secrets_file(module);
	int fd, found=0;
	char line[MAXPATHLEN];
	char *p, *pass=NULL;
	STRUCT_STAT st;
	int ok = 1;
	extern int am_root;

	if (!fname || !*fname) return 0;

	fd = open(fname,O_RDONLY);
	if (fd == -1) return 0;

	if (do_stat(fname, &st) == -1) {
		rsyserr(FERROR, errno, "stat(%s)", fname);
		ok = 0;
	} else if (lp_strict_modes(module)) {
		if ((st.st_mode & 06) != 0) {
			rprintf(FERROR,"secrets file must not be other-accessible (see strict modes option)\n");
			ok = 0;
		} else if (am_root && (st.st_uid != 0)) {
			rprintf(FERROR,"secrets file must be owned by root when running as root (see strict modes)\n");
			ok = 0;
		}
	}
	if (!ok) {
		rprintf(FERROR,"continuing without secrets file\n");
		close(fd);
		return 0;
	}

	while (!found) {
		int i = 0;
		memset(line, 0, sizeof line);
		while ((size_t) i < (sizeof(line)-1)) {
			if (read(fd, &line[i], 1) != 1) {
				memset(line, 0, sizeof(line));
				close(fd);
				return 0;
			}
			if (line[i] == '\r') continue;
			if (line[i] == '\n') break;
			i++;
		}
		line[i] = 0;
		if (line[0] == '#') continue;
		p = strchr(line,':');
		if (!p) continue;
		*p = 0;
		if (strcmp(user, line)) continue;
		pass = p+1;
		found = 1;
	}

	close(fd);
	if (!found) return 0;

	strlcpy(secret, pass, len);
	return 1;
}

static char *getpassf(char *filename)
{
	char buffer[100];
	int fd=0;
	STRUCT_STAT st;
	int ok = 1;
	extern int am_root;
	char *envpw=getenv("RSYNC_PASSWORD");

	if (!filename) return NULL;

	if ( (fd=open(filename,O_RDONLY)) == -1) {
		rsyserr(FERROR, errno, "could not open password file \"%s\"",filename);
		if (envpw) rprintf(FERROR,"falling back to RSYNC_PASSWORD environment variable.\n");	
		return NULL;
	}
	
	if (do_stat(filename, &st) == -1) {
		rsyserr(FERROR, errno, "stat(%s)", filename);
		ok = 0;
	} else if ((st.st_mode & 06) != 0) {
		rprintf(FERROR,"password file must not be other-accessible\n");
		ok = 0;
	} else if (am_root && (st.st_uid != 0)) {
		rprintf(FERROR,"password file must be owned by root when running as root\n");
		ok = 0;
	}
	if (!ok) {
		rprintf(FERROR,"continuing without password file\n");
		if (envpw) rprintf(FERROR,"using RSYNC_PASSWORD environment variable.\n");
		close(fd);
		return NULL;
	}

	if (envpw) rprintf(FERROR,"RSYNC_PASSWORD environment variable ignored\n");

	buffer[sizeof(buffer)-1]='\0';
	if (read(fd,buffer,sizeof(buffer)-1) > 0)
	{
		char *p = strtok(buffer,"\n\r");
		close(fd);
		if (p) p = strdup(p);
		return p;
	}	

	return NULL;
}

/* generate a 16 byte hash from a password and challenge */
static void generate_hash(char *in, char *challenge, char *out)
{
	char buf[16];

	sum_init();
	sum_update(in, strlen(in));
	sum_update(challenge, strlen(challenge));
	sum_end(buf);

	base64_encode(buf, 16, out);
}

/* possible negotiate authentication with the client. Use "leader" to
   start off the auth if necessary 

   return NULL if authentication failed

   return "" if anonymous access

   otherwise return username
*/
char *auth_server(int f_in, int f_out, int module, char *addr, char *leader)
{
	char *users = lp_auth_users(module);
	char challenge[16];
	char b64_challenge[30];
	char line[MAXPATHLEN];
	static char user[100];
	char secret[100];
	char pass[30];
	char pass2[30];
	char *tok;

	/* if no auth list then allow anyone in! */
	if (!users || !*users) return "";

	gen_challenge(addr, challenge);
	
	base64_encode(challenge, 16, b64_challenge);

	io_printf(f_out, "%s%s\n", leader, b64_challenge);

	if (!read_line(f_in, line, sizeof(line)-1)) {
		return NULL;
	}

	memset(user, 0, sizeof(user));
	memset(pass, 0, sizeof(pass));

	if (sscanf(line,"%99s %29s", user, pass) != 2) {
		return NULL;
	}
	
	users = strdup(users);
	if (!users) return NULL;

	for (tok=strtok(users," ,\t"); tok; tok = strtok(NULL," ,\t")) {
		if (fnmatch(tok, user, 0) == 0) break;
	}
	free(users);

	if (!tok) {
		return NULL;
	}
	
	memset(secret, 0, sizeof(secret));
	if (!get_secret(module, user, secret, sizeof(secret)-1)) {
		memset(secret, 0, sizeof(secret));
		return NULL;
	}

	generate_hash(secret, b64_challenge, pass2);
	memset(secret, 0, sizeof(secret));
	
	if (strcmp(pass, pass2) == 0)
		return user;

	return NULL;
}


void auth_client(int fd, char *user, char *challenge)
{
	char *pass;
	char pass2[30];
	extern char *password_file;

	if (!user || !*user) return;

	if (!(pass=getpassf(password_file)) && !(pass=getenv("RSYNC_PASSWORD"))) {
		/* XXX: cyeoh says that getpass is deprecated, because
		   it may return a truncated password on some systems,
		   and it is not in the LSB. */
		pass = getpass("Password: ");
	}

	if (!pass || !*pass) {
		pass = "";
	}

	generate_hash(pass, challenge, pass2);
	io_printf(fd, "%s %s\n", user, pass2);
}


rsync-2.5.7/patches/0040755000111500011150000000000007763533616015276 5ustar  rsync-bugsrsync-bugsrsync-2.5.7/patches/db3l_ignore-case.diff0100644000111500011150000001777607457740311021237 0ustar  rsync-bugsrsync-bugsFrom rsync-admin@lists.samba.org  Thu Apr 18 20:05:33 2002
Return-Path: <rsync-admin@lists.samba.org>
Delivered-To: mbp@samba.org
Received: from va.samba.org (localhost [127.0.0.1])
	by lists.samba.org (Postfix) with ESMTP
	id 8AD0349D4; Thu, 18 Apr 2002 20:05:32 -0700 (PDT)
Delivered-To: rsync@lists.samba.org
Received: from ctmsg01.corp.fitlinxx.com (mail.fitlinxx.com [208.247.212.10])
	by lists.samba.org (Postfix) with ESMTP id 12ED449C6
	for <rsync@lists.samba.org>; Thu, 18 Apr 2002 20:05:00 -0700 (PDT)
Received: by ctmsg01.corp.fitlinxx.com with Internet Mail Service (5.5.2653.19)
	id <JCL2B4NB>; Thu, 18 Apr 2002 23:04:07 -0400
Message-ID: <926F937512224245A616323693D3F16B1C0022@ctmsg01.corp.fitlinxx.com>
From: David Bolen <db3l@fitlinxx.com>
To: 'Peter Tattam' <peter@jazz-1.trumpet.com.au>
Cc: rsync@lists.samba.org
Subject: RE: mixed case file systems.
MIME-Version: 1.0
X-Mailer: Internet Mail Service (5.5.2653.19)
Content-Type: text/plain;
	charset="iso-8859-1"
Sender: rsync-admin@lists.samba.org
Errors-To: rsync-admin@lists.samba.org
X-BeenThere: rsync@lists.samba.org
X-Mailman-Version: 2.0.8
Precedence: bulk
List-Help: <mailto:rsync-request@lists.samba.org?subject=help>
List-Post: <mailto:rsync@lists.samba.org>
List-Subscribe: <http://lists.samba.org/mailman/listinfo/rsync>,
	<mailto:rsync-request@lists.samba.org?subject=subscribe>
List-Id: rsync user list <rsync.lists.samba.org>
List-Unsubscribe: <http://lists.samba.org/mailman/listinfo/rsync>,
	<mailto:rsync-request@lists.samba.org?subject=unsubscribe>
List-Archive: <http://lists.samba.org/pipermail/rsync/>
X-Original-Date: Thu, 18 Apr 2002 23:04:06 -0400
Date: Thu, 18 Apr 2002 23:04:06 -0400
Status: RO
X-Status: A
Content-Length: 6452
Lines: 205

Peter Tattam [peter@jazz-1.trumpet.com.au] writes:

> I believe a suitable workaround would be to ignore case for file names
> when the rsync process is undertaken.  Is this facility available or
> planned in the near future?

I've attached a context diff for some changes I made to our local copy
a while back to add an "--ignore-case" option just for this purpose.
In our case it came up in the context of disting between NTFS and FAT
remote systems.  I think we ended up not needing it, but it does make
rsync match filenames in a case insensitive manner, so it might at
least be worth trying to see if it resolves your issue.

A few caveats - both ends have to support the option - I couldn't make
it backwards compatible because both ends exchange information about a
sorted file list that has to sort the same way on either side (which
very subtly bit me when I first did this).  I also didn't bump the
protocol in this patch (wasn't quite sure it was appropriate just for an
incompatible command line option) since since it was for local use.

The patch is based on a 2.4.x series rsync, but if it doesn't apply
cleanly to 2.5.x, it's should be simple enough to just apply manually.

-- David

/-----------------------------------------------------------------------\
 \               David Bolen            \   E-mail: db3l@fitlinxx.com  /
  |             FitLinxx, Inc.            \  Phone: (203) 708-5192    |
 /  860 Canal Street, Stamford, CT  06902   \  Fax: (203) 316-5150     \
\-----------------------------------------------------------------------/

	  - - - - - - - - - - - - - - - - - - - - - - - - -

Index: options.c
===================================================================
RCS file: e:/binaries/cvs/ni/bin/rsync/options.c,v
retrieving revision 1.5
retrieving revision 1.7
diff -c -r1.5 -r1.7
*** options.c	2000/12/28 00:30:18	1.5
--- options.c	2001/06/20 19:25:24	1.7
***************
*** 72,77 ****
--- 72,78 ----
  #else
  int modify_window=0;
  #endif /* _WIN32 */
+ int ignore_case=0;
  int modify_window_set=0;
  int delete_sent=0;
  
***************
*** 162,167 ****
--- 164,170 ----
    rprintf(F,"     --exclude-from=FILE     exclude patterns listed in
FILE\n");
    rprintf(F,"     --include=PATTERN       don't exclude files matching
PATTERN\n");
    rprintf(F,"     --include-from=FILE     don't exclude patterns listed in
FILE\n");
+   rprintf(F,"     --ignore-case           ignore case when comparing
filenames\n");
    rprintf(F,"     --version               print version number\n");  
    rprintf(F,"     --daemon                run as a rsync daemon\n");  
    rprintf(F,"     --address               bind to the specified
address\n");  
***************
*** 186,194 ****
        OPT_PROGRESS, OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS,
OPT_COMPARE_DEST,
        OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
        OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR, 
!       OPT_IGNORE_ERRORS, OPT_MODIFY_WINDOW, OPT_DELETE_SENT};
  
! static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
  
  static struct option long_options[] = {
    {"version",     0,     0,    OPT_VERSION},
--- 189,198 ----
        OPT_PROGRESS, OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS,
OPT_COMPARE_DEST,
        OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
        OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR, 
!       OPT_IGNORE_ERRORS, OPT_MODIFY_WINDOW, OPT_DELETE_SENT,
!       OPT_IGNORE_CASE};
  
! static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
  
  static struct option long_options[] = {
    {"version",     0,     0,    OPT_VERSION},
***************
*** 204,209 ****
--- 208,214 ----
    {"exclude-from",1,     0,    OPT_EXCLUDE_FROM},
    {"include",     1,     0,    OPT_INCLUDE},
    {"include-from",1,     0,    OPT_INCLUDE_FROM},
+   {"ignore-case", 0,     0,    OPT_IGNORE_CASE},
    {"rsync-path",  1,     0,    OPT_RSYNC_PATH},
    {"password-file", 1,	0,     OPT_PASSWORD_FILE},
    {"one-file-system",0,  0,    'x'},
***************
*** 401,406 ****
--- 406,415 ----
  			add_exclude_file(optarg,1, 1);
  			break;
  
+ 		case OPT_IGNORE_CASE:
+ 		        ignore_case=1;
+ 			break;
+ 		      
  		case OPT_COPY_UNSAFE_LINKS:
  			copy_unsafe_links=1;
  			break;
***************
*** 712,717 ****
--- 727,736 ----
  	        slprintf(mwindow,sizeof(mwindow),"--modify-window=%d",
  			 modify_window);
  		args[ac++] = mwindow;
+ 	}
+ 
+ 	if (ignore_case) {
+ 	   args[ac++] = "--ignore-case";
  	}
  
  	if (keep_partial)
Index: exclude.c
===================================================================
RCS file: e:/binaries/cvs/ni/bin/rsync/exclude.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** exclude.c	2000/05/30 18:08:19	1.1.1.1
--- exclude.c	2001/06/14 04:30:17	1.2
***************
*** 31,36 ****
--- 31,37 ----
  static struct exclude_struct *make_exclude(char *pattern, int include)
  {
  	struct exclude_struct *ret;
+ 	extern int ignore_case;
  
  	ret = (struct exclude_struct *)malloc(sizeof(*ret));
  	if (!ret) out_of_memory("make_exclude");
***************
*** 72,77 ****
--- 73,82 ----
  
  	if (!strchr(ret->pattern,'/')) {
  		ret->local = 1;
+ 	}
+ 
+ 	if (ignore_case) {
+ 	   ret->fnmatch_flags |= FNM_CASEFOLD;
  	}
  
  	return ret;
Index: util.c
===================================================================
RCS file: e:/binaries/cvs/ni/bin/rsync/util.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -c -r1.2 -r1.3
*** util.c	2000/07/07 03:23:40	1.2
--- util.c	2001/06/14 04:30:17	1.3
***************
*** 838,849 ****
  {
  	const uchar *s1 = (const uchar *)cs1;
  	const uchar *s2 = (const uchar *)cs2;
  
! 	while (*s1 && *s2 && (*s1 == *s2)) {
! 		s1++; s2++;
  	}
- 	
- 	return (int)*s1 - (int)*s2;
  }
  
  static OFF_T last_ofs;
--- 836,856 ----
  {
  	const uchar *s1 = (const uchar *)cs1;
  	const uchar *s2 = (const uchar *)cs2;
+ 	extern int ignore_case;
+ 	
+ 	if (ignore_case) {
+ 		while (*s1 && *s2 && (toupper(*s1) == toupper(*s2))) {
+ 			s1++; s2++;
+ 		}
+ 
+ 		return (int)toupper(*s1) - (int)toupper(*s2);
+ 	} else {
+ 		while (*s1 && *s2 && (*s1 == *s2)) {
+ 			s1++; s2++;
+ 		}
  
! 		return (int)*s1 - (int)*s2;
  	}
  }
  
  static OFF_T last_ofs;

-- 
To unsubscribe or change options: http://lists.samba.org/mailman/listinfo/rsync
Before posting, read: http://www.tuxedo.org/~esr/faqs/smart-questions.html

rsync-2.5.7/patches/craigb-perf.diff0100644000111500011150000002472707611103567020310 0ustar  rsync-bugsrsync-bugsTo: rsync@lists.samba.org
Subject: Rsync performance increase through buffering
From: Craig Barratt <craig@atheros.com>
Message-ID: <auto-000002369223@atheros.com>
Date: Sun, 08 Dec 2002 23:48:57 -0800

I've been studying the read and write buffering in rsync and it turns
out most I/O is done just a couple of bytes at a time.  This means there
are lots of system calls, and also most network traffic comprises lots
of small packets.  The behavior is most extreme when sending/receiving
file deltas of identical files.

The main case where I/O is buffered is writes from the server (when
io multiplexing is on). These are usually buffered in 4092 byte
chunks with a 4 byte header. However, reading of these packets is
usually unbuffered, and writes from the client are generally not
buffered.  For example: when receiving 1st phase checksums (6 bytes
per block), 2 reads are done: one of 4 bytes and one of 2 bytes,
meaning there are 4 system calls (select/read/select/read) per 6
bytes of checksum data).

One cost of this is some performance, but a significant issue is that
unbuffered writes generate very short (and very many) ethernet packets,
which means the overhead is quite large on slow network connections.

The initial file_list writing is typically buffered, but reading it on
the client is not.

There are some other unneeded system calls:

  - One example is that show_progress() calls gettimeofday() even
    if do_progress is not set.  show_progress() is called on every
    block, so there is an extra system call per (700 byte) block.

  - Another example is that file_write writes each matching (700 byte)
    block without buffering, so that's another system call per block.

To study this behavior I used rsync-2.5.6cvs and had a benchmark area
comprising around 7800 files of total size 530MB.

Here are some results doing sends and receives via rsyncd, all on the
same machine, with identical source and destination files.  In each
case --ignore-times (-I) is set, so that every file is processed:

  - Send test:
  
        strace -f rsync -Ir . localhost::test |& wc

    shows there are about 2,488,775 system calls.

  - Receive test:

        strace -f rsync -Ir localhost::test . |& wc

    shows there are about 1,615,931 system calls.

  - Rsyncd has a roughly similar numbers of system calls.

  - Send test from another machine (cygwin/WinXP laptop):

        tcpdump port 873 |& wc

    shows there are about 701,111 ethernet packets (many of them only
    have a 4 byte payload).

Since the source and dest files are the same, the send test only
wrote 1,738,797 bytes and read 2,139,848 bytes.

These results are similar to rsync 2.5.5.

Below is a patch to a few files that adds read and write buffering in
the places where the I/O was unbuffered, adds buffering to write_file()
and removes the unneeded gettimeofday() system call in show_progress().

The results with the patch are:

  - Send test: 46,835 system calls, versus 2,488,775.
  
  - Receive test: 138,367 system calls, versus 1,615,931.

  - Send test from another machine: 5,255 ethernet packets, versus 701,111.
    If the tcp/ip/udp/802.3 per-packet overhead is around 60 bytes, that
    means the base case transfers an extra 42MB of data, even though the
    useful data is only around 2MB.

The absolute running time on the local rsyncd test isn't much different,
probably because the test is really disk io limited and system calls on
an unloaded linux system are pretty fast.

However, on a network test doing a send from cygwin/WinXP to rsyncd
on rh-linux the running time improves from about 700 seconds to 215
seconds (with a cpu load of around 17% versus 58%, if you believe
cygwin's cpu stats).  This is probably an extreme case since the system
call penalty in cygwin is high.  But I would suspect a significant
improvement is possible with a slow network connection, since a lot
less data is being sent.

Note also that without -I rsync is already very fast, since it skips
(most) files based on attributes.

With or without this patch the test suite passes except for
daemon-gzip-upload.  One risk of buffering is the potential for
a bug caused by a missing io_flush: deadlock is possible, so try
the patch at your own risk...

Craig

###########################################################################
diff -bur rsync/fileio.c rsync-craig/fileio.c
--- rsync/fileio.c	Fri Jan 25 15:07:34 2002
+++ rsync-craig/fileio.c	Sat Dec  7 22:21:10 2002
@@ -76,7 +76,35 @@
 	int ret = 0;
 
 	if (!sparse_files) {
-		return write(f,buf,len);
+		static char *writeBuf;
+		static size_t writeBufSize;
+		static size_t writeBufCnt;
+
+		if ( !writeBuf ) {
+		    writeBufSize = MAX_MAP_SIZE;
+		    writeBufCnt  = 0;
+		    writeBuf = (char*)malloc(MAX_MAP_SIZE);
+		    if (!writeBuf) out_of_memory("write_file");
+		}
+		ret = len;
+		do {
+		    if ( buf && writeBufCnt < writeBufSize ) {
+			size_t copyLen = len;
+			if ( copyLen > writeBufSize - writeBufCnt ) {
+			    copyLen = writeBufSize - writeBufCnt;
+			}
+			memcpy(writeBuf + writeBufCnt, buf, copyLen);
+			writeBufCnt += copyLen;
+			buf += copyLen;
+			len -= copyLen;
+		    }
+		    if ( !buf || writeBufCnt == writeBufSize ) {
+			int thisRet = write(f, writeBuf, writeBufCnt);
+			if ( thisRet < 0 ) return thisRet;
+			writeBufCnt = 0;
+		    }
+		} while ( buf && len > 0 );
+		return ret;
 	}
 
 	while (len>0) {
diff -bur rsync/flist.c rsync-craig/flist.c
--- rsync/flist.c	Sat Jul 27 11:01:21 2002
+++ rsync-craig/flist.c	Sun Dec  8 16:28:14 2002
@@ -889,7 +889,7 @@
 	flist = flist_new();
 
 	if (f != -1) {
-		io_start_buffering(f);
+		io_start_buffering_out(f);
 	}
 
 	for (i = 0; i < argc; i++) {
diff -bur rsync/io.c rsync-craig/io.c
--- rsync/io.c	Wed Apr 10 19:11:50 2002
+++ rsync-craig/io.c	Sun Dec  8 17:54:23 2002
@@ -41,8 +41,8 @@
 
 static int io_multiplexing_out;
 static int io_multiplexing_in;
-static int multiplex_in_fd;
-static int multiplex_out_fd;
+static int multiplex_in_fd = -1;
+static int multiplex_out_fd = -1;
 static time_t last_io;
 static int no_flush;
 
@@ -286,17 +286,31 @@
 	static size_t remaining;
 	int tag, ret = 0;
 	char line[1024];
+        static char *buffer;
+        static size_t bufferIdx = 0;
+        static size_t bufferSz;
 
-	if (!io_multiplexing_in || fd != multiplex_in_fd)
+	if (fd != multiplex_in_fd)
 		return read_timeout(fd, buf, len);
 
+	if (!io_multiplexing_in && remaining == 0) {
+		if (!buffer) {
+			bufferSz = 2 * IO_BUFFER_SIZE;
+			buffer   = malloc(bufferSz);
+			if (!buffer) out_of_memory("read_unbuffered");
+		}
+		remaining = read_timeout(fd, buffer, bufferSz);
+                bufferIdx = 0;
+        }
+
 	while (ret == 0) {
 		if (remaining) {
 			len = MIN(len, remaining);
-			read_loop(fd, buf, len);
+			memcpy(buf, buffer + bufferIdx, len);
+			bufferIdx += len;
 			remaining -= len;
 			ret = len;
-			continue;
+			break;
 		}
 
 		read_loop(fd, line, 4);
@@ -305,8 +319,16 @@
 		remaining = tag & 0xFFFFFF;
 		tag = tag >> 24;
 
-		if (tag == MPLEX_BASE)
+		if (tag == MPLEX_BASE) {
+			if (!buffer || remaining > bufferSz) {
+				buffer = Realloc(buffer, remaining);
+				if (!buffer) out_of_memory("read_unbuffered");
+				bufferSz = remaining;
+			}
+			read_loop(fd, buffer, remaining);
+                        bufferIdx = 0;
 			continue;
+                }
 
 		tag -= MPLEX_BASE;
 
@@ -327,7 +349,9 @@
 		rprintf((enum logcode) tag, "%s", line);
 		remaining = 0;
 	}
-
+        if (remaining == 0) {
+		io_flush();
+	}
 	return ret;
 }
 
@@ -344,8 +368,6 @@
 	size_t total=0;  
 	
 	while (total < N) {
-		io_flush();
-
 		ret = read_unbuffered (fd, buffer + total, N-total);
 		total += ret;
 	}
@@ -531,7 +553,7 @@
 static char *io_buffer;
 static int io_buffer_count;
 
-void io_start_buffering(int fd)
+void io_start_buffering_out(int fd)
 {
 	if (io_buffer) return;
 	multiplex_out_fd = fd;
@@ -540,6 +562,11 @@
 	io_buffer_count = 0;
 }
 
+void io_start_buffering_in(int fd)
+{
+	multiplex_in_fd = fd;
+}
+
 /**
  * Write an message to a multiplexed stream. If this fails then rsync
  * exits.
@@ -726,7 +753,7 @@
 {
 	multiplex_out_fd = fd;
 	io_flush();
-	io_start_buffering(fd);
+	io_start_buffering_out(fd);
 	io_multiplexing_out = 1;
 }
 
diff -bur rsync/main.c rsync-craig/main.c
--- rsync/main.c	Thu Aug  1 13:46:59 2002
+++ rsync-craig/main.c	Sun Dec  8 17:39:07 2002
@@ -346,6 +346,8 @@
 		exit_cleanup(0);
 	}
 
+        io_start_buffering_in(f_in);
+        io_start_buffering_out(f_out);
 	send_files(flist,f_out,f_in);
 	io_flush();
 	report(f_out);
@@ -421,7 +423,7 @@
 	close(error_pipe[1]);
 	if (f_in != f_out) close(f_in);
 
-	io_start_buffering(f_out);
+	io_start_buffering_out(f_out);
 
 	io_set_error_fd(error_pipe[0]);
 
@@ -476,6 +478,7 @@
 		}    
 	}
 
+        io_start_buffering_in(f_in);
 	if (delete_mode && !delete_excluded)
 		recv_exclude_list(f_in);
 
@@ -569,6 +572,7 @@
 		extern int cvs_exclude;
 		extern int delete_mode;
 		extern int delete_excluded;
+                io_start_buffering_out(f_out);
 		if (cvs_exclude)
 			add_cvs_excludes();
 		if (delete_mode && !delete_excluded) 
@@ -578,7 +582,10 @@
 		if (verbose > 3) 
 			rprintf(FINFO,"file list sent\n");
 
+                io_flush();
+                io_start_buffering_out(f_out);
 		send_files(flist,f_out,f_in);
+                io_flush();
 		if (remote_version >= 24) {
 			/* final goodbye message */		
 			read_int(f_in);
@@ -590,6 +597,7 @@
 			wait_process(pid, &status);
 		}
 		report(-1);
+		io_flush();
 		exit_cleanup(status);
 	}
 
diff -bur rsync/progress.c rsync-craig/progress.c
--- rsync/progress.c	Sun Apr  7 22:28:57 2002
+++ rsync-craig/progress.c	Sat Dec  7 18:57:19 2002
@@ -97,6 +97,8 @@
 	extern int do_progress, am_server;
         struct timeval now;
 
+	if (!do_progress) return;
+
         gettimeofday(&now, NULL);
 
         if (!start_time.tv_sec && !start_time.tv_usec) {
diff -bur rsync/proto.h rsync-craig/proto.h
--- rsync/proto.h	Wed Jul 31 17:37:02 2002
+++ rsync-craig/proto.h	Sun Dec  8 16:27:55 2002
@@ -102,7 +102,8 @@
 void read_buf(int f,char *buf,size_t len);
 void read_sbuf(int f,char *buf,size_t len);
 unsigned char read_byte(int f);
-void io_start_buffering(int fd);
+void io_start_buffering_out(int fd);
+void io_start_buffering_in(int fd);
 void io_flush(void);
 void io_end_buffering(void);
 void write_int(int f,int32 x);
diff -bur rsync/receiver.c rsync-craig/receiver.c
--- rsync/receiver.c	Tue May 28 08:42:51 2002
+++ rsync-craig/receiver.c	Sat Dec  7 22:09:04 2002
@@ -273,6 +273,11 @@
 		offset += len;
 	}
 
+	/*
+	 * do a write flush
+	 */
+	write_file(fd, NULL, 0);
+
 	end_progress(total_size);
 
 	if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
rsync-2.5.7/patches/marco_soften-links.diff0100644000111500011150000000274107456474213021722 0ustar  rsync-bugsrsync-bugsFrom md@Linux.IT Fri Apr 12 21:45:04 2002
Return-Path: <md@Linux.IT>
Delivered-To: mbp@samba.org
Received: from attila.bofh.it (attila.bofh.it [213.92.8.2])
	by lists.samba.org (Postfix) with ESMTP id 1D3674500
	for <mbp@samba.org>; Fri, 12 Apr 2002 04:45:04 -0700 (PDT)
Received: by attila.bofh.it (Postfix, from userid 10)
	id 462BB5FA70; Fri, 12 Apr 2002 13:44:29 +0200 (CEST)
Received: by wonderland.linux.it (Postfix/Md, from userid 1001)
	id D8B4E33B2D; Fri, 12 Apr 2002 13:44:22 +0200 (CEST)
Date: Fri, 12 Apr 2002 13:44:22 +0200
From: Marco d'Itri <md@Linux.IT>
To: mbp@samba.org
Subject: rsync and debian mirrors
Message-ID: <20020412114422.GA1664@wonderland.linux.it>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
User-Agent: Mutt/1.3.28i
Status: RO
X-Status: A
Content-Length: 658
Lines: 26

I run one of the debian mirrors, and I had to write this patch because
my archive is split between more than one disk. Would you accept a more
polished version of this patch for inclusion in rsync?

--- syscall.c.orig      Thu May 31 16:14:07 2001
+++ syscall.c   Thu May 31 16:40:46 2001
@@ -45,9 +45,14 @@
 #if HAVE_LINK
 int do_link(char *fname1, char *fname2)
 {
+       int st;
+
        if (dry_run) return 0;
        CHECK_RO
-       return link(fname1, fname2);
+       st = link(fname1, fname2);
+       if (/*soften_links &&*/ st != 0 && errno == EXDEV)
+               st = symlink(fname1, fname2);
+       return st;
 }
 #endif


-- 
ciao,
Marco

rsync-2.5.7/patches/gzip-rsyncable.diff0100644000111500011150000002547707454172521021064 0ustar  rsync-bugsrsync-bugsIn message <20020403094739.GA5434@samba.org> you write:
> On  3 Apr 2002, Rusty Russell <rusty@rustcorp.com.au> wrote:
> > In message <20020403020455.GC18851@samba.org> you write:
> > > Hi,
> > > 
> > > I think you said the other day that you had a working --rsyncable
> > > patch for gzip.  Could I have it please?
> 
> Thanks for that.  I'll put it in with our contrib patches and probably
> merge it soon.
> 
> I was actually after the patch to gzip, rather than the fuzzy patch
> for rsync.  I'd like to try it myself and also distribute it along
> with rsync.

It's pending for actual gzip inclusion!  The maintainer was dug up and
everything: it'll even be on by default.

But here's the old patch,
Rusty.
--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

diff -ur gzip-1.2.4.orig/deflate.c gzip-1.2.4-rsync/deflate.c
--- gzip-1.2.4.orig/deflate.c	Fri Aug 13 22:35:31 1993
+++ gzip-1.2.4-rsync/deflate.c	Sat Dec 30 15:33:25 2000
@@ -121,6 +121,14 @@
 #endif
 /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
 
+#ifndef RSYNC_WIN
+#  define RSYNC_WIN 4096
+#endif
+/* Size of rsync window, must be < MAX_DIST */
+
+#define RSYNC_SUM_MATCH(sum) ((sum) % RSYNC_WIN == 0)
+/* Whether window sum matches magic value */
+
 /* ===========================================================================
  * Local data used by the "longest match" routines.
  */
@@ -202,6 +210,8 @@
 unsigned near good_match;
 /* Use a faster search when the previous match is longer than this */
 
+local ulg rsync_sum;  /* rolling sum of rsync window */
+local ulg rsync_chunk_end; /* next rsync sequence point */
 
 /* Values for max_lazy_match, good_match and max_chain_length, depending on
  * the desired pack level (0..9). The values given below have been tuned to
@@ -300,6 +310,10 @@
 #endif
     /* prev will be initialized on the fly */
 
+    /* rsync params */
+    rsync_chunk_end = 0xFFFFFFFFUL;
+    rsync_sum = 0;
+
     /* Set the default configuration parameters:
      */
     max_lazy_match   = configuration_table[pack_level].max_lazy;
@@ -536,6 +550,8 @@
         memcpy((char*)window, (char*)window+WSIZE, (unsigned)WSIZE);
         match_start -= WSIZE;
         strstart    -= WSIZE; /* we now have strstart >= MAX_DIST: */
+	if (rsync_chunk_end != 0xFFFFFFFFUL)
+	    rsync_chunk_end -= WSIZE;
 
         block_start -= (long) WSIZE;
 
@@ -563,13 +579,46 @@
     }
 }
 
+local void rsync_roll(start, num)
+    unsigned start;
+    unsigned num;
+{
+    unsigned i;
+
+    if (start < RSYNC_WIN) {
+	/* before window fills. */
+	for (i = start; i < RSYNC_WIN; i++) {
+	    if (i == start + num) return;
+	    rsync_sum += (ulg)window[i];
+	}
+	num -= (RSYNC_WIN - start);
+	start = RSYNC_WIN;
+    }
+
+    /* buffer after window full */
+    for (i = start; i < start+num; i++) {
+	/* New character in */
+	rsync_sum += (ulg)window[i];
+	/* Old character out */
+	rsync_sum -= (ulg)window[i - RSYNC_WIN];
+	if (rsync_chunk_end == 0xFFFFFFFFUL && RSYNC_SUM_MATCH(rsync_sum))
+	    rsync_chunk_end = i;
+    }
+}
+
+/* ===========================================================================
+ * Set rsync_chunk_end if window sum matches magic value.
+ */
+#define RSYNC_ROLL(s, n) \
+   do { if (rsync) rsync_roll((s), (n)); } while(0)
+
 /* ===========================================================================
  * Flush the current block, with given end-of-file flag.
  * IN assertion: strstart is set to the end of the current match.
  */
 #define FLUSH_BLOCK(eof) \
    flush_block(block_start >= 0L ? (char*)&window[(unsigned)block_start] : \
-                (char*)NULL, (long)strstart - block_start, (eof))
+                (char*)NULL, (long)strstart - block_start, flush-1, (eof))
 
 /* ===========================================================================
  * Processes a new input file and return its compressed length. This
@@ -580,7 +629,7 @@
 local ulg deflate_fast()
 {
     IPos hash_head; /* head of the hash chain */
-    int flush;      /* set if current block must be flushed */
+    int flush;      /* set if current block must be flushed, 2=>and padded  */
     unsigned match_length = 0;  /* length of best match */
 
     prev_length = MIN_MATCH-1;
@@ -609,6 +658,7 @@
 
             lookahead -= match_length;
 
+	    RSYNC_ROLL(strstart, match_length);
 	    /* Insert new strings in the hash table only if the match length
              * is not too large. This saves time but degrades compression.
              */
@@ -637,9 +687,14 @@
             /* No match, output a literal byte */
             Tracevv((stderr,"%c",window[strstart]));
             flush = ct_tally (0, window[strstart]);
+	    RSYNC_ROLL(strstart, 1);
             lookahead--;
 	    strstart++; 
         }
+	if (rsync && strstart > rsync_chunk_end) {
+	    rsync_chunk_end = 0xFFFFFFFFUL;
+	    flush = 2;
+	} 
         if (flush) FLUSH_BLOCK(0), block_start = strstart;
 
         /* Make sure that we always have enough lookahead, except
@@ -715,6 +770,7 @@
              */
             lookahead -= prev_length-1;
             prev_length -= 2;
+	    RSYNC_ROLL(strstart, prev_length+1);
             do {
                 strstart++;
                 INSERT_STRING(strstart, hash_head);
@@ -727,24 +783,39 @@
             match_available = 0;
             match_length = MIN_MATCH-1;
             strstart++;
-            if (flush) FLUSH_BLOCK(0), block_start = strstart;
 
+	    if (rsync && strstart > rsync_chunk_end) {
+		rsync_chunk_end = 0xFFFFFFFFUL;
+		flush = 2;
+	    }
+            if (flush) FLUSH_BLOCK(0), block_start = strstart;
         } else if (match_available) {
             /* If there was no match at the previous position, output a
              * single literal. If there was a match but the current match
              * is longer, truncate the previous match to a single literal.
              */
             Tracevv((stderr,"%c",window[strstart-1]));
-            if (ct_tally (0, window[strstart-1])) {
-                FLUSH_BLOCK(0), block_start = strstart;
-            }
+	    flush = ct_tally (0, window[strstart-1]);
+	    if (rsync && strstart > rsync_chunk_end) {
+		rsync_chunk_end = 0xFFFFFFFFUL;
+		flush = 2;
+	    }
+            if (flush) FLUSH_BLOCK(0), block_start = strstart;
+	    RSYNC_ROLL(strstart, 1);
             strstart++;
             lookahead--;
         } else {
             /* There is no previous match to compare with, wait for
              * the next step to decide.
              */
+	    if (rsync && strstart > rsync_chunk_end) {
+		/* Reset huffman tree */
+		rsync_chunk_end = 0xFFFFFFFFUL;
+		flush = 2;
+		FLUSH_BLOCK(0), block_start = strstart;
+	    }
             match_available = 1;
+	    RSYNC_ROLL(strstart, 1);
             strstart++;
             lookahead--;
         }
diff -ur gzip-1.2.4.orig/gzip.c gzip-1.2.4-rsync/gzip.c
--- gzip-1.2.4.orig/gzip.c	Thu Aug 19 23:39:43 1993
+++ gzip-1.2.4-rsync/gzip.c	Fri Dec 29 21:20:54 2000
@@ -239,6 +239,7 @@
 unsigned insize;           /* valid bytes in inbuf */
 unsigned inptr;            /* index of next byte to be processed in inbuf */
 unsigned outcnt;           /* bytes in output buffer */
+int rsync = 0;             /* make ryncable chunks */
 
 struct option longopts[] =
 {
@@ -268,6 +269,7 @@
     {"best",       0, 0, '9'}, /* compress better */
     {"lzw",        0, 0, 'Z'}, /* make output compatible with old compress */
     {"bits",       1, 0, 'b'}, /* max number of bits per code (implies -Z) */
+    {"rsyncable",  0, 0, 'R'}, /* make rsync-friendly archive */
     { 0, 0, 0, 0 }
 };
 
@@ -357,6 +359,7 @@
  " -Z --lzw         produce output compatible with old compress",
  " -b --bits maxbits   max number of bits per code (implies -Z)",
 #endif
+ "    --rsyncable   Make rsync-friendly archive",
  " file...          files to (de)compress. If none given, use standard input.",
   0};
     char **p = help_msg;
@@ -516,6 +519,9 @@
 #else
 	    recursive = 1; break;
 #endif
+	case 'R':
+	    rsync = 1; break;
+
 	case 'S':
 #ifdef NO_MULTIPLE_DOTS
             if (*optarg == '.') optarg++;
diff -ur gzip-1.2.4.orig/gzip.h gzip-1.2.4-rsync/gzip.h
--- gzip-1.2.4.orig/gzip.h	Fri Aug 13 22:35:33 1993
+++ gzip-1.2.4-rsync/gzip.h	Sat Dec 30 15:26:56 2000
@@ -131,6 +131,7 @@
 extern unsigned insize; /* valid bytes in inbuf */
 extern unsigned inptr;  /* index of next byte to be processed in inbuf */
 extern unsigned outcnt; /* bytes in output buffer */
+extern int rsync;  /* deflate into rsyncable chunks */
 
 extern long bytes_in;   /* number of input bytes */
 extern long bytes_out;  /* number of output bytes */
@@ -282,7 +283,7 @@
         /* in trees.c */
 void ct_init     OF((ush *attr, int *method));
 int  ct_tally    OF((int dist, int lc));
-ulg  flush_block OF((char *buf, ulg stored_len, int eof));
+ulg  flush_block OF((char *buf, ulg stored_len, int pad, int eof));
 
         /* in bits.c */
 void     bi_init    OF((file_t zipfile));
diff -ur gzip-1.2.4.orig/gzip.texi gzip-1.2.4-rsync/gzip.texi
--- gzip-1.2.4.orig/gzip.texi	Thu Aug 19 06:42:50 1993
+++ gzip-1.2.4-rsync/gzip.texi	Fri Dec 29 21:20:54 2000
@@ -316,6 +316,14 @@
 into the directory and compress all the files it finds there (or
 decompress them in the case of @code{gunzip}).
 
+@item --rsyncable
+While compressing, synchronize the output occasionally based on the
+input.  This reduces compression by about 1 percent most cases, but
+means that the @code{rsync} program can take advantage of similarities
+in the uncompressed input when syncronizing two files compressed with
+this flag.  @code{gunzip} cannot tell the difference between a
+compressed file created with this option, and one created without it.
+
 @item --suffix @var{suf}
 @itemx -S @var{suf}
 Use suffix @samp{@var{suf}} instead of @samp{.gz}. Any suffix can be
diff -ur gzip-1.2.4.orig/trees.c gzip-1.2.4-rsync/trees.c
--- gzip-1.2.4.orig/trees.c	Wed Aug 18 03:36:32 1993
+++ gzip-1.2.4-rsync/trees.c	Sat Dec 30 15:37:00 2000
@@ -850,9 +850,10 @@
  * trees or store, and output the encoded block to the zip file. This function
  * returns the total compressed length for the file so far.
  */
-ulg flush_block(buf, stored_len, eof)
+ulg flush_block(buf, stored_len, pad, eof)
     char *buf;        /* input block, or NULL if too old */
     ulg stored_len;   /* length of input block */
+    int pad;          /* pad output to byte boundary */
     int eof;          /* true if this is the last block for a file */
 {
     ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
@@ -944,6 +967,10 @@
         Assert (input_len == isize, "bad input size");
         bi_windup();
         compressed_len += 7;  /* align on byte boundary */
+    } else if (pad && (compressed_len % 8) != 0) {
+        send_bits((STORED_BLOCK<<1)+eof, 3);  /* send block type */
+        compressed_len = (compressed_len + 3 + 7) & ~7L;
+        copy_block(buf, 0, 1); /* with header */
     }
     Tracev((stderr,"\ncomprlen %lu(%lu) ", compressed_len>>3,
            compressed_len-7*eof));
rsync-2.5.7/patches/jjb-date-only.diff0100644000111500011150000000565307447742573020600 0ustar  rsync-bugsrsync-bugsGreetings, and thanks for all of your work on the wonderful rsync!

I recently had the need to transfer files only with different mod
dates (and to *not* transfer them based on file size differences).
This is because I'm backing up files remotely on an untrusted machine,
so I'm encrypting them with gpg before transfer.  I discovered that
rsync didn't already have a --date-only flag, so I added one and am
enclosing the diffs in case you (as I hope) decide to include this
option in future releases.

Again, thanks!

Best Regards,
Jeremy Bornstein
diff rsync-2.5.4/README rsync-2.5.4-patched/README
70a71
>      --date-only             only use modification date when determining if a file should be transferred
Common subdirectories: rsync-2.5.4/doc and rsync-2.5.4-patched/doc
diff rsync-2.5.4/generator.c rsync-2.5.4-patched/generator.c
39a40
> extern int date_only;
50a52,56
> 	if (date_only) {
> 		return (cmp_modtime(st->st_mtime,file->modtime) == 0);
> 	}
> 
> 
Common subdirectories: rsync-2.5.4/lib and rsync-2.5.4-patched/lib
diff rsync-2.5.4/options.c rsync-2.5.4-patched/options.c
64a65
> int date_only=0;
223a225
>   rprintf(F,"     --date-only             only use modification date when determining if a file should be transferred\n");
265c267
<       OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
---
>       OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_DATE_ONLY, OPT_ADDRESS,
278a281
>   {"date-only",        0,  POPT_ARG_NONE,   &date_only},
704a708,710
> 
> 	if (date_only)
> 		args[ac++] = "--date-only";
Common subdirectories: rsync-2.5.4/packaging and rsync-2.5.4-patched/packaging
Common subdirectories: rsync-2.5.4/popt and rsync-2.5.4-patched/popt
diff rsync-2.5.4/rsync.1 rsync-2.5.4-patched/rsync.1
289a290
>      --date-only             only use modification date when determining if a file should be transferred
363a365,371
> .IP 
> .IP "\fB--date-only\fP" 
> Normally rsync will skip any files that are
> already the same length and have the same time-stamp\&. With the
> --date-only option files will be skipped if they have the same timestamp,
> regardless of size\&. This may be useful when the remote files have passed
> through a size-changing filter, e.g. for encryption\&.
diff rsync-2.5.4/rsync.yo rsync-2.5.4-patched/rsync.yo
260a261
>      --date-only             only use modification date when determining if a file should be transferred
326a328,333
> 
> dit(bf(--date-only)) Normally rsync will skip any files that are
> already the same length and have the same time-stamp. With the
> --date-only option files will be skipped if they have the same
> timestamp, regardless of size. This may be useful when the remote
> files have passed through a size-changing filter, e.g. for encryption.
Common subdirectories: rsync-2.5.4/testhelp and rsync-2.5.4-patched/testhelp
Common subdirectories: rsync-2.5.4/testsuite and rsync-2.5.4-patched/testsuite
Common subdirectories: rsync-2.5.4/zlib and rsync-2.5.4-patched/zlib
rsync-2.5.7/patches/kikuchi_set_rsyncdconf_location.diff0100644000111500011150000000537407454174112024545 0ustar  rsync-bugsrsync-bugsFrom ayamura@ayamura.org  Wed Feb 20 08:48:40 2002
Return-Path: <ayamura@ayamura.org>
Delivered-To: rsync@samba.org
Received: from sea.ayamura.org (sea.ayamura.org [61.199.236.10])
	by lists.samba.org (Postfix) with ESMTP id 075604919
	for <rsync@samba.org>; Wed, 20 Feb 2002 08:48:39 -0800 (PST)
Received: (from ayamura@localhost)
	by sea.ayamura.org (8.12.2/8.12.2) id g1KGhHvt011659
	for rsync@samba.org; Thu, 21 Feb 2002 01:43:17 +0900 (JST)
	env-from (ayamura)
Date: Thu, 21 Feb 2002 01:43:17 +0900 (JST)
Message-Id: <200202201643.g1KGhHvt011659@sea.ayamura.org>
From: Ayamura KIKUCHI <ayamura@ayamura.org>
To: rsync@samba.org
Subject: [patch] configurable RSYNCD_CONF
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Sender: rsync-admin@lists.samba.org
Errors-To: rsync-admin@lists.samba.org
X-BeenThere: rsync@lists.samba.org
X-Mailman-Version: 2.0.8
Precedence: bulk
List-Help: <mailto:rsync-request@lists.samba.org?subject=help>
List-Post: <mailto:rsync@lists.samba.org>
List-Subscribe: <http://lists.samba.org/mailman/listinfo/rsync>,
	<mailto:rsync-request@lists.samba.org?subject=subscribe>
List-Id: Rsync user list <rsync.lists.samba.org>
List-Unsubscribe: <http://lists.samba.org/mailman/listinfo/rsync>,
	<mailto:rsync-request@lists.samba.org?subject=unsubscribe>
List-Archive: <http://lists.samba.org/pipermail/rsync/>

I prefer configurable RSYNCD_CONF by autoconf to RSYNCD_CONF in rsync.h.

--- rsync.h.orig	Tue Feb 19 06:46:49 2002
+++ rsync.h	Thu Feb 21 00:59:11 2002
@@ -26,7 +26,8 @@
 #define RSYNC_RSH_ENV "RSYNC_RSH"
 
 #define RSYNC_NAME "rsync"
-#define RSYNCD_CONF "/etc/rsyncd.conf"
+
+/* RSYNCD_CONF is always set in config.h */
 
 #define DEFAULT_LOCK_FILE "/var/run/rsyncd.lock"
 #define URL_PREFIX "rsync://"
--- configure.in.orig	Wed Feb 20 08:40:47 2002
+++ configure.in	Thu Feb 21 01:26:47 2002
@@ -85,6 +85,30 @@
 
 AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [location of rsync on remote machine])
 
+AC_ARG_WITH(rsyncd-conf,
+	AC_HELP_STRING([--with-rsyncd-conf=PATH], [set configuration file for rsync server to PATH (default: /etc/rsyncd.conf)]),
+	[ if test ! -z "$with_rsyncd_conf" ; then
+		case $with_rsyncd_conf in
+			yes)
+				RSYNCD_CONF="/etc/rsyncd.conf"
+				;;
+			no)
+				RSYNCD_CONF="/etc/rsyncd.conf"
+				;;
+			/*)
+				RSYNCD_CONF="$with_rsyncd_conf"
+				;;
+			*)
+                                AC_MSG_ERROR(You must specify an absolute path to --with-rsyncd-conf=PATH)
+				;;
+		esac
+	else
+		RSYNCD_CONF="/etc/rsyncd.conf"
+	fi ],
+	[ RSYNCD_CONF="/etc/rsyncd.conf" ])
+
+AC_DEFINE_UNQUOTED(RSYNCD_CONF, "$RSYNCD_CONF", [location of configuration file for rsync server])
+
 AC_ARG_WITH(rsh,
 	AC_HELP_STRING([--with-rsh=CMD], [set rsh command to CMD (default: \"remsh\" or \"rsh\")]))
 

-- ayamura
Ayamura KIKUCHI, M.D., Ph.D.


rsync-2.5.7/patches/proxy-auth.diff0100644000111500011150000001215307454174252020241 0ustar  rsync-bugsrsync-bugsHi all,

I have put together a patch for supporting "Basic" HTTP
Proxy Authentication. The patch changes the interpretation
of the RSYNC_PROXY environment variable so that the syntax

   user:pass@proxy.foo:port

may be used instead of just

   proxy.foo:port

(the old syntax is of course still supported).  
The patch has only been tested lightly, but it should(TM)
work.

The patch (and future versions of it) is available at:

    http://www.imada.sdu.dk/~bardur/personal/patches.html

(and i've attached the rsync-2.5.5 version). Any comments
and suggestions are welcome, but please CC them to my
email, as I am not a member of the list.

-- 
Bardur Arantsson
<bardur@imada.sdu.dk>
<bardur@odense.kollegienet.dk>

- "Information wants to be tied up and spanked..."
                  - Faulty Dreamer on kuro5hin.org
diff -u rsync-2.5.5.orig/authenticate.c rsync-2.5.5/authenticate.c
--- rsync-2.5.5.orig/authenticate.c	2002-01-24 03:33:45.000000000 +0100
+++ rsync-2.5.5/authenticate.c	2002-04-04 12:32:58.000000000 +0200
@@ -24,7 +24,7 @@
 encode a buffer using base64 - simple and slow algorithm. null terminates
 the result.
   ***************************************************************************/
-static void base64_encode(char *buf, int len, char *out)
+void base64_encode(char *buf, int len, char *out)
 {
 	char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 	int bit_offset, byte_offset, idx, i;
diff -u rsync-2.5.5.orig/socket.c rsync-2.5.5/socket.c
--- rsync-2.5.5.orig/socket.c	2002-03-16 10:00:44.000000000 +0100
+++ rsync-2.5.5/socket.c	2002-04-04 12:32:58.000000000 +0200
@@ -33,15 +33,52 @@
 
 #include "rsync.h"
 
+/* declare the base64_encode function from authenticate.c */
+void base64_encode(char *buf, int len, char *out);
 
-/* Establish a proxy connection on an open socket to a web roxy by
- * using the CONNECT method. */
-static int establish_proxy_connection(int fd, char *host, int port)
+/* Establish a proxy connection on an open socket to a web proxy by
+ * using the CONNECT method. If proxy_user and proxy_pass are not NULL,
+ * they are used to authenticate to the proxy using the "Basic"
+ * proxy authorization protocol */
+static int establish_proxy_connection(int fd, char *host, int port, 
+				      char *proxy_user, char *proxy_pass)
 {
 	char buffer[1024];
+	char authbuf[1024];
+	size_t authlen;
 	char *cp;
 
-	snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
+	/* use the proxy_user and proxy_pass
+	 * variables to determine authentication string */
+	if ((proxy_user != NULL) &&
+	    (proxy_pass != NULL)) {
+		/* copy "user:pass" into buffer */
+		strlcpy(buffer, proxy_user, sizeof(buffer));
+		strlcat(buffer, ":", sizeof(buffer));
+		strlcat(buffer, proxy_pass, sizeof(buffer));
+		
+		/* how long will the base64 encoded string be? */
+		authlen = (strlen(buffer)*8 + 5)/6;
+		if (authlen>sizeof(authbuf)+1) {
+			rprintf(FERROR,
+				"authentication information too long\n");
+			return -1;
+		}
+		
+		/* encode in base64 into authbuf */
+		base64_encode(buffer, strlen(buffer), authbuf);
+		
+		/* request */
+		snprintf(buffer, sizeof(buffer), 
+			 "CONNECT %s:%d HTTP/1.0\r\n"
+			 "Proxy-Authorization: Basic %s\r\n\r\n", 
+			 host, port, authbuf);
+	} else {
+		/* request */
+		snprintf(buffer, sizeof(buffer), 
+			 "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
+	}
+
 	if (write(fd, buffer, strlen(buffer)) != (int) strlen(buffer)) {
 		rprintf(FERROR, "failed to write to proxy: %s\n",
 			strerror(errno));
@@ -166,6 +203,9 @@
 	int proxied = 0;
 	char buffer[1024];
 	char *cp;
+	char *proxy_user = NULL;
+	char *proxy_pass = NULL;
+	char *buffer_hostpart;
 
 	/* if we have a RSYNC_PROXY env variable then redirect our
 	 * connetcion via a web proxy at the given address. The format
@@ -175,7 +215,34 @@
 
 	if (proxied) {
 		strlcpy(buffer, h, sizeof(buffer));
-		cp = strchr(buffer, ':');
+
+		/* authentication information present? */
+		cp = strchr(buffer, '@');
+		if (cp != NULL) {
+			/* rest of buffer points past the '@' */ 
+			buffer_hostpart = cp+1;
+			/* null separate auth portion from host:port */
+			*cp = '\0';
+			/* find a ':' in the auth portion */
+			cp = strchr(buffer, ':');
+			if (cp == NULL) {
+				rprintf(FERROR,
+					"invalid proxy specification: should be USER:PASS@HOST:PORT\n");
+				return -1;
+			};
+
+			/* null separate USER from PASS */
+		        *cp++ = '\0';
+			
+			/* set up pointers to USER and PASS */
+			proxy_user = buffer;
+			proxy_pass = cp;
+		} else {
+			/* whole buffer is the host part */
+			buffer_hostpart = buffer;
+		}
+
+		cp = strchr(buffer_hostpart, ':');
 		if (cp == NULL) {
 			rprintf(FERROR,
 				"invalid proxy specification: should be HOST:PORT\n");
@@ -183,7 +250,7 @@
 		}
 		*cp++ = '\0';
 		strcpy(portbuf, cp);
-		h = buffer;
+		h = buffer_hostpart;
 		if (verbose >= 2) {
 			rprintf(FINFO, "connection via http proxy %s port %s\n",
 				h, portbuf);
@@ -227,7 +294,8 @@
 			continue;
 		}
 		if (proxied &&
-		    establish_proxy_connection(s, host, port) != 0) {
+		    establish_proxy_connection(s, host, port, 
+					       proxy_user, proxy_pass) != 0) {
 			close(s);
 			s = -1;
 			continue;
rsync-2.5.7/patches/rsync-chmod-v1.patch0100644000111500011150000002466107452763634021077 0ustar  rsync-bugsrsync-bugsdiff --unified -r --new-file rsync-2.5.5.orig/Makefile.in rsync-2.5.5/Makefile.in
--- rsync-2.5.5.orig/Makefile.in	Mon Mar 25 15:36:56 2002
+++ rsync-2.5.5/Makefile.in	Wed Apr  3 21:45:22 2002
@@ -31,7 +31,7 @@
 	zlib/zutil.o zlib/adler32.o 
 OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o main.o checksum.o match.o syscall.o log.o backup.o
 OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o fileio.o batch.o \
-	clientname.o
+	clientname.o chmod.o
 DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
 popt_OBJS=popt/findme.o  popt/popt.o  popt/poptconfig.o \
 	popt/popthelp.o popt/poptparse.o
diff --unified -r --new-file rsync-2.5.5.orig/chmod.c rsync-2.5.5/chmod.c
--- rsync-2.5.5.orig/chmod.c	Thu Jan  1 10:00:00 1970
+++ rsync-2.5.5/chmod.c	Wed Apr  3 22:56:30 2002
@@ -0,0 +1,134 @@
+#include "rsync.h"
+
+struct chmod_mode_struct {
+	int ModeAND;
+	int ModeOR;
+	char Xkeep;
+	struct chmod_mode_struct *next;
+};
+
+#define CHMOD_ADD 1
+#define CHMOD_SUB 2
+#define CHMOD_EQ  3
+
+/* Parse a chmod-style argument, and break it down into one or more AND/OR
+   pairs in a linked list.
+   We use a state machine to walk through the options - states 1 and 3
+   before/including the operation (+, - or =), state 2 after the operation and
+   state 4 if we hit an error.
+*/
+struct chmod_mode_struct *
Results 1 - 1
Help - FTP Sites List - Software Dir.
Searching half a billion files worldwide
© 1997-2009 MARUHN Internet Solutions