1 /* $Id: extern.h,v 1.28 2019/04/04 04:19:54 bket 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 * Use this for debugging deadlocks. 46 * All poll events will use it and catch time-outs. 47 */ 48 #define POLL_TIMEOUT (INFTIM) 49 50 /* 51 * Operating mode for a client or a server. 52 * Sender means we synchronise local files with those from remote. 53 * Receiver is the opposite. 54 * This is relative to which host we're running on. 55 */ 56 enum fmode { 57 FARGS_SENDER, 58 FARGS_RECEIVER 59 }; 60 61 /* 62 * File arguments given on the command line. 63 * See struct opts. 64 */ 65 struct fargs { 66 char *host; /* hostname or NULL if local */ 67 char **sources; /* transfer source */ 68 size_t sourcesz; /* number of sources */ 69 char *sink; /* transfer endpoint */ 70 enum fmode mode; /* mode of operation */ 71 int remote; /* uses rsync:// or :: for remote */ 72 char *module; /* if rsync://, the module */ 73 }; 74 75 /* 76 * The subset of stat(2) information that we need. 77 * (There are some parts we don't use yet.) 78 */ 79 struct flstat { 80 mode_t mode; /* mode */ 81 uid_t uid; /* user */ 82 gid_t gid; /* group */ 83 dev_t rdev; /* device type */ 84 off_t size; /* size */ 85 time_t mtime; /* modification */ 86 unsigned int flags; 87 #define FLSTAT_TOP_DIR 0x01 /* a top-level directory */ 88 89 }; 90 91 /* 92 * A list of files with their statistics. 93 */ 94 struct flist { 95 char *path; /* path relative to root */ 96 const char *wpath; /* "working" path for receiver */ 97 struct flstat st; /* file information */ 98 char *link; /* symlink target or NULL */ 99 }; 100 101 /* 102 * Options passed into the command line. 103 * See struct fargs. 104 */ 105 struct opts { 106 int sender; /* --sender */ 107 int server; /* --server */ 108 int recursive; /* -r */ 109 int verbose; /* -v */ 110 int dry_run; /* -n */ 111 int preserve_times; /* -t */ 112 int preserve_perms; /* -p */ 113 int preserve_links; /* -l */ 114 int preserve_gids; /* -g */ 115 int preserve_uids; /* -u */ 116 int del; /* --delete */ 117 int devices; /* --devices */ 118 int specials; /* --specials */ 119 int numeric_ids; /* --numeric-ids */ 120 int one_file_system; /* -x */ 121 char *rsync_path; /* --rsync-path */ 122 char *ssh_prog; /* --rsh or -e */ 123 char *port; /* --port */ 124 }; 125 126 /* 127 * An individual block description for a file. 128 * See struct blkset. 129 */ 130 struct blk { 131 off_t offs; /* offset in file */ 132 size_t idx; /* block index */ 133 size_t len; /* bytes in block */ 134 uint32_t chksum_short; /* fast checksum */ 135 unsigned char chksum_long[CSUM_LENGTH_PHASE2]; /* slow checksum */ 136 }; 137 138 enum blkstatst { 139 BLKSTAT_NONE = 0, 140 BLKSTAT_NEXT, 141 BLKSTAT_DATA, 142 BLKSTAT_TOK, 143 BLKSTAT_HASH, 144 BLKSTAT_DONE, 145 BLKSTAT_PHASE, 146 }; 147 148 /* 149 * Information for the sender updating receiver blocks reentrantly. 150 */ 151 struct blkstat { 152 off_t offs; /* position in sender file */ 153 off_t total; /* total amount processed */ 154 off_t dirty; /* total amount sent */ 155 size_t hint; /* optimisation: next probable match */ 156 void *map; /* mapped file or MAP_FAILED otherwise */ 157 size_t mapsz; /* size of file or zero */ 158 int fd; /* descriptor girding the map */ 159 enum blkstatst curst; /* FSM for sending file blocks */ 160 off_t curpos; /* sending: position in file to send */ 161 off_t curlen; /* sending: length of send */ 162 int32_t curtok; /* sending: next matching token or zero */ 163 }; 164 165 /* 166 * When transferring file contents, we break the file down into blocks 167 * and work with those. 168 */ 169 struct blkset { 170 off_t size; /* file size */ 171 size_t rem; /* terminal block length if non-zero */ 172 size_t len; /* block length */ 173 size_t csum; /* checksum length */ 174 struct blk *blks; /* all blocks */ 175 size_t blksz; /* number of blks */ 176 }; 177 178 /* 179 * Values required during a communication session. 180 */ 181 struct sess { 182 const struct opts *opts; /* system options */ 183 int32_t seed; /* checksum seed */ 184 int32_t lver; /* local version */ 185 int32_t rver; /* remote version */ 186 uint64_t total_read; /* non-logging wire/reads */ 187 uint64_t total_size; /* total file size */ 188 uint64_t total_write; /* non-logging wire/writes */ 189 int mplex_reads; /* multiplexing reads? */ 190 size_t mplex_read_remain; /* remaining bytes */ 191 int mplex_writes; /* multiplexing writes? */ 192 }; 193 194 /* 195 * Combination of name and numeric id for groups and users. 196 */ 197 struct ident { 198 int32_t id; /* the gid_t or uid_t */ 199 int32_t mapped; /* if receiving, the mapped gid */ 200 char *name; /* resolved name */ 201 }; 202 203 typedef struct arglist arglist; 204 struct arglist { 205 char **list; 206 u_int num; 207 u_int nalloc; 208 }; 209 void addargs(arglist *, char *, ...) 210 __attribute__((format(printf, 2, 3))); 211 void freeargs(arglist *); 212 213 struct download; 214 struct upload; 215 216 #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 217 218 #define LOG0(_sess, _fmt, ...) \ 219 rsync_log((_sess), __FILE__, __LINE__, -1, (_fmt), ##__VA_ARGS__) 220 #define LOG1(_sess, _fmt, ...) \ 221 rsync_log((_sess), __FILE__, __LINE__, 0, (_fmt), ##__VA_ARGS__) 222 #define LOG2(_sess, _fmt, ...) \ 223 rsync_log((_sess), __FILE__, __LINE__, 1, (_fmt), ##__VA_ARGS__) 224 #define LOG3(_sess, _fmt, ...) \ 225 rsync_log((_sess), __FILE__, __LINE__, 2, (_fmt), ##__VA_ARGS__) 226 #define LOG4(_sess, _fmt, ...) \ 227 rsync_log((_sess), __FILE__, __LINE__, 3, (_fmt), ##__VA_ARGS__) 228 #define ERRX1(_sess, _fmt, ...) \ 229 rsync_errx1((_sess), __FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 230 #define WARNX(_sess, _fmt, ...) \ 231 rsync_warnx((_sess), __FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 232 #define WARN(_sess, _fmt, ...) \ 233 rsync_warn((_sess), 0, __FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 234 #define WARN1(_sess, _fmt, ...) \ 235 rsync_warn((_sess), 1, __FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 236 #define WARN2(_sess, _fmt, ...) \ 237 rsync_warn((_sess), 2, __FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 238 #define ERR(_sess, _fmt, ...) \ 239 rsync_err((_sess), __FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 240 #define ERRX(_sess, _fmt, ...) \ 241 rsync_errx((_sess), __FILE__, __LINE__, (_fmt), ##__VA_ARGS__) 242 243 void rsync_log(struct sess *, 244 const char *, size_t, int, const char *, ...) 245 __attribute__((format(printf, 5, 6))); 246 void rsync_warnx1(struct sess *, 247 const char *, size_t, const char *, ...) 248 __attribute__((format(printf, 4, 5))); 249 void rsync_warn(struct sess *, int, 250 const char *, size_t, const char *, ...) 251 __attribute__((format(printf, 5, 6))); 252 void rsync_warnx(struct sess *, const char *, 253 size_t, const char *, ...) 254 __attribute__((format(printf, 4, 5))); 255 void rsync_err(struct sess *, const char *, 256 size_t, const char *, ...) 257 __attribute__((format(printf, 4, 5))); 258 void rsync_errx(struct sess *, const char *, 259 size_t, const char *, ...) 260 __attribute__((format(printf, 4, 5))); 261 void rsync_errx1(struct sess *, const char *, 262 size_t, const char *, ...) 263 __attribute__((format(printf, 4, 5))); 264 265 int flist_del(struct sess *, int, 266 const struct flist *, size_t); 267 int flist_gen(struct sess *, size_t, char **, 268 struct flist **, size_t *); 269 int flist_gen_local(struct sess *, const char *, 270 struct flist **, size_t *); 271 void flist_free(struct flist *, size_t); 272 int flist_recv(struct sess *, int, 273 struct flist **, size_t *); 274 int flist_send(struct sess *, int, int, 275 const struct flist *, size_t); 276 int flist_gen_dels(struct sess *, const char *, 277 struct flist **, size_t *, 278 const struct flist *, size_t); 279 280 char **fargs_cmdline(struct sess *, const struct fargs *, size_t *); 281 282 int io_read_buf(struct sess *, int, void *, size_t); 283 int io_read_byte(struct sess *, int, uint8_t *); 284 int io_read_check(struct sess *, int); 285 int io_read_flush(struct sess *, int); 286 int io_read_int(struct sess *, int, int32_t *); 287 int io_read_uint(struct sess *, int, uint32_t *); 288 int io_read_long(struct sess *, int, int64_t *); 289 int io_read_size(struct sess *, int, size_t *); 290 int io_read_ulong(struct sess *, int, uint64_t *); 291 int io_write_buf(struct sess *, int, const void *, size_t); 292 int io_write_byte(struct sess *, int, uint8_t); 293 int io_write_int(struct sess *, int, int32_t); 294 int io_write_uint(struct sess *, int, uint32_t); 295 int io_write_line(struct sess *, int, const char *); 296 int io_write_long(struct sess *, int, int64_t); 297 int io_write_ulong(struct sess *, int, uint64_t); 298 299 int io_lowbuffer_alloc(struct sess *, void **, 300 size_t *, size_t *, size_t); 301 void io_lowbuffer_int(struct sess *, void *, 302 size_t *, size_t, int32_t); 303 void io_lowbuffer_buf(struct sess *, void *, 304 size_t *, size_t, const void *, size_t); 305 306 void io_buffer_int(struct sess *, void *, 307 size_t *, size_t, int32_t); 308 void io_buffer_buf(struct sess *, void *, 309 size_t *, size_t, const void *, size_t); 310 311 void io_unbuffer_int(struct sess *, const void *, 312 size_t *, size_t, int32_t *); 313 int io_unbuffer_size(struct sess *, const void *, 314 size_t *, size_t, size_t *); 315 void io_unbuffer_buf(struct sess *, const void *, 316 size_t *, size_t, void *, size_t); 317 318 int rsync_receiver(struct sess *, int, int, const char *); 319 int rsync_sender(struct sess *, int, int, size_t, char **); 320 int rsync_client(const struct opts *, int, const struct fargs *); 321 int rsync_connect(const struct opts *, int *, 322 const struct fargs *); 323 int rsync_socket(const struct opts *, int, const struct fargs *); 324 int rsync_server(const struct opts *, size_t, char *[]); 325 int rsync_downloader(struct download *, struct sess *, int *); 326 int rsync_set_metadata(struct sess *, int, int, 327 const struct flist *, const char *); 328 int rsync_set_metadata_at(struct sess *, int, int, 329 const struct flist *, const char *); 330 int rsync_uploader(struct upload *, 331 int *, struct sess *, int *); 332 int rsync_uploader_tail(struct upload *, struct sess *); 333 334 struct download *download_alloc(struct sess *, int, 335 const struct flist *, size_t, int); 336 void download_free(struct download *); 337 struct upload *upload_alloc(struct sess *, const char *, int, int, size_t, 338 const struct flist *, size_t, mode_t); 339 void upload_free(struct upload *); 340 341 struct blkset *blk_recv(struct sess *, int, const char *); 342 void blk_recv_ack(struct sess *, 343 char [20], const struct blkset *, int32_t); 344 void blk_match(struct sess *, const struct blkset *, 345 const char *, struct blkstat *); 346 int blk_send(struct sess *, int, size_t, 347 const struct blkset *, const char *); 348 int blk_send_ack(struct sess *, int, struct blkset *); 349 350 uint32_t hash_fast(const void *, size_t); 351 void hash_slow(const void *, size_t, 352 unsigned char *, const struct sess *); 353 void hash_file(const void *, size_t, 354 unsigned char *, const struct sess *); 355 356 int mkpath(struct sess *, char *); 357 358 int mkstempat(int, char *); 359 char *mkstemplinkat(char*, int, char *); 360 char *mkstempfifoat(int, char *); 361 char *mkstempnodat(int, char *, mode_t, dev_t); 362 char *mkstempsock(const char *, char *); 363 int mktemplate(struct sess *, char **, const char *, int); 364 365 char *symlink_read(struct sess *, const char *); 366 char *symlinkat_read(struct sess *, int, const char *); 367 368 int sess_stats_send(struct sess *, int); 369 int sess_stats_recv(struct sess *, int); 370 371 int idents_add(struct sess *, int, struct ident **, size_t *, 372 int32_t); 373 void idents_assign_gid(struct sess *, 374 struct flist *, size_t, const struct ident *, size_t); 375 void idents_assign_uid(struct sess *, 376 struct flist *, size_t, const struct ident *, size_t); 377 void idents_free(struct ident *, size_t); 378 int idents_recv(struct sess *, int, struct ident **, size_t *); 379 void idents_remap(struct sess *, int, struct ident *, size_t); 380 int idents_send(struct sess *, int, const struct ident *, size_t); 381 382 #endif /*!EXTERN_H*/ 383