forked from kristapsdz/openrsync
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextern.h
1075 lines (957 loc) · 35.3 KB
/
extern.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* $OpenBSD: extern.h,v 1.45 2023/04/28 10:24:38 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <[email protected]>
* Copyright (c) 2024, Klara, Inc.
*
* 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
#include <dirent.h>
#include <getopt.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fts.h>
#include <stdio.h>
#include <stdbool.h>
#include "md4.h"
#ifndef __printflike
#define __printflike(fmtarg, firstvararg) \
__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
#endif
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
#if !HAVE_PLEDGE
# define pledge(x, y) (1)
#endif
#if !HAVE_UNVEIL
# define unveil(x, y) (1)
#endif
/*
* Mirror the reference rsync here; they don't really entertain path limitations
* lower than 4096.
*/
#if PATH_MAX <= 4096
#define BIGPATH_MAX (4096 + 1024)
#else
#define BIGPATH_MAX (PATH_MAX + 1024)
#endif
#define STRMODE_BUFSZ 12 /* Documented size of all strmode calls */
/*
* This is the rsync protocol version that we support.
*/
#define RSYNC_PROTOCOL (29)
#define RSYNC_PROTOCOL_MIN (27)
#define RSYNC_PROTOCOL_MAX (40)
#define protocol_newflist (sess->protocol >= 28)
#define protocol_itemize (sess->protocol >= 29)
#define protocol_newsort (sess->protocol >= 29)
#define protocol_dlrename (sess->protocol >= 29)
#define protocol_keepalive (sess->protocol >= 29)
#define protocol_fliststats (sess->protocol >= 29)
#define protocol_newbatch (sess->protocol >= 29)
#define protocol_delrules (sess->protocol >= 29)
/*
* itemize-changes flags.
*/
#define IFLAG_ATIME (1<<0)
#define IFLAG_CHECKSUM (1<<1)
#define IFLAG_SIZE (1<<2)
#define IFLAG_TIME (1<<3)
#define IFLAG_PERMS (1<<4)
#define IFLAG_OWNER (1<<5)
#define IFLAG_GROUP (1<<6)
#define IFLAG_ACL (1<<7)
#define IFLAG_XATTR (1<<8)
#define IFLAG_BASIS_FOLLOWS (1<<11)
#define IFLAG_HLINK_FOLLOWS (1<<12)
#define IFLAG_NEW (1<<13)
#define IFLAG_LOCAL_CHANGE (1<<14)
#define IFLAG_TRANSFER (1<<15)
/*
* Not for transmission.
*/
#define IFLAG_MISSING_DATA (1<<16) /* used by log_formatted() */
#define IFLAG_DELETED (1<<17) /* used by log_formatted() */
#define IFLAG_HAD_BASIS (1<<18) /* had basis, used by sender_get_iflags() */
#define SIGNIFICANT_IFLAGS \
(~(IFLAG_BASIS_FOLLOWS | ITEM_HLINK_FOLLOWS | IFLAG_LOCAL_CHANGE))
/*
* Defaults from the reference rsync; the max password size is specifically for
* password files, and not otherwise strictly enforced.
*/
#define RSYNCD_DEFAULT_USER "nobody"
#define RSYNCD_MAX_PASSWORDSZ 511
/* In future versions, this may be higher to support flexible digest choices. */
#define RSYNCD_CHALLENGE_RESPONSESZ (MD4_DIGEST_LENGTH * 16)
/* Maximum auth response size. */
#define RSYNCD_MAXAUTHSZ 2048
/* Some daemon values */
/* In future versions, this may be higher to support flexible digest choices. */
#define RSYNCD_CHALLENGE_RESPONSESZ (MD4_DIGEST_LENGTH * 16)
/*
* Maximum amount of file data sent over the wire at once.
*/
#define MAX_CHUNK (32 * 1024)
/* Save 2 bytes to fit a 14 bit count and compression flags */
#define MAX_COMP_CHUNK 16383
/*
* zlib needs a bit of extra space in the buffer.
*/
#define MAX_CHUNK_BUF ((MAX_CHUNK)*1001/1000+16)
/*
* This is the minimum size for a block of data not including those in
* the remainder block.
*/
#define BLOCK_SIZE_MIN (700)
/*
* Maximum number of base directories that can be used.
*/
#define MAX_BASEDIR 20
#define PHASE_XFER 0
#define PHASE_REDO 1
#define PHASE_DLUPDATES 2 /* Protocol 29 */
enum basemode {
BASE_MODE_COMPARE = 1, /* Just compare */
BASE_MODE_COPY, /* Copy into rootfd */
BASE_MODE_LINK, /* Hardlink into rootfd */
};
enum dirmode {
DIRMODE_OFF = 0, /* No --dirs */
DIRMODE_IMPLIED, /* Implied --dirs */
DIRMODE_REQUESTED, /* --dirs */
};
enum dryrun {
DRY_DISABLED = 0, /* Full run */
DRY_XFER, /* Xfer only */
DRY_FULL, /* Full dry-run*/
};
/*
* 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)
/*
* Rsync error codes.
*/
#define ERR_SYNTAX 1
#define ERR_PROTOCOL 2
#define ERR_FILEGEN 3
#define ERR_SOCK_IO 10
#define ERR_FILE_IO 11
#define ERR_WIREPROTO 12
#define ERR_IPC 14 /* catchall for any kind of syscall error */
#define ERR_TERMINATED 16
#define ERR_SIGUSR1 19
#define ERR_SIGNAL 20
#define ERR_WAITPID 21
#define ERR_NOMEM 22
#define ERR_PARTIAL 23
#define ERR_DEL_LIMIT 25
#define TOKEN_END 0x00 /* end of sequence */
#define TOKEN_LONG 0x20 /* Token is 32-bits */
#define TOKEN_LONG_RUN 0x21 /* Token is 32-bits and has 16 bit run count */
#define TOKEN_DEFLATED 0x40 /* Data is deflated */
#define TOKEN_RELATIVE 0x80 /* Token number is relative */
#define TOKEN_RUN_RELATIVE 0xc0 /* Run count is 16-bit */
#define TOKEN_MAX_DATA MAX_COMP_CHUNK /* reserve 2 bytes for flags */
#define TOKEN_MAX_BUF (TOKEN_MAX_DATA + 2)
/* Forward declarations */
struct flist;
struct sess;
/*
* Use this for --timeout.
* All poll events will use it and catch time-outs.
*/
extern int poll_timeout;
/*
* Use this for --contimeout.
*/
extern int poll_contimeout;
/*
* 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
};
#define IOTAG_OFFSET 7
enum compat_loglvl {
LOGNONE = 0,
/* Protocol == * */
LOGERROR_XFER,
LOGINFO,
/* Protocols >= 30 */
LOGERROR,
LOGWARNING,
};
struct iobuf {
uint8_t *buffer;
size_t offset;
size_t resid;
size_t size;
};
enum iotag {
IT_DATA = 0,
IT_ERROR_XFER = LOGERROR_XFER,
IT_INFO = LOGINFO,
IT_ERROR = LOGERROR,
IT_WARNING = LOGWARNING,
IT_SUCCESS = 100,
IT_DELETED,
IT_NO_SEND,
};
struct vstring {
char *vstring_buffer;
size_t vstring_offset;
size_t vstring_size;
};
typedef int (io_tag_handler_fn)(void *, const void *, size_t sz);
enum zlib_state {
COMPRESS_INIT = 0,
COMPRESS_READY,
COMPRESS_SEQUENCE,
COMPRESS_RUN,
COMPRESS_DONE,
};
/*
* Delete modes:
* - unspecified: transforms into one of the below after option processing,
* i.e., --del / --delete.
* - before: delete files up-front
* - during: delete files during transfer
* - delay: gather deletions and delete after after
* - after: delete after transfer
* - excluded: delete excluded files, too
*/
enum delmode {
DMODE_NONE,
DMODE_UNSPECIFIED,
DMODE_BEFORE,
DMODE_DURING,
DMODE_DELAY,
DMODE_AFTER,
};
/* --numeric-ids mode */
enum nidsmode {
NIDS_OFF, /* No numeric IDs */
NIDS_STEALTH, /* Numeric IDs, client side is unaware */
NIDS_FULL, /* Numeric IDs, both sides know */
};
/*
* Super modes; we can either force an attempt of super-user activities, write
* them into xattrs (fake), or we can disable super-user activities altogether.
*/
enum smode {
SMODE_UNSET,
SMODE_ON, /* --super */
SMODE_OFF, /* --no-super */
};
/*
* File arguments given on the command line.
* See struct opts.
*/
struct fargs {
char *user; /* username or NULL if unspecified or local */
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 */
const 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;
int64_t device; /* device number, for hardlink detection */
int64_t inode; /* inode number, for hardlink detection */
uint64_t nlink; /* number of links, for hardlink detection */
#define FLSTAT_TOP_DIR 0x01 /* a top-level directory */
/* Platform use */
#define FLSTAT_PLATFORM_BIT1 0x10000000
#define FLSTAT_PLATFORM_BIT2 0x20000000
#define FLSTAT_PLATFORM_BIT3 0x40000000
#define FLSTAT_PLATFORM_BIT4 0x80000000
#define FLSTAT_PLATFORM_MASK 0xf0000000
};
#ifdef __APPLE__
#define st_atim st_atimespec
#define st_mtim st_mtimespec
#endif /* __APPLE__ */
/*
* Subset of stat(2) information from the original destination
* file that we need to apply to backup files.
*/
struct fldstat {
mode_t mode; /* mode */
struct timespec atime; /* access */
struct timespec mtime; /* modification */
uid_t uid; /* user */
gid_t gid; /* group */
};
enum name_basis {
BASIS_DIR_LOW = 0,
BASIS_DIR_HIGH = 0x7F,
BASIS_NORMAL,
BASIS_PARTIAL_DIR,
BASIS_BACKUP,
BASIS_FUZZY,
};
/*
* A list of files with their statistics.
* Note that the md[] field is only used by the --checksum option, and
* hence could be eliminated (when not needed) by making struct flist
* a variably-sized structure and handling its variability in both the
* sender and receiver.
*/
typedef int platform_open(const struct sess *, const struct flist *, int);
typedef int platform_flist_sent(struct sess *, int, const struct flist *);
struct flist {
char *path; /* path relative to root */
int pdfd; /* dirfd for partial */
const char *wpath; /* "working" path for receiver */
struct flstat st; /* file information */
char *link; /* symlink target, hlink name, or NULL */
unsigned char md[MD4_DIGEST_LENGTH]; /* MD4 hash for --checksum */
int flstate; /* flagged for redo, or complete? */
int32_t iflags; /* Itemize flags */
enum name_basis basis; /* name basis */
platform_open *open; /* special open() for this entry */
platform_flist_sent *sent; /* notify the platform an entry was sent */
int sendidx; /* Sender index */
struct fldstat dstat; /* original destination file information */
};
#define FLIST_COMPLETE 0x01 /* Finished */
#define FLIST_REDO 0x02 /* Finished, but go again */
#define FLIST_SUCCESS 0x04 /* Finished and in place */
#define FLIST_FAILED 0x08 /* Failed */
#define FLIST_SUCCESS_ACKED 0x10 /* Sent success message */
#define FLIST_DONE_MASK (FLIST_SUCCESS | FLIST_REDO | FLIST_FAILED)
/*
* Holds many struct flist and takes care of memory management.
*/
struct fl {
struct flist *flp;
size_t sz; /* Actual entries */
size_t max; /* Allocated size */
};
void fl_init(struct fl *);
long fl_new_index(struct fl *); /* Returns index of new element */
struct flist *fl_new(struct fl *); /* Returns pointer to new element */
struct flist *fl_atindex(struct fl *, size_t idx);
long fl_curridx(struct fl *); /* Current size */
void fl_print(const char *id, struct fl *fl);
void fl_pop(struct fl *);
/*
* Options passed into the command line.
* See struct fargs.
*/
struct opts {
int sender; /* --sender */
int server; /* --server */
int daemon; /* --daemon (fake) */
int protocol; /* --protocol */
int append; /* --append */
int checksum; /* -c --checksum */
int checksum_seed; /* --checksum-seed */
const char *chmod; /* --chmod */
int recursive; /* -r */
enum dryrun dry_run; /* -n */
int inplace; /* --inplace */
int partial; /* --partial */
char *partial_dir; /* --partial-dir */
int preserve_times; /* -t */
int preserve_perms; /* -p */
int copy_links; /* -L */
int copy_unsafe_links; /* --copy-unsafe-links */
int safe_links; /* --safe-links */
int copy_dirlinks; /* -k */
int keep_dirlinks; /* -K */
int preserve_links; /* -l */
int preserve_gids; /* -g */
int preserve_uids; /* -u */
enum delmode del; /* --delete */
int del_excl; /* --delete-excluded */
int devices; /* --devices */
int specials; /* --specials */
int no_cache; /* --no-cache */
int no_motd; /* --no-motd */
enum nidsmode numeric_ids; /* --numeric-ids */
int one_file_system; /* -x */
int omit_dir_times; /* -O */
int ignore_times; /* -I --ignore-times */
int progress; /* --progress */
int alt_base_mode;
int sparse; /* -S --sparse */
int update; /* -u --update */
int backup; /* --backup */
char *backup_dir; /* --backup-dir */
char *backup_suffix; /* --suffix */
int backup_suffix_given; /* --suffix given flag */
int human_readable; /* --human-readable */
int ign_exist; /* --ignore-existing */
int ign_non_exist; /* --ignore-nonexisting */
int relative; /* --relative */
enum dirmode dirs; /* -d --dirs */
int noimpdirs; /* --no-implied-dirs */
int dlupdates; /* --delay-updates */
int hard_links; /* -H --hard-links */
int remove_source; /* --remove-source-files */
int supermode; /* --{no-,}super */
int bit8; /* -8 --8-bit-output */
int stats; /* --stats */
off_t max_size; /* --max-size */
off_t min_size; /* --min-size */
char *rsync_path; /* --rsync-path */
char *ssh_prog; /* --rsh or -e */
const char *port; /* --port */
const char *address; /* --address */
char *basedir[MAX_BASEDIR];
char *filesfrom; /* --files-from */
int from0; /* -0 */
const char *outformat; /* --out-format */
const char *sockopts; /* --sockopts */
off_t bwlimit; /* --bwlimit */
int size_only; /* --size-only */
long block_size; /* --block-size */
char *filesfrom_host; /* --files-from */
char *filesfrom_path; /* --files-from */
int whole_file; /* --whole-file */
const char *read_batch; /* --read-batch */
const char *write_batch; /* --write-batch */
const char *password_file; /* --password-file */
char *temp_dir; /* --temp-dir */
int compress; /* -z --compress */
int compression_level; /* --compress-level */
#if 0
char *syncfile; /* --sync-file */
#endif
int ipf; /* -4 / -6 */
int force_delete; /* --force */
int ignore_errors; /* --ignore-errors */
int preserve_executability; /* --executability */
int modwin; /* --modify-windows=sec */
int fuzzy_basis; /* -y */
int quiet; /* -q, --quiet */
long max_delete; /* --max-delete */
#ifdef __APPLE__
int extended_attributes; /* --extended-attributes */
#endif
int ignore_nonreadable; /* daemon: ignore nonreadable */
int list_only; /* --list-only */
int prune_empty_dirs; /* --prune-empty-dirs */
};
enum rule_type {
RULE_NONE,
RULE_EXCLUDE,
RULE_INCLUDE,
RULE_CLEAR,
RULE_MERGE,
RULE_DIR_MERGE,
RULE_SHOW,
RULE_HIDE,
RULE_PROTECT,
RULE_RISK,
};
/*
* 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,
BLKSTAT_FLUSH,
};
/*
* 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 */
struct blktab *blktab; /* hashtable of blocks */
uint32_t s1; /* partial sum for computing fast hash */
uint32_t s2; /* partial sum for computing fast hash */
};
/*
* 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 */
};
enum send_dl_state {
SDL_META = 0,
SDL_IFLAGS,
SDL_BLOCKS,
SDL_DONE,
SDL_SKIP,
};
typedef const char *(role_fetch_outfmt_fn)(const struct sess *, void *, char);
/*
* Context for the role (sender/receiver). The role may embed this into their
* own context struct.
*/
struct role {
int append; /* Append mode active */
/* Propagated between successive roles */
role_fetch_outfmt_fn *role_fetch_outfmt; /* --out-format field */
void *role_fetch_outfmt_cookie;
/*
* We basically track two different forms of phase: the metadata phase,
* and the transfer phase. The metadata phase may be advanced from the
* transfer phase, as we'll immediately move on to checking for or
* processing redo entries when the first phase's file requests are
* done.
*
* Each role has its own way of tracking these, so we just have them
* drop a pointer here to avoid having to keep things in sync. `append`
* above will be reset as the transfer phase progresses, so parts
* dealing with block metadata should check `*phase` *and* `append` to
* determine if they need to send/receive block checksums, and anything
* part of the data transfer process should just be checking `append`.
*/
const int *phase; /* Metadata phase */
};
/*
* The filter should return 0 on success, or -1 on failure. If *outlink is
* populated on a successful return, then it should be used in place of the
* symlink we were given. If it is NULL on a successful return, then the filter
* is declining to act and the caller should proceed with the original link.
*/
typedef int (symlink_filter)(const char *, char **, enum fmode);
/*
* Values required during a communication session.
*/
struct sess {
const struct opts *opts; /* system options */
enum fmode mode; /* sender or receiver */
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_read_lf; /* reads at time of last file */
uint64_t total_size; /* total file size */
uint64_t total_write; /* non-logging wire/writes */
uint64_t total_write_lf; /* writes at last file*/
uint64_t total_files; /* file count */
uint64_t total_files_xfer; /* files transferred */
uint64_t total_xfer_size; /* total file size transferred */
uint64_t total_unmatched; /* data we transferred */
uint64_t total_matched; /* data we recreated */
uint64_t flist_size; /* items on the flist */
uint64_t flist_build; /* time to build flist */
uint64_t flist_xfer; /* time to transfer flist */
uint64_t xfer_time; /* time to transfer data */
int mplex_reads; /* multiplexing reads? */
size_t mplex_read_remain; /* remaining bytes */
int mplex_writes; /* multiplexing writes? */
double last_time; /* last time printed --progress */
uint64_t last_bytes; /* last bytes printed --progress */
int itemize; /* --itemize or %i in --output-format */
int lateprint; /* Does output format contain a flag requiring late print? */
char **filesfrom; /* Contents of files-from */
size_t filesfrom_n; /* Number of lines for filesfrom */
int filesfrom_fd; /* --files-from */
int wbatch_fd; /* --write-batch */
struct dlrename *dlrename; /* Deferred renames for --delay-update */
struct role *role; /* Role context */
mode_t chmod_dir_AND;
mode_t chmod_dir_OR;
mode_t chmod_dir_X;
mode_t chmod_file_AND;
mode_t chmod_file_OR;
mode_t chmod_file_X;
double start_time; /* Time of first transfer */
symlink_filter *symlink_filter;
uint64_t total_errors; /* Total non-fatal errors */
long total_deleted; /* Total files deleted */
bool err_del_limit; /* --max-delete limit exceeded */
int protocol; /* negotiated protocol version */
char *token_buf; /* used for protocol token processing */
size_t token_bufsz; /* used for protocol token processing */
char *token_cbuf; /* used for protocol token processing */
size_t token_cbufsz; /* used for protocol token processing */
char *token_dbuf; /* used for protocol token processing */
size_t token_dbufsz; /* used for protocol token processing */
DIR *fuzzy_dirp; /* cached fuzzy dir stream pointer */
int fuzzy_rootfd; /* cached fuzzy root dir filedes */
char *fuzzy_root; /* cached path from fuzzy_rootfd */
};
/*
* 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 */
};
typedef struct arglist arglist;
struct arglist {
char **list;
u_int num;
u_int nalloc;
};
void addargs(arglist *, const char *, ...)
__attribute__((format(printf, 2, 3)));
const char *getarg(arglist *, size_t);
void freeargs(arglist *);
struct cleanup_ctx;
struct download;
struct upload;
struct hardlinks;
const struct flist *find_hl(const struct flist *this,
const struct hardlinks *hl);
extern const char rsync_shopts[];
extern const struct option rsync_lopts[];
extern int verbose;
#define TMPDIR_FD (sess->opts->temp_dir && p->tempfd != -1 ? p->tempfd : p->rootfd)
#define IS_TMPDIR (sess->opts->temp_dir != NULL)
#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
#define LOG0(_fmt, ...) \
rsync_log( -1, (_fmt), ##__VA_ARGS__)
#define LOG1(_fmt, ...) \
rsync_log( 0, (_fmt), ##__VA_ARGS__)
#define LOG2(_fmt, ...) \
rsync_log( 1, (_fmt), ##__VA_ARGS__)
#define LOG3(_fmt, ...) \
rsync_log( 2, (_fmt), ##__VA_ARGS__)
#define LOG4(_fmt, ...) \
rsync_log( 3, (_fmt), ##__VA_ARGS__)
#define ERRX1(_fmt, ...) \
rsync_errx1( (_fmt), ##__VA_ARGS__)
#define WARNX(_fmt, ...) \
rsync_warnx( (_fmt), ##__VA_ARGS__)
#define WARNX1(_fmt, ...) \
rsync_warnx1( (_fmt), ##__VA_ARGS__)
#define WARN(_fmt, ...) \
rsync_warn(0, (_fmt), ##__VA_ARGS__)
#define WARN1(_fmt, ...) \
rsync_warn(1, (_fmt), ##__VA_ARGS__)
#define WARN2(_fmt, ...) \
rsync_warn(2, (_fmt), ##__VA_ARGS__)
#if defined(__sun) && defined(ERR)
# undef ERR
#endif
#define ERR(_fmt, ...) \
rsync_err( (_fmt), ##__VA_ARGS__)
#define ERRX(_fmt, ...) \
rsync_errx( (_fmt), ##__VA_ARGS__)
int rsync_set_logfacility(const char *);
void rsync_set_logfile(FILE *);
void rsync_log(int, const char *, ...)
__attribute__((format(printf, 2, 3)));
void rsync_warnx1(const char *, ...)
__attribute__((format(printf, 1, 2)));
void rsync_warn(int, const char *, ...)
__attribute__((format(printf, 2, 3)));
void rsync_warnx(const char *, ...)
__attribute__((format(printf, 1, 2)));
void rsync_err(const char *, ...)
__attribute__((format(printf, 1, 2)));
void rsync_errx(const char *, ...)
__attribute__((format(printf, 1, 2)));
void rsync_errx1(const char *, ...)
__attribute__((format(printf, 1, 2)));
/* Opaque */
struct daemon_cfg *cfg_parse(const struct sess *, const char *,
int module);
typedef int cfg_module_iter(struct daemon_cfg *, const char *, void *);
void cfg_free(struct daemon_cfg *);
int cfg_foreach_module(struct daemon_cfg *, cfg_module_iter *, void *);
int cfg_is_valid_module(struct daemon_cfg *, const char *);
int cfg_param_bool(struct daemon_cfg *, const char *, const char *,
int *);
int cfg_param_int(struct daemon_cfg *, const char *, const char *,
int *);
int cfg_param_long(struct daemon_cfg *, const char *, const char *,
long *);
int cfg_param_str(struct daemon_cfg *, const char *, const char *,
const char **);
int cfg_has_param(struct daemon_cfg *, const char *, const char *);
int flist_dir_cmp(const void *, const void *);
int flist_fts_check(struct sess *, FTSENT *, enum fmode);
int flist_del(struct sess *, int, const struct flist *, size_t);
int flist_gen(struct sess *, size_t, char **, struct fl *);
void flist_free(struct flist *, size_t);
int flist_recv(struct sess *, int, 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);
int flist_add_del(struct sess *, const char *, size_t, struct flist **,
size_t *, size_t *, const struct stat *st);
const char *alt_base_mode(int);
char **fargs_cmdline(struct sess *, const struct fargs *, size_t *);
int batch_open(struct sess *);
void batch_close(struct sess *, const struct fargs *, int);
int check_file_mode(const char *, int);
void cleanup_hold(struct cleanup_ctx *);
void cleanup_release(struct cleanup_ctx *);
void cleanup_init(struct cleanup_ctx *);
void cleanup_run(int code);
void cleanup_set_args(struct cleanup_ctx *, struct fargs *);
void cleanup_set_child(struct cleanup_ctx *, pid_t);
void cleanup_set_session(struct cleanup_ctx *, struct sess *);
void cleanup_set_download(struct cleanup_ctx *, struct download *);
int io_register_handler(enum iotag, io_tag_handler_fn *, void *);
int io_read_line(struct sess *, int, char *, size_t *);
int io_read_buf(struct sess *, int, void *, size_t);
int io_read_byte(struct sess *, int, uint8_t *);
int io_read_check(const struct sess *, int);
int io_read_close(struct sess *, int);
int io_read_flush(struct sess *, int);
int io_read_ushort(struct sess *, int, uint32_t *);
int io_read_short(struct sess *, int, int32_t *);
int io_read_int(struct sess *, int, int32_t *);
int io_read_uint(struct sess *, int, uint32_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_read_vstring(struct sess *, int, char *, size_t);
int io_write_buf_tagged(struct sess *, int, const void *, size_t,
enum iotag);
int io_write_buf(struct sess *, int, const void *, size_t);
int io_write_byte(struct sess *, int, uint8_t);
int io_write_int_tagged(struct sess *, int, int32_t, enum iotag);
int io_write_int(struct sess *, int, int32_t);
int io_write_uint(struct sess *, int, uint32_t);
int io_write_short(struct sess *, int, int32_t);
int io_write_ushort(struct sess *, int, uint32_t);
int io_write_line(struct sess *, int, const char *);
int io_write_long(struct sess *, int, int64_t);
int io_write_ulong(struct sess *, int, uint64_t);
int io_write_vstring(struct sess *, int, char *, size_t);
int io_data_written(struct sess *, int, const void *, size_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_short(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_lowbuffer_byte(struct sess *sess, void *buf, size_t *bufpos,
size_t buflen, int8_t val);
void io_lowbuffer_vstring(struct sess *sess, void *buf, size_t *bufpos,
size_t buflen, char *str, size_t sz);
void io_buffer_buf(void *, size_t *, size_t, const void *, size_t);
void io_buffer_byte(void *, size_t *, size_t, int8_t);
void io_buffer_int(void *, size_t *, size_t, int32_t);
void io_buffer_short(void *, size_t *, size_t, int32_t);
void io_buffer_vstring(void *, size_t *, size_t, char *, size_t);
void io_unbuffer_int(const void *, size_t *, size_t, int32_t *);
int io_unbuffer_size(const void *, size_t *, size_t, size_t *);
void io_unbuffer_buf(const void *, size_t *, size_t, void *, size_t);
int iobuf_alloc(struct sess *, struct iobuf *, size_t);
size_t iobuf_get_readsz(const struct iobuf *);
int iobuf_fill(struct sess *, struct iobuf *, int);
void iobuf_read_buf(struct iobuf *, void *, size_t);
void iobuf_read_byte(struct iobuf *, uint8_t *);
int32_t iobuf_peek_int(struct iobuf *);
void iobuf_read_int(struct iobuf *, int32_t *);
void iobuf_read_ushort(struct iobuf *, uint32_t *);
void iobuf_read_short(struct iobuf *, int32_t *);
int iobuf_read_size(struct iobuf *, size_t *);
int iobuf_read_vstring(struct iobuf *, struct vstring *);
void iobuf_free(struct iobuf *);
/* accept(2) callback */
struct sockaddr_storage;
typedef int (rsync_client_handler)(struct sess *, int,
struct sockaddr_storage *, socklen_t);
/*
* The option filter should return 1 to allow an option to be processed, 0 to
* stop processing, or -1 to simply skip it.
*/
struct option;
typedef int (rsync_option_filter)(struct sess *, int, const struct option *);
struct opts *rsync_getopt(int, char *[], rsync_option_filter *,
struct sess *);
int send_iflags(struct sess *, void **, size_t *, size_t *,
size_t *, struct flist *, int32_t);
int rsync_receiver(struct sess *, struct cleanup_ctx *, int, int,
const char *);
int rsync_sender(struct sess *, int, int, size_t, char **);
int rsync_batch(struct cleanup_ctx *, struct opts *, const struct fargs *);
int rsync_client(struct cleanup_ctx *, const struct opts *, int,
const struct fargs *);
int rsync_daemon(int, char *[], struct opts *);
int rsync_connect(const struct opts *, int *, const struct fargs *);
int rsync_listen(struct sess *, rsync_client_handler *);
int rsync_setsockopts(int, const char *);
int rsync_socket(struct cleanup_ctx *, const struct opts *, int,
const struct fargs *);
int rsync_is_socket(int);
int rsync_password_hash(const char *, const char *, char *, size_t);
int rsync_server(struct cleanup_ctx *, const struct opts *, size_t,
char *[]);
int rsync_downloader(struct download *, struct sess *, int *, size_t,
const struct hardlinks *);
int rsync_set_metadata(struct sess *, int, int, const struct flist *,
const char *);
int rsync_set_metadata_at(struct sess *, int, int, struct flist *,
const char *);
int rsync_uploader(struct upload *, int *, struct sess *, int *,
const struct hardlinks *);
int rsync_uploader_tail(struct upload *, struct sess *);
struct download *download_alloc(struct sess *, int, struct flist *, size_t,
int, int);
size_t download_needs_redo(struct download *);
const char *download_partial_path(struct sess *, const struct flist *,
char *, size_t);
const char *download_partial_filepath(const struct flist *);
void download_interrupted(struct sess *, struct download *);
void download_free(struct sess *, struct download *);
struct upload *upload_alloc(const char *, int, int, int, size_t,
struct flist *, size_t, mode_t);
void upload_next_phase(struct upload *, struct sess *, int);
void upload_ack_complete(struct upload *, struct sess *, int);
void upload_free(struct upload *);
int upload_del(struct upload *, struct sess *);
struct blktab *blkhash_alloc(void);
int blkhash_set(struct blktab *, const struct blkset *);
void blkhash_free(struct blktab *);
struct blkset *blk_recv(struct sess *, int, struct iobuf *, const char *,
struct blkset *, size_t *, enum send_dl_state *);
void blk_recv_ack(char [16], 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 hash_file_by_path(int, const char *, size_t, unsigned char *);
/*
* Use of move_file should ideally be limited to copy.c and platform.c -- in
* recent versions of openrsync, there's a platform_move_file that may implement
* it slightly differently for a given platform, or it may call back into the
* generic move_file() that should handle things well enough for the majority of
* platforms.
*/
int move_file(int, const char *, int, const char *, int);
void copy_file(int, const char *, const struct flist *);
int backup_file(int, const char *, int, const char *, int, const struct fldstat *);
int backup_to_dir(struct sess *, int, const struct flist *,
const char *, mode_t);
int is_unsafe_link(const char *, const char *, const char *);
char *make_safe_link(const char *);
int mkpath(char *, mode_t);
int mkpathat(int fd, char *, mode_t);
int mksock(const char *, char *);
int mkstempat(int, char *);
char *mkstemplinkat(char*, int, char *);