This repository has been archived by the owner on Mar 21, 2024. It is now read-only.
forked from MatthewSteeples/rsync.net
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Options.cs
698 lines (679 loc) · 26 KB
/
Options.cs
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
/**
* Copyright (C) 2006 Alex Pedenko
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
using System;
using System.Collections.Generic;
using System.IO;
namespace NetSync
{
class CommandLineParser
{
public static int ParseArguments(string[] args, Options options)
{
int argsNotUsed = 0;
int i = 0;
Exclude excl = new Exclude(options);
while (i < args.Length)
{
try
{
switch (args[i])
{
case "--version":
MainClass.PrintRsyncVersion();
MainClass.Exit(String.Empty, null);
break;
case "--suffix":
options.backupSuffix = args[++i];
break;
case "--rsync-path":
options.rsyncPath = args[++i];
break;
case "--password-file":
options.passwordFile = args[++i];
break;
case "--ignore-times":
case "-I":
options.ignoreTimes = true;
break;
case "--size-only":
options.sizeOnly = true;
break;
case "--modify-window":
options.usingModifyWindow = true;
options.modifyWindow = Convert.ToInt32(args[++i]);
break;
case "--one-file-system":
case "-x":
options.oneFileSystem = true;
break;
case "--delete":
options.deleteMode = true;
break;
case "--existing":
options.onlyExisting = true;
break;
case "--ignore-existing":
options.optIgnoreExisting = true;
break;
case "--delete-after":
options.deleteMode = true;
options.deleteAfter = true;
break;
case "--delete-excluded":
options.deleteMode = true;
options.deleteExcluded = true;
break;
case "--force":
options.forceDelete = true;
break;
case "--numeric-ids":
options.numericIds = true;
break;
case "--exclude":
excl.AddExclude(ref options.excludeList, args[++i], 0);
break;
case "--include":
excl.AddExclude(ref options.excludeList, args[++i], (int)Options.XFLG_DEF_INCLUDE);
options.forceDelete = true;
break;
case "--exclude-from":
case "--include-from":
string arg = args[i];
excl.AddExcludeFile(ref options.excludeList, args[++i],
(arg.CompareTo("--exclude-from") == 0) ? 0 : (int)Options.XFLG_DEF_INCLUDE);
break;
case "--safe-links":
options.safeSymlinks = true;
break;
case "--help":
case "-h":
MainClass.Usage();
MainClass.Exit(String.Empty, null);
break;
case "--backup":
case "-b":
options.makeBackups = true;
break;
case "--dry-run":
case "-n":
options.dryRun = true;
break;
case "--sparse":
case "-S":
options.sparseFiles = true;
break;
case "--cvs-exclude":
case "-C":
options.cvsExclude = true;
break;
case "--update":
case "-u":
options.updateOnly = true;
break;
case "--inplace":
options.inplace = true;
break;
case "--keep-dirlinks":
case "-K":
options.keepDirLinks = true;
break;
case "--links":
case "-l":
options.preserveLinks = true;
break;
case "--copy-links":
case "-L":
options.copyLinks = true;
break;
case "--whole-file":
case "-W":
options.wholeFile = 1;
break;
case "--no-whole-file":
options.wholeFile = 0;
break;
case "--copy-unsafe-links":
options.copyUnsafeLinks = true;
break;
case "--perms":
case "-p":
options.preservePerms = true;
break;
case "--owner":
case "-o":
options.preserveUID = true;
break;
case "--group":
case "-g":
options.preserveGID = true;
break;
case "--devices":
case "-D":
options.preserveDevices = true;
break;
case "--times":
case "-t":
options.preserveTimes = true;
break;
case "--checksum":
case "-c":
options.alwaysChecksum = true;
break;
case "--verbose":
case "-v":
options.verbose++;
break;
case "--quiet":
case "-q":
options.quiet++;
break;
case "--archive":
case "-a":
options.archiveMode = true;
break;
case "--server":
options.amServer = true;
break;
case "--sender":
options.amSender = true;
break;
case "--recursive":
case "-r":
options.recurse = true;
break;
case "--relative":
case "-R":
options.relativePaths = true;
break;
case "--no-relative":
options.relativePaths = false;
break;
case "--rsh":
case "-e":
options.shellCmd = args[++i];
break;
case "--block-size":
case "-B":
options.blockSize = Convert.ToInt32(args[++i]);
break;
case "--max-delete":
options.maxDelete = Convert.ToInt32(args[++i]);
break;
case "--timeout":
options.ioTimeout = Convert.ToInt32(args[++i]);
break;
case "--temp-dir":
case "-T":
options.tmpDir = args[++i];
break;
case "--compare-dest":
options.compareDest = args[++i];
break;
case "--link-dest":
options.compareDest = args[++i];
break;
case "--compress":
case "-z":
options.doCompression = true;
break;
case "--stats":
options.doStats = true;
break;
case "--progress":
options.doProgress = true;
break;
case "--partial":
options.keepPartial = true;
break;
case "--partial-dir":
options.partialDir = args[++i];
break;
case "--ignore-errors":
options.ignoreErrors = true;
break;
case "--blocking-io":
options.blockingIO = 1;
break;
case "--no-blocking-io":
options.blockingIO = 0;
break;
case "-P":
options.doProgress = true;
options.keepPartial = true;
break;
case "--log-format":
options.logFormat = args[++i];
break;
case "--bwlimit":
options.bwLimit = Convert.ToInt32(args[++i]);
break;
case "--backup-dir":
options.backupDir = args[++i];
break;
case "--hard-links":
case "-H":
options.preserveHardLinks = true;
break;
case "--read-batch":
options.batchName = args[++i];
options.readBatch = true;
break;
case "--write-batch":
options.batchName = args[++i];
options.writeBatch = true;
break;
case "--files-from":
options.filesFrom = args[++i];
break;
case "--from0":
options.eolNulls = true;
break;
case "--no-implied-dirs":
options.impliedDirs = true;
break;
case "--protocol":
options.protocolVersion = Convert.ToInt32(args[++i]);
break;
case "--checksum-seed":
options.checksumSeed = Convert.ToInt32(args[++i]);
break;
case "--daemon":
options.amDaemon = true;
break;
case "--address":
options.bindAddress = args[++i];
break;
case "--port":
options.rsyncPort = Convert.ToInt32(args[++i]);
break;
case "--config":
options.configFile = args[++i].Trim();
break;
default:
{
argsNotUsed += ParseMergeArgs(args[i], options);
break;
}
}
i++;
}
catch { return -1; }
}
if (options.amSender && !options.amServer)
{
MainClass.Usage();
MainClass.Exit(String.Empty, null);
}
if (options.ioTimeout > 0 && options.ioTimeout < options.selectTimeout)
{
options.selectTimeout = options.ioTimeout;
}
return argsNotUsed;
}
private static int ParseMergeArgs(string MergeArgs, Options options)
{
if (MergeArgs != null && MergeArgs.StartsWith("-") && MergeArgs.Substring(1).IndexOf('-') == -1)
{
MergeArgs = MergeArgs.Substring(1);
string[] args = new string[MergeArgs.Length];
for (int i = 0; i < MergeArgs.Length; i++)
{
args[i] = "-" + MergeArgs[i];
}
return ParseArguments(args, options);
}
return 1;
}
}
public class Stats
{
public Int64 totalSize = 0;
public Int64 totalTransferredSize = 0;
public Int64 totalWritten = 0;
public Int64 totalRead = 0;
public Int64 literalData = 0;
public Int64 matchedData = 0;
public int fileListSize = 0;
public int numFiles = 0;
public int numTransferredFiles = 0;
public int currentFileIndex = 0;
}
public class Options
{
public void Init()
{
excludeList.Add(new ExcludeStruct(String.Empty, 0, 0));
localExcludeList.Add(new ExcludeStruct("per-dir .cvsignore ", 0, 0));
serverExcludeList.Add(new ExcludeStruct("server ", 0, 0));
}
public static System.DateTime lastIO = System.DateTime.MinValue;
//public static System.IO.StreamReader filesFromFD = null;
/// <summary>
/// Seems to be null all the time
/// </summary>
public static System.IO.Stream filesFromFD = null;
public static Stats stats = new Stats();
/// <summary>
/// "rsync://"
/// </summary>
public const string URL_PREFIX = "rsync://";
/// <summary>
/// 873
/// </summary>
public const int RSYNC_PORT = 873;
public int rsyncPort = RSYNC_PORT;
/// <summary>
/// 1024
/// </summary>
public const int MAXPATHLEN = 1024;
/// <summary>
/// 700
/// </summary>
public const int BLOCK_SIZE = 700;
/// <summary>
/// 1000
/// </summary>
public const int MAX_ARGS = 1000;
/// <summary>
/// 20
/// </summary>
public const int MIN_PROTOCOL_VERSION = 20;
/// <summary>
/// 25
/// </summary>
public const int OLD_PROTOCOL_VERSION = 25;
/// <summary>
/// 40
/// </summary>
public const int MAX_PROTOCOL_VERSION = 40;
/// <summary>
/// (256 * 1024)
/// </summary>
public const int MAX_MAP_SIZE = (256 * 1024);
/// <summary>
/// (1 << 0)
/// </summary>
public const int FLAG_TOP_DIR = (1 << 0);
/// <summary>
/// (1 << 1)
/// </summary>
public const int FLAG_HLINK_EOL = (1 << 1); /* generator only */
/// <summary>
/// (1 << 2)
/// </summary>
public const int FLAG_MOUNT_POINT = (1 << 2); /* sender only */
/// <summary>
/// 0
/// </summary>
public const int NO_EXCLUDES = 0;
/// <summary>
/// 1
/// </summary>
public const int SERVER_EXCLUDES = 1;
/// <summary>
/// 2
/// </summary>
public const int ALL_EXCLUDES = 2;
/// <summary>
/// 0
/// </summary>
public const int GID_NONE = 0;
/// <summary>
/// (1 << 0)
/// </summary>
public const UInt32 XFLG_FATAL_ERRORS = (1 << 0);
/// <summary>
/// (1 << 1)
/// </summary>
public const UInt32 XFLG_DEF_INCLUDE = (1 << 1);
/// <summary>
/// (1 << 2)
/// </summary>
public const UInt32 XFLG_WORDS_ONLY = (1 << 2);
/// <summary>
/// (1 << 3)
/// </summary>
public const UInt32 XFLG_WORD_SPLIT = (1 << 3);
/// <summary>
/// (1 << 4)
/// </summary>
public const UInt32 XFLG_DIRECTORY = (1 << 4);
/// <summary>
/// (1 << 0)
/// </summary>
public const UInt32 MATCHFLG_WILD = (1 << 0); /* pattern has '*', '[', and/or '?' */
/// <summary>
///
/// </summary>
public const UInt32 MATCHFLG_WILD2 = (1 << 1); /* pattern has '**' */
/// <summary>
/// (1 << 2)
/// </summary>
public const UInt32 MATCHFLG_WILD2_PREFIX = (1 << 2); /* pattern starts with '**' */
/// <summary>
/// (1 << 3)
/// </summary>
public const UInt32 MATCHFLG_ABS_PATH = (1 << 3); /* path-match on absolute path */
/// <summary>
/// (1 << 4)
/// </summary>
public const UInt32 MATCHFLG_INCLUDE = (1 << 4); /* this is an include, not an exclude */
/// <summary>
/// (1 << 5)
/// </summary>
public const UInt32 MATCHFLG_DIRECTORY = (1 << 5); /* this matches only directories */
/// <summary>
/// (1 << 6)
/// </summary>
public const UInt32 MATCHFLG_CLEAR_LIST = (1 << 6); /* this item is the "!" token */
/// <summary>
/// (1 << 0)
/// </summary>
public const UInt32 XMIT_TOP_DIR = (1 << 0);
/// <summary>
/// (1 << 1)
/// </summary>
public const UInt32 XMIT_SAME_MODE = (1 << 1);
/// <summary>
/// (1 << 2)
/// </summary>
public const UInt32 XMIT_EXTENDED_FLAGS = (1 << 2);
/// <summary>
/// XMIT_EXTENDED_FLAGS = (1 << 2)
/// </summary>
public const UInt32 XMIT_SAME_RDEV_pre28 = XMIT_EXTENDED_FLAGS; /* Only in protocols < 28 */
/// <summary>
/// (1 << 3)
/// </summary>
public const UInt32 XMIT_SAME_UID = (1 << 3);
/// <summary>
/// (1 << 4)
/// </summary>
public const UInt32 XMIT_SAME_GID = (1 << 4);
/// <summary>
/// (1 << 5)
/// </summary>
public const UInt32 XMIT_SAME_NAME = (1 << 5);
/// <summary>
/// (1 << 6)
/// </summary>
public const UInt32 XMIT_LONG_NAME = (1 << 6);
/// <summary>
/// (1 << 7)
/// </summary>
public const UInt32 XMIT_SAME_TIME = (1 << 7);
/// <summary>
/// (1 << 8)
/// </summary>
public const UInt32 XMIT_SAME_RDEV_MAJOR = (1 << 8);
/// <summary>
/// (1 << 9)
/// </summary>
public const UInt32 XMIT_HAS_IDEV_DATA = (1 << 9);
/// <summary>
/// (1 << 10)
/// </summary>
public const UInt32 XMIT_SAME_DEV = (1 << 10);
/// <summary>
/// (1 << 11)
/// </summary>
public const UInt32 XMIT_RDEV_MINOR_IS_SMALL = (1 << 11);
//
public List<ExcludeStruct> excludeList = new List<ExcludeStruct>();
public List<ExcludeStruct> localExcludeList = new List<ExcludeStruct>();
public List<ExcludeStruct> serverExcludeList = new List<ExcludeStruct>();
public string excludePathPrefix = null;
public DateTime startTime = System.DateTime.Now;
public string backupSuffix = null;
public string rsyncPath = null;
public string passwordFile = null;
public bool ignoreTimes = false;
public bool sizeOnly = false;
/// <summary>
/// Allowed difference between two files modification time
/// </summary>
public int modifyWindow = 0;
public bool usingModifyWindow = false;
public bool oneFileSystem = false;
public bool deleteMode = false;
public bool onlyExisting = false;
public bool optIgnoreExisting = false;
public bool deleteAfter = false;
public bool deleteExcluded = false;
public bool forceDelete = false;
public bool numericIds = false;
public bool safeSymlinks = false;
public bool makeBackups = false;
public bool dryRun = false;
public bool sparseFiles = false;
public bool cvsExclude = false;
public bool updateOnly = false;
public bool inplace = false;
public bool keepDirLinks = false;
public bool preserveLinks = false;
public bool copyLinks = false;
public int wholeFile = -1;
public bool copyUnsafeLinks = false;
public bool preservePerms = false;
public bool preserveUID = false;
public bool preserveGID = false;
public bool preserveDevices = false;
public bool preserveTimes = false;
public bool alwaysChecksum = false;
public bool archiveMode = false;
public bool amServer = false;
public bool recurse = false;
public int verbose = 0;
public int quiet = 0;
public bool amSender = false;
public bool relativePaths = true; //changed to bool and set true as init value
public string shellCmd = null;
public int blockSize = 0;
public int maxDelete = 0;
public int ioTimeout = 0;
public string tmpDir = null;
public string compareDest = null;
public int selectTimeout = 0;
public bool doCompression = false;
public bool doStats = false;
public bool doProgress = false;
public bool keepPartial = false;
public string partialDir = null;
public bool ignoreErrors = false;
public int blockingIO = -1;
public string logFormat = null;
public int bwLimit = 0;
public string backupDir = null;
public bool preserveHardLinks = false;
public string batchName = null;
public string filesFrom = null;
public bool eolNulls = false;
public bool impliedDirs = false;
public int protocolVersion = 28;
public int checksumSeed = 0;
public bool readBatch = false;
public bool writeBatch = false;
public bool listOnly = false;
public bool delayUpdates = false;
public string bindAddress = "127.0.0.1";
public string configFile = "rsyncd.conf";
public bool daemonOpt = false;
public bool noDetach = false;
//public int defaultafHint = AIF_INET;
public bool amDaemon = false;
public bool amRoot = true;
public bool amGenerator = false;
public string remoteFilesFromFile = null;
public bool readOnly = false;
public bool sanitizePath = false;
public Stream sockFIn = null;
public Stream sockFOut = null;
public int remoteProtocol = 0;
public string dir = String.Empty;
public FileStream logFile = null;
public int ModuleId = -1;
public string remoteAddr = null;
public string remoteHost = null;
public string WhoAmI()
{
return amSender ? "sender" : amGenerator ? "generator" : "receiver";
}
public int ServerOptions(string[] args)
{
int argc = 0;
args[argc++] = "--server";
for (int i = 0; i < verbose; i++)
{
args[argc++] = "-v";
}
args[argc++] = "-R";
if (alwaysChecksum)
{
args[argc++] = "-c";
}
if (recurse)
{
args[argc++] = "-r";
}
if (amSender)
{
if (deleteExcluded)
{
args[argc++] = "--delete-excluded";
}
else if (deleteMode)
{
args[argc++] = "--delete";
}
if (deleteAfter)
{
args[argc++] = "--delete-after";
}
if (forceDelete)
{
args[argc++] = "--force";
}
}
if (!amSender)
{
args[argc++] = "--sender";
}
return argc;
}
}
}