home *** CD-ROM | disk | FTP | other *** search
/ ftp.ee.pdx.edu / 2014.02.ftp.ee.pdx.edu.tar / ftp.ee.pdx.edu / oss / cvs-2004 / bahasa / utilities / config_app.pl next >
Perl Script  |  2003-08-12  |  24KB  |  1,099 lines

  1. #!/usr/bin/perl -w
  2. use strict;
  3. use Cwd;
  4. use File::Copy;
  5.  
  6. show_introduction();
  7.  
  8. while(1) {
  9.  
  10.     my ($response) = 
  11.     promptyn("Would you like to continue?");
  12.  
  13.     if (!$response) {
  14.  
  15.         print "\nInstallation script terminated!\n\n";
  16.  
  17.         exit;
  18.     }
  19.  
  20.     last;
  21. }
  22.  
  23. my (%DICTIONARY_CFG) = ();
  24.  
  25. $DICTIONARY_CFG{"INSTALLATION_DIRECTORY"} = 
  26. prompt_installation_directory();
  27.  
  28. my ($SLASH) = "/";
  29.  
  30. $SLASH = "\\"
  31. if ($DICTIONARY_CFG{"INSTALLATION_DIRECTORY"} =~ /\\/);
  32.  
  33. #These are all the required directories and 
  34. #files associated with this project.
  35. #They are followed by default permissions.
  36. #Change these permissions to best suite your needs 
  37. #Add your own files and directories if applicable
  38. #Changing the paths to these files is likely cause
  39. #the project to fail
  40. my (%manifest) = (
  41. "backups" => 0703,
  42. "docs" => 0700,
  43. "mysql" => 0703,
  44. "php" => 0701,
  45. "utilities" => 0700,
  46. "web" => 0700,
  47. "mysql${SLASH}administration.sql" => 0606,
  48. "mysql${SLASH}administrators.sql" => 0606,
  49. "mysql${SLASH}alphabet.sql" => 0606,
  50. "mysql${SLASH}create.sql" => 0604,
  51. "mysql${SLASH}destroy.sql" => 0604,
  52. "mysql${SLASH}dictionary.sql" => 0606,
  53. "mysql${SLASH}hits.sql" => 0606,
  54. "mysql${SLASH}misses.sql" => 0606,
  55. "mysql${SLASH}parts_of_speech.sql" => 0606,
  56. "mysql${SLASH}pronunciation.sql" => 0606,
  57. "mysql${SLASH}requests.sql" => 0606,
  58. "mysql${SLASH}searches.sql" => 0606,
  59. "mysql${SLASH}tasks.sql" => 0606,
  60. "php${SLASH}Dictionary.php" => 0604,
  61. "php${SLASH}Indonesia.php" => 0604,
  62. "php${SLASH}Statistics.php" => 0604,
  63. "php${SLASH}Web.php" => 0604,
  64. "utilities${SLASH}config_app.pl" => 0700,
  65. "utilities${SLASH}config_db.pl" => 0700,
  66. "web${SLASH}admin.php" => 0604, 
  67. "web${SLASH}admins.php" => 0604, 
  68. "web${SLASH}backup.php" => 0604, 
  69. "web${SLASH}cpwd.php" => 0604, 
  70. "web${SLASH}delete.php" => 0604, 
  71. "web${SLASH}dictionary.php" => 0604, 
  72. "web${SLASH}download.php" => 0604, 
  73. "web${SLASH}email.php" => 0604, 
  74. "web${SLASH}insert.php" => 0604, 
  75. "web${SLASH}login.php" => 0604, 
  76. "web${SLASH}logout.php" => 0604, 
  77. "web${SLASH}misses.php" => 0604, 
  78. "web${SLASH}offline.php" => 0604, 
  79. "web${SLASH}online.php" => 0604, 
  80. "web${SLASH}pos.php" => 0604, 
  81. "web${SLASH}reference.php" => 0604, 
  82. "web${SLASH}request.php" => 0604, 
  83. "web${SLASH}requests.php" => 0604, 
  84. "web${SLASH}search.php" => 0604, 
  85. "web${SLASH}sql.php" => 0604, 
  86. "web${SLASH}statistics.php" => 0604,
  87. "web${SLASH}update.php" => 0604,
  88. "web${SLASH}upload.php" => 0604
  89. );
  90.  
  91. my (%class_files) = (
  92.  
  93. "php${SLASH}Indonesia.php" =>
  94. "php${SLASH}Dictionary.php",
  95.  
  96. "php${SLASH}Statistics.php" =>
  97. "php${SLASH}Dictionary.php");
  98.  
  99. my (%web_files) = (
  100.  
  101. "web${SLASH}admin.php" => 
  102. "php${SLASH}Indonesia.php",
  103.  
  104. "web${SLASH}admins.php" => 
  105. "php${SLASH}Indonesia.php",
  106.  
  107. "web${SLASH}backup.php" => 
  108. "php${SLASH}Indonesia.php",
  109.  
  110. "web${SLASH}cpwd.php" =>
  111. "php${SLASH}Indonesia.php",
  112.  
  113. "web${SLASH}delete.php" =>
  114. "php${SLASH}Indonesia.php",
  115.  
  116. "web${SLASH}download.php" =>
  117. "php${SLASH}Indonesia.php",
  118.  
  119. "web${SLASH}dictionary.php" =>
  120. "php${SLASH}Indonesia.php",
  121.  
  122. "web${SLASH}email.php" =>
  123. "php${SLASH}Indonesia.php",
  124.  
  125. "web${SLASH}insert.php" =>
  126. "php${SLASH}Indonesia.php",
  127.  
  128. "web${SLASH}login.php" =>
  129. "php${SLASH}Indonesia.php",
  130.  
  131. "web${SLASH}logout.php" =>
  132. "php${SLASH}Indonesia.php",
  133.  
  134. "web${SLASH}misses.php" =>
  135. "php${SLASH}Indonesia.php",
  136.  
  137. "web${SLASH}offline.php" =>
  138. "php${SLASH}Indonesia.php",
  139.  
  140. "web${SLASH}online.php" =>
  141. "php${SLASH}Indonesia.php",
  142.  
  143. "web${SLASH}pos.php" =>
  144. "php${SLASH}Indonesia.php",
  145.  
  146. "web${SLASH}reference.php" =>
  147. "php${SLASH}Indonesia.php",
  148.  
  149. "web${SLASH}request.php" =>  
  150. "php${SLASH}Indonesia.php",
  151.  
  152. "web${SLASH}requests.php" =>  
  153. "php${SLASH}Indonesia.php",
  154.  
  155. "web${SLASH}search.php" =>
  156. "php${SLASH}Indonesia.php",
  157.  
  158. "web${SLASH}sql.php" =>
  159. "php${SLASH}Indonesia.php",
  160.  
  161. "web${SLASH}statistics.php" =>  
  162. "php${SLASH}Statistics.php",
  163.  
  164. "web${SLASH}tasks.php" =>  
  165. "php${SLASH}Indonesia.php",
  166.  
  167. "web${SLASH}update.php" =>  
  168. "php${SLASH}Indonesia.php",
  169.  
  170. "web${SLASH}upload.php" =>  
  171. "php${SLASH}Indonesia.php");
  172.  
  173. my ($dictionary_class) = "php${SLASH}Dictionary.php";
  174.  
  175. my ($web_class) = "php${SLASH}Web.php";
  176.  
  177. my (%modified_manifest) = ();
  178.  
  179. print "Verifying setup directories and files...\n\n";
  180.  
  181. #Now verify that all directories and files exist
  182. #We will change the permissions only after the 
  183. #configuration is finished.
  184. foreach(sort(keys(%manifest))) {
  185.  
  186.     my ($path) = $_;
  187.  
  188.     my ($permissions) = $manifest{$path};
  189.  
  190.     $path = 
  191.     $DICTIONARY_CFG{INSTALLATION_DIRECTORY} . $SLASH . $path; 
  192.  
  193.     $modified_manifest{$path} = $permissions;
  194.  
  195.     print "${path} ";
  196.  
  197.     show_error("\nCan't find ${path}", -1) if (!-e "$path");
  198.  
  199.     print "[OK]\n";
  200. }
  201.  
  202. $DICTIONARY_CFG{"DB_HOST"} = 
  203. prompt("What is or will be the name or IP address of the database server?", 1);
  204.  
  205. $DICTIONARY_CFG{"DB_NAME"} = 
  206. prompt("What is or will be the database name for the dictionary database?", 1);
  207.  
  208. $DICTIONARY_CFG{"DB_USER"} = 
  209. prompt("What is or will be the database user's name?", 1);
  210.  
  211. $DICTIONARY_CFG{"DB_PASSWORD"} = 
  212. prompt("What is or will be $DICTIONARY_CFG{DB_USER}'s password?", 1);
  213.  
  214. while(1) {
  215.  
  216.     $DICTIONARY_CFG{"EMAIL"} = 
  217.     prompt("What is or will be the website's primary e-mail address?", 1);
  218.  
  219.     last if (is_email($DICTIONARY_CFG{"EMAIL"}));
  220.  
  221.     show_error(
  222.     "This doesn't appear to be a valid e-mail address.  Try again.", 0);
  223. }
  224.  
  225. my (%modified_web_files) = ();
  226.  
  227. #Qualify the default directories by prepending the installation 
  228. #directories then check to ensure the files exist then assign 
  229. #then to hash that indicates which class file to use.  These files
  230. #pertain to the PHP web code.
  231. foreach(sort(keys(%web_files))) {
  232.  
  233.     my ($web_file) = 
  234.     $DICTIONARY_CFG{"INSTALLATION_DIRECTORY"} . 
  235.     $SLASH . ${_};
  236.  
  237.     my ($class_file) = 
  238.     $DICTIONARY_CFG{"INSTALLATION_DIRECTORY"} . 
  239.     $SLASH . $web_files{$_};
  240.  
  241.     #Check here if exists...abort if doesn't
  242.     show_error(
  243.     "Can't find PHP web file ${web_file}\n" .
  244.     "Please make sure you installation path is correct.", -1)
  245.         if (!-f "$web_file");
  246.  
  247.     #Check here if exists...abort if doesn't
  248.     show_error(
  249.     "Can't find PHP class file ${class_file}\n" .
  250.     "Please make sure you installation path is correct.", -1)
  251.         if (!-f "$class_file");
  252.  
  253.     $modified_web_files{"$web_file"} = "$class_file";
  254. }
  255.  
  256. my (%modified_class_files) = ();
  257.  
  258. #Do the same for child class files 
  259. foreach(sort(keys(%class_files))) {
  260.  
  261.     my ($child_class) = 
  262.     $DICTIONARY_CFG{"INSTALLATION_DIRECTORY"} . 
  263.     $SLASH . ${_};
  264.  
  265.     my ($parent_class) = 
  266.     $DICTIONARY_CFG{"INSTALLATION_DIRECTORY"} . 
  267.     $SLASH . $class_files{$_};
  268.  
  269.     #Check here if exists...abort if doesn't
  270.     show_error(
  271.     "Can't find PHP class file ${child_class}\n" .
  272.     "Please make sure you installation path is correct.", -1)
  273.         if (!-f "$child_class");
  274.  
  275.     #Check here if exists...abort if doesn't
  276.     show_error(
  277.     "Can't find PHP parent class file ${parent_class}\n" .
  278.     "Please make sure you installation path is correct.", -1)
  279.         if (!-f "$parent_class");
  280.  
  281.     $modified_class_files{"$child_class"} = "$parent_class";
  282. }
  283.  
  284. #Dictionary class is the parent class of everything 
  285. $dictionary_class = $DICTIONARY_CFG{"INSTALLATION_DIRECTORY"} . 
  286. $SLASH . $dictionary_class;
  287.  
  288. #Check here if exists...abort if doesn't
  289. show_error(
  290. "Can't find PHP parent dictionary class file ${dictionary_class}\n" .
  291. "Please make sure you installation path is correct.", -1)
  292.     if (!-f "$dictionary_class");
  293.  
  294. #Web class to be inserted into web PHP files
  295. $web_class = $DICTIONARY_CFG{"INSTALLATION_DIRECTORY"} . 
  296. $SLASH . $web_class;
  297.  
  298. #Check here if exists...abort if doesn't
  299. show_error(
  300. "Can't find PHP web class file ${web_class}\n" .
  301. "Please make sure you installation path is correct.", -1)
  302.     if (!-f "$web_class");
  303.  
  304. #Verify that configuration values given are correct before 
  305. #proceeding 
  306. while(1) {
  307.  
  308.     print "\n[VERIFY THESE VALUES]\n\n";
  309.  
  310.     foreach(sort(keys(%DICTIONARY_CFG))) {
  311.  
  312.         my ($name) = $_;
  313.  
  314.         my ($value) = $DICTIONARY_CFG{$name};
  315.  
  316.         print "${name} = ${value}\n";
  317.     }
  318.  
  319.     my ($response) = 
  320.     promptyn("Are these values correct?");
  321.  
  322.     if (!$response) {
  323.  
  324.         print "\nInstallation script terminated!\n\n";
  325.  
  326.         exit;
  327.     }
  328.  
  329.     last;
  330. }
  331.  
  332. print "Configuring Dictionary.pm class file...\n";
  333.  
  334. #Configure the Dictionary.php class with given values
  335. configure_dictionary_class("$dictionary_class", \%DICTIONARY_CFG, $SLASH);
  336.  
  337. print "Configuring other class file...\n";
  338.  
  339. #Modify the web files' require_once() statements to include full path
  340. #to source class files
  341. foreach(sort(keys(%modified_class_files))) {
  342.  
  343.     my ($child_class) = $_;
  344.  
  345.     my ($parent_class) = $modified_class_files{$child_class};
  346.  
  347.     configure_php_file($child_class, $parent_class, $SLASH, "");
  348. }
  349.  
  350. print "Configuring PHP web files...\n";
  351.  
  352. #Modify the web files' require_once() statements to include full path
  353. #to source class files
  354. foreach(sort(keys(%modified_web_files))) {
  355.  
  356.     my ($web_file) = $_;
  357.  
  358.     my ($class_file) = $modified_web_files{$web_file};
  359.  
  360.     configure_php_file($web_file, $class_file, $SLASH, $web_class);
  361. }
  362.  
  363. print "Setting default permissions to directories and files...\n";
  364.  
  365. change_permissions(\%modified_manifest);
  366.  
  367. #Prompt if user wants to install web files to web server
  368. while(1) {
  369.  
  370.     my ($response) = 
  371.     promptyn(
  372.     "Would you like to install the PHP web files to your web server?");
  373.      
  374.     if (!$response) {
  375.  
  376.         print "\nInstallation script completed!\n\n";
  377.  
  378.         exit;
  379.     }
  380.  
  381.     last;
  382. }
  383.  
  384. my ($web_directory) = "";
  385.  
  386. #Prompt for web server installation directory
  387. while(1) {
  388.  
  389.     $web_directory = 
  390.     prompt(
  391.     "What is the name of the web directory to copy the " .
  392.     "PHP web files?", 1); 
  393.  
  394.     #Remove trailing slash for UNIX systems if exists
  395.     $web_directory =~ s/\/$//;
  396.  
  397.     #Remove trailing slash for Windows systems if exists
  398.     $web_directory =~ s/\\$//;
  399.  
  400.     if (!-d "$web_directory") {
  401.  
  402.         show_error(    
  403.         "Directory ${web_directory} does not exist.\n"  .
  404.         "Manually create this directory or use an existing one\n" .
  405.         "before continuing.  I'll wait.", 0);
  406.  
  407.         my ($response) =
  408.         promptyn("Try again?", 1);  
  409.  
  410.         if (!$response) {
  411.  
  412.             print 
  413.             "\nInstallation script done.\n" .
  414.             "Manually copy web PHP files and sub-directories " .
  415.             "when you are ready.\n\n"; 
  416.  
  417.             exit;
  418.         } 
  419.  
  420.     } else {
  421.  
  422.         last;
  423.     }
  424. }
  425.  
  426. print "Copying PHP web files...\n";
  427.  
  428. foreach(sort(keys(%modified_web_files))) {
  429.  
  430.     my ($src) = $_;
  431.     my ($tgt) = $web_directory . $SLASH . get_basename($src); 
  432.  
  433.     copy("$src", "$tgt");
  434.  
  435.     chmod(0604, "$tgt");
  436.  
  437.     show_error(
  438.     "Can't copy\n${src} to\n${tgt}\n" .
  439.     "Read documentation about manual web installation.", -1) 
  440.         if (!-f "$tgt");
  441. }
  442.  
  443. print 
  444. "\nInstallation script completed!\n" .
  445. "Once again double check permissions for directories and files.\n\n"; 
  446.  
  447. #----------------------------------------------------------------------------
  448. #Changes installation directories and files to default permissions 
  449. #----------------------------------------------------------------------------
  450. sub change_permissions {
  451.  
  452.     my ($modified_manifest) = shift;
  453.  
  454.     foreach(sort(keys(%$modified_manifest))) {
  455.  
  456.         my ($path) = $_;
  457.  
  458.         my ($permissions) = $$modified_manifest{$path};
  459.  
  460.         chmod($permissions, $path);
  461.     }
  462.  
  463.     return;
  464. }
  465. #----------------------------------------------------------------------------
  466. #Configures the Dictionary.pm class files to run under this environment.
  467. #----------------------------------------------------------------------------
  468. sub configure_dictionary_class {
  469.  
  470.     my ($file) = shift;
  471.     my ($cfg) = shift;
  472.     my ($slash) = shift;
  473.     my ($file_backup) = $file . "." . $$ . ".bak"; 
  474.     my ($cfg_entry) = "";
  475.  
  476.     #Compose the dictionary configuration PHP entries
  477.     #Also change permissions to directories if applicable
  478.     foreach(sort(keys(%$cfg))) {
  479.  
  480.         my ($name) = $_;
  481.         my ($value) = $$cfg{$_};
  482.  
  483.         $value =~ s/\\/\\\\/g
  484.         if (($name eq "INSTALLATION_DIRECTORY") && ($slash eq "\\"));
  485.  
  486.         $cfg_entry .= 
  487.         "\$this->configuration[\"${name}\"] = \"${value}\";\n\n"; 
  488.     }
  489.  
  490.     #Clean it up
  491.     chomp($cfg_entry);
  492.  
  493.     #Remove existing backup file if exists
  494.     unlink("$file_backup") if (-f "$file_backup");
  495.  
  496.     #Make a backup copy just to be safe
  497.     copy("$file", "$file_backup") || goto RECOVER_AND_ABORT_A;
  498.  
  499.     #Remove the original file
  500.     unlink("$file");
  501.  
  502.     #Create a new PHP file 
  503.     open(NEW_FILE, ">${file}") || goto RECOVER_AND_ABORT_B;
  504.  
  505.     #Open the original file (backup)
  506.     open(OLD_FILE, "${file_backup}") || goto RECOVERY_AND_ABORT_C;
  507.  
  508.     my ($ignore_flag) = 0;
  509.  
  510.     while(<OLD_FILE>) {
  511.  
  512.         my ($tmp) = $_;
  513.  
  514.         if ($tmp =~ /\/\/\<CONFIGURATION\>/) {
  515.  
  516.             print NEW_FILE $tmp;
  517.  
  518.             print NEW_FILE $cfg_entry; 
  519.  
  520.             $ignore_flag = 1;
  521.  
  522.             next;
  523.  
  524.         } elsif (($tmp =~ /\/\/\<\/CONFIGURATION\>/) &&
  525.                  ($ignore_flag)) { 
  526.  
  527.             print NEW_FILE $tmp;
  528.  
  529.             $ignore_flag = 0;
  530.  
  531.         } elsif (!$ignore_flag) {
  532.  
  533.             print NEW_FILE $tmp;
  534.         }
  535.     }
  536.  
  537.     close(NEW_FILE);
  538.  
  539.     close(OLD_FILE);
  540.  
  541.     #Double check to ensure new file exists
  542.     goto  RECOVERY_AND_ABORT_D if (!-f "$file");
  543.  
  544.     #Remove the backup file
  545.     unlink("$file_backup") if (-f "$file_backup");
  546.  
  547.     #Give proper permissions
  548.     chmod(0604, "$file");
  549.  
  550.     return;
  551.  
  552. RECOVER_AND_ABORT_A:
  553.  
  554.     #Remove backup if exists
  555.     unlink("$file_backup") if (-f "$file_backup");
  556.  
  557.     show_error(
  558.     "Can't copy ${file} to ${file_backup}\n" .
  559.     "Make sure you have proper permissions or enough space.",
  560.     -1);
  561.  
  562. RECOVER_AND_ABORT_B:
  563.  
  564.     close(NEW_FILE);
  565.  
  566.     #Remove the new file if it was partially created
  567.     unlink("$file");
  568.  
  569.     #Move backup file back to its original spot
  570.     move("$file_backup", "$file"); 
  571.  
  572.     if (!-f "$file") {
  573.  
  574.         show_error(
  575.         "Could not configure and restore PHP file ${file}\n" .
  576.         "Correct the error and reinstall before running " .
  577.         "this script again.", -1); 
  578.     }
  579.  
  580.     show_error(
  581.     "Could not configure PHP file ${file}\n" .
  582.     "Correct the error and try again.", -1); 
  583.  
  584. RECOVER_AND_ABORT_C:
  585.  
  586.     close(NEW_FILE);
  587.  
  588.     close(OLD_FILE);
  589.  
  590.     #Remove the new file if it was partially created
  591.     unlink("$file");
  592.  
  593.     #Move backup file back to its original spot
  594.     move("$file_backup", "$file");
  595.  
  596.     if (!-f "$file") {
  597.  
  598.         show_error(
  599.         "Could not configure and restore PHP file ${file}\n" .
  600.         "Correct the error and reinstall before running " .
  601.         "this script again.", -1); 
  602.     }
  603.  
  604.     show_error(
  605.     "Could not configure PHP file ${file}\n" .
  606.     "Correct the error and try again.", -1); 
  607.  
  608. RECOVER_AND_ABORT_D:
  609.  
  610.     #Remove the new file if it was partially created
  611.     unlink("$file");
  612.  
  613.     #Move backup file back to its original spot
  614.     move("$file_backup", "$file");
  615.  
  616.     if (!-f "$file") {
  617.  
  618.         show_error(
  619.         "Could not configure and restore PHP file ${file}\n" .
  620.         "Correct the error and reinstall before running " .
  621.         "this script again.", -1); 
  622.     }
  623.  
  624.     show_error(
  625.     "Could not configure PHP file ${file}\n" .
  626.     "Correct the error and try again.", -1); 
  627. }
  628. #----------------------------------------------------------------------------
  629. #Configures PHP files to include required absolute class file paths
  630. #----------------------------------------------------------------------------
  631. sub configure_php_file {
  632.  
  633.     my ($file) = shift; 
  634.     my ($class_file) = shift;
  635.     my ($slash) = shift;
  636.     my ($web_class) = shift || "";
  637.     my ($file_backup) = $file . "." . $$ . ".bak"; 
  638.  
  639.     #Remove existing backup file if exists
  640.     unlink("$file_backup") if (-f "$file_backup");
  641.  
  642.     #Make a backup copy just to be safe
  643.     copy("$file", "$file_backup") || goto RECOVER_AND_ABORT_A;
  644.  
  645.     #Remove the original file
  646.     unlink("$file");
  647.  
  648.     #Create a new PHP file 
  649.     open(NEW_FILE, ">${file}") || goto RECOVER_AND_ABORT_B;
  650.  
  651.     #Open the original file (backup)
  652.     open(OLD_FILE, "${file_backup}") || goto RECOVERY_AND_ABORT_C;
  653.  
  654.     $class_file =~ s/\\/\\\\/g if ($slash eq "\\");
  655.  
  656.     #New require_once() string
  657.     my ($new_require) = 
  658.     "require_once(\"${class_file}\");\n";
  659.  
  660.     #Also add web class if applicable
  661.     if ($web_class ne "") {
  662.  
  663.         $web_class =~ s/\\/\\\\/g if ($slash eq "\\");
  664.  
  665.         $new_require .= 
  666.         "require_once(\"${web_class}\");\n";
  667.     }
  668.  
  669.     my ($ignore_old_require_flag) = 0;
  670.  
  671.     while(<OLD_FILE>) {
  672.  
  673.         my ($tmp) = $_;
  674.  
  675.         #Insert the new one
  676.         if (
  677.         ($tmp =~ /require_once\(/) && 
  678.         ($tmp =~ /\)\;/) && 
  679.         (!$ignore_old_require_flag)) {
  680.  
  681.             print NEW_FILE $new_require; 
  682.  
  683.             $ignore_old_require_flag = 1;
  684.  
  685.         #Ignore the old requires
  686.         } elsif (
  687.           ($tmp =~ /require_once\(/) && 
  688.           ($tmp =~ /\)\;/))  {
  689.  
  690.             next;
  691.  
  692.         }  else {
  693.  
  694.             print NEW_FILE $tmp; 
  695.         }
  696.     }
  697.  
  698.     close(NEW_FILE);
  699.  
  700.     close(OLD_FILE);
  701.  
  702.     #Double check to ensure new file exists
  703.     goto  RECOVERY_AND_ABORT_D if (!-f "$file");
  704.  
  705.     #Remove the backup file
  706.     unlink("$file_backup") if (-f "$file_backup");
  707.  
  708.     chmod(0604, "$file");
  709.  
  710.     return;
  711.  
  712. RECOVER_AND_ABORT_A:
  713.  
  714.     #Remove backup if exists
  715.     unlink("$file_backup") if (-f "$file_backup");
  716.  
  717.     show_error(
  718.     "Can't copy ${file} to ${file_backup}\n" .
  719.     "Make sure you have propery permissions or enough space.",
  720.     -1);
  721.  
  722. RECOVER_AND_ABORT_B:
  723.  
  724.     close(NEW_FILE);
  725.  
  726.     #Remove the new file if it was partially created
  727.     unlink("$file");
  728.  
  729.     #Move backup file back to its original spot
  730.     move("$file_backup", "$file"); 
  731.  
  732.     if (!-f "$file") {
  733.  
  734.         show_error(
  735.         "Could not configure and restore PHP file ${file}\n" .
  736.         "Correct the error and reinstall before running " .
  737.         "this script again.", -1); 
  738.     }
  739.  
  740.     show_error(
  741.     "Could not configure PHP file ${file}\n" .
  742.     "Correct the error and try again.", -1); 
  743.  
  744. RECOVER_AND_ABORT_C:
  745.  
  746.     close(NEW_FILE);
  747.  
  748.     close(OLD_FILE);
  749.  
  750.     #Remove the new file if it was partially created
  751.     unlink("$file");
  752.  
  753.     #Move backup file back to its original spot
  754.     move("$file_backup", "$file");
  755.  
  756.     if (!-f "$file") {
  757.  
  758.         show_error(
  759.         "Could not configure and restore PHP file ${file}\n" .
  760.         "Correct the error and reinstall before running " .
  761.         "this script again.", -1); 
  762.     }
  763.  
  764.     show_error(
  765.     "Could not configure PHP file ${file}\n" .
  766.     "Correct the error and try again.", -1); 
  767.  
  768. RECOVER_AND_ABORT_D:
  769.  
  770.     #Remove the new file if it was partially created
  771.     unlink("$file");
  772.  
  773.     #Move backup file back to its original spot
  774.     move("$file_backup", "$file");
  775.  
  776.     if (!-f "$file") {
  777.  
  778.         show_error(
  779.         "Could not configure and restore PHP file ${file}\n" .
  780.         "Correct the error and reinstall before running " .
  781.         "this script again.", -1); 
  782.     }
  783.  
  784.     show_error(
  785.     "Could not configure PHP file ${file}\n" .
  786.     "Correct the error and try again.", -1); 
  787. }
  788. #----------------------------------------------------------------------------
  789. #Returns the basename of a path
  790. #----------------------------------------------------------------------------
  791. sub get_basename {
  792.  
  793.     my ($path) = shift;
  794.     my (@path_tree) = shift;
  795.  
  796.     if ($path =~ /\\/) {
  797.  
  798.         @path_tree = split(/\\/, $path);
  799.  
  800.         return($path_tree[$#path_tree]);
  801.  
  802.     } elsif ($path =~ /\//) {
  803.  
  804.         @path_tree = split(/\//, $path);
  805.  
  806.         return($path_tree[$#path_tree]);
  807.     }
  808.  
  809.     return($path);
  810. }
  811. #----------------------------------------------------------------------------
  812. #Verifies given token is an e-mail address.  This can be greatly enhanced.
  813. #It just lloks for @ and . with spacing before, in between, and after for 
  814. #the time being.  Should be good enough though.
  815. #----------------------------------------------------------------------------
  816. sub is_email {
  817.  
  818.     my ($token) = shift;
  819.  
  820.     return(1) if ($token =~ /\w+\@\w+\.\w+/);
  821. }
  822. #----------------------------------------------------------------------------
  823. #Generic prompt 
  824. #----------------------------------------------------------------------------
  825. sub prompt {
  826.  
  827.     my ($prompt) = shift;
  828.     my ($required_flag) = shift;
  829.     my ($response) = "";
  830.  
  831.     #Iterate until correct response is found
  832.     while(1) {
  833.  
  834.         #Show prompt message
  835.         print "\n${prompt}\n\n";
  836.  
  837.         #Grab response
  838.         $response = <STDIN>;
  839.  
  840.         #Remove leading and trailing white-spaces
  841.         trim(\$response);
  842.         
  843.         if (($response) eq "" && ($required_flag)) {
  844.  
  845.             show_error("This parameter requires a value!", 0);
  846.     
  847.             next;
  848.         } 
  849.  
  850.         last;
  851.     }
  852.  
  853.     return($response);
  854. }
  855. #----------------------------------------------------------------------------
  856. #Generic yes or no prompt 
  857. #----------------------------------------------------------------------------
  858. sub promptyn {
  859.  
  860.     my ($prompt) = shift;
  861.     my ($response);
  862.     my ($ucresponse);
  863.     my (%responses) = (YES => 1, NO => 1, Y => 1, N => 1);
  864.  
  865.     #Iterate until correct response is found
  866.     while(1) {
  867.  
  868.         #Show prompt message
  869.         print "\n${prompt} [y|n]\n\n";
  870.  
  871.         #Grab response
  872.         $response = <STDIN>;
  873.         
  874.         #Clean leading and trailing white spaces
  875.         trim(\$response);
  876.  
  877.         if ($response eq "") {
  878.  
  879.             show_error(
  880.             "Please respond with a 'y' or 'n' answer!", 0);
  881.  
  882.             next;
  883.  
  884.         }  else {
  885.  
  886.             $ucresponse = uc($response);
  887.  
  888.             if (exists($responses{$ucresponse})) {
  889.  
  890.                 last;
  891.  
  892.             } else {
  893.  
  894.                 show_error(
  895.                 "Please respond with a 'y' or 'n' answer!", 0);
  896.             }
  897.         }
  898.     }
  899.  
  900.     return(1) if ($ucresponse =~ /^Y/);
  901.  
  902.     return(0);
  903. }
  904. #----------------------------------------------------------------------------
  905. #Generic prompt with default
  906. #----------------------------------------------------------------------------
  907. sub promptx {
  908.  
  909.     my ($prompt) = shift;
  910.     my ($default) = shift;
  911.     my ($required_flag) = shift;
  912.     my ($response) = "";
  913.  
  914.     #Iterate until correct response is found
  915.     while(1) {
  916.  
  917.         print "\n${prompt} [${default}]\n\n";
  918.  
  919.         $response = <STDIN>;
  920.  
  921.         chomp($response);
  922.  
  923.         if ($response eq "") {
  924.  
  925.             $response = $default;
  926.  
  927.             last;
  928.  
  929.         } else {
  930.  
  931.             trim(\$response);
  932.  
  933.             if (($response) eq "" && ($required_flag)) {
  934.  
  935.                 show_error(
  936.                 "This parameter requires a value!", 0);
  937.  
  938.                 next;
  939.  
  940.             } else {
  941.  
  942.  
  943.                 last;
  944.             }
  945.         }
  946.     }
  947.  
  948.     return("$response");
  949. }
  950. #----------------------------------------------------------------------------
  951. #Prompt for installation directory
  952. #----------------------------------------------------------------------------
  953. sub prompt_installation_directory {
  954.  
  955.     my ($pwd) = cwd();
  956.     my ($default_dir) = "";
  957.     my ($installation_directory) = "";
  958.  
  959.     if ($pwd) {
  960.  
  961.         if (-d "$pwd") {
  962.  
  963.             show_error(
  964.             "You must run this installation script " .
  965.             "under the same directory that it resides.", -1)
  966.                 if ($pwd !~ /bahasa\/utilities$/);
  967.  
  968.             $default_dir = $pwd;
  969.  
  970.             $default_dir =~ s/\/utilities$//;
  971.         } 
  972.     }
  973.  
  974.     if (-d "$default_dir") {
  975.  
  976.         while(1) {
  977.  
  978.             $installation_directory =
  979.             promptx(
  980.             "Enter the installation directory:\n", 
  981.             "$default_dir", 1);
  982.     
  983.             if (!-d "$installation_directory") {
  984.  
  985.                 show_error(
  986.                 "'${installation_directory}'" .
  987.                 " does not exists.  Please try again.", 0);
  988.  
  989.                 next;
  990.             }
  991.  
  992.             last;
  993.         }
  994.  
  995.     } else {
  996.  
  997.  
  998.         while(1) {
  999.     
  1000.             $installation_directory =
  1001.             prompt("Enter the installation directory: ", 1);
  1002.  
  1003.             if (!-d "$installation_directory") {
  1004.  
  1005.                 show_error(
  1006.                 "'${installation_directory}'" .
  1007.                 " does not exists.  Please try again.", 0);
  1008.  
  1009.                 next;
  1010.             }
  1011.  
  1012.             last;
  1013.         }
  1014.     }
  1015.  
  1016.     #Remove trailing slash for UNIX systems if exists
  1017.     $installation_directory =~ s/\/$//;
  1018.  
  1019.     #Remove trailing slash for Windows systems if exists
  1020.     $installation_directory =~ s/\\$//;
  1021.  
  1022.     return("$installation_directory");
  1023. }
  1024. #----------------------------------------------------------------------------
  1025. #Display error message then terminate script
  1026. #----------------------------------------------------------------------------
  1027. sub show_error {
  1028.  
  1029.     my ($msg) = shift;
  1030.     my ($exit_flag) = shift || 0;
  1031.  
  1032.     print "\nInstallation Error:\n${msg}\n\n";
  1033.  
  1034.     exit(-1) if ($exit_flag);
  1035.  
  1036.     return;
  1037. }
  1038. #----------------------------------------------------------------------------
  1039. #Introduction message
  1040. #----------------------------------------------------------------------------
  1041. sub show_introduction {
  1042.  
  1043.     print "\n\n";
  1044.  
  1045.     print "-" x 77;
  1046.  
  1047.     print "\n";
  1048.  
  1049.     print <<EOF;
  1050. [BAHASA INDONESIA DICTIONARY CONFIGURATION]
  1051.  
  1052. The purpose of this script is to configure 
  1053. the Bahasa Indonesia Dictionary PHP files to
  1054. run on this host.  It doesn't do any 
  1055. mySQL database configuration, but it will 
  1056. prompt you for database questions.  
  1057.  
  1058. This script assumes that your web server is
  1059. running on this host.  You are responsible 
  1060. for setting the correct permissions for 
  1061. these files after configuration.
  1062.  
  1063. I've tried to make this script as portable 
  1064. as possible.  If for some reason this script 
  1065. fails then you will have to configure the files
  1066. manually.  See documentation for more details. 
  1067.  
  1068. Please feel free to modify this script to best 
  1069. fit your needs.
  1070.  
  1071. You can abort at any time by pressing CTRL C.
  1072.  
  1073. EOF
  1074.  
  1075.     print "-" x 77;
  1076.  
  1077.     print "\n";
  1078.  
  1079.     return;
  1080. }
  1081. #----------------------------------------------------------------------------
  1082. #Trim leading and trailing white-spaces from string token.  Pass token by
  1083. #reference only.
  1084. #----------------------------------------------------------------------------
  1085. sub trim {
  1086.  
  1087.     my ($token) = shift;
  1088.  
  1089.     return if (!$token);
  1090.  
  1091.     $$token =~ s/^\s+//;
  1092.     $$token =~ s/\s+$//;
  1093.  
  1094.     return;
  1095. }
  1096. #----------------------------------------------------------------------------
  1097. #----------------------------------------------------------------------------
  1098.  
  1099.