Edit

IABSD.fr/src/usr.bin/rsync/extern.h

Branch :

  • Show log

    Commit

  • Author : deraadt
    Date : 2020-05-17 19:54:41
    Hash : 7ddad9c7
    Message : __FILE__ and __LINE__ information are fine during early development, or occasionally for fatal source-code bugs are critical and must be hunted down. It is NOT suitable to expose regular users to this on a regular basis though. ok kn beck

  • usr.bin/rsync/extern.h
  • /*	$Id: extern.h,v 1.33 2020/05/17 19:54:41 deraadt Exp $ */
    /*
     * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
     *
     * 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
     * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
     */
    #ifndef EXTERN_H
    #define EXTERN_H
    
    /*
     * This is the rsync protocol version that we support.
     */
    #define	RSYNC_PROTOCOL	(27)
    
    /*
     * Maximum amount of file data sent over the wire at once.
     */
    #define MAX_CHUNK	(32 * 1024)
    
    /*
     * This is the minimum size for a block of data not including those in
     * the remainder block.
     */
    #define	BLOCK_SIZE_MIN  (700)
    
    /*
     * The sender and receiver use a two-phase synchronisation process.
     * The first uses two-byte hashes; the second, 16-byte.
     * (The second must hold a full MD4 digest.)
     */
    #define	CSUM_LENGTH_PHASE1 (2)
    #define	CSUM_LENGTH_PHASE2 (16)
    
    /*
     * Use this for debugging deadlocks.
     * All poll events will use it and catch time-outs.
     */
    #define POLL_TIMEOUT	(INFTIM)
    
    /*
     * Operating mode for a client or a server.
     * Sender means we synchronise local files with those from remote.
     * Receiver is the opposite.
     * This is relative to which host we're running on.
     */
    enum	fmode {
    	FARGS_SENDER,
    	FARGS_RECEIVER
    };
    
    /*
     * File arguments given on the command line.
     * See struct opts.
     */
    struct	fargs {
    	char	  *host; /* hostname or NULL if local */
    	char	 **sources; /* transfer source */
    	size_t	   sourcesz; /* number of sources */
    	char	  *sink; /* transfer endpoint */
    	enum fmode mode; /* mode of operation */
    	int	   remote; /* uses rsync:// or :: for remote */
    	char	  *module; /* if rsync://, the module */
    };
    
    /*
     * The subset of stat(2) information that we need.
     * (There are some parts we don't use yet.)
     */
    struct	flstat {
    	mode_t		 mode;	/* mode */
    	uid_t		 uid;	/* user */
    	gid_t		 gid;	/* group */
    	dev_t		 rdev;	/* device type */
    	off_t		 size;	/* size */
    	time_t		 mtime;	/* modification */
    	unsigned int	 flags;
    #define	FLSTAT_TOP_DIR	 0x01	/* a top-level directory */
    
    };
    
    /*
     * A list of files with their statistics.
     */
    struct	flist {
    	char		*path; /* path relative to root */
    	const char	*wpath; /* "working" path for receiver */
    	struct flstat	 st; /* file information */
    	char		*link; /* symlink target or NULL */
    };
    
    /*
     * Options passed into the command line.
     * See struct fargs.
     */
    struct	opts {
    	int		 sender;		/* --sender */
    	int		 server;		/* --server */
    	int		 recursive;		/* -r */
    	int		 dry_run;		/* -n */
    	int		 preserve_times;	/* -t */
    	int		 preserve_perms;	/* -p */
    	int		 preserve_links;	/* -l */
    	int		 preserve_gids;		/* -g */
    	int		 preserve_uids;		/* -u */
    	int		 del;			/* --delete */
    	int		 devices;		/* --devices */
    	int		 specials;		/* --specials */
    	int		 numeric_ids;		/* --numeric-ids */
    	int		 one_file_system;	/* -x */
    	char		*rsync_path;		/* --rsync-path */
    	char		*ssh_prog;		/* --rsh or -e */
    	char		*port;			/* --port */
    	char		*address;		/* --address */
    };
    
    /*
     * An individual block description for a file.
     * See struct blkset.
     */
    struct	blk {
    	off_t		 offs; /* offset in file */
    	size_t		 idx; /* block index */
    	size_t		 len; /* bytes in block */
    	uint32_t	 chksum_short; /* fast checksum */
    	unsigned char	 chksum_long[CSUM_LENGTH_PHASE2]; /* slow checksum */
    };
    
    enum	blkstatst {
    	BLKSTAT_NONE = 0,
    	BLKSTAT_NEXT,
    	BLKSTAT_DATA,
    	BLKSTAT_TOK,
    	BLKSTAT_HASH,
    	BLKSTAT_DONE,
    	BLKSTAT_PHASE,
    };
    
    /*
     * Information for the sender updating receiver blocks reentrantly.
     */
    struct	blkstat {
    	off_t		 offs; /* position in sender file */
    	off_t		 total; /* total amount processed */
    	off_t		 dirty; /* total amount sent */
    	size_t		 hint; /* optimisation: next probable match */
    	void		*map; /* mapped file or MAP_FAILED otherwise */
    	size_t		 mapsz; /* size of file or zero */
    	int		 fd; /* descriptor girding the map */
    	enum blkstatst	 curst; /* FSM for sending file blocks */
    	off_t		 curpos; /* sending: position in file to send */
    	off_t		 curlen; /* sending: length of send */
    	int32_t		 curtok; /* sending: next matching token or zero */
    	struct blktab	*blktab; /* hashtable of blocks */
    	uint32_t	 s1; /* partial sum for computing fast hash */
    	uint32_t	 s2; /* partial sum for computing fast hash */
    };
    
    /*
     * When transferring file contents, we break the file down into blocks
     * and work with those.
     */
    struct	blkset {
    	off_t		 size; /* file size */
    	size_t		 rem; /* terminal block length if non-zero */
    	size_t		 len; /* block length */
    	size_t		 csum; /* checksum length */
    	struct blk	*blks; /* all blocks */
    	size_t		 blksz; /* number of blks */
    };
    
    /*
     * Values required during a communication session.
     */
    struct	sess {
    	const struct opts *opts; /* system options */
    	int32_t		   seed; /* checksum seed */
    	int32_t		   lver; /* local version */
    	int32_t		   rver; /* remote version */
    	uint64_t	   total_read; /* non-logging wire/reads */
    	uint64_t	   total_size; /* total file size */
    	uint64_t	   total_write; /* non-logging wire/writes */
    	int		   mplex_reads; /* multiplexing reads? */
    	size_t		   mplex_read_remain; /* remaining bytes */
    	int		   mplex_writes; /* multiplexing writes? */
    };
    
    /*
     * Combination of name and numeric id for groups and users.
     */
    struct	ident {
    	int32_t	 id; /* the gid_t or uid_t */
    	int32_t	 mapped; /* if receiving, the mapped gid */
    	char	*name; /* resolved name */
    };
    
    typedef struct arglist arglist;
    struct arglist {
    	char	**list;
    	u_int	num;
    	u_int	nalloc;
    };
    void	addargs(arglist *, char *, ...)
    	    __attribute__((format(printf, 2, 3)));
    void	freeargs(arglist *);
    
    struct	download;
    struct	upload;
    
    extern int verbose;
    
    #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
    
    #define LOG0(_fmt, ...) \
    	rsync_log( -1, (_fmt), ##__VA_ARGS__)
    #define LOG1(_fmt, ...) \
    	rsync_log( 0, (_fmt), ##__VA_ARGS__)
    #define LOG2(_fmt, ...) \
    	rsync_log( 1, (_fmt), ##__VA_ARGS__)
    #define LOG3(_fmt, ...) \
    	rsync_log( 2, (_fmt), ##__VA_ARGS__)
    #define LOG4(_fmt, ...) \
    	rsync_log( 3, (_fmt), ##__VA_ARGS__)
    #define ERRX1(_fmt, ...) \
    	rsync_errx1( (_fmt), ##__VA_ARGS__)
    #define WARNX(_fmt, ...) \
    	rsync_warnx( (_fmt), ##__VA_ARGS__)
    #define WARN(_fmt, ...) \
    	rsync_warn(0,  (_fmt), ##__VA_ARGS__)
    #define WARN1(_fmt, ...) \
    	rsync_warn(1,  (_fmt), ##__VA_ARGS__)
    #define WARN2(_fmt, ...) \
    	rsync_warn(2,  (_fmt), ##__VA_ARGS__)
    #define ERR(_fmt, ...) \
    	rsync_err( (_fmt), ##__VA_ARGS__)
    #define ERRX(_fmt, ...) \
    	rsync_errx( (_fmt), ##__VA_ARGS__)
    
    void		  rsync_log(int, const char *, ...)
    			__attribute__((format(printf, 2, 3)));
    void		  rsync_warnx1(const char *, ...)
    			__attribute__((format(printf, 1, 2)));
    void		  rsync_warn(int, const char *, ...)
    			__attribute__((format(printf, 2, 3)));
    void		  rsync_warnx(const char *, ...)
    			__attribute__((format(printf, 1, 2)));
    void		  rsync_err(const char *, ...)
    			__attribute__((format(printf, 1, 2)));
    void		  rsync_errx(const char *, ...)
    			__attribute__((format(printf, 1, 2)));
    void		  rsync_errx1(const char *, ...)
    			__attribute__((format(printf, 1, 2)));
    
    int		  flist_del(struct sess *, int,
    			const struct flist *, size_t);
    int		  flist_gen(struct sess *, size_t, char **,
    			struct flist **, size_t *);
    int		  flist_gen_local(struct sess *, const char *,
    			struct flist **, size_t *);
    void		  flist_free(struct flist *, size_t);
    int		  flist_recv(struct sess *, int,
    			struct flist **, size_t *);
    int		  flist_send(struct sess *, int, int,
    			const struct flist *, size_t);
    int		  flist_gen_dels(struct sess *, const char *,
    			struct flist **, size_t *,
    			const struct flist *, size_t);
    
    char		**fargs_cmdline(struct sess *, const struct fargs *, size_t *);
    
    int		  io_read_buf(struct sess *, int, void *, size_t);
    int		  io_read_byte(struct sess *, int, uint8_t *);
    int		  io_read_check(int);
    int		  io_read_flush(struct sess *, int);
    int		  io_read_int(struct sess *, int, int32_t *);
    int		  io_read_uint(struct sess *, int, uint32_t *);
    int		  io_read_long(struct sess *, int, int64_t *);
    int		  io_read_size(struct sess *, int, size_t *);
    int		  io_read_ulong(struct sess *, int, uint64_t *);
    int		  io_write_buf(struct sess *, int, const void *, size_t);
    int		  io_write_byte(struct sess *, int, uint8_t);
    int		  io_write_int(struct sess *, int, int32_t);
    int		  io_write_uint(struct sess *, int, uint32_t);
    int		  io_write_line(struct sess *, int, const char *);
    int		  io_write_long(struct sess *, int, int64_t);
    int		  io_write_ulong(struct sess *, int, uint64_t);
    
    int		  io_lowbuffer_alloc(struct sess *, void **,
    			size_t *, size_t *, size_t);
    void		  io_lowbuffer_int(struct sess *, void *,
    			size_t *, size_t, int32_t);
    void		  io_lowbuffer_buf(struct sess *, void *,
    			size_t *, size_t, const void *, size_t);
    
    void		  io_buffer_int(void *, size_t *, size_t, int32_t);
    void		  io_buffer_buf(void *, size_t *, size_t, const void *, size_t);
    
    void		  io_unbuffer_int(const void *,
    			size_t *, size_t, int32_t *);
    int		  io_unbuffer_size(const void *, size_t *, size_t, size_t *);
    void		  io_unbuffer_buf(const void *, size_t *, size_t, void *, size_t);
    
    int		  rsync_receiver(struct sess *, int, int, const char *);
    int		  rsync_sender(struct sess *, int, int, size_t, char **);
    int		  rsync_client(const struct opts *, int, const struct fargs *);
    int		  rsync_connect(const struct opts *, int *,
    			const struct fargs *);
    int		  rsync_socket(const struct opts *, int, const struct fargs *);
    int		  rsync_server(const struct opts *, size_t, char *[]);
    int		  rsync_downloader(struct download *, struct sess *, int *);
    int		  rsync_set_metadata(struct sess *, int, int,
    			const struct flist *, const char *);
    int		  rsync_set_metadata_at(struct sess *, int, int,
    			const struct flist *, const char *);
    int		  rsync_uploader(struct upload *,
    			int *, struct sess *, int *);
    int		  rsync_uploader_tail(struct upload *, struct sess *);
    
    struct download	 *download_alloc(struct sess *, int,
    			const struct flist *, size_t, int);
    void		  download_free(struct download *);
    struct upload	 *upload_alloc(const char *, int, int, size_t,
    			const struct flist *, size_t, mode_t);
    void		  upload_free(struct upload *);
    
    struct blktab	*blkhash_alloc(void);
    int		 blkhash_set(struct blktab *, const struct blkset *);
    void		 blkhash_free(struct blktab *);
    
    struct blkset	 *blk_recv(struct sess *, int, const char *);
    void		  blk_recv_ack(char [20], const struct blkset *, int32_t);
    void		  blk_match(struct sess *, const struct blkset *,
    			const char *, struct blkstat *);
    int		  blk_send(struct sess *, int, size_t,
    			const struct blkset *, const char *);
    int		  blk_send_ack(struct sess *, int, struct blkset *);
    
    uint32_t	  hash_fast(const void *, size_t);
    void		  hash_slow(const void *, size_t,
    			unsigned char *, const struct sess *);
    void		  hash_file(const void *, size_t,
    			unsigned char *, const struct sess *);
    
    int		  mkpath(char *);
    
    int		  mkstempat(int, char *);
    char		 *mkstemplinkat(char*, int, char *);
    char		 *mkstempfifoat(int, char *);
    char		 *mkstempnodat(int, char *, mode_t, dev_t);
    char		 *mkstempsock(const char *, char *);
    int		  mktemplate(char **, const char *, int);
    
    char		 *symlink_read(const char *);
    char		 *symlinkat_read(int, const char *);
    
    int		  sess_stats_send(struct sess *, int);
    int		  sess_stats_recv(struct sess *, int);
    
    int		  idents_add(int, struct ident **, size_t *, int32_t);
    void		  idents_assign_gid(struct sess *,
    			struct flist *, size_t, const struct ident *, size_t);
    void		  idents_assign_uid(struct sess *,
    			struct flist *, size_t, const struct ident *, size_t);
    void		  idents_free(struct ident *, size_t);
    int		  idents_recv(struct sess *, int, struct ident **, size_t *);
    void		  idents_remap(struct sess *, int, struct ident *, size_t);
    int		  idents_send(struct sess *, int, const struct ident *, size_t);
    
    #endif /*!EXTERN_H*/