root/trunk/engine/setup/ispcp-update

Revision 1340, 31.1 kB (checked in by scitech, 3 months ago)

RC6 remote database support for upgrade script

Line 
1 #!/usr/bin/perl
2
3 # ispCP ω (OMEGA) a Virtual Hosting Control Panel
4 # Copyright (c) 2007-2008 by ispCP
5 # http://isp-control.net
6 #
7 #
8 # License:
9 #    This program is free software; you can redistribute it and/or
10 #    modify it under the terms of the GPL General Public License
11 #    as published by the Free Software Foundation; either version 2.0
12 #    of the License, or (at your option) any later version.
13 #
14 #    This program is distributed in the hope that it will be useful,
15 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
16 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 #    GPL General Public License for more details.
18 #
19 #    You may have received a copy of the GPL General Public License
20 #    along with this program.
21 #
22 #    An on-line copy of the GPL General Public License can be found
23 #    http://www.fsf.org/licensing/licenses/gpl.txt
24 #
25 # The ispCP ω Home Page is at:
26 #
27 #    http://isp-control.net
28 #
29
30 use FindBin;
31 use lib "$FindBin::Bin/..";
32
33 require 'ispcp_common_code.pl';
34 require 'ispcp-setup-methods.pl';
35 use strict;
36 use warnings;
37
38 %main::ua = ();
39 $main::vhcs2conf = undef;
40 $main::cfg_re = '^[ \t]*([\_A-Za-z0-9]+) *= *([^\n\r]*)[\n\r]';
41
42 ################################################################################
43 ##                                 CONSTANTS                                  ##
44 ################################################################################
45
46 use constant {
47                 ABORT   => 0,
48         VHCS247 => 1,
49         VHCS248 => 2,
50         RC2             => 3,
51         RC3             => 4,
52         RC4             => 5,
53         RC5             => 6,
54         };
55
56 ################################################################################
57 ##                                SUBROUTINES                                 ##
58 ################################################################################
59
60 sub get_vhcs2conf {
61
62     push_el(\@main::el, 'get_vhcs2conf()', 'Starting...');
63
64     my ($rs, $fline) = get_file($main::vhcs2conf);
65     return -1 if ($rs != 0);
66
67     my @frows = split(/\n/, $fline);
68     my $i = '';
69
70     for ($i = 0; $i < scalar(@frows); $i++) {
71         $frows[$i] = "$frows[$i]\n";
72
73         if ($frows[$i] =~ /$main::cfg_re/) {
74                         $main::vhcs2{$1} = $2;
75         }
76     }
77
78     return -1 if (setup_main_vars() != 0);
79
80     push_el(\@main::el, 'get_vhcs2conf()', 'Ending...');
81
82     return 0;
83 }
84
85 sub ask_vhcs2conf {
86         push_el(\@main::el, 'ask_vhcs2conf()', 'Starting...');
87
88         my ($rs, $rdata) = (undef, undef);
89
90         # Get path to vhcs2.conf
91         print STDOUT "\tPlease enter path to vhcs2.conf [/etc/vhcs2/vhcs2.conf]: ";
92
93         $rdata = readline(\*STDIN);
94         chop($rdata);
95
96         if (!defined($rdata) || $rdata eq '') {
97                 $rdata = '/etc/vhcs2/vhcs2.conf';
98         }
99
100         # set VHCS2 config
101         $main::vhcs2conf = $rdata;
102
103         # Get VHCS2 config
104         $rs = get_vhcs2conf();
105         return $rs if ($rs != 0);
106
107         $rs = setup_main_vars();
108         return $rs if ($rs != 0);
109
110         push_el(\@main::el, 'ask_vhcs2conf()', 'Ending...');
111
112         return 0;
113
114 }
115
116 sub welcome_note {
117         my ($rs, $rdata) = (undef, undef);
118
119         push_el(\@main::el, 'welcome_note()', 'Starting...');
120
121         my $welcome_message = <<MSG;
122
123 \tWelcome to ispCP '$main::cfg{'Version'}' Update Dialog.
124 \tThis program will update your VHCS / ispCP OMEGA system on your server.
125 \tPlease make sure you have a backup of your server data.
126
127 \tNOTE: During the migration process some or all services might require to be
128 \tshut down or restarted.
129
130 \tPlease select from which version you want to update:
131 \t(1) VHCS 2.4.7 or VHCS 2.4.7.1
132 \t(2) VHCS 2.4.8 RC1
133 \t(3) ispCP OMEGA 1.0.0 RC2 (incl. b and c)
134 \t(4) ispCP OMEGA 1.0.0 RC3
135 \t(5) ispCP OMEGA 1.0.0 RC4
136 \t(6) ispCP OMEGA 1.0.0 RC5
137 \t(0) abort
138 MSG
139
140         print STDOUT $welcome_message;
141         print STDOUT "\tYour selection: ";
142
143         $rdata = readline(\*STDIN);
144         chop($rdata);
145
146         while ($rdata < 0 || $rdata > 6) {
147                 print STDOUT "\tPlease select an item mentioned above: ";
148                 $rdata = readline(\*STDIN);
149                 chop($rdata);
150         }
151
152         $main::ua{'update'} = $rdata;
153
154         if (($main::ua{'update'} eq VHCS247) || ($main::ua{'update'} eq VHCS248)) {
155
156                 my $vhcs_update_msg = <<MSG;
157
158 \tMake sure you have installed ispCP OMEGA first as described in the INSTALL
159 \tdocument.
160
161 \tContinue?
162 \t(1) Yes
163 \t(0) No
164 MSG
165
166                 print STDOUT $vhcs_update_msg;
167                 print STDOUT "\tYour selection: ";
168
169                 $rdata = readline(\*STDIN);
170                 chop($rdata);
171
172                 while ($rdata < 0 || $rdata > 1) {
173                         print STDOUT "\tPlease select an item mentioned above: ";
174                         $rdata = readline(\*STDIN);
175                         chop($rdata);
176                 }
177
178                 # Set to 0 if not ready
179                 if ($rdata == 0) {
180                         $main::ua{'update'} = $rdata;
181                 }
182         }
183
184         push_el(\@main::el, 'welcome_note()', 'Ending...');
185
186         return 0;
187 }
188
189 sub stop_services {
190         push_el(\@main::el, 'stop_services()', 'Starting...');
191     my ($lock_file) = @_;
192
193     if (-e $lock_file) {
194         exit_werror("\tVHCS2's backups engine is currently running. Aborting...");
195     }
196
197     if ( -e "/etc/init.d/vhcs2_daemon" ) {
198         print STDOUT "\t";
199         sys_command("/etc/init.d/vhcs2_daemon stop");
200     }
201
202     if ( -e "/etc/init.d/ispcp_daemon" ) {
203         print STDOUT "\t";
204         sys_command("$main::cfg{'CMD_ISPCPD'} stop");
205     }
206
207     if ( -e "/etc/init.d/ispcp_network" ) {
208         print STDOUT "\t";
209         sys_command("$main::cfg{'CMD_ISPCPN'} stop");
210     }
211
212         push_el(\@main::el, 'stop_services()', 'Ending...');
213     return 0;
214 }
215
216 sub start_services {
217
218     sys_command("$main::cfg{'CMD_ISPCPD'} start");
219     sys_command("$main::cfg{'CMD_ISPCPN'} start");
220     sleep(2);
221
222     # Restart servers to make them use the newly generated config
223     sys_command("$main::cfg{'CMD_HTTPD'} restart");
224     sleep(2);
225     sys_command("$main::cfg{'CMD_MTA'} restart");
226     sleep(2);
227     if (-e "$main::cfg{'CMD_NAMED'}") {
228         sys_command("$main::cfg{'CMD_NAMED'} restart");
229         sleep(2);
230     }
231     sys_command("$main::cfg{'CMD_POP'} restart");
232     sleep(2);
233     if (-e "$main::cfg{'CMD_POP_SSL'}") {
234         sys_command("$main::cfg{'CMD_POP_SSL'} restart");
235         sleep(2);
236     }
237     sys_command("$main::cfg{'CMD_IMAP'} restart");
238     sleep(2);
239     if (-e "$main::cfg{'CMD_IMAP_SSL'}") {
240         sys_command("$main::cfg{'CMD_IMAP_SSL'} restart");
241         sleep(2);
242     }
243     sys_command("$main::cfg{'CMD_FTPD'} restart");
244     sleep(2);
245     sys_command("$main::cfg{'CMD_AUTHD'} restart");
246
247     return 0;
248 }
249
250 sub rebuild_configs {
251         push_el(\@main::el, 'rebuild_configs()', 'Starting...');
252
253         my $rs = undef;
254
255         # The folowing functions are specified in 'ispcp-setup'
256         $rs = setup_crontab();
257         return 1 if ($rs != 0);
258
259         $rs = setup_named();
260         return 2 if ($rs != 0);
261
262         $rs = setup_php_master_user_dirs();
263         return 3 if ($rs != 0);
264
265         $rs = setup_php();
266         return 4 if ($rs != 0);
267
268         $rs = setup_httpd();
269         return 5 if ($rs != 0);
270
271         $rs = setup_mta();
272         return 6 if ($rs != 0);
273
274         $rs = setup_po();
275         return 7 if ($rs != 0);
276
277         $rs = setup_ftpd();
278         return 8 if ($rs != 0);
279
280         $rs = setup_ispcpd();
281         return 9 if ($rs != 0);
282
283         push_el(\@main::el, 'rebuild_configs()', 'Ending...');
284         return 0;
285 }
286
287 sub migrate_vhcs2 {
288         push_el(\@main::el, 'migrate_vhcs2()', 'Starting...');
289
290         my ($rdata, $rs, $sql) = (undef, undef, undef);
291
292     print STDOUT "\tDropping empty ispcp table...";
293
294     ($rs, $rdata) = doSQL("DROP DATABASE IF EXISTS `ispcp`;");
295
296     if ($rs != 0) {
297         print STDOUT "failed!\n";
298         exit_werror($rdata, $rs);
299     }
300
301     print STDOUT "done\n";
302
303     print STDOUT "\tCreating new database...";
304
305         # Escape " and '
306         $main::db_pwd =~ s/([\'\"])/\\$1/g;
307     if (sys_command("mysqladmin -u\"$main::db_user\" -p\"$main::db_pwd\" create ispcp ") != 0) {
308         print STDOUT "failed!\n";
309         exit_werror();
310     }
311
312     print STDOUT "done\n";
313
314     print STDOUT "\tCopying database...";
315
316     if (sys_command("$main::cfg{'CMD_MYSQLDUMP'} --opt --host=\"$main::db_host\" -u\"$main::db_user\" -p\"$main::db_pwd\" $main::vhcs2{'DATABASE_NAME'} | $main::cfg{'CMD_MYSQL'} --host=\"$main::db_host\" -u\"$main::db_user\" -p\"$main::db_pwd\" $main::db_name") != 0) {
317         print STDOUT "failed!\n";
318         exit_werror();
319     }
320
321     print STDOUT "done\n";
322
323     print STDOUT "\tUpgrading database structure...";
324
325         # Update from VHCS 2.4.7
326         if ($main::ua{'update'} eq VHCS247) {
327                 ($rs, $rdata) = get_file("$main::cfg{'ROOT_DIR'}/engine/setup/vhcs2.4.7-ispcp.sql");
328                 return $rs if ($rs != 0);
329         }
330         # Update from VHCS 2.4.8
331         elsif ($main::ua{'update'} eq VHCS248) {
332                 ($rs, $rdata) = get_file("$main::cfg{'ROOT_DIR'}/engine/setup/vhcs2.4.8-ispcp.sql");
333                 return $rs if ($rs != 0);
334         }
335
336         $rdata =~ s/\{DATABASE\}/$main::db_name/gi;
337         $rs = store_file("/tmp/db.sql", $rdata, $main::cfg{'ROOT_USER'}, $main::cfg{'ROOT_GROUP'}, 0644);
338         return $rs if ($rs != 0);
339
340         $rs = sys_command("$main::cfg{'CMD_MYSQL'} --host=\"$main::db_host\" -u\"$main::db_user\" -p\"$main::db_pwd\" < /tmp/db.sql");
341         if ($rs != 0) {
342         print STDOUT "failed!\n";
343                 exit_werror("SQL Update failed.");
344         }
345
346         # Delete vhcs2 Database
347         ($rs, $rdata) = doSQL("DROP DATABASE IF EXISTS `vhcs2`;");
348     if ($rs != 0) {
349         print STDOUT "failed!\n";
350         exit_werror($rdata, $rs);
351     }
352
353     print STDOUT "\tdone\n";
354
355         push_el(\@main::el, 'migrate_vhcs2()', 'Ending...');
356         return 0;
357 }
358
359 sub remove_vhcs2 {
360         my ($rs, $cmd, $rdata) = (undef, undef, undef);
361
362         push_el(\@main::el, 'remove_vhcs2()', 'Starting...');
363
364         print STDOUT "\tNow you can remove VHCS2. Do you want to remove VHCS2 auomaticly? (yes|no) [yes]: ";
365         $rdata = readline(\*STDIN);
366         chop($rdata);
367
368         if (!defined($rdata) || $rdata eq '') {
369                 $rdata = 'yes';
370         }
371
372         # Remove VHCS2 files
373         if ($rdata eq 'yes') {
374                 # Get vhcs2.conf
375                 $rs = get_conf($main::vhcs2conf);
376                 return $rs if ($rs != 0);
377
378                 # Remove VHCS2 Web/Engine folder
379                 print STDOUT "\tRemoving $main::vhcs2{'ROOT_DIR'}...";
380                 del_dir($main::vhcs2{'ROOT_DIR'});
381                 print STDOUT "done\n";
382
383                 # Remove VHCS2 Config folder
384                 print STDOUT "\tRemoving $main::vhcs2{'CONF_DIR'}...";
385                 del_dir($main::vhcs2{'CONF_DIR'});
386                 print STDOUT "done\n";
387
388                 # Remove VHCS2 Log folder
389                 print STDOUT "\tRemoving $main::vhcs2{'LOG_DIR'}...";
390                 del_dir($main::vhcs2{'LOG_DIR'});
391                 print STDOUT "done\n";
392
393                 # Remove VHCS2 Postfix folders
394                 print STDOUT "\tRemoving $main::vhcs2{'MTA_VIRTUAL_CONF_DIR'}...";
395                 del_dir($main::vhcs2{'MTA_VIRTUAL_CONF_DIR'});
396                 print STDOUT "done\n";
397
398                 # Remove VHCS2 logrotation
399                 print STDOUT "\tRemoving logrotation...";
400                 del_file("/etc/logrotate.d/vhcs2");
401                 print STDOUT "done\n";
402
403                 # Remove Bind files
404                 print STDOUT "\tRemoving old bind files...";
405                 del_file("/etc/bind/vhcs.conf");
406
407                 # Remove old Include if exists
408                 ($rs, $rdata) = get_file("/etc/bind/named.conf");
409                 if ($rs != 0) {
410                 print STDOUT "failed!\n";
411                 exit_werror("Could not open /etc/bind/named.conf");
412         }
413
414                 $rdata =~ s/include "\/etc\/bind\/vhcs.conf";//gi;
415                 $rs = store_file("/etc/bind/named.conf", $rdata, $main::cfg{'ROOT_USER'}, $main::cfg{'ROOT_GROUP'}, 0644);
416                 if ($rs != 0) {
417                 print STDOUT "failed!\n";
418                 exit_werror("Could not store /etc/bind/named.conf");
419         }
420                 print STDOUT "done\n";
421
422                 # Remove VHCS2 crontab
423                 print STDOUT "\tDo you really want to remove crontab? All custom entries will be deleted. (yes|no) [no]: ";
424                 $rdata = readline(\*STDIN);
425                 chop($rdata);
426
427                 if (!defined($rdata) || $rdata eq '') {
428                         $rdata = 'no';
429                 }
430                 if ($rdata eq 'yes') {
431                         print STDOUT "\tRemoving crontab...";
432                         sys_command("crontab -r");
433                         print STDOUT "done\n";
434                 }
435
436                 # Remove VHCS2 apache files
437                 print STDOUT "\tRemoving apache vhost file...";
438                 if ( -e "/usr/sbin/a2dissite" ) {
439                         $rs = sys_command("/usr/sbin/a2dissite vhcs2.conf");
440
441                         if ($rs == 0) {
442                                 $rs = sys_command("unlink $main::vhcs2{'APACHE_CONF_FILE'}");
443                         if ($rs != 0) {
444                                 print STDOUT "failed!\n";
445                                 exit_werror();
446                         }
447                     }
448                 }
449                 else {
450                     $rs = sys_command("unlink /etc/apache2/sites-enabled/vhcs2.conf");
451                     if ($rs != 0) {
452                         print STDOUT "failed!\n";
453                         exit_werror();
454                     }
455                 }
456                 print STDOUT "done\n";
457
458                 # Restart apache
459                 $cmd = $main::cfg{'CMD_HTTPD'};
460                 sys_command_rs("$cmd stop");
461                 sleep(5);
462             sys_command_rs("$cmd start");
463             sleep(5);
464
465                 if (-e "/usr/sbin/vhcs2-mkdirs.pl") {
466                         print STDOUT "\tRemoving vhcs2-mkdirs.pl";
467                         del_file("/usr/sbin/vhcs2-mkdirs.pl");
468                 }
469
470                 # Remove VHCS2 Daemons
471                 print STDOUT "\tRemoving Daemons";
472                 if ( -x "/usr/sbin/update-rc.d" ) {
473                         sys_command_rs("/usr/sbin/update-rc.d ispcp_daemon remove &> /tmp/ispcp-setup-services.log");
474                         sys_command_rs("/usr/sbin/update-rc.d ispcp_network remove &> /tmp/ispcp-setup-services.log");
475                 }
476                 elsif ( -x "/usr/lib/lsb/remove_initd" ) { #LSB 3.1 Core section 20.4 compatibility
477                         sys_command_rs("/usr/lib/lsb/remove_initd $main::cfg{'CMD_ISPCPD'} &> /tmp/ispcp-setup-services.log");
478                         sys_command_rs("/usr/lib/lsb/remove_initd $main::cfg{'CMD_ISPCPN'} &> /tmp/ispcp-setup-services.log");
479         }
480
481         if ( -e "/etc/init.d/vhcs2_daemon" ) {
482                 del_file($main::vhcs2{'CMD_VHCS2D'});
483                         del_file($main::vhcs2{'CMD_VHCS2N'});
484         }
485         }
486
487         push_el(\@main::el, 'remove_vhcs2()', 'Ending...');
488         return 0;
489 }
490
491 sub update_pma {
492         push_el(\@main::el, 'update_pma()', 'Starting...');
493
494         my ($rs, $cfg, $cfg_tpl, $sql, $rdata) = (undef, undef, undef, undef, undef);
495         @main::db_connect = undef;
496         my $hostname = $main::cfg{'DATABASE_HOST'};
497
498         #
499         # PMA user for SQL
500         #
501
502         $rs = ask_db_pma_user();
503         return $rs if ($rs != 0);
504
505         do {
506                 $rs = ask_db_pma_password();
507         } while ($rs == 1);
508
509         @main::db_connect = (
510                                                         "DBI:mysql:mysql:$main::db_host",
511                                                         $main::db_user,
512                                                         $main::db_pwd
513                                                 );
514
515         my $pma_sql_user = $main::ua{'db_pma_user'};
516         my $pma_sql_password = $main::ua{'db_pma_password'};
517
518         $sql = "DELETE FROM tables_priv WHERE Host = '$main::db_host' AND Db = '$main::cfg{'DATABASE_NAME'}' and User = '$pma_sql_user'";
519
520         ($rs, $rdata) = doSQL($sql);
521         return $rs if ($rs != 0);
522
523         $sql = " delete from user where Host = '$hostname' and User = '$pma_sql_user'";
524
525         ($rs, $rdata) = doSQL($sql);
526         return $rs if ($rs != 0);
527
528         $sql = "flush privileges";
529
530         ($rs, $rdata) = doSQL($sql);
531         return $rs if ($rs != 0);
532
533         $sql = "GRANT USAGE ON mysql.* TO \'$pma_sql_user\'\@\'$hostname\' IDENTIFIED BY \'$pma_sql_password\';";
534
535         ($rs, $rdata) = doSQL($sql);
536         return $rs if ($rs != 0);
537
538         $sql = "GRANT SELECT (Host, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv, File_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv, Execute_priv, Repl_slave_priv, Repl_client_priv) ON mysql.user TO \'$pma_sql_user\'\@\'$hostname\';";
539
540         ($rs, $rdata) = doSQL($sql);
541         return $rs if ($rs != 0);
542
543         $sql = "GRANT SELECT ON mysql.db TO \'$pma_sql_user\'\@\'$hostname\';";
544
545         ($rs, $rdata) = doSQL($sql);
546         return $rs if ($rs != 0);
547
548         $sql = "GRANT SELECT ON mysql.host TO \'$pma_sql_user\'\@\'$hostname\';";
549
550         ($rs, $rdata) = doSQL($sql);
551         return $rs if ($rs != 0);
552
553         $sql = "GRANT SELECT (Host, Db, User, Table_name, Table_priv, Column_priv) ON mysql.tables_priv TO \'$pma_sql_user\'\@\'$hostname\';";
554
555         ($rs, $rdata) = doSQL($sql);
556         return $rs if ($rs != 0);
557
558         #
559         # Insert pma user and password to config file
560         # together with some other information
561         #
562
563         my $cfg_dir = "$main::cfg{'GUI_ROOT_DIR'}/tools/pma/";
564         my $tmp_dir = "$main::cfg{'GUI_ROOT_DIR'}/phptmp";
565
566         print STDOUT "\tGeneration Blowfish key\n";
567         my $blowfish = gen_sys_rand_num(31);
568         $blowfish =~ s/'/\\'/gi;
569
570         ($rs, $cfg_tpl) = get_tpl($cfg_dir, 'config.inc.php');
571         return $rs if ($rs != 0);
572
573         my %tag_hash = (
574                                         '{PMA_USER}' => $pma_sql_user,
575                                         '{PMA_PASS}' => $pma_sql_password,
576                                         '{HOSTNAME}' => $main::cfg{'DATABASE_HOST'},
577                                         '{TMP_DIR}'  => $tmp_dir,
578                                         '{BLOWFISH}' => $blowfish
579                                    );
580
581         ($rs, $cfg) = prep_tpl(\%tag_hash, $cfg_tpl);
582         return $rs if ($rs != 0);
583
584         $rs = store_file("$cfg_dir/config.inc.php", $cfg, "$main::cfg{'APACHE_SUEXEC_USER_PREF'}$main::cfg{'APACHE_SUEXEC_MIN_UID'}", "$main::cfg{'APACHE_GROUP'}", 0440);
585         return $rs if ($rs != 0);
586
587         push_el(\@main::el, 'update_pma()', 'Ending...');
588         return 0;
589 }
590
591 sub update_httpd {
592         push_el(\@main::el, 'update_httpd()', 'Starting...');
593
594         my ($rs, $rdata) = (undef, undef);
595         my $cfg_dir = "$main::cfg{'CONF_DIR'}/apache";
596         my $bk_dir = "$cfg_dir/backup";
597         my $wrk_dir = "$cfg_dir/working";
598         my ($cfg_tpl, $cfg, $cmd) = (undef, undef, undef);
599         my %tag_hash = ();
600
601         if ($main::cfg{'CMD_HTTPD'} ne 'no') {
602                 sys_command_rs("$main::cfg{'CMD_HTTPD'} stop &> /tmp/ispcp-setup-services.log");
603         }
604
605         #
606         # Apache Master file
607         #
608
609         $cmd = "$main::cfg{'CMD_CP'} -p $cfg_dir/00_master.conf $bk_dir/00_master.ispcp-rc4.conf";
610         $rs = sys_command($cmd);
611         return $rs if ($rs != 0);
612
613         ($rs, $cfg_tpl) = get_file("$cfg_dir/00_master.conf");
614         return $rs if ($rs != 0);
615
616         %tag_hash = (
617                                         '{BASE_SERVER_IP}'                      => $main::cfg{'BASE_SERVER_IP'},
618                                         '{BASE_SERVER_VHOST}'           => $main::cfg{'BASE_SERVER_VHOST'},
619                                         '{DEFAULT_ADMIN_ADDRESS}'       => $main::cfg{'DEFAULT_ADMIN_ADDRESS'},
620                                         '{ROOT_DIR}'                            => $main::cfg{'ROOT_DIR'},
621                                         '{APACHE_WWW_DIR}'              => $main::cfg{'APACHE_WWW_DIR'},
622                                         '{APACHE_USERS_LOG_DIR}'        => $main::cfg{'APACHE_USERS_LOG_DIR'},
623                                         '{APACHE_LOG_DIR}'                      => $main::cfg{'APACHE_LOG_DIR'},
624                                         '{PHP_STARTER_DIR}'             => $main::cfg{'PHP_STARTER_DIR'},
625                                         '{PHP_VERSION}'                         => $main::cfg{'PHP_VERSION'},
626                                         '{WWW_DIR}'                                     => $main::cfg{'ROOT_DIR'},
627                                         '{DMN_NAME}'                            => 'gui',
628                                         '{CONF_DIR}'                            => $main::cfg{'CONF_DIR'},
629                                         '{MR_LOCK_FILE}'                        => $main::cfg{'MR_LOCK_FILE'},
630                                         '{RKHUNTER_LOG}'                        => $main::cfg{'RKHUNTER_LOG'},
631                                         '{CHKROOTKIT_LOG}'                      => $main::cfg{'CHKROOTKIT_LOG'},
632                                         '{PEAR_DIR}'                            => $main::cfg{'PEAR_DIR'},
633                                         '{OTHER_ROOTKIT_LOG}'           => $main::cfg{'OTHER_ROOTKIT_LOG'},
634                                         '{APACHE_SUEXEC_USER_PREF}'     => $main::cfg{'APACHE_SUEXEC_USER_PREF'},
635                                         '{APACHE_SUEXEC_MIN_UID}'       => $main::cfg{'APACHE_SUEXEC_MIN_UID'},
636                                         '{APACHE_SUEXEC_MIN_GID}'       => $main::cfg{'APACHE_SUEXEC_MIN_GID'}
637                                         );
638
639         ($rs, $cfg) = prep_tpl(\%tag_hash, $cfg_tpl);
640         return $rs if ($rs != 0);
641
642         $rs = store_file("$main::cfg{'APACHE_SITES_DIR'}/00_master.conf", $cfg, $main::cfg{'ROOT_USER'}, $main::cfg{'ROOT_GROUP'}, 0644);
643         return $rs if ($rs != 0);
644
645         $cmd = "$main::cfg{'CMD_CP'} -p $cfg_dir/01_awstats.conf $bk_dir/01_awstats.ispcp-rc4.conf";
646         $rs = sys_command($cmd);
647         return $rs if ($rs != 0);
648
649         ($rs, $cfg_tpl) = get_file("$cfg_dir/01_awstats.conf");
650         return $rs if ($rs != 0);
651
652         %tag_hash = (
653                                         '{AWSTATS_ENGINE_DIR}'          => $main::cfg{'AWSTATS_ENGINE_DIR'},
654                                         '{AWSTATS_WEB_DIR}'             => $main::cfg{'AWSTATS_WEB_DIR'}
655                                         );
656
657         ($rs, $cfg) = prep_tpl(\%tag_hash, $cfg_tpl);
658         return $rs if ($rs != 0);
659
660         $rs = store_file("$main::cfg{'APACHE_SITES_DIR'}/01_awstats.conf", $cfg, $main::cfg{'ROOT_USER'}, $main::cfg{'ROOT_GROUP'}, 0644);
661         return $rs if ($rs != 0);
662
663         $rs = setfmode("$main::cfg{'APACHE_SITES_DIR'}/01_awstats.conf", $main::cfg{'ROOT_USER'}, $main::cfg{'ROOT_GROUP'}, 0644);
664         return $rs if ($rs != 0);
665
666         #
667         # Configure the fastcgi_ispcp.conf
668         #
669
670         $cfg_dir = "$main::cfg{'CONF_DIR'}/apache";
671         $bk_dir = "$cfg_dir/backup";
672
673         ($rs, $cfg_tpl) = get_tpl("$cfg_dir/working", 'fastcgi_ispcp.conf');
674         return $rs if ($rs != 0);
675
676         %tag_hash = (
677                                         '{APACHE_SUEXEC_MIN_UID}' => $main::cfg{'APACHE_SUEXEC_MIN_UID'},
678                                         '{APACHE_SUEXEC_MIN_GID}' => $main::cfg{'APACHE_SUEXEC_MIN_GID'},
679                                         '{APACHE_SUEXEC_USER_PREF}' => $main::cfg{'APACHE_SUEXEC_USER_PREF'},
680                                         '{PHP_STARTER_DIR}' => $main::cfg{'PHP_STARTER_DIR'},
681                                         '{PHP_VERSION}' => $main::cfg{'PHP_VERSION'}
682                                         );
683
684         ($rs, $cfg) = prep_tpl(\%tag_hash, $cfg_tpl);
685         return $rs if ($rs != 0);
686
687         $cmd = "$main::cfg{'CMD_CP'} -p $main::cfg{'APACHE_MODS_DIR'}/fastcgi_ispcp.conf $bk_dir/fastcgi_ispcp.ispcp-rc4.conf";
688         $rs = sys_command($cmd);
689         return $rs if ($rs != 0);
690
691         $rs = store_file("$bk_dir/fastcgi_ispcp.conf.ispcp", $cfg, $main::cfg{'ROOT_USER'}, $main::cfg{'ROOT_GROUP'}, 0644);
692         return $rs if ($rs != 0);
693
694         $cmd = "$main::cfg{'CMD_CP'} -p $bk_dir/fastcgi_ispcp.conf.ispcp $main::cfg{'APACHE_MODS_DIR'}/fastcgi_ispcp.conf";
695         $rs = sys_command($cmd);
696         return $rs if ($rs != 0);
697
698         if ( -e "$main::cfg{'APACHE_MODS_DIR'}/fastcgi.load" && ! -e "$main::cfg{'APACHE_MODS_DIR'}/fastcgi_ispcp.load") {
699             $cmd = "$main::cfg{'CMD_CP'} -p $main::cfg{'APACHE_MODS_DIR'}/fastcgi.load $main::cfg{'APACHE_MODS_DIR'}/fastcgi_ispcp.rc4.load";
700             $rs = sys_command($cmd);
701             return $rs if ($rs != 0);
702
703             ($rs, $rdata) = get_file("$main::cfg{'APACHE_MODS_DIR'}/fastcgi_ispcp.load");
704             return $rs if ($rs != 0);
705
706             $rdata = "<IfModule !mod_fastcgi.c>\n" . $rdata . "</IfModule>\n";
707             $rs = save_file("$main::cfg{'APACHE_MODS_DIR'}/fastcgi_ispcp.load", $rdata);
708             return $rs if ($rs != 0);
709         }
710
711         if ($main::cfg{'CMD_HTTPD'} ne 'no') {
712                 sys_command_rs("$main::cfg{'CMD_HTTPD'} start &> /tmp/ispcp-setup-services.log");
713         }
714
715         push_el(\@main::el, 'update_httpd()', 'Ending...');
716         return 0;
717 }
718
719 sub search_and_replace {
720     my $dir = shift;
721     my ($cmd, $rs) = (undef, undef);
722     my $sed = $main::cfg{'CMD_SED'};
723
724     if (opendir(DIRH, "$dir")) {
725         foreach (readdir(DIRH)) {
726             # ignore . and .. :
727             next if ($_ eq "." || $_ eq "..");
728             if (/$ARGV[0]/io) {
729                 $cmd = "$sed -i -e 's~/phptmp\"~/phptmp/\"~' php.ini";
730                                 $rs = sys_command($cmd);
731                                 #return $rs if ($rs != 0);
732             }
733             search_and_replace("$dir/$_") if (-d "$dir/$_" && ! -l "$dir/$_");
734         }
735         closedir DIRH;
736     }
737 }
738
739 sub update_conf {
740         push_el(\@main::el, 'update_conf()', 'Starting...');
741
742         my ($oldconf, $newconf) = ($_[0], $_[1]);
743
744         if (!defined($oldconf) || !defined($newconf)) {
745                 push_el(\@main::el, 'update_conf()', 'ERROR: Undefined input data...');
746                 return 1;
747         }
748
749     my ($rs, $fline) = get_file($oldconf);
750     return 1 if ($rs != 0);
751     $rs = get_conf($newconf);
752     return 1 if ($rs != 0);
753
754     my @frows = split(/\n/, $fline);
755
756     my $i = undef;
757
758     for ($i = 0; $i < scalar(@frows); $i++) {
759             $frows[$i] = "$frows[$i]\n";
760             if (($frows[$i] =~ /$main::cfg_re/)) {
761                     # Lines should not match variables that have to be changed
762                     if ($1 ne 'BuildDate' && $1 ne 'Version' && $1 ne 'CodeName') {
763                             # now overwrite new conf values with old if exists
764                             if (defined($main::cfg{$1})) {
765                                     $rs = set_conf_val($1, $2);
766                                     return $rs if ($rs != 0);
767                             }
768                     }
769             }
770     }
771
772         $rs = store_conf($newconf);
773     return 1 if ($rs != 0);
774
775         push_el(\@main::el, 'update_conf()', 'Ending...');
776         return 0;
777 }
778
779 sub patch_ispcp_rc2 {
780         push_el(\@main::el, 'patch_ispcp_rc2()', 'Starting...');
781
782         my ($rs, $rdata) = (undef, undef);
783
784         print STDOUT "\tUpgrading system values ...";
785
786         # AWStats questions
787         do {
788                 $rs = ask_awstats_on();
789         } while ($rs == 1);
790
791         if ($main::ua{'awstats_on'} eq 'yes') {
792                 do {
793                         $rs = ask_awstats_dyn();
794                 } while ($rs == 1);
795         } else {
796                 # Just a dummy to prevent warnings
797                 $main::ua{'awstats_dyn'} = 0;
798         }
799
800         if ($main::cfg{'MYSQL_PREFIX'} eq 'no') {
801                 do {
802                         $rs = ask_mysql_prefix();
803                 } while ($rs == 1);
804         }
805         else {
806                 $main::ua{'mysql_prefix'} = $main::cfg{'MYSQL_PREFIX'};
807                 $main::ua{'mysql_prefix_type'} = $main::cfg{'MYSQL_PREFIX_TYPE'};
808         }
809
810         # update ispcp.conf
811         my $cfg_file = $main::cfg_file;
812         my $old_cfg_file = $main::ua{'old_cfg_file'};
813         $rs = update_conf($old_cfg_file, $cfg_file);
814         if ($rs != 0) {
815                 exit_werror("failed to get $cfg_file or $old_cfg_file");
816         }
817
818         # add new variables to new ispcp.conf
819         $rs = set_conf_val('AWSTATS_ACTIVE', $main::ua{'awstats_on'});
820         $rs = set_conf_val('AWSTATS_MODE', $main::ua{'awstats_dyn'});
821
822         # save into /etc/ispcp/ispcp.conf
823         $rs = store_conf();
824         if ($rs != 0) {
825                 exit_werror("Storing new ispcp.conf failed!");
826         }
827         print STDOUT "done\n";
828
829         # database upgrade
830     print STDOUT "\tUpgrading database structure...";
831
832         ($rs, $rdata) = get_file("$main::cfg{'ROOT_DIR'}/engine/setup/ispcp1.0.0rc2-ispcp.sql");
833         return $rs if ($rs != 0);
834
835         $rdata =~ s/\{DATABASE\}/$main::db_name/gi;
836         $rs = store_file("/tmp/db.sql", $rdata, $main::cfg{'ROOT_USER'}, $main::cfg{'ROOT_GROUP'}, 0644);
837         return $rs if ($rs != 0);
838
839         $main::db_pwd =~ s/([\'\"])/\\$1/g;
840         $rs = sys_command("$main::cfg{'CMD_MYSQL'} --host=\"$main::db_host\" -u\"$main::db_user\" -p\"$main::db_pwd\" < /tmp/db.sql");
841         if ($rs != 0) {
842                 exit_werror("SQL Update failed.");
843         }
844
845     print STDOUT "done\n";
846
847     # Rebuild system configs
848     print STDOUT "\tRebuilding system configurations...";
849
850         $rs = rebuild_configs();
851
852         if ($rs != 0) {
853                 exit_werror("Config Rebuild failed.");
854         }
855
856         print STDOUT "done\n";
857
858         # Update PMA's config.inc.php
859         print STDOUT "\tUpdating PMA's config.inc.php...";
860
861         $rs = update_pma();
862
863         if ($rs != 0) {
864                 exit_werror("Updating PMA's config.inc.php failed.");
865         }
866
867         print STDOUT "\tdone\n";
868
869         push_el(\@main::el, 'patch_ispcp_rc2()', 'Ending...');
870         return 0;
871 }
872
873 sub patch_ispcp_rc3 {
874         push_el(\@main::el, 'patch_ispcp_rc3()', 'Ending...');
875
876         my ($rs, $rdata) = (undef, undef);
877
878         # database upgrade
879     print STDOUT "\tUpgrading database structure...";
880
881         ($rs, $rdata) = get_file("$main::cfg{'ROOT_DIR'}/engine/setup/ispcp1.0.0rc3-ispcp.sql");
882         return $rs if ($rs != 0);
883
884         $rdata =~ s/\{DATABASE\}/$main::db_name/gi;
885         $rs = store_file("/tmp/db.sql", $rdata, $main::cfg{'ROOT_USER'}, $main::cfg{'ROOT_GROUP'}, 0644);
886         return $rs if ($rs != 0);
887
888         $main::db_pwd =~ s/([\'\"])/\\$1/g;
889         $rs = sys_command("$main::cfg{'CMD_MYSQL'} --host=\"$main::db_host\" -u\"$main::db_user\" -p\"$main::db_pwd\" < /tmp/db.sql");
890         if ($rs != 0) {
891         print STDOUT "failed!\n";
892                 exit_werror("SQL Update failed.");
893         }
894
895     print STDOUT "done\n";
896
897     # Rebuild system configs:
898     print STDOUT "\tRebuilding system configurations...";
899
900         $rs = rebuild_configs();
901
902         if ($rs != 0) {
903                 exit_werror("Config Rebuild failed.");
904         }
905
906         print STDOUT "done\n";
907
908         push_el(\@main::el, 'patch_ispcp_rc3()', 'Ending...');
909         return 0;
910 }
911
912 sub patch_ispcp_rc4 {
913         push_el(\@main::el, 'patch_ispcp_rc4()', 'Starting...');
914
915         my $rs = setup_mta();
916         return 2 if ($rs != 0);
917
918         $rs = setup_ftpd();
919         return 3 if ($rs != 0);
920
921         # FastCGI-Security
922         print STDOUT "\tYou can ignore this error: /bin/sed: can't read php.ini: No such file or directory\n";
923         search_and_replace("$main::cfg{'PHP_STARTER_DIR'}");
924
925         # Update Apache
926         $rs = update_httpd();
927         return 4 if ($rs != 0);
928
929         push_el(\@main::el, 'patch_ispcp_rc4()', 'Ending...');
930         return 0;
931 }
932
933 sub patch_ispcp_rc5 {
934         push_el(\@main::el, 'patch_ispcp_rc5()', 'Starting...');
935
936         if ($main::cfg{'ISPCP_SUPPORT_SYSTEM_PATH'} eq "support_system.php") {
937                 my $rs = set_conf_val('ISPCP_SUPPORT_SYSTEM_PATH', "ticket_system.php");
938                 return $rs if ($rs != 0);
939
940                 $rs = store_conf();
941                 return $rs if ($rs != 0);
942         }
943
944         push_el(\@main::el, 'patch_ispcp_rc5()', 'Ending...');
945         return 0;
946 }
947
948 sub prepare_update {
949         my ($rs, $rdata) = (undef, undef);
950
951         push_el(\@main::el, 'user_dialog()', 'Starting...');
952
953         $rs = welcome_note();
954
955         return $rs if ($rs != 0);
956
957         # Abort
958         if ($main::ua{'update'} eq ABORT) {
959                 exit_werror("Script was aborted by user.");
960         }
961         # VHCS update
962         elsif (($main::ua{'update'} eq VHCS247) || ($main::ua{'update'} eq VHCS248)) {
963
964                 # look up vhcs2.conf
965                 $rs = ask_vhcs2conf();
966
967                 if ($rs != 0) {
968                         my $el_data = pop_el(\@main::el);
969                         my ($sub_name, $msg) = split(/$main::el_sep/, $el_data);
970
971                         print STDERR "$msg\n";
972
973                         exit 1;
974                 }
975                 stop_services("/tmp/vhcs2-backup-all.lock");
976                 $rs = migrate_vhcs2();
977                 if ($rs == 0) {
978                         $rs = remove_vhcs2();
979                 }
980
981                 if ($rs != 0) {
982                 print STDOUT "\tUpdate failed!\n";
983                         exit_werror("ispCP Update failed.");
984                 }
985         }
986         # ispCP 1.0.0 RC2/3/4/5 Update
987         elsif ($main::ua{'update'} >= RC2) {
988                 stop_services("/tmp/vhcs2-backup-all.lock");
989
990                 # get ispcp.old.conf
991                 my $cfg_file = '/etc/ispcp/ispcp.old.conf';
992                 $rs = get_conf($cfg_file);
993                 if ($rs != 0) {
994                         do {
995                                 print STDOUT "\tPlease enter path to ispcp.old.conf [/etc/ispcp/ispcp.old.conf]: ";
996
997                                 $rdata = readline(\*STDIN);
998                                 chop($rdata);
999
1000                                 $cfg_file = $rdata;
1001                                 $rs = get_conf($cfg_file);
1002                         } while ($rs == 0);
1003                 }
1004                 $main::ua{'old_cfg_file'} = $cfg_file;
1005
1006                 if ($main::ua{'update'} >= RC3) {
1007                         # update ispcp.conf
1008                         my $cfg_file = $main::cfg_file;
1009                         if (defined($main::ua{'old_cfg_file'})) {
1010                                 print STDOUT "\tUpgrading system values...";
1011
1012                                 $rs = update_conf($main::ua{'old_cfg_file'}, $cfg_file);
1013                                 if ($rs != 0) {
1014                                         exit_werror("failed to get $cfg_file or $main::ua{'old_cfg_file'}");
1015                                 }
1016
1017                                 # save into /etc/ispcp/ispcp.conf
1018                                 $rs = store_conf();
1019                                 if ($rs != 0) {
1020                                         exit_werror("Storing new ispcp.conf failed!");
1021                                 }
1022                                 print STDOUT "done\n";
1023                     &