Advertisement
odielag

Untitled

Sep 28th, 2011
154
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. use subs qw/cmd Save_World Backup_World generateSymlink/;
  5. my %Reports; #For future use.
  6. $|=1; # Don't change this.
  7.  
  8.  
  9. # PURE-PERL
  10. # Backup script written by Mash of MCPub.org. This script is released under the
  11. # GPL providing this notice, my alias and website remain unchanged in this source.
  12. # Feel free to distribute but please post back any bugfixes or changes to the
  13. # source as it may be of use for others.
  14. #
  15. # DONATIONS ARE WELCOME! SEE WEBSITE -> -- Mash - MCPub.org
  16. #
  17.  
  18.  
  19. #-> Leaving a _message option blank("") will disable the message entirely. :)
  20. my %Config = (
  21. "username" => "odminecraft",
  22. "chown_to_user" => "odminecraft",
  23. "chown_to_group" => "odminecraft",
  24. "mc_dir" => "/home/odminecraft/minecraft-test/",
  25. "worlds" => ["world", "world_nether"],
  26. "backup_dir" => "/home/odminecraft/minecraft-test/backups/",
  27. "max_backups" => 72,
  28. "say_command" => "broadcast",
  29. "saving_message" => "Beginning World Save",
  30. "backup_message" => "",
  31. "backup_end_message" => "",
  32. # To disable any of the options below, set them to 'undef'
  33. # (without 's) not 0 or wonky things COULD possibly happen.
  34. "multiworld" => 1,
  35. "skip_counter" => undef, #any valid number, 1, 2, 5, 30, etc.
  36. "save" => 1,
  37. "backup" => 1,
  38. "symlink" => 1,
  39. "report_stats" => 1,
  40. "perworld_reports" => 1,
  41. # Options below are unchangable. Please, please do not change them.
  42. "mpsay_installed" => undef, #Determined automatically for safety
  43. "chown_uid_gid" => [], #Determined automatically for safety
  44. );
  45.  
  46. ################################################################################
  47. ################## NON-USER EDITABLE CODE :: SUBROUTINES #######################
  48. ################################################################################
  49. #-> Before we process ANYTHING, we make sure symlinking is supported by the OS
  50. #-> and determine the UID and GID of the user we're chowning files away to
  51. my $symsupport = eval { symlink("",""); 1 };
  52. $Config{'symlink'} = undef unless $symsupport;
  53. if (($Config{'chown_to_user'} ne "") && ($Config{'chown_to_group'} ne "")){
  54. my $uid = getpwnam($Config{'chown_to_user'});
  55. my $gid = getgrnam($Config{'chown_to_group'});
  56. $Config{'chown_uid_gid'} = [$uid, $gid];
  57. }
  58.  
  59. &MCPubMPSay();
  60. &checkSkip();
  61. &doWork();
  62.  
  63.  
  64.  
  65.  
  66. sub doWork { #Doing it this way so it calls save-all once, but multiple backups
  67. Save_World if $Config{'save'};
  68. return unless $Config{'backup'};
  69. cmd("save-off");
  70. select(undef,undef,undef,0.5);
  71. my @worldList = @{$Config{'worlds'}};
  72. for (@worldList){
  73. next unless -d "$Config{'mc_dir'}$_";
  74. Backup_World($_);
  75. }
  76. cmd("save-on");
  77. do {
  78. cmd("$Config{'say_command'} " . $Config{'backup_end_message'}) if $Config{'backup_end_message'} ne "";
  79. } unless (($Config{'perworld_reports'}) && ($Config{'mpsay_installed'}));
  80. }
  81.  
  82. sub Save_World { # stupidly simple.. Almost a waste to do it at all lol ;)
  83. cmd("$Config{'say_command'} $Config{'saving_message'}") if $Config{'saving_message'} ne "";
  84. cmd("save-all");
  85. }
  86.  
  87. #-> Complicating the fuck out of this subroutine because I don't want
  88. #-> multiple routines that essentially do the same thing. Making this
  89. #-> deterministic and sequential. (Also added directory creating in
  90. #-> the off chance users didn't create their own backup directories.)
  91. sub Backup_World {
  92. my $worldName = $_[0];
  93. $worldName = "world" unless $worldName ne "";
  94. my $startTime = time;
  95. my $counter=0;
  96. my $f=undef;
  97. my @FileList;
  98. if (!-d "$Config{'backup_dir'}"){mkdir($Config{'backup_dir'});$f=1;}
  99. if (!-d "$Config{'backup_dir'}$worldName") {mkdir("$Config{'backup_dir'}$worldName", "0777");$f=1;}
  100. if ($f){ die "BAD USER, NO BISCUIT! D:<\n"; }
  101. if (($Config{'multiworld'}) && ($worldName ne "")){
  102. if ($Config{'mpsay_installed'}){
  103. cmd("mpsay $worldName $Config{'backup_message'}") if $Config{'backup_message'} ne "";
  104. } else {
  105. cmd("$Config{'say_command'} $Config{'backup_message'} ($worldName)") if $Config{'backup_message'} ne "";
  106. }
  107. opendir(MC, "$Config{'backup_dir'}$worldName/") || die "Failed to open '$Config{'backup_dir'}$worldName'\n";
  108. @FileList = grep { /\.tar\.gz$/i && -f "$Config{'backup_dir'}$worldName/$_" } readdir(MC);
  109. } else {
  110. opendir(MC, "$Config{'backup_dir'}$worldName/") || die "Failed to open '$Config{'backup_dir'}'\n";
  111. @FileList = grep { /\.tar\.gz$/i && -f "$Config{'backup_dir'}$worldName/$_" } readdir(MC);
  112. cmd("$Config{'say_command'} $Config{'backup_message'} ($worldName)") if $Config{'backup_message'} ne "";
  113. }
  114. closedir(MC);
  115. my $numBackups = scalar @FileList;
  116. if (($numBackups >= $Config{'max_backups'}) && ($numBackups > 0)) {
  117. my $dif = $numBackups - $Config{'max_backups'};
  118. for (0 .. $dif){
  119. unlink("$Config{'backup_dir'}$worldName/$FileList[$_]");
  120. }
  121. }
  122. my $timestamp = &get_timestamp();
  123. my $backup_file = $Config{'backup_dir'} . $worldName . "/" . $timestamp . ".tar.gz";
  124. open(COMMAND, "tar -cvzf $backup_file $Config{'mc_dir'}$worldName/* |");
  125. $counter++ while <COMMAND>;
  126. close(COMMAND);
  127. system("chown $Config{'chown_to_user'}" . ":" . $Config{'chown_to_group'} . " " . $backup_file);
  128. generateSymlink($worldName, $backup_file);
  129. &generate_report($counter, $backup_file, $startTime, $worldName) if $Config{'report_stats'};
  130. if (($Config{'mpsay_installed'}) && ($Config{'perworld_reports'})){
  131. cmd("mpsay $worldName $Config{'backup_end_message'}") if $Config{'backup_end_message'} ne "";
  132. }
  133. }
  134.  
  135. sub get_timestamp {
  136. my ($sec,$min,$hour,$mday,$mon,$year) = (localtime(time))[0..5];
  137. $year += 1900;
  138. return "$year\_$mon\_$mday\_-_$hour\.$min\.$sec";
  139. }
  140.  
  141. sub MCPubMPSay {
  142. opendir(PLUGS, "$Config{'mc_dir'}plugins/") || die "Can't read plugins directory\n";
  143. my @f = grep { /^mpsay.jar$/i && -f "$Config{'mc_dir'}plugins/$_" } readdir(PLUGS);
  144. closedir(PLUGS);
  145. if (($f[0]) && ($f[0] ne "")) {
  146. my ($t) = (caller(0))[4];
  147. $Config{'mpsay_installed'} = substr($t, 0, 5);
  148. } else {
  149. $Config{'mpsay_installed'} = undef;
  150. }
  151. }
  152.  
  153. sub generate_report {
  154. my ($numFilesArchived, $backup_file, $startTime, $worldName) = @_;
  155. my $elapsedTime = time - $startTime;
  156. my ($outMin,$outSec) = (gmtime($elapsedTime))[1,0];
  157. $elapsedTime = "$outMin\:$outSec";
  158. my $backupFileSizeDirty = -s $backup_file;
  159. my $backupFileSize = $backupFileSizeDirty / (1024 * 1024);
  160. my $formattedSize;
  161. ($formattedSize = sprintf("%.2f", $backupFileSize)) =~ s/\G(\d{1,3})(?=(?:\d\d\d)+(?:\.|$))/$1,/g;
  162. if (($Config{'mpsay_installed'}) && ($Config{'perworld_reports'})){
  163. cmd("mpsay $worldName Backed up $numFilesArchived files ($formattedSize MB in $elapsedTime)");
  164. } else {
  165. cmd("$Config{'say_command'} Backed up \'$worldName\' - $numFilesArchived files ($formattedSize MB in $elapsedTime)");
  166. }
  167. }
  168.  
  169. sub cmd {
  170. my $CMD = $_[0];
  171. system("su -c \"screen -p 0 -S $Config{'username'} -X eval 'stuff \\\"$CMD\\\"\015'\" $Config{'username'}");
  172. }
  173.  
  174. sub checkSkip {
  175. my $skipFlag = 1;
  176. if (!$Config{'skip_counter'}){
  177. unlink($Config{'mc_dir'}."$Config{'mpsay_installed'}")
  178. if -e $Config{'mc_dir'}."$Config{'mpsay_installed'}";
  179. undef($skipFlag);
  180. } else {
  181. if (!-e "$Config{'mc_dir'}$Config{'mpsay_installed'}"){
  182. open(C, ">$Config{'mc_dir'}$Config{'mpsay_installed'}");
  183. print C "0";
  184. close(C);
  185. return;
  186. }
  187. open(C, "$Config{'mc_dir'}$Config{'mpsay_installed'}");
  188. chomp(my $cn = <C>); close C;
  189. if ($cn =~ m/^(\d+)$/g){
  190. unlink("$Config{'mc_dir'}$Config{'mpsay_installed'}");
  191. open C, ">$Config{'mc_dir'}$Config{'mpsay_installed'}";
  192. print C "0"; close C;
  193. }
  194. open C, "+<", "$Config{'mc_dir'}$Config{'mpsay_installed'}";
  195. if ($cn >= $Config{'skip_counter'}){
  196. $cn = 0;
  197. print C $cn;
  198. undef($skipFlag);
  199. } else {
  200. $cn++;
  201. print C $cn;
  202. }
  203. close C;
  204. }
  205. exit if $skipFlag;
  206. }
  207.  
  208. sub generateSymlink {
  209. my($w,$f) = @_;
  210. symlink "$f", "$Config{'mc_dir'}$w.backup.tar.gz" || die "Failed to create symlink\n";
  211. my @list = ("$Config{'mc_dir'}$w.backup.tar.gz");
  212. system("chown $Config{'chown_to_user'}" . ":" . $Config{'chown_to_group'} . " " . "$Config{'mc_dir'}$w.backup.tar.gz");
  213. }
  214.  
Advertisement
RAW Paste Data Copied
Advertisement