1 /* $Id: extern.h,v 1.37 2021/05/17 11:54:14 claudio Exp $ */ 2 /* 3 * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 #ifndef EXTERN_H 18 #define EXTERN_H 19 20 /* 21 * This is the rsync protocol version that we support. 22 */ 23 #define RSYNC_PROTOCOL (27) 24 25 /* 26 * Maximum amount of file data sent over the wire at once. 27 */ 28 #define MAX_CHUNK (32 * 1024) 29 30 /* 31 * This is the minimum size for a block of data not including those in 32 * the remainder block. 33 */ 34 #define BLOCK_SIZE_MIN (700) 35 36 /* 37 * The sender and receiver use a two-phase synchronisation process. 38 * The first uses two-byte hashes; the second, 16-byte. 39 * (The second must hold a full MD4 digest.) 40 */ 41 #define CSUM_LENGTH_PHASE1 (2) 42 #define CSUM_LENGTH_PHASE2 (16) 43 44 /* 45 * Rsync error codes. 46 */ 47 #define ERR_SYNTAX 1 48 #define ERR_PROTOCOL 2 49 #define ERR_SOCK_IO 10 50 #define ERR_FILE_IO 11 51 #define ERR_WIREPROTO 12 52 #define ERR_IPC 14 /* catchall for any kind of syscall error */ 53 #define ERR_TERMIMATED 16 54 #define ERR_WAITPID 21 55 #define ERR_NOMEM 22 56 57 /* 58 * Use this for --timeout. 59 * All poll events will use it and catch time-outs. 60 */ 61 extern int poll_timeout; 62 63 /* 64 * Operating mode for a client or a server. 65 * Sender means we synchronise local files with those from remote. 66 * Receiver is the opposite. 67 * This is relative to which host we're running on. 68 */ 69 enum fmode { 70 FARGS_SENDER, 71 FARGS_RECEIVER 72 }; 73 74 /* 75 * File arguments given on the command line. 76 * See struct opts. 77 */ 78 struct fargs { 79 char *host; /* hostname or NULL if local */ 80 char **sources; /* transfer source */ 81 size_t sourcesz; /* number of sources */ 82 char *sink; /* transfer endpoint */ 83 enum fmode mode; /* mode of operation */ 84 int remote; /* uses rsync:// or :: for remote */ 85 char *module; /* if rsync://, the module */ 86 }; 87 88 /* 89 * The subset of stat(2) information that we need. 90 * (There are some parts we don't use yet.) 91 */ 92 struct flstat { 93 mode_t mode; /* mode */ 94 uid_t uid; /* user */ 95 gid_t gid; /* group */ 96 dev_t rdev; /* device type */ 97 off_t size; /* size */ 98 time_t mtime; /* modification */ 99 unsigned int flags; 100 #define FLSTAT_TOP_DIR 0x01 /* a top-level directory */ 101 102 }; 103 104 /* 105 * A list of files with their statistics. 106 */ 107 struct flist { 108 char *path; /* path relative to root */ 109 const char *wpath; /* "working" path for receiver */ 110 struct flstat st; /* file information */ 111 char *link; /* symlink target or NULL */ 112 }; 113 114 /* 115 * Options passed into the command line. 116 * See struct fargs. 117 */ 118 struct opts { 119 int sender; /* --sender */ 120 int server; /* --server */ 121 int recursive; /* -r */ 122 int dry_run; /* -n */ 123 int preserve_times; /* -t */ 124 int preserve_perms; /* -p */ 125 int preserve_links; /* -l */ 126 int preserve_gids; /* -g */ 127 int preserve_uids; /* -u */ 128 int del; /* --delete */ 129 int devices; /* --devices */ 130 int specials; /* --specials */ 131 int no_motd; /* --no-motd */ 132 int numeric_ids; /* --numeric-ids */ 133 int one_file_system; /* -x */ 134 char *rsync_path; /* --rsync-path */ 135 char *ssh_prog; /* --rsh or -e */ 136 char *port; /* --port */ 137 char *address; /* --address */ 138 }; 139 140 /* 141 * An individual block description for a file. 142 * See struct blkset. 143 */ 144 struct blk { 145 off_t offs; /* offset in file */ 146 size_t idx; /* block index */ 147 size_t len; /* bytes in block */ 148 uint32_t chksum_short; /* fast checksum */ 149 unsigned char chksum_long[CSUM_LENGTH_PHASE2]; /* slow checksum */ 150 }; 151 152 enum blkstatst { 153 BLKSTAT_NONE = 0, 154 BLKSTAT_NEXT, 155 BLKSTAT_DATA, 156 BLKSTAT_TOK, 157 BLKSTAT_HASH, 158 BLKSTAT_DONE, 159 BLKSTAT_PHASE, 160 }; 161 162 /* 163 * Information for the sender updating receiver blocks reentrantly. 164 */ 165 struct blkstat { 166 off_t offs; /* position in sender file */ 167 off_t total; /* total amount processed */ 168 off_t dirty; /* total amount sent */ 169 size_t hint; /* optimisation: next probable match */ 170 void *map; /* mapped file or MAP_FAILED otherwise */ 171 size_t mapsz; /* size of file or zero */ 172 int fd; /* descriptor girding the map */ 173 enum blkstatst curst; /* FSM for sending file blocks */ 174 off_t curpos; /* sending: position in file to send */ 175 off_t curlen; /* sending: length of send */ 176 int32_t curtok; /* sending: next matching token or zero */ 177 struct blktab *blktab; /* hashtable of blocks */ 178 uint32_t s1; /* partial sum for computing fast hash */ 179 uint32_t s2; /* partial sum for computing fast hash */ 180 }; 181 182 /* 183 * When transferring file contents, we break the file down into blocks 184 * and work with those. 185 */ 186 struct blkset { 187 off_t size; /* file size */ 188 size_t rem; /* terminal block length if non-zero */ 189 size_t len; /* block length */ 190 size_t csum; /* checksum length */ 191 struct blk *blks; /* all blocks */ 192 size_t blksz; /* number of blks */ 193 }; 194 195 /* 196 * Values required during a communication session. 197 */ 198 struct sess { 199 const struct opts *opts; /* system options */ 200 int32_t seed; /* checksum seed */ 201 int32_t lver; /* local version */ 202 int32_t rver; /* remote version */ 203 uint64_t total_read; /* non-logging wire/reads */ 204 uint64_t total_size; /* total file size */ 205 uint64_t total_write; /* non-logging wire/writes */ 206 int mplex_reads; /* multiplexing reads? */ 207 size_t mplex_read_remain; /* remaining bytes */ 208 int mplex_writes; /* multiplexing writes? */ 209 }; 210 211 /* 212 * Combination of name and numeric id for groups and users. 213 */ 214 struct ident { 215 int32_t id; /* the gid_t or uid_t */ 216 int32_t mapped; /* if receiving, the mapped gid */ 217 char *name; /* resolved name */ 218 }; 219 220 typedef struct arglist arglist; 221 struct arglist { 222 char **list; 223 u_int num; 224 u_int nalloc; 225 }; 226 void addargs(arglist *, const char *, ...) 227 __attribute__((format(printf, 2, 3))); 228 void freeargs(arglist *); 229 230 struct download; 231 struct upload; 232 233 extern int verbose; 234 235 #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 236 237 #define LOG0(_fmt, ...) \ 238 rsync_log( -1, (_fmt), ##__VA_ARGS__) 239 #define LOG1(_fmt, ...) \ 240 rsync_log( 0, (_fmt), ##__VA_ARGS__) 241 #define LOG2(_fmt, ...) \ 242 rsync_log( 1, (_fmt), ##__VA_ARGS__) 243 #define LOG3(_fmt, ...) \ 244 rsync_log( 2, (_fmt), ##__VA_ARGS__) 245 #define LOG4(_fmt, ...) \ 246 rsync_log( 3, (_fmt), ##__VA_ARGS__) 247 #define ERRX1(_fmt, ...) \ 248 rsync_errx1( (_fmt), ##__VA_ARGS__) 249 #define WARNX(_fmt, ...) \ 250 rsync_warnx( (_fmt), ##__VA_ARGS__) 251 #define WARN(_fmt, ...) \ 252 rsync_warn(0, (_fmt), ##__VA_ARGS__) 253 #define WARN1(_fmt, ...) \ 254 rsync_warn(1, (_fmt), ##__VA_ARGS__) 255 #define WARN2(_fmt, ...) \ 256 rsync_warn(2, (_fmt), ##__VA_ARGS__) 257 #define ERR(_fmt, ...) \ 258 rsync_err( (_fmt), ##__VA_ARGS__) 259 #define ERRX(_fmt, ...) \ 260 rsync_errx( (_fmt), ##__VA_ARGS__) 261 262 void rsync_log(int, const char *, ...) 263 __attribute__((format(printf, 2, 3))); 264 void rsync_warnx1(const char *, ...) 265 __attribute__((format(printf, 1, 2))); 266 void rsync_warn(int, const char *, ...) 267 __attribute__((format(printf, 2, 3))); 268 void rsync_warnx(const char *, ...) 269 __attribute__((format(printf, 1, 2))); 270 void rsync_err(const char *, ...) 271 __attribute__((format(printf, 1, 2))); 272 void rsync_errx(const char *, ...) 273 __attribute__((format(printf, 1, 2))); 274 void rsync_errx1(const char *, ...) 275 __attribute__((format(printf, 1, 2))); 276 277 int flist_del(struct sess *, int, 278 const struct flist *, size_t); 279 int flist_gen(struct sess *, size_t, char **, 280 struct flist **, size_t *); 281 int flist_gen_local(struct sess *, const char *, 282 struct flist **, size_t *); 283 void flist_free(struct flist *, size_t); 284 int flist_recv(struct sess *, int, 285 struct flist **, size_t *); 286 int flist_send(struct sess *, int, int, 287 const struct flist *, size_t); 288 int flist_gen_dels(struct sess *, const char *, 289 struct flist **, size_t *, 290 const struct flist *, size_t); 291 292 char **fargs_cmdline(struct sess *, const struct fargs *, size_t *); 293 294 int io_read_buf(struct sess *, int, void *, size_t); 295 int io_read_byte(struct sess *, int, uint8_t *); 296 int io_read_check(int); 297 int io_read_flush(struct sess *, int); 298 int io_read_int(struct sess *, int, int32_t *); 299 int io_read_uint(struct sess *, int, uint32_t *); 300 int io_read_long(struct sess *, int, int64_t *); 301 int io_read_size(struct sess *, int, size_t *); 302 int io_read_ulong(struct sess *, int, uint64_t *); 303 int io_write_buf(struct sess *, int, const void *, size_t); 304 int io_write_byte(struct sess *, int, uint8_t); 305 int io_write_int(struct sess *, int, int32_t); 306 int io_write_uint(struct sess *, int, uint32_t); 307 int io_write_line(struct sess *, int, const char *); 308 int io_write_long(struct sess *, int, int64_t); 309 int io_write_ulong(struct sess *, int, uint64_t); 310 311 int io_lowbuffer_alloc(struct sess *, void **, 312 size_t *, size_t *, size_t); 313 void io_lowbuffer_int(struct sess *, void *, 314 size_t *, size_t, int32_t); 315 void io_lowbuffer_buf(struct sess *, void *, 316 size_t *, size_t, const void *, size_t); 317 318 void io_buffer_int(void *, size_t *, size_t, int32_t); 319 void io_buffer_buf(void *, size_t *, size_t, const void *, size_t); 320 321 void io_unbuffer_int(const void *, 322 size_t *, size_t, int32_t *); 323 int io_unbuffer_size(const void *, size_t *, size_t, size_t *); 324 void io_unbuffer_buf(const void *, size_t *, size_t, void *, size_t); 325 326 int rsync_receiver(struct sess *, int, int, const char *); 327 int rsync_sender(struct sess *, int, int, size_t, char **); 328 int rsync_client(const struct opts *, int, const struct fargs *); 329 int rsync_connect(const struct opts *, int *, 330 const struct fargs *); 331 int rsync_socket(const struct opts *, int, const struct fargs *); 332 int rsync_server(const struct opts *, size_t, char *[]); 333 int rsync_downloader(struct download *, struct sess *, int *); 334 int rsync_set_metadata(struct sess *, int, int, 335 const struct flist *, const char *); 336 int rsync_set_metadata_at(struct sess *, int, int, 337 const struct flist *, const char *); 338 int rsync_uploader(struct upload *, 339 int *, struct sess *, int *); 340 int rsync_uploader_tail(struct upload *, struct sess *); 341 342 struct download *download_alloc(struct sess *, int, 343 const struct flist *, size_t, int); 344 void download_free(struct download *); 345 struct upload *upload_alloc(const char *, int, int, size_t, 346 const struct flist *, size_t, mode_t); 347 void upload_free(struct upload *); 348 349 struct blktab *blkhash_alloc(void); 350 int blkhash_set(struct blktab *, const struct blkset *); 351 void blkhash_free(struct blktab *); 352 353 struct blkset *blk_recv(struct sess *, int, const char *); 354 void blk_recv_ack(char [20], const struct blkset *, int32_t); 355 void blk_match(struct sess *, const struct blkset *, 356 const char *, struct blkstat *); 357 int blk_send(struct sess *, int, size_t, 358 const struct blkset *, const char *); 359 int blk_send_ack(struct sess *, int, struct blkset *); 360 361 uint32_t hash_fast(const void *, size_t); 362 void hash_slow(const void *, size_t, 363 unsigned char *, const struct sess *); 364 void hash_file(const void *, size_t, 365 unsigned char *, const struct sess *); 366 367 int mkpath(char *); 368 369 int mkstempat(int, char *); 370 char *mkstemplinkat(char*, int, char *); 371 char *mkstempfifoat(int, char *); 372 char *mkstempnodat(int, char *, mode_t, dev_t); 373 char *mkstempsock(const char *, char *); 374 int mktemplate(char **, const char *, int); 375 376 char *symlink_read(const char *); 377 char *symlinkat_read(int, const char *); 378 379 int sess_stats_send(struct sess *, int); 380 int sess_stats_recv(struct sess *, int); 381 382 int idents_add(int, struct ident **, size_t *, int32_t); 383 void idents_assign_gid(struct sess *, 384 struct flist *, size_t, const struct ident *, size_t); 385 void idents_assign_uid(struct sess *, 386 struct flist *, size_t, const struct ident *, size_t); 387 void idents_free(struct ident *, size_t); 388 int idents_recv(struct sess *, int, struct ident **, size_t *); 389 void idents_remap(struct sess *, int, struct ident *, size_t); 390 int idents_send(struct sess *, int, const struct ident *, size_t); 391 392 #endif /*!EXTERN_H*/ 393