Annotation of loncom/debugging_tools/move_construction_spaces.pl, revision 1.5
1.1 raeburn 1: #!/usr/bin/perl
2: #
1.3 raeburn 3: # The LearningOnline Network
4: #
1.1 raeburn 5: # Move Construction Spaces from /home/$user/public_html
6: # to /home/httpd/html/priv/$domain/$user and vice versa
1.3 raeburn 7: #
1.5 ! raeburn 8: # $Id: move_construction_spaces.pl,v 1.4 2011/10/27 03:43:53 raeburn Exp $
1.3 raeburn 9: #
10: # Copyright Michigan State University Board of Trustees
11: #
12: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
13: #
14: # LON-CAPA is free software; you can redistribute it and/or modify
15: # it under the terms of the GNU General Public License as published by
16: # the Free Software Foundation; either version 2 of the License, or
17: # (at your option) any later version.
18: #
19: # LON-CAPA is distributed in the hope that it will be useful,
20: # but WITHOUT ANY WARRANTY; without even the implied warranty of
21: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22: # GNU General Public License for more details.
23: #
24: # You should have received a copy of the GNU General Public License
25: # along with LON-CAPA; if not, write to the Free Software
26: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27: #
28: # /home/httpd/html/adm/gpl.txt
29: #
30: # http://www.lon-capa.org/
31: #
32: #################################################
1.1 raeburn 33:
34: use strict;
35: use lib '/home/httpd/lib/perl/';
36: use LONCAPA::Configuration;
37: use LONCAPA qw(:DEFAULT :match);
38: use Apache::lonlocal;
39: use File::Copy;
40: use GDBM_File;
41:
1.5 ! raeburn 42: my ($lonusersdir,$londocroot,$londaemons);
! 43:
! 44: BEGIN {
! 45: my $perlvar=&LONCAPA::Configuration::read_conf();
! 46: if (ref($perlvar) eq 'HASH') {
! 47: $lonusersdir = $perlvar->{'lonUsersDir'};
! 48: $londocroot = $perlvar->{'lonDocRoot'};
! 49: $londaemons = $perlvar->{'lonDaemons'};
! 50: }
! 51: undef($perlvar);
! 52: }
! 53:
1.1 raeburn 54: my $lang = &Apache::lonlocal::choose_language();
55: &Apache::lonlocal::get_language_handle(undef,$lang);
1.2 raeburn 56:
57: if ($< != 0) {
1.3 raeburn 58: print &mt('You must be root in order to move Construction Spaces.')."\n".
59: &mt('Stopping')."\n";
1.2 raeburn 60: exit;
61: }
62:
1.5 ! raeburn 63: if ($lonusersdir eq '') {
1.4 raeburn 64: print &mt('Could not determine location of [_1] directory.',"'lonUsersDir'")."\n".
65: &mt('Stopping')."\n";
66: exit;
67: }
68:
69: if ($londocroot eq '') {
70: print &mt('Could not determine location of [_1] directory.',"'lonDocRoot'")."\n".
71: &mt('Stopping')."\n";
72: exit;
73: }
74:
1.3 raeburn 75: my $distro;
1.4 raeburn 76: if ($londaemons eq '') {
77: print &mt('Could not determine location of [_1] directory.',"'lonDaemons'")."\n".
78: &mt('Stopping')."\n";
79: exit;
80: } else {
1.3 raeburn 81: if (-e "$londaemons/distprobe") {
82: if (open(PIPE,"perl $londaemons/distprobe|")) {
83: $distro = <PIPE>;
84: close(PIPE);
85: }
86: }
87: }
88:
89: if ($distro eq '') {
90: print &mt('Could not determine Linux distro.')."\n".
91: &mt('Stopping')."\n";
92: exit;
93: } else {
94: my $stopapachecmd = '/etc/init.d/httpd stop';
95: my $apacheprocess = '/usr/sbin/httpd';
96: my $stopapachecmd = '/etc/init.d/httpd stop';
97: my $proc_owner = 'root';
98: if ($distro =~ /^(suse|sles)/) {
99: if ($distro =~ /^(suse|sles)9/) {
100: $stopapachecmd = '/etc/init.d/apache stop';
101: } else {
102: $apacheprocess = '/usr/sbin/httpd2';
103: $stopapachecmd = '/etc/init.d/apache2 stop';
104: }
105: } elsif ($distro =~ /^(?:debian|ubuntu)(\d+)/) {
106: $apacheprocess = '/usr/sbin/apache2';
107: $stopapachecmd = '/etc/init.d/apache2 stop';
108: } elsif ($distro =~ /^(?:fedora)(\d+)/) {
109: my $version = $1;
110: if ($version >= 16) {
111: $stopapachecmd = '/bin/systemctl stop httpd.service';
112: }
113: }
114: if (open(PIPE,"ps -ef |grep '$apacheprocess' |grep -v grep 2>&1 |")) {
115: my $status = <PIPE>;
116: close(PIPE);
117: chomp($status);
118: if ($status =~ /^\Q$proc_owner\E\s+\d+\s+/) {
119: print "\n".
120: &mt('You need to stop the Apache daemon before moving Construction Spaces.')."\n".
121: &mt('To do so use the following command: [_1]',"\n\n$stopapachecmd")."\n\n".
122: &mt('Now stopping the move_construction_spaces.pl script.')."\n";
123: exit;
124: }
125: } else {
126: print &mt('Could not determine if Apache daemon is running.')."\n";
127: }
128: }
129:
130: my $stoploncontrol = '/etc/init.d/loncontrol stop';
131: if (open(PIPE,"ps -ef |grep lond |grep -v grep 2>&1 |")) {
132: my $status = <PIPE>;
133: close(PIPE);
134: chomp($status);
135: if ($status =~ /^www\s+\d+\s+/) {
136: print "\n".
137: &mt('You need to stop the LON-CAPA daemons before moving Construction Spaces.')."\n".
138: &mt('To do so use the following command: [_1]',"\n\n$stoploncontrol")."\n\n".
139: &mt('Now stopping the move_construction_spaces.pl script.')."\n";
140: exit;
141: }
142: }
143:
1.1 raeburn 144: # Abort if more than one argument.
1.2 raeburn 145:
146: my $parameter=$ARGV[0];
147: $parameter =~ s/^\s+//;
148: $parameter =~ s/\s+$//;
149:
150: if ((@ARGV > 1) || (($parameter ne '') && ($parameter !~ /^(move|undo)$/))) {
1.1 raeburn 151: print &mt('usage: [_1]','move_construction_spaces.pl [move|undo]')."\n\n".
152: &mt('You should enter either no arguments, or just one argument -- either move or undo.')."\n".
1.2 raeburn 153: &mt("move - to move authors' Construction Spaces from: [_1] to [_2].",
154: "'/home'","'$londocroot/priv/'")."\n".
155: &mt('undo - to reverse those changes and move Construction Spaces back from: [_1] to [_2].',
156: "'$londocroot/priv/'","'/home'")."\n".
1.1 raeburn 157: &mt('no argument to do a dry run of the move option, without actually moving anything.')."\n";
158: exit;
159: }
160:
1.2 raeburn 161: print "\n".&mt("Moving authors' Construction Spaces.")."\n".
1.1 raeburn 162: "-----------------------------\n\n".
1.2 raeburn 163: &mt('If run without an argument, the script will report what it would do when moving Construction Spaces from [_1] to [_2].',
164: "'/home'","'$londocroot/priv/'")."\n\n".
165: &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";
1.1 raeburn 166:
167: my (undef,undef,$uid,$gid) = getpwnam('www');
168: my ($action) = ($parameter=~/^(move|undo)$/);
169: if ($action eq '') {
170: $action = 'dryrun';
171: }
172:
173: if ($action eq 'dryrun') {
1.5 ! raeburn 174: print "\n\n".
1.3 raeburn 175: &mt('Running in exploratory mode ...')."\n\n".
1.2 raeburn 176: &mt('Run with argument [_1] to actually move Construction Spaces to [_2], i.e., [_3]',
1.3 raeburn 177: "'move'","'$londocroot/priv'","\n\nperl move_construction_spaces.pl move")."\n\n\n".
1.2 raeburn 178: &mt('Run with argument [_1] to move Construction spaces back to [_2], i.e., [_3]',
1.3 raeburn 179: "'undo'","'/home'","\n\nperl move_construction_spaces.pl undo")."\n\n\n".
1.2 raeburn 180: &mt('Continue? ~[y/N~] ');
181: if (!&get_user_selection()) {
182: exit;
1.3 raeburn 183: } else {
184: print "\n";
1.2 raeburn 185: }
1.1 raeburn 186: } else {
1.3 raeburn 187: print "\n *** ".&mt('Running in a mode where changes will be made.')." ***\n";
1.1 raeburn 188: if ($action eq 'move') {
1.2 raeburn 189: print "\n".
190: &mt('Mode is [_1] -- directories will be moved to [_2].',
191: "'$action'","'$londocroot/priv'")."\n";
1.1 raeburn 192: } else {
1.2 raeburn 193: print "\n".
194: &mt('Mode is [_1] -- directories will be moved back to [_2].',
195: "'$action'","'/home'")."\n";
1.1 raeburn 196: }
197: print &mt('Continue? ~[y/N~] ');
198: if (!&get_user_selection()) {
199: exit;
1.3 raeburn 200: } else {
201: print "\n";
202: }
203: }
204:
205: my $logfh;
206: if ($action ne 'dryrun') {
207: if (!open($logfh,">>$londaemons/logs/move_construction_spaces.log")) {
208: print &mt('Could not open log file: [_1] for writing.',
209: "'$londaemons/logs/move_construction_spaces.log'")."\n".
210: &mt('Stopping.')."\n";
211: } else {
212: &start_logging($logfh,$action);
1.1 raeburn 213: }
214: }
215:
216: # Authors hosted on this server
217: my %allauthors;
218: my %pubusers;
219:
220: if ($action eq 'move') {
1.3 raeburn 221: my $output;
1.1 raeburn 222: if (-d "$londocroot/priv") {
1.3 raeburn 223: $output = &mt('New Construction Spaces directory: [_1] already exists.',
224: "'$londocroot/priv'")."\n";
225: print $output;
226: print $logfh $output;
1.1 raeburn 227: } else {
1.3 raeburn 228: $output = &mt('Creating new directory: [_1] for Construction Spaces.',
229: "'$londocroot/priv'")."\n";
230: if (mkdir("$londocroot/priv",0750)) {
1.1 raeburn 231: if (chown($uid,$gid,"$londocroot/priv")) {
1.3 raeburn 232: $output .= &mt('Creation Successful')."\n";
233: print $output;
234: print $logfh $output;
1.1 raeburn 235: } else {
1.3 raeburn 236: $output .= &mt('Failed to change ownership to [_1].',"'$uid:$gid'")."\n";
237: print $output;
238: &stop_logging($logfh,$output);
239: print &mt('Stopping')."\n";
1.1 raeburn 240: exit;
241: }
242: } else {
1.3 raeburn 243: $output .= &mt('Failed to create directory [_1].',"'$londocroot/priv'")."\n";
244: print $output;
245: &stop_logging($logfh,$output);
246: print &mt('Stopping')."\n";
1.2 raeburn 247: exit;
1.1 raeburn 248: }
249: }
250: }
251:
252: my @machinedoms;
1.5 ! raeburn 253: if ($lonusersdir) {
1.3 raeburn 254: my ($dir,$output);
1.5 ! raeburn 255: if (opendir($dir,$lonusersdir)) {
1.1 raeburn 256: my @contents = (grep(!/^\.{1,2}$/,readdir($dir)));
257: foreach my $item (@contents) {
1.5 ! raeburn 258: if (-d "$lonusersdir/$item") {
1.1 raeburn 259: if ($item =~ /^$match_domain$/) {
260: my $domain = $item;
261: unless (grep(/^\Q$domain\E$/,@machinedoms)) {
262: push(@machinedoms,$domain);
263: }
1.4 raeburn 264: my $dom_target="$londocroot/priv/$domain";
1.1 raeburn 265: if ($action eq 'move') {
266: if (!-e $dom_target) {
267: if (mkdir($dom_target,0755)) {
268: chown($uid,$gid,$dom_target);
1.3 raeburn 269: $output = &mt('Made [_1].',"'$dom_target'")."\n";
270: print $output;
271: print $logfh $output;
1.1 raeburn 272: } else {
1.3 raeburn 273: $output = &mt('Failed to make [_1].',"'$dom_target'")."\n";
274: print $output;
275: print $logfh $output;
276: &stop_logging($logfh,$output);
277: print &mt('Stopping')."\n";
1.1 raeburn 278: exit;
279: }
280: } elsif ($action eq 'dryrun') {
1.2 raeburn 281: print &mt('Would make [_1].',"'$dom_target'")."\n";
1.1 raeburn 282: }
283: }
284: my %authors=();
1.5 ! raeburn 285: my $fname = "$lonusersdir/$domain/nohist_domainroles.db";
1.1 raeburn 286: my $dbref;
287: if (-e $fname) {
288: $dbref=&LONCAPA::locking_hash_tie($fname,&GDBM_READER());
289: }
290: if (!$dbref) {
1.2 raeburn 291: print &mt('Unable to tie to [_1].',"'$fname'")."\n";
1.1 raeburn 292: } elsif (ref($dbref) eq 'HASH') {
293: foreach my $key (keys(%{$dbref})) {
294: $key = &unescape($key);
295: if ($key =~ /^au\:($match_username)\Q:$domain\E/) {
296: push(@{$allauthors{$1}},$domain);
297: }
298: }
299: &LONCAPA::locking_hash_untie($dbref);
300: }
301: }
302: }
303: }
304: closedir($dir);
305: } else {
1.5 ! raeburn 306: $output = &mt('Could not open [_1].',"'$lonusersdir'")."\n";
1.3 raeburn 307: print $output;
308: &stop_logging($logfh,$output);
309: print &mt('Stopping')."\n";
1.1 raeburn 310: exit;
311: }
312: }
313:
314: if ($londocroot ne '') {
315: if (-d "$londocroot/res") {
316: my ($dir,$domdir);
317: if (opendir($dir,"$londocroot/res")) {
318: my @contents = (grep(!/^\.{1,2}$/,readdir($dir)));
319: foreach my $dom (@contents) {
320: if ((grep(/^\Q$dom\E/,@machinedoms)) && (-d "$londocroot/res/$dom")) {
321: if (opendir($domdir,"$londocroot/res/$dom")) {
322: my @unames = (grep(!/^\.{1,2}$/,readdir($domdir)));
323: foreach my $uname (@unames) {
324: if ($uname =~ /^$match_username$/) {
325: push(@{$pubusers{$uname}},$dom);
326: }
327: }
328: }
329: }
330: }
331: }
332: }
333: }
334:
335: if ($action eq 'undo') {
336: my %privspaces;
337: if ($londocroot ne '') {
338: if (-d "$londocroot/priv") {
339: my ($dir,$domdir);
340: if (opendir($dir,"$londocroot/priv")) {
341: my @contents = (grep(!/^\.{1,2}/,readdir($dir)));
342: foreach my $dom (@contents) {
343: next if (!-d "$londocroot/priv/$dom");
344: if (opendir($domdir,"$londocroot/priv/$dom")) {
345: my @unames = (grep(!/^\.{1,2}$/,readdir($domdir)));
346: foreach my $uname (@unames) {
347: if ($uname =~ /^$match_username$/) {
348: push(@{$privspaces{$uname}},$dom);
349: }
350: }
351: }
352: }
353: }
354: }
355: }
356: foreach my $uname (keys(%privspaces)) {
357: if (ref($privspaces{$uname}) eq 'ARRAY') {
358: if (@{$privspaces{$uname}} > 1) {
1.2 raeburn 359: my $displaydoms = join(', ',@{$privspaces{$uname}});
360: print &mt('Same username used for authors in multiple domains.')."\n".
361: &mt('This configuration is not supported where Construction Spaces are located in [_1].','/home').".\n".
362: &mt('You will be able to move files for just one of the domains, choose which one.')."\n".
363: &mt('The domains to choose from are: [_1].',"'$displaydoms'")."\n".
364: &mt('Enter choice: ');
1.1 raeburn 365: my $choice=<STDIN>;
366: chomp($choice);
367: if (grep(/^\Q$choice\E$/,@{$privspaces{$uname}})) {
1.3 raeburn 368: my $output = &move_priv_to_home($londocroot,$uid,$gid,$uname,$choice);
369: print $output;
370: print $logfh $output;
1.1 raeburn 371: } else {
1.3 raeburn 372: print &mt('Invalid choice of domain:')." $choice\n";
373: my $output = &mt('Skipping this user: [_1].',"'$uname'")."\n";
374: print $output;
375: print $logfh $output;
1.1 raeburn 376: next;
377: }
378: } elsif (@{$privspaces{$uname}} == 1) {
1.3 raeburn 379: my $output = &move_priv_to_home($londocroot,$uid,$gid,$uname,$privspaces{$uname}[0]);
380: print $output;
381: print $logfh $output;
1.1 raeburn 382: } else {
1.2 raeburn 383: print &mt('Username [_1] found in [_2] was not within a domain',
384: "'$uname'","'$londocroot/priv'")."\n";
1.3 raeburn 385: my $output = &mt('Skipping this user: [_1].',"'$uname'")."\n";
386: print $output;
387: print $logfh $output;
1.1 raeburn 388: }
389: }
390: }
1.3 raeburn 391: &stop_logging($logfh);
392: print "\n".&mt('Done')."\n";
1.1 raeburn 393: exit;
394: }
395:
1.5 ! raeburn 396: my @allskipped;
! 397: my %allmoved;
! 398:
1.1 raeburn 399: # Iterate over directories in /home
400: if (opendir(my $dir,"/home")) {
1.5 ! raeburn 401: my @possibles = grep(!/^\.{1,2}$/,readdir($dir));
! 402: foreach my $item (sort(@possibles)) {
1.1 raeburn 403: next if ($item eq 'www');
1.3 raeburn 404: if ((-d "/home/$item") && ($item ne '')) {
1.1 raeburn 405: # Is there a public_html-directory?
406: if (-d "/home/$item/public_html") {
407: my $author = $item;
1.3 raeburn 408: my ($domain,$skipped,$output);
1.5 ! raeburn 409: if (ref($allauthors{$author}) eq 'ARRAY') {
! 410: ($domain,$skipped) = &choose_domain($action,$author,$allauthors{$author});
1.1 raeburn 411: }
412: if (($domain eq '') && (!$skipped)) {
1.5 ! raeburn 413: if (ref($pubusers{$author}) eq 'ARRAY') {
! 414: ($domain,$skipped) = &choose_domain($action,$author,$pubusers{$author});
! 415: }
! 416: }
! 417: if (($domain eq '') && (!$skipped)) {
! 418: my @foundauthor = ();
! 419: foreach my $dom (@machinedoms) {
! 420: my $posspath = &LONCAPA::propath($dom,$author);
! 421: if (-e $posspath) {
! 422: my $rolesdbref;
! 423: my $fname = "$posspath/roles.db";
! 424: if (-e "$fname") {
! 425: $rolesdbref=&LONCAPA::locking_hash_tie($fname,&GDBM_READER());
! 426: if (!$rolesdbref) {
! 427: print &mt('Unable to tie to [_1].',"'$fname'")."\n";
! 428: } elsif (ref($rolesdbref) eq 'HASH') {
! 429: foreach my $key (keys(%{$rolesdbref})) {
! 430: if ($key eq "/$dom/_au") {
! 431: unless(grep(/^\Q$dom\E$/,@foundauthor)) {
! 432: push(@foundauthor,$dom);
! 433: }
! 434: }
! 435: }
! 436: &LONCAPA::locking_hash_untie($rolesdbref);
! 437: }
! 438: }
! 439: }
! 440: }
! 441: if (@foundauthor > 0) {
! 442: ($domain,$skipped) = &choose_domain($action,$author,\@foundauthor);
1.1 raeburn 443: }
444: }
1.3 raeburn 445: my $source_path="/home/$author/public_html";
1.5 ! raeburn 446: if ($domain) {
1.1 raeburn 447: my $target_path="$londocroot/priv/$domain/$author";
448: if ($action eq 'move') {
1.3 raeburn 449: if (move($source_path,$target_path)) {
1.5 ! raeburn 450: my (undef,undef,$userid,$groupid) = getpwnam($author);
! 451: if ($userid eq '' && $groupid eq '' && $author ne '') {
! 452: chown($uid,$gid,$target_path);
! 453: }
1.3 raeburn 454: $output = &mt('Moved [_1] to [_2].',
455: "'$source_path'","'$target_path'")."\n";
1.5 ! raeburn 456: push(@{$allmoved{$domain}},$author);
1.3 raeburn 457: my (undef,undef,$userid,$groupid) = getpwnam($author);
458: if ($userid eq '' && $groupid eq '' && $author ne '') {
459: &check_for_restore_files($londaemons,$author,$domain);
460: if (opendir(my $homedir,"/home/$author")) {
461: my @contents =
462: grep(!/^\.{1,2}$/,readdir($homedir));
463: if (@contents == 0) {
464: if (rmdir("/home/$author/")) {
465: $output .= &mt('Removed empty directory: [_1]',
466: "'/home/$author/'")."\n";
467: } else {
468: $output .= &mt('Failed to remove directory: [_1]',
469: "'/home/$author/'")."\n";
470: }
471: } else {
472: $output .= &mt('Not removing directory [_1] as it still contains: [_2]',
473: "'/home/$author/'",
474: "\n".join("\n",@contents)."\n");
475: }
476: }
477: } else {
478: $output .= &mt('Not removing directory [_1] for UNIX user account',
479: "'/home/$author/'")."\n";
480: }
481: } else {
482: $output = &mt('Failed to move [_1] to [_2].',
483: "'$source_path'","'$target_path'")."\n";
484: }
485: print $output;
486: print $logfh $output;
1.1 raeburn 487: } elsif ($action eq 'dryrun') {
1.5 ! raeburn 488: push(@{$allmoved{$domain}},$author);
1.2 raeburn 489: print &mt('Would move [_1] to [_2].',"'$source_path'","'$target_path'")."\n";
1.1 raeburn 490: }
1.3 raeburn 491: } elsif ($skipped) {
1.5 ! raeburn 492: push(@allskipped,$author);
1.3 raeburn 493: if ($action ne 'dryrun') {
1.5 ! raeburn 494: my $output = &mt('Skipping this user: [_1].',"'$author'")."\n";
! 495: print $logfh $output;
1.3 raeburn 496: }
497: } else {
1.2 raeburn 498: print '*** '.&mt('WARNING: [_1] has no domain.',"'$author'")."\n".
499: &mt('Enter [_1]: do nothing, continue.','1')."\n".
1.5 ! raeburn 500: &mt('Enter [_1]: stop.','2')."\n".
1.2 raeburn 501: &mt('or enter domain for user to be placed into')."\n".
502: &mt('Your input: ');
1.1 raeburn 503: my $choice=<STDIN>;
504: chomp($choice);
1.5 ! raeburn 505: $choice =~ s/^\s+//;
! 506: $choice =~ s/\s+$//;
! 507: if ($choice == 1) {
! 508: my $output = &mt('Skipping -- no domain for user: [_1].',"'$author'")."\n";
! 509: print $output;
! 510: if ($action ne 'dryrun') {
! 511: print $logfh $output;
! 512: }
! 513: push(@allskipped,$author);
! 514: next;
1.3 raeburn 515: }
1.2 raeburn 516: if ($choice == 2) {
517: print &mt('Stopped.')."\n";
1.3 raeburn 518: if ($action ne 'dryrun') {
519: my $output = &mt('Stopped by user because of author without domain: [_1].',
520: "'$author'")/"\n";
521: &stop_logging($logfh,$output);
522: }
1.2 raeburn 523: exit;
1.5 ! raeburn 524: } elsif ($choice =~ /^$match_domain$/) {
! 525: print &mt('You entered:')." $choice\n".
! 526: &mt('Is this ok? ~[Y/n~] ');
! 527: if (!&get_user_selection(1)) {
! 528: print &mt('Try again ...')."\n".
! 529: &mt('Enter [_1]: do nothing, continue.','1')."\n".
! 530: &mt('Enter [_1]: stop.','2')."\n".
! 531: &mt('or enter domain for user to be placed into')."\n".
! 532: &mt('Your input: ');
! 533: $choice=<STDIN>;
! 534: chomp($choice);
! 535: $choice =~ s/^\s+//;
! 536: $choice =~ s/\s+$//;
! 537: if ($choice == 1) {
! 538: my $output = &mt('Skipping -- no domain for user: [_1].',"'$author'")."\n";
! 539: print $output;
! 540: if ($action ne 'dryrun') {
! 541: print $logfh $output;
! 542: }
! 543: push(@allskipped,$author);
! 544: next;
! 545: }
! 546: if ($choice == 2) {
! 547: print &mt('Stopped.')."\n";
! 548: if ($action ne 'dryrun') {
! 549: my $output = &mt('Stopped by user because of author without domain: [_1].',
! 550: "'$author'")/"\n";
! 551: &stop_logging($logfh,$output);
! 552: }
! 553: exit;
! 554: } elsif ($choice !~ /^$match_domain$/) {
! 555: print &mt('Invalid domain entered:')." $choice\n";
! 556: my $output = &mt('Skipping -- no domain for user: [_1].',"'$author'")."\n";
! 557: print $output;
! 558: if ($action ne 'dryrun') {
! 559: print $logfh $output;
! 560: }
! 561: push(@allskipped,$author);
! 562: next;
! 563: }
! 564: }
1.1 raeburn 565: my $dompath="$londocroot/priv/$choice";
566: my $newpath="$londocroot/priv/$choice/$author";
567: unless (-e $dompath) {
1.5 ! raeburn 568: if ($action eq 'move') {
! 569: print '*** '.&mt('WARNING: [_1] does not yet exist.',"'$dompath'")."\n";
! 570: }
1.1 raeburn 571: }
572: if ($action eq 'move') {
573: unless (-e $dompath) {
1.3 raeburn 574: $output .= &mt('Making [_1].',"'$dompath'")."\n";
575: if (mkdir($dompath,0755)) {
576: chown($uid,$gid,$dompath);
577: }
578: }
579: if (-e $dompath) {
580: if (move($source_path,$newpath)) {
581: chown($uid,$gid,$newpath);
582: chmod($newpath,0750);
583: $output = &mt('Moved [_1] to [_2].',
584: "'$source_path'","'$newpath'")."\n";
585: } else {
586: $output = &mt('Failed to move [_1] to [_2].',
587: "'$source_path'","'$newpath'")."\n";
588: }
589: print $output;
590: print $logfh $output;
591: } else {
592: $output = &mt('Failed to move [_1] to [_2] -- missing [_3].',
593: "'$source_path'","'$newpath'","'$dompath'")."\n";
1.1 raeburn 594: }
595: } elsif ($action eq 'dryrun') {
1.2 raeburn 596: print &mt('Would make author [_1] in domain [_2].',"'$author'","'$choice'")."\n";
1.1 raeburn 597: unless (-e $dompath) {
1.2 raeburn 598: print &mt('Would make [_1].',"'$dompath'")."\n";
1.1 raeburn 599: }
1.2 raeburn 600: print &mt('Would make [_1].',"'$newpath'")."\n";
1.1 raeburn 601: }
1.5 ! raeburn 602: } else {
! 603: print &mt('Invalid domain:')." $choice\n";
! 604: if ($action eq 'move') {
! 605: print $logfh &mt('Skipping -- no domain for user: [_1].',"'$author'")."\n";
! 606: }
! 607: push(@allskipped,$author);
! 608: next;
1.1 raeburn 609: }
610: }
611: }
612: }
613: }
614: }
1.5 ! raeburn 615:
! 616: my ($moveinfo,$skipcount);
! 617: if (keys(%allmoved) == 0) {
! 618: $moveinfo = &mt('None')."\n";
! 619: } else {
! 620: foreach my $dom (sort(keys(%allmoved))) {
! 621: if (ref($allmoved{$dom}) eq 'ARRAY') {
! 622: $moveinfo .= "\n ".&mt('Domain: [_1], number of authors: [_2]',
! 623: "'$dom'",scalar(@{$allmoved{$dom}}));
! 624: }
! 625: }
! 626: }
! 627:
! 628: $skipcount = scalar(@allskipped);
! 629:
! 630: print "\n";
1.3 raeburn 631: if ($action ne 'dryrun') {
1.5 ! raeburn 632: my $output = &mt('You skipped: [_1].',$skipcount)."\n".
! 633: &mt('Moved ... [_1]',$moveinfo);
! 634: print $output;
! 635: print $logfh $output;
1.3 raeburn 636: &stop_logging($logfh);
1.5 ! raeburn 637: } else {
! 638: print &mt('You would have skipped: [_1].',$skipcount)."\n".
! 639: &mt('You would have moved ... [_1]',$moveinfo);
1.3 raeburn 640: }
1.5 ! raeburn 641: print "\n\n".&mt('Done.')."\n";
1.1 raeburn 642:
643: sub choose_domain {
644: my ($action,$author,$domarrayref) = @_;
645: my ($domain,$skipped);
646: if (ref($domarrayref) eq 'ARRAY') {
647: if (@{$domarrayref} > 1) {
1.2 raeburn 648: print '*** '.&mt('ERROR: [_1] found in multiple domains.',"'$author'")."\n".
649: &mt('Enter a number to choose what action to take.')."\n";
1.1 raeburn 650: my $num = 1;
651: for (my $i=0; $i<@{$domarrayref}; $i++) {
1.2 raeburn 652: print &mt('To use: [_1] enter [_2].',$domarrayref->[$i],$num)."\n";
1.1 raeburn 653: $num ++;
654: }
1.2 raeburn 655: print &mt('To skip this user enter: [_1].',$num)."\n".
656: &mt('Your choice:').' ';
1.1 raeburn 657: my $choice=<STDIN>;
658: chomp($choice);
659: if ($choice =~ /^\d+$/) {
660: if (($choice == $num) || ($choice > $num)) {
661: $skipped = 1;
662: } elsif (($choice < $num) && ($choice > 0)) {
663: $domain = $domarrayref->[$choice-1];
664: } else {
1.2 raeburn 665: print &mt('Invalid choice:')." $choice\n";
1.1 raeburn 666: $skipped = 1;
667: }
668: } else {
1.2 raeburn 669: print &mt('Invalid choice:')." $choice\n";
1.1 raeburn 670: $skipped = 1;
671: }
672: } elsif (@{$domarrayref} == 1) {
673: $domain = $domarrayref->[0];
674: }
675: }
676: return ($domain,$skipped);
677: }
678:
679: sub move_priv_to_home {
1.3 raeburn 680: my ($londocroot,$uid,$gid,$uname,$domain) = @_;
681: my $output;
1.1 raeburn 682: if ($uname =~ /^$match_username$/ && $domain =~ /^$match_domain$/) {
683: my $source_path="$londocroot/priv/$domain/$uname";
684: my $target_path="/home/$uname/public_html";
685: if (!-e "/home/$uname") {
1.3 raeburn 686: my (undef,undef,$userid,$groupid) = getpwnam($uname);
687: if (mkdir("/home/$uname",0750)) {
688: if ($userid ne '' && $groupid ne '') {
689: chown($userid,$groupid,"/home/$uname");
690: }
1.1 raeburn 691: } else {
1.3 raeburn 692: $output = &mt('Failed to create directory [_1] -- not moving [_2].',
1.2 raeburn 693: "'/home/$uname'","'$source_path'")."\n";
1.3 raeburn 694: return $output;
1.1 raeburn 695: }
696: }
1.3 raeburn 697: if (-e "/home/$uname") {
698: if (!-e $target_path) {
699: move($source_path,$target_path);
700: chown($uid,$gid,$target_path);
701: chmod($target_path,2770);
702: $output = &mt('Moved [_1] to [_2].',"'$source_path'","'$target_path'")."\n";
703: } else {
704: $output = &mt('Directory [_1] already exists -- not moving [_2].',
705: "'$target_path'","'$source_path'")."\n";
706: }
1.1 raeburn 707: }
708: }
1.3 raeburn 709: return $output;
1.1 raeburn 710: }
711:
712: sub get_user_selection {
713: my ($defaultrun) = @_;
714: my $do_action = 0;
715: my $choice = <STDIN>;
716: chomp($choice);
717: $choice =~ s/(^\s+|\s+$)//g;
718: my $yes = &mt('y');
719: if ($defaultrun) {
720: if (($choice eq '') || ($choice =~ /^\Q$yes\E/i)) {
721: $do_action = 1;
722: }
723: } else {
724: if ($choice =~ /^\Q$yes\E/i) {
725: $do_action = 1;
726: }
727: }
728: return $do_action;
729: }
730:
1.3 raeburn 731: sub start_logging {
732: my ($fh,$action) = @_;
733: my $start = localtime(time);
734: print $fh "*****************************************************\n".
735: &mt('[_1] - mode is [_2].',
736: 'move_construction_spaces.pl',"'$action'")."\n".
737: &mt('Started -- time: [_1]',$start)."\n".
738: "*****************************************************\n\n";
739: return;
740: }
741:
742: sub stop_logging {
743: my ($fh) = @_;
744: my $end = localtime(time);
745: print $fh "*****************************************************\n".
746: &mt('Ended -- time: [_1]',$end)."\n".
747: "*****************************************************\n\n\n";
748: close($fh);
749: return;
750: }
751:
752: sub check_for_restore_files {
753: my ($londaemons,$author,$domain) = @_;
754: if (opendir(my $homedir,"/home/$author")) {
755: my @contents = grep(!/^\.{1,2}$/,readdir($homedir));
756: if (@contents > 0) {
757: if (grep(/^restore_\d+\.sh$/,@contents)) {
758: if (!-e "$londaemons/logs/moved_construction_spaces") {
759: mkdir("$londaemons/logs/moved_construction_spaces",0755);
760: }
761: if (!-e "$londaemons/logs/moved_construction_spaces/$domain") {
762: mkdir("$londaemons/logs/moved_construction_spaces/$domain",0755);
763: }
764: if (-e "$londaemons/logs/moved_construction_spaces/$domain") {
765: if (open(my $restorefh,">>$londaemons/logs/moved_construction_spaces/$domain/$author")) {
766: foreach my $item (@contents) {
767: if ($item =~ /^restore_\d+\.sh$/) {
768: my @stats = stat("/home/$author/$item");
769: my $lastmod = $stats[9];
770: if (open(my $fh,"</home/$author/$item")) {
771: print $restorefh
772: "*******************************\n".
773: "$item -- ".localtime(time)."\n".
774: "*******************************\n";
775: while (<$fh>) {
776: print $restorefh $_;
777: }
778: print $restorefh
779: "*******************************\n\n";
780: close($fh);
781: unlink("/home/$author/$item");
782: }
783: }
784: }
785: close($restorefh);
786: }
787: }
788: }
789: }
790: }
791: return;
792: }
793:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>