File: [local] / src / usr.bin / rsync / extern.h (download)
Revision 1.19, Mon Feb 18 21:34:54 2019 UTC (5 years, 3 months ago) by benno
Branch: MAIN
Changes since 1.18: +12 -6 lines
sync with kristaps up to Sun Feb 17 2019
339cf5998c0c022623cd68de50722b6c14543952 Push "error trail" further into code.
baf58ce5fe1bc6ce431b3b0ac8264b83ae8c7d02 Document all arguments. Add
common -av usage. Remove bits about not supporting anything but
files/dirs.
821a811a8c80e52fb56b241fc65a16cae1b4fb2c Disambiguate as prodded by deraadt@
6c4475b8f226e9031ec0ec1b3f14f7d347132c87 Add -h to usage string
4d344ae6156873b44c95de0c1ed629e637c2d7ab Clarify error message
language, use service name instead of port, specify that the socket is
SOCK_STREAM. From deraadt@. Tweaked for lowercase messages.
f3ec049e76257fc96bcdc872f1d3b967b98f3eb6 In consideration to benno@'s
comments, let the mktemp functions propogate an errno handled by the
caller. Also keep the original line lengths. While in mktemp.c, make
some defines into an enum.
e116c2bd00e634b56e4276120135915ceaa31cf2 Put the FSM of the sender
into its own function. Put dry_run ack and end of phase ack into the
send buffer too, further reducing the possibility of deadlock.
c7745aa4c7394ca89d841f8ee76782256d694340 Make the sender write loop be
fully non-blocking. This frees us of deadlocking the protocol because
the sender will always be able to pull down data.
93c7b4843e80aeac2ec6ae6ffc395df4deaf4a31 Remove "yoda" notation to be
more in tune with OpenBSD. Most found by deraadt@.
|
/* $Id: extern.h,v 1.19 2019/02/18 21:34:54 benno 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)
/*
* The default service (see services(5)) for rsync.
*/
#define RSYNC_SERVICE "rsync"
/*
* 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 verbose; /* -v */
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 */
char *rsync_path; /* --rsync-path */
char *ssh_prog; /* --rsh or -e */
char *port; /* --port */
};
/*
* 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 */
};
/*
* 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 */
};
struct download;
struct upload;
#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
#define LOG0(_sess, _fmt, ...) \
rsync_log((_sess), __FILE__, __LINE__, -1, (_fmt), ##__VA_ARGS__)
#define LOG1(_sess, _fmt, ...) \
rsync_log((_sess), __FILE__, __LINE__, 0, (_fmt), ##__VA_ARGS__)
#define LOG2(_sess, _fmt, ...) \
rsync_log((_sess), __FILE__, __LINE__, 1, (_fmt), ##__VA_ARGS__)
#define LOG3(_sess, _fmt, ...) \
rsync_log((_sess), __FILE__, __LINE__, 2, (_fmt), ##__VA_ARGS__)
#define LOG4(_sess, _fmt, ...) \
rsync_log((_sess), __FILE__, __LINE__, 3, (_fmt), ##__VA_ARGS__)
#define ERRX1(_sess, _fmt, ...) \
rsync_errx1((_sess), __FILE__, __LINE__, (_fmt), ##__VA_ARGS__)
#define WARNX(_sess, _fmt, ...) \
rsync_warnx((_sess), __FILE__, __LINE__, (_fmt), ##__VA_ARGS__)
#define WARN(_sess, _fmt, ...) \
rsync_warn((_sess), 0, __FILE__, __LINE__, (_fmt), ##__VA_ARGS__)
#define WARN1(_sess, _fmt, ...) \
rsync_warn((_sess), 1, __FILE__, __LINE__, (_fmt), ##__VA_ARGS__)
#define WARN2(_sess, _fmt, ...) \
rsync_warn((_sess), 2, __FILE__, __LINE__, (_fmt), ##__VA_ARGS__)
#define ERR(_sess, _fmt, ...) \
rsync_err((_sess), __FILE__, __LINE__, (_fmt), ##__VA_ARGS__)
#define ERRX(_sess, _fmt, ...) \
rsync_errx((_sess), __FILE__, __LINE__, (_fmt), ##__VA_ARGS__)
__BEGIN_DECLS
void rsync_log(struct sess *,
const char *, size_t, int, const char *, ...)
__attribute__((format(printf, 5, 6)));
void rsync_warnx1(struct sess *,
const char *, size_t, const char *, ...)
__attribute__((format(printf, 4, 5)));
void rsync_warn(struct sess *, int,
const char *, size_t, const char *, ...)
__attribute__((format(printf, 5, 6)));
void rsync_warnx(struct sess *, const char *,
size_t, const char *, ...)
__attribute__((format(printf, 4, 5)));
void rsync_err(struct sess *, const char *,
size_t, const char *, ...)
__attribute__((format(printf, 4, 5)));
void rsync_errx(struct sess *, const char *,
size_t, const char *, ...)
__attribute__((format(printf, 4, 5)));
void rsync_errx1(struct sess *, const char *,
size_t, const char *, ...)
__attribute__((format(printf, 4, 5)));
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 *);
int io_read_buf(struct sess *, int, void *, size_t);
int io_read_byte(struct sess *, int, uint8_t *);
int io_read_check(struct sess *, int);
int io_read_flush(struct sess *, int);
int io_read_int(struct sess *, int, int32_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_line(struct sess *, int, const char *);
int io_write_long(struct sess *, int, int64_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(struct sess *, void *,
size_t *, size_t, int32_t);
void io_buffer_buf(struct sess *, void *,
size_t *, size_t, const void *, size_t);
void io_unbuffer_int(struct sess *, const void *,
size_t *, size_t, int32_t *);
int io_unbuffer_size(struct sess *, const void *,
size_t *, size_t, size_t *);
void io_unbuffer_buf(struct sess *, const void *,
size_t *, size_t, void *, size_t);
void rsync_child(const struct opts *, int, const struct fargs *)
__attribute__((noreturn));
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_socket(const struct opts *, 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(struct sess *, const char *, int, int, size_t,
const struct flist *, size_t, mode_t);
void upload_free(struct upload *);
struct blkset *blk_recv(struct sess *, int, const char *);
void blk_recv_ack(struct sess *,
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(struct sess *, 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(struct sess *, char **, const char *, int);
char *symlink_read(struct sess *, const char *);
char *symlinkat_read(struct sess *, int, const char *);
int sess_stats_send(struct sess *, int);
int sess_stats_recv(struct sess *, int);
int idents_add(struct sess *, 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);
__END_DECLS
#endif /*!EXTERN_H*/