File:  [LON-CAPA] / loncom / debugging_tools / move_construction_spaces.pl
Revision 1.2: download - view: text, annotated - select for diffs
Wed Oct 26 17:35:10 2011 UTC (12 years, 8 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD
- Early out if not run as root.
- &mt().

    1: #!/usr/bin/perl
    2: #
    3: # Move Construction Spaces from /home/$user/public_html
    4: # to /home/httpd/html/priv/$domain/$user and vice versa
    5: # 
    6: 
    7: use strict;
    8: use lib '/home/httpd/lib/perl/';
    9: use LONCAPA::Configuration;
   10: use LONCAPA qw(:DEFAULT :match);
   11: use Apache::lonlocal;
   12: use File::Copy;
   13: use GDBM_File;
   14: 
   15: my $lang = &Apache::lonlocal::choose_language();
   16: &Apache::lonlocal::get_language_handle(undef,$lang);
   17: 
   18: if ($< != 0) {
   19:     print(&mt('You must be root in order to move Construction Spaces.').
   20:          "\n");
   21:     exit;
   22: }
   23: 
   24: my $perlvar=&LONCAPA::Configuration::read_conf();
   25: my ($lonuserdir,$londocroot);
   26: if (ref($perlvar) eq 'HASH') {
   27:     $lonuserdir = $perlvar->{'lonUsersDir'};
   28:     $londocroot = $perlvar->{'lonDocRoot'};
   29: }
   30: undef($perlvar);
   31: 
   32: # Abort if more than one argument.
   33: 
   34: my $parameter=$ARGV[0];
   35: $parameter =~ s/^\s+//;
   36: $parameter =~ s/\s+$//;
   37: 
   38: if ((@ARGV > 1) || (($parameter ne '') && ($parameter !~ /^(move|undo)$/))) {
   39:     print &mt('usage: [_1]','move_construction_spaces.pl [move|undo]')."\n\n".
   40:           &mt('You should enter either no arguments, or just one argument -- either move or undo.')."\n".
   41:           &mt("move - to move authors' Construction Spaces from: [_1] to [_2].",
   42:               "'/home'","'$londocroot/priv/'")."\n".
   43:           &mt('undo - to reverse those changes and move Construction Spaces back from: [_1] to [_2].',
   44:               "'$londocroot/priv/'","'/home'")."\n".
   45:           &mt('no argument to do a dry run of the move option, without actually moving anything.')."\n";
   46:     exit;
   47: }
   48: 
   49: print "\n".&mt("Moving authors' Construction Spaces.")."\n".
   50:       "-----------------------------\n\n".
   51:       &mt('If run without an argument, the script will report what it would do when moving Construction Spaces from [_1] to [_2].',
   52:           "'/home'","'$londocroot/priv/'")."\n\n".
   53:       &mt('If there are ambiguities (i.e., the same username belongs to two domains), this will be flagged, and you will be able to decide how to proceed.')."\n";
   54: 
   55: my $perlvar=&LONCAPA::Configuration::read_conf();
   56: my ($lonuserdir,$londocroot);
   57: if (ref($perlvar) eq 'HASH') {
   58:     $lonuserdir = $perlvar->{'lonUsersDir'};
   59:     $londocroot = $perlvar->{'lonDocRoot'};
   60: }
   61: undef($perlvar);
   62: 
   63: my (undef,undef,$uid,$gid) = getpwnam('www');
   64: my ($action) = ($parameter=~/^(move|undo)$/);
   65: if ($action eq '') {
   66:     $action = 'dryrun';
   67: }
   68: 
   69: if ($action eq 'dryrun') {
   70:     print "\n".
   71:           &mt('Running in exploratory mode.')."\n".
   72:           &mt('Run with argument [_1] to actually move Construction Spaces to [_2], i.e., [_3]',
   73:               "'move'","'$londocroot/priv'","\nperl move_construction_spaces.pl move")."\n\n".
   74:           &mt('Run with argument [_1] to move Construction spaces back to [_2], i.e., [_3]',
   75:               "'undo'","'/home'","\nperl move_construction_spaces.pl undo")."\n\n".
   76:           &mt('Continue? ~[y/N~] ');
   77:     if (!&get_user_selection()) {
   78:         exit;
   79:     }
   80: } else {
   81:     print "\n ***".&mt('Running in a mode where changes will be made.')."\n";
   82:     if ($action eq 'move') {
   83:         print "\n".
   84:               &mt('Mode is [_1] -- directories will be moved to [_2].',
   85:                   "'$action'","'$londocroot/priv'")."\n";
   86:     } else {
   87:         print "\n".
   88:               &mt('Mode is [_1] -- directories will be moved back to [_2].',
   89:                   "'$action'","'/home'")."\n";
   90:     }
   91:     print &mt('Continue? ~[y/N~] ');
   92:     if (!&get_user_selection()) {
   93:         exit;
   94:     }
   95: }
   96: 
   97: # Authors hosted on this server
   98: my %allauthors;
   99: my %pubusers;
  100: 
  101: if ($action eq 'move') {
  102:     if (-d "$londocroot/priv") {
  103:         print "\n".
  104:               &mt('New Construction Spaces directory: [_1] already exists.',
  105:                   "'$londocroot/priv'")."\n";
  106:     } else {
  107:         print "\n".
  108:               &mt('Creating new directory: [_1] for Construction Spaces.',
  109:                   "'$londocroot/priv'")."\n";
  110:         if (mkdir("$londocroot/priv",0755)) {
  111:             if (chown($uid,$gid,"$londocroot/priv")) {
  112:                 print &mt('Creation Successful')."\n";
  113:             } else {
  114:                 print &mt('Failed to change ownership to [_1].',"'$uid:$gid'")."\n".
  115:                 &mt('Stopping')."\n";
  116:                 exit;
  117:             }
  118:         } else {
  119:             print &mt('Failed to create directory [_1].',"'$londocroot/priv'")."\n".
  120:                   &mt('Stopping')."\n";
  121:             exit;
  122:         }
  123:     }
  124: }
  125: 
  126: my @machinedoms;
  127: if ($lonuserdir) {
  128:     my $dir;
  129:     if (opendir($dir,$lonuserdir)) {
  130:         my @contents = (grep(!/^\.{1,2}$/,readdir($dir)));
  131:         foreach my $item (@contents) {
  132:             if (-d "$lonuserdir/$item") {
  133:                 if ($item =~ /^$match_domain$/) {
  134:                     my $domain = $item;
  135:                     unless (grep(/^\Q$domain\E$/,@machinedoms)) {
  136:                         push(@machinedoms,$domain);  
  137:                     }
  138:                     my $dom_target="/home/httpd/html/priv/$domain";
  139:                     if ($action eq 'move') {
  140:                         if (!-e $dom_target) {
  141:                             if (mkdir($dom_target,0755)) {
  142:                                 chown($uid,$gid,$dom_target);
  143:                                 print &mt('Made [_1].',"'$dom_target'")."\n";
  144:                             } else {
  145:                                 print &mt('Failed to make [_1].',"'$dom_target'")."\n".
  146:                                       &mt('Stopping')."\n";
  147:                                 exit;
  148:                             }
  149:                         } elsif ($action eq 'dryrun') {
  150:                             print &mt('Would make [_1].',"'$dom_target'")."\n";
  151:                         }
  152:                     }
  153:                     my %authors=();
  154:                     my $fname = "$lonuserdir/$domain/nohist_domainroles.db";
  155:                     my $dbref;
  156:                     if (-e $fname) {
  157:                         $dbref=&LONCAPA::locking_hash_tie($fname,&GDBM_READER());
  158:                     }
  159:                     if (!$dbref) {
  160:                         print &mt('Unable to tie to [_1].',"'$fname'")."\n";
  161:                     } elsif (ref($dbref) eq 'HASH') {
  162:                         foreach my $key (keys(%{$dbref})) {
  163:                             $key = &unescape($key);
  164:                             if ($key =~ /^au\:($match_username)\Q:$domain\E/) {
  165:                                 push(@{$allauthors{$1}},$domain);
  166:                             }
  167:                         }
  168:                         &LONCAPA::locking_hash_untie($dbref);
  169:                     }
  170:                 }
  171:             }
  172:         }
  173:         closedir($dir);
  174:     } else {
  175:         print &mt('Could not open [_1].',"'$lonuserdir'")."\n".
  176:               &mt('Stopping')."\n";
  177:         exit;
  178:     }
  179: }
  180: 
  181: if ($londocroot ne '') {
  182:     if (-d "$londocroot/res") {
  183:         my ($dir,$domdir);
  184:         if (opendir($dir,"$londocroot/res")) {
  185:             my @contents = (grep(!/^\.{1,2}$/,readdir($dir)));
  186:             foreach my $dom (@contents) {
  187:                 if ((grep(/^\Q$dom\E/,@machinedoms)) && (-d "$londocroot/res/$dom")) {
  188:                     if (opendir($domdir,"$londocroot/res/$dom")) {
  189:                         my @unames = (grep(!/^\.{1,2}$/,readdir($domdir)));
  190:                         foreach my $uname (@unames) {
  191:                             if ($uname =~ /^$match_username$/) {
  192:                                 push(@{$pubusers{$uname}},$dom);
  193:                             }
  194:                         }
  195:                     }
  196:                 }
  197:             }
  198:         }
  199:     }
  200: }
  201: 
  202: if ($action eq 'undo') {
  203:     my %privspaces;
  204:     if ($londocroot ne '') {
  205:         if (-d "$londocroot/priv") {
  206:             my ($dir,$domdir);
  207:             if (opendir($dir,"$londocroot/priv")) {
  208:                 my @contents = (grep(!/^\.{1,2}/,readdir($dir)));
  209:                 foreach my $dom (@contents) {
  210:                     next if (!-d "$londocroot/priv/$dom");
  211:                     if (opendir($domdir,"$londocroot/priv/$dom")) {
  212:                         my @unames = (grep(!/^\.{1,2}$/,readdir($domdir)));
  213:                         foreach my $uname (@unames) {
  214:                             if ($uname =~ /^$match_username$/) {
  215:                                 push(@{$privspaces{$uname}},$dom);
  216:                             }
  217:                         }
  218:                     }
  219:                 }
  220:             }
  221:         }
  222:     }
  223:     foreach my $uname (keys(%privspaces)) {
  224:         if (ref($privspaces{$uname}) eq 'ARRAY') {
  225:             if (@{$privspaces{$uname}} > 1) {
  226:                 my $displaydoms = join(', ',@{$privspaces{$uname}});
  227:                 print &mt('Same username used for authors in multiple domains.')."\n".
  228:                       &mt('This configuration is not supported where Construction Spaces are located in [_1].','/home').".\n".
  229:                       &mt('You will be able to move files for just one of the domains, choose which one.')."\n".
  230:                       &mt('The domains to choose from are: [_1].',"'$displaydoms'")."\n".
  231:                       &mt('Enter choice: ');
  232:                 my $choice=<STDIN>;
  233:                 chomp($choice);
  234:                 if (grep(/^\Q$choice\E$/,@{$privspaces{$uname}})) {
  235:                     &move_priv_to_home($londocroot,$uname,$choice);
  236:                 } else {
  237:                     print &mt('Invalid choice of domain:')." $choice\n".
  238:                           &mt('Skipping this user: [_1].',"'$uname'")."\n";
  239:                     next;
  240:                 }
  241:             } elsif (@{$privspaces{$uname}} == 1) {
  242:                     &move_priv_to_home($londocroot,$uname,$privspaces{$uname}[0]);
  243:             } else {
  244:                 print &mt('Username [_1] found in [_2] was not within a domain',
  245:                           "'$uname'","'$londocroot/priv'")."\n";
  246:             }
  247:         }
  248:     }
  249:     print &mt('Done')."\n";
  250:     exit;
  251: }
  252: 
  253: # Iterate over directories in /home
  254: if (opendir(my $dir,"/home")) {
  255:     foreach my $item (grep(!/^\.{1,2}$/,readdir($dir))) {
  256:         next if ($item eq 'www');
  257:         if (-d "/home/$item") {
  258: # Is there a public_html-directory?
  259:             if (-d "/home/$item/public_html") {
  260:                 my $author = $item;
  261:                 my ($domain,$skipped);
  262:                 if (ref($pubusers{$author}) eq 'ARRAY') {
  263:                     ($domain,$skipped) = &choose_domain($action,$author,$pubusers{$author});
  264:                 }
  265:                 if (($domain eq '') && (!$skipped)) {
  266:                     if (ref($allauthors{$author}) eq 'ARRAY') {
  267:                         ($domain,$skipped) = &choose_domain($action,$author,$allauthors{$author});
  268:                     }
  269:                 }
  270:                 if ($domain) { 
  271:                     my $source_path="/home/$author/public_html";
  272:                     my $target_path="$londocroot/priv/$domain/$author";
  273:                     if ($action eq 'move') {
  274:                         move($source_path,$target_path);
  275:                             chown($uid,$gid,$target_path);
  276:                             chmod($target_path,0755);
  277:                         print &mt('Moved [_1] to [_2].',"'$source_path'","'$target_path'")."\n";
  278:                     } elsif ($action eq 'dryrun') {
  279:                         print &mt('Would move [_1] to [_2].',"'$source_path'","'$target_path'")."\n";
  280:                     }
  281:                 } elsif (!$skipped) {
  282:                     print '*** '.&mt('WARNING: [_1] has no domain.',"'$author'")."\n".
  283:                           &mt('Enter [_1]: do nothing, continue.','1')."\n".
  284:                           &mt('Enter [_2]: stop.','2')."\n".
  285:                           &mt('or enter domain for user to be placed into')."\n".
  286:                           &mt('Your input: ');
  287:                     my $choice=<STDIN>;
  288:                     chomp($choice);
  289:                     next if ($choice ==1);
  290:                     if ($choice == 2) {
  291:                         print &mt('Stopped.')."\n";
  292:                         exit;
  293:                     } 
  294:                     if ($choice =~ /^$match_domain$/) {
  295:                         my $dompath="$londocroot/priv/$choice";
  296:                         my $newpath="$londocroot/priv/$choice/$author";
  297:                         unless (-e $dompath) {
  298:                             print '*** '.&mt('WARNING: [_1] does not yet exist.',"'$dompath'")."\n";
  299:                         }
  300:                         if ($action eq 'move') {
  301:                             print &mt('Making author [_1] in domain [_2].',"'$author'","'$choice'")."\n";
  302:                             unless (-e $dompath) {
  303:                                 print &mt('Making [_1].',"'$dompath'")."\n";
  304:                                 mkdir($dompath,0755);
  305:                                 chown($uid,$gid,$dompath);
  306:                             }
  307:                             print &mt('Making [_1].',"'$newpath'")."\n";
  308:                             mkdir($newpath,0755);
  309:                             chown($uid,$gid,$newpath);
  310:                         } elsif ($action eq 'dryrun') {
  311:                            print &mt('Would make author [_1] in domain [_2].',"'$author'","'$choice'")."\n";
  312:                            unless (-e $dompath) {
  313:                                print &mt('Would make [_1].',"'$dompath'")."\n";
  314:                            }
  315:                            print &mt('Would make [_1].',"'$newpath'")."\n";
  316:                         }
  317:                     }
  318:                 }
  319:             }
  320:         }
  321:     }
  322: }
  323: print "\nDone.\n";
  324: 
  325: sub choose_domain { 
  326:     my ($action,$author,$domarrayref) = @_;
  327:     my ($domain,$skipped);
  328:     if (ref($domarrayref) eq 'ARRAY') {
  329:          if (@{$domarrayref} > 1) {
  330:              print '*** '.&mt('ERROR: [_1] found in multiple domains.',"'$author'")."\n".
  331:                    &mt('Enter a number to choose what action to take.')."\n";
  332:              my $num = 1;
  333:              for (my $i=0; $i<@{$domarrayref}; $i++) {
  334:                  print &mt('To use: [_1] enter [_2].',$domarrayref->[$i],$num)."\n";
  335:                  $num ++;
  336:              }
  337:              print &mt('To skip this user enter: [_1].',$num)."\n".
  338:                    &mt('Your choice:').' ';
  339:              my $choice=<STDIN>;
  340:              chomp($choice);
  341:              if ($choice =~ /^\d+$/) {
  342:                  if (($choice == $num) || ($choice > $num)) {
  343:                      $skipped = 1;       
  344:                  } elsif (($choice < $num) && ($choice > 0)) {
  345:                      $domain = $domarrayref->[$choice-1];
  346:                  } else {
  347:                      print &mt('Invalid choice:')." $choice\n";
  348:                      $skipped = 1;
  349:                  }
  350:              } else {
  351:                  print &mt('Invalid choice:')." $choice\n";
  352:                  $skipped = 1;
  353:              }
  354:          } elsif (@{$domarrayref} == 1) {
  355:              $domain = $domarrayref->[0];
  356:          }
  357:     }
  358:     return ($domain,$skipped);
  359: }
  360: 
  361: sub move_priv_to_home {
  362:     my ($londocroot,$uname,$domain) = @_;
  363:     if ($uname =~ /^$match_username$/ && $domain =~ /^$match_domain$/) {
  364:         my $source_path="$londocroot/priv/$domain/$uname";
  365:         my $target_path="/home/$uname/public_html";
  366:         if (!-e "/home/$uname") {
  367:             if (mkdir("/home/$uname",0755)) {
  368:                 chown($uid,$gid,"/home/$uname");
  369:             } else {
  370:                 print &mt('Failed to create directory [_1] -- not moving [_2].',
  371:                           "'/home/$uname'","'$source_path'")."\n";
  372:             }
  373:         }
  374:         if (!-e $target_path) {
  375:              move($source_path,$target_path);
  376:              chown($uid,$gid,$target_path);
  377:              chmod($target_path,0755);
  378:              print &mt('Moved [_1] to [_2].',"'$source_path'","'$target_path'")."\n";
  379:         } else {
  380:              print &mt('Directory [_1] already exists -- not moving [_2].',
  381:                        "'$target_path'","'$source_path'")."\n";
  382:         }
  383:     }
  384:     return;
  385: }
  386: 
  387: sub get_user_selection {
  388:     my ($defaultrun) = @_;
  389:     my $do_action = 0;
  390:     my $choice = <STDIN>;
  391:     chomp($choice);
  392:     $choice =~ s/(^\s+|\s+$)//g;
  393:     my $yes = &mt('y');
  394:     if ($defaultrun) {
  395:         if (($choice eq '') || ($choice =~ /^\Q$yes\E/i)) {
  396:             $do_action = 1;
  397:         }
  398:     } else {
  399:         if ($choice =~ /^\Q$yes\E/i) {
  400:             $do_action = 1;
  401:         }
  402:     }
  403:     return $do_action;
  404: }
  405: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>