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