Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
4.9 KiB

  1. @echo off
  2. for %%i in (%0.cmd) do perl -w -x %%~dp$PATH:i%0.cmd %*
  3. goto :eof
  4. #!perl
  5. # line 6
  6. #
  7. # FileName: sdbackup.cmd
  8. #
  9. # Usage = sdbackup [-v] [-d altdir] <backupdir>
  10. #
  11. # Enumerates all the SD opened files in all depots and copies the
  12. # changes out to the specified path. This can be useful simply as
  13. # a regular backup of local changes, or as a mechanism for sharing
  14. # private changes with another person.
  15. #
  16. # Example:
  17. # sdbackup \\scratch\scratch\jvert\sdbackup
  18. # copies all opened files to \\scratch\scratch\jvert\sdbackup\<currentdate>
  19. # sdbackup -d newchange \\scratch\scratch\jvert
  20. # copies all opened files to \\scratch\scratch\jvert\newchange
  21. #
  22. #
  23. use Getopt::Std;
  24. use File::Path;
  25. use File::Spec;
  26. use File::Copy;
  27. #
  28. # initialize globals
  29. #
  30. $opt_v = 0;
  31. $opt_d = 0;
  32. %revisionlist = ();
  33. %changelist = ();
  34. %clientfilelist = ();
  35. $Usage = "
  36. USAGE: $0 [-v] [-d altdir] [backupdir]
  37. -v Verbose output
  38. -d altdir use <altdir> instead of <currentdate> as the root directory
  39. backupdir Supplies directory where files will be backed up to.
  40. The directory structure created will look like this:
  41. <backupdir>\<currentdate>
  42. backup.log - list of files and their versions
  43. \\nt\.. - directories and files
  44. If -n is specified, the directory structure will look
  45. like this:
  46. <backupdir>\\nt.. - directories and files
  47. If not specified, the filenames will just be printed to stdout.\n";
  48. #
  49. # Finds the full filenames of all checked out files
  50. #
  51. getopts('vd:') or die $Usage;
  52. $backupdir = $ARGV[0];
  53. $opt_v and print("backupdir is $backupdir\n");
  54. foreach $line (`sdx opened`) {
  55. chomp $line;
  56. #
  57. # throw away blank lines, depot specifiers, and empty lists
  58. #
  59. $line =~ /^[\t\s]*$|^------|^File\(s\) not opened/ and next;
  60. #
  61. # throw away files that aren't in the default change list. Kind of sleazy,
  62. # but it prevents the public libraries from getting in the list
  63. #
  64. $line =~ /edit change \d/ and next;
  65. #
  66. # throw away deleted files
  67. #
  68. $line =~ /delete default change/ and next;
  69. #
  70. # If we hit the summary, we're done
  71. #
  72. $line =~ /^== Summary/ and last;
  73. $opt_v and print ("line = $line\n");
  74. #
  75. # parse the resulting filename
  76. #
  77. ($depotfilename, $revision, $change) = split(/#| - /,$line);
  78. $opt_v and print ("\tfilename: $depotfilename\n\trevision: $revision\n\tchange: $change\n\n");
  79. $depotfilename = lc($depotfilename);
  80. $revisionlist{$depotfilename} = $revision;
  81. $changelist{$depotfilename} = $change;
  82. }
  83. #
  84. # Now we have a list of depot names. Translate those into clientnames
  85. # by calling sdx where
  86. #
  87. $filelist = join(' ',keys(%revisionlist));
  88. foreach $line (`sdx where $filelist`) {
  89. #
  90. # throw away blank lines, depot specifiers, "not found" lines,
  91. # and lines that start with "-"
  92. #
  93. $line =~ /^[\t\s]*$|^-------|file\(s\) not in client view|^-/ and next;
  94. chomp $line;
  95. $opt_v and print("mapping: $line\n");
  96. ($depotfilename, $trash, $clientfilename) = split(/\s/,$line);
  97. $depotfilename = lc($depotfilename);
  98. $clientfilelist{$depotfilename} = lc($clientfilename);
  99. -e $clientfilename or die "file: $clientfilename should exist but doesn't!\n";
  100. }
  101. if ($backupdir) {
  102. if ($opt_d) {
  103. $backupdir .= "\\$opt_d";
  104. } else {
  105. @time = localtime;
  106. $backupdir .= sprintf("\\%02d-%02d-%4d",$time[4]+1,$time[3],($time[5]+1900));
  107. }
  108. mkpath($backupdir) unless -d $backupdir;
  109. open(LOGFILE, "+> $backupdir\\backup.log") or die "Couldn't open $backupdir\\backup.log: $!\n";
  110. #
  111. # Write all the files to backup.log. Format is:
  112. # SDfilename #<versionnumber> clientfilename
  113. #
  114. foreach $file (sort keys %clientfilelist) {
  115. $clientfile = $clientfilelist{$file};
  116. #
  117. # Each client filename is in the form X:<full pathname>\<filename>
  118. # Split this up into volume, path, filename components (we don't
  119. # care about the volume)
  120. #
  121. ($trash,$dir,$filename) = File::Spec->splitpath($clientfile);
  122. #
  123. # Write this file's data to the logfile
  124. #
  125. $srcfile = File::Spec->catfile($dir, $filename);
  126. print LOGFILE "$file #$revisionlist{$file} $srcfile\n";
  127. #
  128. # compute the destination directory and make sure it exists.
  129. #
  130. $destdir = File::Spec->catdir($backupdir, $dir);
  131. -d $destdir || mkpath($destdir) or die "Couldn't create destination directory $destdir: $!\n";
  132. #
  133. # compute the full destination path and filename
  134. #
  135. $destfile = File::Spec->catfile($destdir, $filename);
  136. if ($opt_v) {
  137. print("copying $clientfile to $destfile\n");
  138. } else {
  139. print("$clientfile\n");
  140. }
  141. copy($clientfile, $destfile, 0)
  142. or die "Couldn't copy $clientfile -> $destfile: $!\n";
  143. }
  144. } else {
  145. print join("\n", sort values %clientfilelist);
  146. }