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
|
#compdef rsync
_rsync_user_or_host() {
local suf=$1 rsync
shift
if compset -P 1 '*@'; then
local user=${PREFIX%%@*}
_wanted -C user-at hosts expl "host for $user" \
_combination -s '[:@]' "${tag}" users-hosts users="$user" hosts -S "$suf" "$@" -
elif compset -S '@*'; then
_wanted users expl "user" \
_combination -s '[:@]' "${tag}" users-hosts users -q "$@" -
else
[[ $words[CURRENT] = rsync://* ]] || rsync='rsync:rsync: compadd -S "" rsync://'
_alternative \
'users:user:_users -S @' \
"hosts:host:_hosts -S '$suf'" \
$rsync
fi
}
_rsync_remote_files() {
local expl remfiles remdispf remdispd remmodules suf ret=1 tag=accounts
if compset -P '*::*/' || compset -P 'rsync://*/*/'; then
remfiles=(${${(f)"$(_call_program files rsync ${words[CURRENT]%/*}/ 2>/dev/null)"}:#([ ]|MOTD:)*})
remdispf=(${remfiles:#d*})
remdispd=(${(M)remfiles:#d*})
# $remdisp[fd] format:
# attrs size date time name
_wanted files expl 'remote file or directory' \
compadd -d remdispf ${${${${remdispf##[^ ]## ##}##[^ ]## ##}##[^ ]## ##}##[^ ]## ##}
_wanted files expl 'remote file or directory' \
compadd -S/ -d remdispd ${${${${remdispd##[^ ]## ##}##[^ ]## ##}##[^ ]## ##}##[^ ]## ##}
elif compset -P 1 '*::' || compset -P 1 'rsync://*/'; then
local pat=${words[CURRENT]}
if [[ $pat = *::* ]]; then
pat=${pat%::*}::
else
pat=${pat%/*}/
fi
remfiles=(${${(f)"$(_call_program files rsync $pat 2>/dev/null)"}:#([ ]|MOTD:)*})
remmodules=(${remfiles/[ ]##/:})
_describe "remote modules" remmodules -S/
elif compset -P 'rsync://'; then
_rsync_user_or_host / "$@"
elif compset -P 1 '*:'; then
_remote_files -- ssh
else
_rsync_user_or_host : "$@"
fi
}
_rsync_files() {
_alternative "files:file:_files" "remote-files:remote file:_rsync_remote_files"
}
_rsync() {
_arguments -s \
'*'{-v,--verbose}'[increase verbosity]' \
{--no-v,--no-verbose}'[turn off --verbose]' \
'--bwlimit=[limit I/O bandwidth]:limit (KiB per second)' \
'--outbuf=[set output buffering]:buffering:(none line block)' \
'--port=[specify alternate port number]:port:(873)' \
'--address=[bind to the specified address]:bind address:_bind_addresses' \
'(-T --temp-dir)'{-T,--temp-dir=}'[create temporary files in specified directory]:directory:_directories' \
'--sockopts=[specify custom TCP options]' \
'(-4 -6 --ipv4 --ipv6)'{-4,--ipv4}'[prefer IPv4]' \
'(-4 -6 --ipv4 --ipv6)'{-6,--ipv6}'[prefer IPv6]' \
- daemon \
'(-)'{-h,--help}'[display help information]' \
'--config=[specify alternate rsyncd.conf file]:file:_files' \
'--daemon[run as an rsync daemon]' \
'--detach[detach from the parent]' \
'--no-detach[do not detach from the parent]' \
- client \
'(-)--help[display help information]' \
'*: :_rsync_files' \
'(-q --quiet)'{-q,--quiet}'[suppress non-error messages]' \
'--no-motd[suppress the daemon message-of-the-day output]' \
'(-c --checksum)'{-c,--checksum}'[skip based on checksums, not mod-time & size]' \
'(-a --archive)'{-a,--archive}'[archive mode; same as -rlptgoD (no -H)]' \
'(-r --recursive)'{-r,--recursive}'[recurse into directories]' \
{--no-r,--no-recursive}'[turn off --recursive]' \
{--no-inc-recursive,--no-i-r}'[disable incremental recursive mode]' \
'(-R --relative)'{-R,--relative}'[use relative path names]' \
{--no-R,--no-relative}'[turn off --relative]' \
{--no-implied-dirs,--no-i-d}'[do not send implied dirs with --relative]' \
'(-b --backup)'{-b,--backup}'[make backups into hierarchy at indicated directory]' \
'--backup-dir=[make backups into specified directory]:backup directory:_directories' \
'--suffix=[set backup suffix]:suffix:(\~)' \
'(-u --update)'{-u,--update}'[skip files that are newer on the receiving side]' \
'--inplace[update destination files in-place]' \
'(--append-verify)--append[append data onto shorter files]' \
'(--append)--append-verify[append data onto shorter files, verifying old data]' \
'(-A --acls)'{-A,--acls}'[preserve access-control lists]' \
'(-X --xattrs)'{-X,--xattrs}'[preserve extended attributes]' \
'--fake-super[use xattrs to save all file attributes]' \
'(-d --dirs)'{-d,--dirs}'[transfer directories without recursing]' \
{--no-d,--no-dirs}'[turn off --dirs]' \
'(-l --links)'{-l,--links}'[copy symlinks as symlinks]' \
{--no-l,--no-links}'[turn off --links]' \
'(-L --copy-links)'{-L,--copy-links}'[transform symlinks into referent file/dir]' \
'(-k --copy-dirlinks)'{-k,--copy-dirlinks}'[transform a symlink to a dir into referent dir]' \
'--copy-unsafe-links[only "unsafe" symlinks are transformed]' \
'--safe-links[ignore symlinks that point outside the source tree]' \
'(-H --hard-links)'{-H,--hard-links}'[preserve hard links]' \
{--no-H,--no-hard-links}'[turn off --hard-links]' \
'(-K --keep-dirlinks)'{-K,--keep-dirlinks}'[treat symlinked dir on receiver as dir]' \
'(-p --perms -E --executability)'{-p,--perms}'[preserve permissions]' \
{--no-p,--no-perms}'[turn off --perms]' \
'(-E --executability)'{-E,--executability}'[preserve executability]' \
'(-o --owner)'{-o,--owner}'[preserve owner]' \
{--no-o,--no-owner}'[turn off --owner]' \
'(-g --group)'{-g,--group}'[preserve group]' \
{--no-g,--no-group}'[turn off --group]' \
'(--devices --specials)-D[same as --devices --specials]' \
'(-D)--devices[preserve devices]' \
'--no-devices[turn off --devices]' \
'(-D)--specials[preserve special files]' \
'--no-specials[turn off --specials]' \
'--no-D[turn off --devices and --specials]' \
'(-t --times)'{-t,--times}'[preserve times]' \
{--no-t,--no-times}'[turn off --times]' \
'(-O --omit-dir-times)'{-O,--omit-dir-times}'[omit directories when preserving times]' \
'(-J --omit-link-times)'{-J,--omit-link-times}'[omit symlinks when preserving times]' \
'--chmod[change destination permissions]:mods' \
'(-S --sparse)'{-S,--sparse}'[handle sparse files efficiently]' \
'(-n --dry-run)'{-n,--dry-run}'[show what would have been transferred]' \
'(-W --whole-file)'{-W,--whole-file}'[copy files whole (without delta-transfer algorithm)]' \
{--no-W,--no-whole-file}'[turn off --whole-file]' \
'(-x --one-file-system)'{-x,--one-file-system}'[do not cross filesystem boundaries]' \
'(-B --block-size)'{-B,--block-size=}'[force a fixed checksum block-size]:block size' \
'(-e --rsh)'{-e+,--rsh=}'[specify the remote shell to use]:remote-shell command:(rsh ssh)' \
'--rsync-path=[specify path to rsync on the remote machine]:remote command' \
'--ignore-existing[ignore files that already exist on receiving side]' \
'(--existing --ignore-non-existing)'{--existing,--ignore-non-existing}'[ignore files that do not exist on receiving side]' \
'--remove-source-files[synchronized files are removed from sending side]' \
'(--delete-before --delete-during --delete-after --delete-delay)--del[an alias for --delete-during]' \
'--delete[delete files that do not exist on the sending side]' \
'(--del --delete-during --delete-after --delete-delay)--delete-before[receiver deletes before transfer]' \
'(--del --delete-before --delete-after --delete-delay)--delete-during[receiver deletes during transfer]' \
'(--del --delete-before --delete-during --delete-delay)--delete-after[receiver deletes after transfer]' \
'(--del --delete-before --delete-during --delete-after)--delete-delay[receiver deletes after transfer]' \
'--delete-excluded[also delete excluded files on the receiving side]' \
'--ignore-errors[delete even if there are I/O errors]' \
'--force[force deletion of directories even if not empty]' \
'--max-delete=[do not delete more than NUM files]:number' \
'--max-size=[do not transfer any file larger than specified size]:number' \
'--min-size=[do not transfer any file smaller than specified size]:number' \
'(-P)--partial[keep partially transferred files]' \
'--no-partial[turn off --partial]' \
'--partial-dir=[put a partially transferred file into specified directory]:directory:_directories' \
'--super[receiver attempts super-user activities]' \
'--no-super[receiver performs normal-user activities]' \
'--delay-updates[put all updated files into place at end of transfer]' \
'(-m --prune-empty-dirs)'{-m,--prune-empty-dirs}'[prune empty directory chains from file-list]' \
'--numeric-ids[do not map uid/gid values by user/group name]' \
'--timeout=[set I/O timeout in seconds for lulls in a transfer]:seconds' \
'--contimeout=[set connect timeout in seconds for daemon connections]:seconds' \
'(-I --ignore-times)'{-I,--ignore-times}'[do not skip files that match in size and mod-time]' \
'--size-only[skip files that match in size]' \
'--modify-window=[compare mod-times with reduced accuracy]:seconds' \
'(-y --fuzzy)'{-y,--fuzzy}'[find similar file for basis if no destination file]' \
'(--copy-dest --link-dest)*--compare-dest=[also compare destination files relative to specified directory]:directory:_directories' \
'(--compare-dest --link-dest)*--copy-dest=[like --compare-dest, but also includes copies of unchanged files]:directory:_directories' \
'(--compare-dest --copy-dest)*--link-dest=[hardlink to files in specified directory hierarchy when unchanged]:directory:_directories' \
'(-z --compress)'{-z,--compress}'[compress file data during the transfer]' \
'--compress-level=[explicitly set compression level]:number' \
'--skip-compress=[skip compressing files with a listed suffix]:suffixes' \
'(-C --cvs-exclude)'{-C,--cvs-exclude}'[auto-ignore files the same way CVS does]' \
'*'{-f=,--filter=}'[add a file-filtering rule]:rule' \
'*-F[same as --filter="dir-merge /.rsync-filter", repeated: --filter="- .rsync-filter"]' \
'--exclude-from=[read exclude patterns from specified file]:file:_files' \
'*--exclude=[exclude files matching pattern]:pattern' \
'--include-from=[read include patterns from specified file]:file:_files' \
'*--include=[do not exclude files matching pattern]:pattern' \
'--files-from=[read list of source-file names from specified file]:file:_files' \
'(-0 --from0)'{-0,--from0}'[all *-from file lists are delimited by nulls]' \
'(-s --protect-args)'{-s,--protect-args}'[no space-splitting; only wildcard special-chars]' \
'--version[print version number]' \
'*'{-h,--human-readable}'[output numbers in a human-readable format]' \
'--blocking-io[use blocking I/O for the remote shell]' \
'--no-blocking-io[turn off --blocking-io]' \
'--stats[give some file-transfer stats]' \
'(-8 --8-bit-output)'{-8,--8-bit-output}'[leave high-bit chars unescaped in output]' \
'(-P)--progress[show progress during transfer]' \
'--no-progress[turn off --progress]' \
'(--partial --progress)-P[same as --partial --progress]' \
'(-i --itemize-changes)'{-i,--itemize-changes}'[output a change-summary for all updates]' \
'--log-format=[deprecated version of --out-format]' \
'--out-format=[output updates using specified format]:format' \
'--log-file-format=[log updates using specified format]:format' \
'--log-file=[log what rsync is doing to the specified file]:file:_files' \
'--password-file=[read daemon-access password from file]:file:_files' \
'--list-only[list the files instead of copying them]' \
'(--only-write-batch)--write-batch=[write a batched update to the specified file]:file:_files' \
'(--write-batch)--only-write-batch=[like --write-batch but w/o updating destination]:file:_files' \
'--protocol=[force an older protocol version to be used]:number' \
'--info=[fine-grained informational verbosity]:comma-separated list' \
'--debug=[fine-grained debug verbosity]:comma-separated list' \
'--msgs2stderr[special output handling for debugging]' \
'--munge-links[munge symlinks to make them safer, but unusable]' \
'--ignore-missing-args[ignore missing source args without error]' \
'--delete-missing-args[delete missing source args from destination]' \
'(--usermap --chown)--usermap=[custom username mapping]:comma-separated mappings' \
'(--groupmap --chown)--groupmap=[custom groupname mapping]:comma-separated mappings' \
'(--usermap --groupmap --chown)--chown=[simple username/groupname mapping]:user and/or group' \
'*'{-M=,--remote-option=}'[send option to the remote side only]:option string' \
'--preallocate[preallocate the full length of new files]' \
'--iconv=[request charset conversion of filenames]:number' \
'--checksum-seed=:number' \
'--read-batch=[read a batched update from the specified file]:file:_files'
}
_rsync "$@"
|