1 /* $Id$ */ 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 #if !HAVE_PLEDGE 21 # define pledge(x, y) (1) 22 #endif 23 #if !HAVE_UNVEIL 24 # define unveil(x, y) (1) 25 #endif 26 27 /* 28 * This is the rsync protocol version that we support. 29 */ 30 #define RSYNC_PROTOCOL (27) 31 32 /* 33 * Maximum amount of file data sent over the wire at once. 34 */ 35 #define MAX_CHUNK (32 * 1024) 36 37 /* 38 * This is the minimum size for a block of data not including those in 39 * the remainder block. 40 */ 41 #define BLOCK_SIZE_MIN (700) 42 43 /* 44 * The sender and receiver use a two-phase synchronisation process. 45 * The first uses two-byte hashes; the second, 16-byte. 46 * (The second must hold a full MD4 digest.) 47 */ 48 #define CSUM_LENGTH_PHASE1 (2) 49 #define CSUM_LENGTH_PHASE2 (16) 50 51 /* 52 * Use this for debugging deadlocks. 53 * All poll events will use it and catch time-outs. 54 */ 55 #define POLL_TIMEOUT (INFTIM) 56 57 /* 58 * Operating mode for a client or a server. 59 * Sender means we synchronise local files with those from remote. 60 * Receiver is the opposite. 61 * This is relative to which host we're running on. 62 */ 63 enum fmode { 64 FARGS_SENDER, 65 FARGS_RECEIVER 66 }; 67 68 /* 69 * File arguments given on the command line. 70 * See struct opts. 71 */ 72 struct fargs { 73 char *host; /* hostname or NULL if local */ 74 char **sources; /* transfer source */ 75 size_t sourcesz; /* number of sources */ 76 char *sink; /* transfer endpoint */ 77 enum fmode mode; /* mode of operation */ 78 int remote; /* uses rsync:// or :: for remote */ 79 char *module; /* if rsync://, the module */ 80 }; 81 82 /* 83 * The subset of stat(2) information that we need. 84 * (There are some parts we don't use yet.) 85 */ 86 struct flstat { 87 mode_t mode; /* mode */ 88 uid_t uid; /* user */ 89 gid_t gid; /* group */ 90 dev_t rdev; /* device type */ 91 off_t size; /* size */ 92 time_t mtime; /* modification */ 93 unsigned int flags; 94 #define FLSTAT_TOP_DIR 0x01 /* a top-level directory */ 95 96 }; 97 98 /* 99 * A list of files with their statistics. 100 */ 101 struct flist { 102 char *path; /* path relative to root */ 103 const char *wpath; /* "working" path for receiver */ 104 struct flstat st; /* file information */ 105 char *link; /* symlink target or NULL */ 106 }; 107 108 /* 109 * Options passed into the command line. 110 * See struct fargs. 111 */ 112 struct opts { 113 int sender; /* --sender */ 114 int server; /* --server */ 115 int recursive; /* -r */ 116 int dry_run; /* -n */ 117 int preserve_times; /* -t */ 118 int preserve_perms; /* -p */ 119 int preserve_links; /* -l */ 120 int preserve_gids; /* -g */ 121 int preserve_uids; /* -u */ 122 int del; /* --delete */ 123 int devices; /* --devices */ 124 int specials; /* --specials */ 125 int numeric_ids; /* --numeric-ids */ 126 int one_file_system; /* -x */ 127 char *rsync_path; /* --rsync-path */ 128 char *ssh_prog; /* --rsh or -e */ 129 char *port; /* --port */ 130 char *address; /* --address */ 131 #if 0 132 char *syncfile; /* --sync-file */ 133 #endif 134 }; 135 136 /* 137 * An individual block description for a file. 138 * See struct blkset. 139 */ 140 struct blk { 141 off_t offs; /* offset in file */ 142 size_t idx; /* block index */ 143 size_t len; /* bytes in block */ 144 uint32_t chksum_short; /* fast checksum */ 145 unsigned char chksum_long[CSUM_LENGTH_PHASE2]; /* slow checksum */ 146 }; 147 148 enum blkstatst { 149 BLKSTAT_NONE = 0, 150 BLKSTAT_NEXT, 151 BLKSTAT_DATA, 152 BLKSTAT_TOK, 153 BLKSTAT_HASH, 154 BLKSTAT_DONE, 155 BLKSTAT_PHASE, 156 }; 157 158 /* 159 * Information for the sender updating receiver blocks reentrantly. 160 */ 161 struct blkstat { 162 off_t offs; /* position in sender file */ 163 off_t total; /* total amount processed */ 164 off_t dirty; /* total amount sent */ 165 size_t hint; /* optimisation: next probable match */ 166 void *map; /* mapped file or MAP_FAILED otherwise */ 167 size_t mapsz; /* size of file or zero */ 168 int fd; /* descriptor girding the map */ 169 enum blkstatst curst; /* FSM for sending file blocks */ 170 off_t curpos; /* sending: position in file to send */ 171 off_t curlen; /* sending: length of send */ 172 int32_t curtok; /* sending: next matching token or zero */ 173 struct blktab *blktab; /* hashtable of blocks */ 174 uint32_t s1; /* partial sum for computing fast hash */ 175 uint32_t s2; /* partial sum for computing fast hash */ 176 }; 177 178 /* 179 * When transferring file contents, we break the file down into blocks 180 * and work with those. 181 */ 182 struct blkset { 183 off_t size; /* file size */ 184 size_t rem; /* terminal block length if non-zero */ 185 size_t len; /* block length */ 186 size_t csum; /* checksum length */ 187 struct blk *blks; /* all blocks */ 188 size_t blksz; /* number of blks */ 189 }; 190 191 /* 192 * Values required during a communication session. 193 */ 194 struct sess { 195 const struct opts *opts; /* system options */ 196 int32_t seed; /* checksum seed */ 197 int32_t lver; /* local version */ 198 int32_t rver; /* remote version */ 199 uint64_t total_read; /* non-logging wire/reads */ 200 uint64_t total_size; /* total file size */ 201 uint64_t total_write; /* non-logging wire/writes */ 202 int mplex_reads; /* multiplexing reads? */ 203 size_t mplex_read_remain; /* remaining bytes */ 204 int mplex_writes; /* multiplexing writes? */ 205 }; 206 207 /* 208 * Combination of name and numeric id for groups and users. 209 */ 210 struct ident { 211 int32_t id; /* the gid_t or uid_t */ 212 int32_t mapped; /* if receiving, the mapped gid */ 213 char *name; /* resolved name */ 214 }; 215 216 typedef struct arglist arglist; 217 struct arglist { 218 char **list; 219 u_int num; 220 u_int nalloc; 221 }; 222 void addargs(arglist *, const char *, ...) 223 __attribute__((format(printf, 2, 3))); 224 void freeargs(arglist *); 225 226 struct download; 227 struct upload; 228 229 extern int verbose; 230 231 #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 232 233 #define LOG0(_fmt, ...) \ 234 rsync_log(__FILE__, __LINE__, -1, (_fmt), ##__VA_ARGS__) 235 #define LOG1(_fmt, ...) \ 236 rsync_log(__FILE__, __LINE__, 0, (_fmt), ##__VA_ARGS__) 237 #define LOG2(_fmt, ...) \ 238 rsync_log(__FILE__, __LINE__, 1, (_fmt), ##__VA_ARGS__) 239 #define LOG3(_fmt, ...) \ 240 rsync_log(__FILE__, __LINE__, 2, (_fmt), ##__VA_ARGS__) 241 #define LOG4(_fmt, ...) \ 242 rsync_log(__FILE__, __LINE__, 3, (_fmt), ##__VA_ARGS__) 243 #define ERRX1(_fmt, ...) \ 244 rsync_errx1(__FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 245 #define WARNX(_fmt, ...) \ 246 rsync_warnx(__FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 247 #define WARN(_fmt, ...) \ 248 rsync_warn(0, __FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 249 #define WARN1(_fmt, ...) \ 250 rsync_warn(1, __FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 251 #define WARN2(_fmt, ...) \ 252 rsync_warn(2, __FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 253 254 #if defined(__sun) && defined(ERR) 255 # undef ERR 256 #endif 257 #define ERR(_fmt, ...) \ 258 rsync_err(__FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 259 #define ERRX(_fmt, ...) \ 260 rsync_errx(__FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 261 262 void rsync_log(const char *, size_t, int, const char *, ...) 263 __attribute__((format(printf, 4, 5))); 264 void rsync_warnx1(const char *, size_t, const char *, ...) 265 __attribute__((format(printf, 3, 4))); 266 void rsync_warn(int, const char *, size_t, const char *, ...) 267 __attribute__((format(printf, 4, 5))); 268 void rsync_warnx(const char *, size_t, const char *, ...) 269 __attribute__((format(printf, 3, 4))); 270 void rsync_err(const char *, size_t, const char *, ...) 271 __attribute__((format(printf, 3, 4))); 272 void rsync_errx(const char *, size_t, const char *, ...) 273 __attribute__((format(printf, 3, 4))); 274 void rsync_errx1(const char *, size_t, const char *, ...) 275 __attribute__((format(printf, 3, 4))); 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