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