#!/usr/bin/perl
my($root,$t_n,$mysqlname,$username,$mysql,$datapath,$mysqlpath,$userpath,$c_ct,
$dbh,$opt_port,$opt_user,$opt_password,$opt_socket,$opt_help,$m_o,$mysqlparms,
$no_err,$menucall,$parms,$parmstemp,$pgroup,@list,$out_f,$in_f,$db,$choosenum,
$opt_host,$ft,$host,$version,$distinct,$press,$log_file,$hostname,$case_val,$mp,
@capture,@sys,@rf,$answer,$ext,$explain,$like,$mysqlcap,$replace,$insert,
$fieldnum,$fieldname,$search_str,$distinct_str,$explain_str);
$mysqlname = "";#your mysql user name for all privileges
$db = "";#the default database name
$datapath = "";#the default database path
$userpath = "";#the default user path
$mysqlpath = "";#the default mysql executable path
 $root = "";#place your super user name for this machine here
$mysql = "mysql";#the name of the mysql client
#You should leave this file as it is for a template for menu.pl
study(@row);
study($sql);
@rt=('','TINYINT','INT','SMALLINT','MEDIUMINT','INTEGER','VITINT','REAL',
'DOUBLE','FLOAT','DECIMAL','NUMERIC','CHAR','VARCHAR','DATE','TIME','TIMESTAMP',
'DATETIME','TINYBLOB','BLOB','MEDIUMBLOB','LONGBLOB','TINYTEXT','TEXT',
'MEDIUMTEXT','LONGTEXT','ENUM','SET');
#This program requires Data-Showable && DBI:: && Msql_Mysql-modules-...
#It uses the socket and pipe line to allow you a chance to learn to use mysql.
#This program is covered under the gpl.
$ext="asc";#default output file extention
$explain="explain";
$distinct="distinct";
$press = "\npress enter to continue:\n";
$like = "not like";#not like inverts the search with the * command
use Cwd;
$currdir=cwd();
$currdir.="\/";
print "$currdir\n";
&mysql_sql;#toggle printing of sql
&password;
$m_o=$mysqlparms=1;
&mysqlparms;#works with the pipe line when socket is disabled
&toggle_explain;
&toggle_distinct;
&invert_search;
if (!$case_val){&case;}
#$no_err=1;#this saves a false connection to the socket
if (!$no_err){
use DBI;
use Getopt::Long;
use vars qw($dbh $hostname $opt_user $opt_password $opt_help $opt_host
 $opt_socket $opt_port $host $version);
$dbh=$host=$opt_user=$opt_password=$opt_help=$opt_host=$opt_socket="";
$opt_port=$log_file=$c_ct=0;
$m_o=$mysqlparms=1;
&mysql_sql;#toggle printing of sql
&mysqlparms;#works with the pipe line when socket is disabled
&toggle_explain;
&toggle_distinct;
&invert_search;
if (!$case_val){&case;}
read_my_cnf(); # Read options from .my.cnf
GetOptions("user=s","password=s","help","host=s","socket=s","port=i","option=s");
&usage() if $opt_help;# the help function
&get_host();
$dbh=DBI->connect(
"DBI:mysql:mysql:host=$hostname:port=$opt_port:mysql_socket=$opt_socket",
$opt_user,$opt_password, {PrintError=> 0})
|| warn("Can't connect to the mysql server.\n The error: $DBI::errstr");
if (! $DBI::errstr){
$sql="USE $db";
$no_err=1;#this saves a false connection to the socket
$choosenum="or number";#used when socket connected
print "The socket connection to $mysql was successful:\n";}
else {
quit();}
print "$sql;";
&pd;}#end of socket
print <<EOF;
The default database is $db The process number is $pgroup
The workin directory is :
$userpath
The mysql path is:
$mysqlpath
The mysql data path is:
$datapath
 your system user name is $username your mysql user is $opt_user
EOF
&ret;
menu_list();
for (;;){#the main menu
$sql = $mp = "";
print "\nDatabase, table and field numbers may not be used:\n" if !$no_err;
if ($log_file == 1 && $no_err){
print "mysql output is sent to the file $0.log\n";}
if ($c_ct){
print "$c_ct commands in the capture array: ";}
if ($case_val==1){
print "MENU>";}
elsif ($case_val==2){
print "menu>";}
else {
print ">";}
$menucall = 1;#allows for the Q or q selection
next if !query();
$menucall = 0;#q or q cause functions to return
$mp = uc($_);
$mp =~s/\s//g;
if ($mp eq '#' || $mp eq '{' || $mp eq 'Q' || $mp eq '[' || $mp eq 'U'
|| $mp eq 'W' || $mp eq 'T' || ($mp ge 'D' && $mp le 'H') || $mp eq 'A'
|| $mp eq 'R' || $mp eq 'N' || $mp eq '1' || $mp eq 'Y'){
&table_open($t_n);}
elsif ($mp eq 'S'){
&database;}
elsif ($mp eq 'I'){
&newdatabase;}
elsif ($mp eq '}'){
&parameters($db);}
elsif ($mp eq 'V'){
&capture_list;}
elsif ($mp eq 'B'){
&create_capture_file;}
elsif ($mp eq'O'){
&capture_execute($sql);}
elsif ($mp eq 'J'){
&toggle_distinct;}
elsif ($mp eq '0'){
&toggle_explain;}
elsif ($mp eq '*'){
&invert_search;}
elsif ($mp eq 'L'){
$sql = "SHOW DATABASES";}
elsif ($mp eq 'M'){
&menu_list;}
elsif ($mp eq 'X'){
&type_mysql_command;}
elsif ($mp eq ']'){
&mysqlparms;}
 elsif ($mp eq 'K'){
 &environment;}
 elsif ($mp eq ','){
 &mysql_sql;}
elsif ($mp eq '2'){
&field_cryteria;}
elsif ($mp eq '3'){
&send_mysql;}
elsif ($mp eq '6'){
&send_greg_mysql;}
elsif ($mp eq '7'){
&send_outfile;}
elsif ($mp eq '9'){
&out_ext;}
elsif ($mp eq '4'){
&q1;}
elsif ($mp eq '5'){
&mysql_view;}
elsif ($mp eq '8'){
&socket;}
elsif ($mp eq '-'){
&log;}
elsif ($mp eq 'Z'){
&dump_name;}
elsif ($mp eq ')'){
&file_check;}
elsif ($mp eq '?'){
&menu_help;}
elsif ($mp eq '('){
&set_path;}
 else {
 print "Invalid command `$mp':";}
&pd;}#end of main

sub pd{#select the pipe or socket and save the command
if ($sql ne ""){
$textnum=0;
&socket() if $log_file==1 && $no_err==1;
$capture[$ct]="$sql;\n";
$c_ct++;
$fieldname="";
if ($no_err==1){#send to the socket
 my($xt,$sth,$zt);
$ft="";
undef @rf;
$num = 1;
$zt=40;#allow 40 fids 2 per line 32 maxwidth
 $sth = $dbh->prepare("$sql") || warn $dbh->errstr;
 $sth->execute || warn $dbh->errstr;
 while(my @r = $sth->fetchrow_array) {
 if ($tbl || $sql=~/DESCRIBE $t_n/){
for ($xt = 0; $xt <=$#r; $xt++){
if (($r[$tx] =~/TEXT\(/ || $r[$tx] =~/text\(/) && $sql=~/DESCRIBE $t_n/){
$fieldname=$r[0];
$textnum=$num;
$ft=$rt[$24];}
$rf[$num] .= "$r[$xt]\n" if length($r[$xt]) && $tbl;}#end of for
print $rf[$num] if $tbl ==1;
 if ($num % 5 == 0 && $tbl == 1){ &ret; }
 } else {
$rf[$num] = $r[0];#save a copy
if (length($r[0])){
if (length($rf[$num])<33){
 printf("%5d: %-33s", $num, $r[0]);}
else {
 printf("\n%5d: %-72s\n", $num, $r[0]) if length($r[$xt]);}
&ret if $num %6==0 && $ct ==0;
print "\n" if $num % 2 == 0 && length($rf[$num])<33; }
}
 $num++;}#end of while
 $sth->finish;
$tbl=0;
 print "\n";}#end of if
else {#send through the pipe
&open_mysql;
print MH "$sql;\n";
if ($m_o){
print "$sql;\n";}
close("MH") || warn "close: status = $?"; }#end of else
return($ft,$tbl,$sql="",$num,@rf);}#end of if
}#end of pd

sub menu_list{#the menu after pressing m
print <<EOF;
   ?  help                             -  toggle screen and mysql output to file
   {  delete a record                  )  check the statistics of a file  
   }  set mysql parameters(pipe line)  ,  toggle display of mysql output sql
   [  drop a field                     (  change user path for files
   ]  toggle mysql parameters          *  invert a mysql query(not)
   1  create a field cryteria list     2  execute a field cryteria list
   3  send a file directly to mysql    4  set mysql permissions
   5  display a file                   6  send a | delimited file to mysql
   7  export | delimited data to file  8  toggle between pipe line and socket
   9  convert dbf text files to mysql  0  toggle explain in searches
   a  add a record                     b  save the capture file to disk
   c  sql reserve words                d  describe a table
   e  multi field select      f  choose fields
   g  optimize a table                 h  add an AUTO_INCREMENT field
   i  create a database directory      j  toggle distinct in searches
   k  environment variables            l  list databases
   m  this menu                        n  create a new table
   o  execute a capture line           p  toggle case conversion
   q  query all fields                 r  replace a record
   s  open a database                  t  list the tables in the database
   u  update a table                   v  view the capture array
   w  count the records in a table     x  type a command 254 chars per line
   y  drop a table                     z  dump a database or table to file
EOF
}#end of menu_list

sub usage{# the parameter help text
 print <<EOL;
 The permission setter for MySQL. Version: $version
 Created by: Luuk de Boer <luuk\@wxs.nl>

The permission setter  can help you to add new users
or databases or change passwords in MySQL. Keep in mind that we don't
check permissions which already been set in MySQL. So if you can't
connect to MySQL using the permission you just added, take a look at
the permissions which have already been set in MySQL.

The permission setter first reads your .my.cnf file in your Home
directory if it exists or in the /etc directory, or in the
$datapath directory if logged as root.

The options shown below are used for making the connection to the MySQL
server. Keep in mind that the permissions for the user specified via
these options must be sufficient to add users / CREATE DATABASEs / set passwords.

--help : print this help message and return to the menu.
--user : is the username to connect with.
--password : the password of the username.
--host : the host to connect to.
--socket : the socket to connect to.
--port : the port number of the host to connect to.

If you don't give a password and no password is set in your .my.cnf
file, then the permission setter will ask for a mysql user name and password.
EOL
}#end of usage

sub menu_help{#help for the program
print <<EOF;
The default database is $db The process number is $pgroup
 your system user name is $username your mysql user is $mysqlname
Numpers take priority in field, database and table names.
use the ) command to goto another directory. Case conversion is disabled during
 its duration. The log file logs the output from mysql. Turn this feature on by
pressing - at the menu prompt if the command may cause problems.
The - command will toggle between screen output and file output from mysql.
saved in: $0.log
if you use the * command to invert a query, an extra line appears before the
 menu prompt. The program exits if the pype to mysql is broken. It will not exit
if a file cannot be opened. Be sure that you have read / write privileges in the
logged directory when asked. Enjoy your databases!Characters are converted
to UPPER CASE. Use p or P to toggle the case setting at most of the prompts.
0 off, 1 convert to upper case, 2 convert to lower case.
Enter ends a request. Strings may be ambiguuous databases, fields and tables may
not. Character conversion is disabled for file names but it is activated
when the file name or path is completed. A blank field input is not allowed
but is permitted to terminate loops where they will not violate mysql syntax.
The case of `MENU' at the menu prompt shows the status of case conversion. The
input line appears again in its converted form if case conversion is active.
The menu prompt shows a `>' when case conversion is disabled.
EOF
&ret;
&usage;
&ret;}#end of menu_help

sub reserve{#sql reserve words
print <<EOF;
action add all alter after and as asc auto_increment between bigint bit binary blob 
bool both by cascade char character change check column columns 
constraint create cross current_date current_time current_timestamp data 
database databases date datetime day day_hour day_minute day_second dayofmonth 
dayofweek dayofyear dec decimal default delete desc describe 
distinct distinctrow double drop escaped enclosed enum explain
exists fields first float float4 float8 foreign from 
for full function grant group having hour hour_minute 
hour_second ignore in index infile insert int integer
interval int1 int2 int3 int4 int8 into if
is join key keys last_insert_id leading left like 
lines limit load lock long longblob longtext low_priority 
match mediumblob mediumtext mediumint middleint minute minute_second month 
monthname natural numeric no not null on option 
optionally or order outer outfile partial password precision 
primary procedure processlist privileges quarter read real references 
rename regexp reverse repeat replace restrict returns rlike 
second select set show smallint soname sql_big_tables sql_big_selects
sql_select_limit sql_low_priority_updatessql_log_off sql_log_update straight_join starting status string 
table tables terminated text time timestamp tinyblob tinytext 
tinyint trailing to use using unique unlock unsigned update usage values
varchar variables varying varbinary with write where year year_month zerofill
EOF
}#end of reserve

sub open_mysql{#open the pipe to mysql
my $file = "|$mysqlpath$mysql $parms $mysqlname $mysqlword$opt_password ";
if ($log_file == 1){#send command to file
&cap_file if !$mysqlcap;
$file .= ">$0.log\n" if $mysqlcap eq "C";
$file .= ">>$0.log\n" if $mysqlcap eq "A";
unless(open(L_F, "$file")){
warn("Can't open the mysql capture file with $file:\n");}
print L_F "USE $db;";
print L_F("$sql\n");
close(L_F);}
$file.="$db\n";
unless(open(MH, "$file")){
warn("Can't oben the $db database with:\n$file\n");}
$capture[$c_ct] = $file;
$c_ct++;#place the command line in @capture for debugging
MH;}#end of open_mysql

sub type_mysql_command{#create your own command
print "100 lines maximum: A ; will be appended if required.\n";
for ($ct = 0; $ct <100; $ct++){
print "Type a mysql command and end the entry with a blank line.\n";
last if !query();
$sql.= "$_\n";}#end of for
&pd;}# end of type_mysql_command

sub toggle_explain{#invert $explain search
if ($explain eq 'explain'){
$explain = "";
$explain_str = "Explain search is now off:\n";
print $explain_str;}
else {
$explain = "explain";
$explain_str = "Explain search is active:\n";
print $explain_str;}
return($explain,$explain_str);}#ende of toggle_explain

sub toggle_distinct{#invert $distinct search
if ($distinct eq 'distinct'){
$distinct = "";
$distinct_str = "Distinct search is now off:\n";
print $distinct_str;}
else {
$distinct = "distinct";
$distinct_str = "Distinct search is active:\n";
print $distinct_str;}
return($distinct,$distinct_str);}#ende of toggle_distinct

sub invert_search{#invert the search using $like
if ($like eq "like"){
$like = "not like";
$search_str = "Inverse serch is active:\n";
print $search_str;}
else {
$like = "like";
$search_str = "Normal search:\n";
print $search_str;}
return($like,$search_str);}#ende of invert_search

sub mysql_view{#view a file
my($tmp);
print "Enter the file name to view.\n";
&load;
for ($ct = 0,$tmp = 0; $ct <= $#row; $ct++, $tmp++){
print "$row[$ct]\n";
last if $_ eq "";
if ($tmp == 19){
$tmp = -1;
next if !query();
print $press;}
}#end of for
}#end of mysql_view

sub row_cryteria{#create a cryteria file
my($tmp,$table_count,$t_c,$ct);
undef @row;
$sql = "SHOW TABLES";
&pd;
print <<EOF;
You may leave the field blank to terminate a loop.
When you choose 2 from the menu to retreive the file that will be created,
you will be asked for a query string to to use with the field names in this
file. Enter the number of tables you wish to query:
EOF
return if !query();
 s/\D//g;
$table_count = $_ if $_ <= $#rf;
if ($table_count){
for ($t_c = 0; $t_c <$table_count; $t_c++){
&table_open($t_n);
$tmp = 0;
$row[$tmp] = "$db.$t_n\n";
$tmp++;
for ($ct=1; $ct <= $#rf; $ct++){
printf("Select this field?(Y,n)\n%s: %s\n", $ct, $rf[$ct]);
&query;
last if $_ eq "";
if (uc($_) eq 'Y'){
$row[$tmp] = "$rf[$ct]\n";
$tmp++;}
}#end of for
$row[$tmp] = "$db.$t_n\n";}#end of for
&cap_file;
if ($_ ne ""){
$out_f = $_;
&save_cap_file($cap, $out_f);
for ($tmp = 0; $tmp <= $#row; $tmp++){
 print OUTFILE("$row[$tmp]");}
close(OUTFILE);
print "The field cryteria file has been written to\n$out_f\n";
} else {
print "Nothing to do\n";}
}
}#end of row_cryteria

sub field_cryteria{#execute a cryteria file
my($tn,$ct);
if (!$db){
&database;}
if ($case_val){
&case;}
print " Enter the file name containing your cryteria:";
&load;
$ct = 0;
print "please enter a search string:\n";
return if !query();
$search_for = $_;
for (; $ct <= $#row; $ct++){
$tn = "$row[$ct]";
$sql.= " select $distinct";
print "The table selected is $tn\n";
next if$row[$ct] eq "$tn";
$field = "$row[$ct]";
for (;$ct <= $#row; $ct++){
last if$row[$ct] eq "$tn";
$sql = " $sql $row[$ct],";}# to allow a chop and get the field names in order
chop($sql);
$sql.= " from $tn where $field $like \"%$search_for%\"";
&pd;}#end of outer loop
}#end of field_cryteria

sub send_mysql{#send large blocks of data through the pipe
print "Send a delimited file or mysqldump ascii file? (D, A)\n";
$tmp=uc(&query());
if ($tmp eq 'D'){
&mysqlfile;
print " `\t represents the tab character'Enter the character to terminate a fields:: ";
$terminate=&ans;
print "Enter the optional character or leave the field blank:";
$optional=&ans();
$optional =" OPTIONALLY ENCLOSED BY '$optional'" if length($optional);
print <<EOF;
`\' Backslash is the escape character amd it must be doubled as in:
`\\r\\n' or `\\n'
You may leave the field blank if an optional escape character string is not
required:
EOF
$escape=&ans();
$escape=" ESCAPED BY '$escape'" if length($escape);
$sql="LOAD DATA INFILE '$file' INTO TABLE $t_n
FIELDS TERMINATED BY '$terminate'$optional$escape";
&pd;}
if ($tmp eq 'A'){
&send_ascii_mysql($tmp);} 
}#end of send_mysql

sub mysqlparms{#toggle the mysql parameters used with the pipe
if (!$no_err){
if ($mysqlparms){
$mysqlparms = 0;
$parmstemp = "$parms";
$parms = "-u";
print "mysql parameters are disabled: `$parms'\n";}
else {
$mysqlparms = 1;
$parms=$parmstemp;
print "mysql parameters are enabled: `$parms'\n";}
}
else {
print "The socket must be disabled for this command to work.\n";}
return($parms,$parmstemp,$mysqlparms);}#end of mysqlparms

sub mysql_sql{#toggle printing of $sql
if ($m_o){
$m_o = 0;
print "mysql output sql is disabled:\n";}
else {
$m_o = 1;
print "mysql output sql is active:\n";}
m_o;}#end of mysql_sql

sub save_cap_file($cap, $out_f){#save an output file
$out_f="$userpath$out_f";
if ($cap eq 'C'){
&check_exist;
print "Creating the file $out_f.\n" if -e $out_f;}
elsif ($cap eq 'A'){
 unless(open(OUTFILE, ">>$out_f")){
 warn("cannot open the output file $out_f\n");
&error_file;}
print "Appending the file $out_f.\n";}
return OUTFILE;}#end of save_cap_file

sub load{#an input file
my $tmp=$no_err;
$no_err =0;
return if (!($in_f=&ans()));
$no_err=$tmp;
&open_in_f($in_f);}#end of load

sub log{#toggle mysql output from the screen to the log file
if ($log_file == 1){
$log_file = 0;
print "mysql output is sent to the screen:\n";}
elsif (!$log_file){
print "mysql output is sent to the file $0.log:\n";
$log_file = 1;}
$log_file;}#end of log

sub cap_file{#choose append or create for files
my $tmp=$no_err;
$no_err=0;
print "Create a new fild or append a current file?(C, A)\n";
return if !query();
$cap = uc($_);
$mysqlcap = $cap if !$mysqlcap;
print "Enter the file name to save, and $press";
return if !($out_f=&ans());
$no_err=$tmp;
return($mysqlcap,$cap,$out_f);}#end of cap_file

sub create_capture_file{#create a file from the capture array
my($tmp);
if ($c_ct ){
&cap_file;
if ($out_f ne ""){
&save_cap_file($cap, $out_f);
for ($tmp = 0; $tmp <= $#capture; $tmp++){
 print OUTFILE "$capture[$tmp]";}
close(OUTFILE);
print "The capture file has been written to\n$out_f\n" if -e $out_f;
$c_ct=0 if -e $out_f;
} else {
print "Nothing to save.\n";}
}
$c_ct;}#end of create_capture_file

sub capture_list{#list the capture array
my($tmp);
if ($c_ct){
for ($tmp = 0; $tmp <= $#capture; $tmp++){
printf("%d:  %s", $tmp, $capture[$tmp]);}
&capture_execute($sql);}
else {
print "Nothing sabed.\n";}
}#end of capture_list

sub capture_execute($sql){#execute a command from the capture array
my($tmp);
if ($c_ct){
printf("%d: Enter the command number in the capture array to execute:\n",
$#capture+1);
return if !query();
 s/\D//g;
$tmp = $_;
$sql = $capture[$tmp-1];
} else {
print "nothing saved\n";}
}#end of capture_execute

sub error_file{#try to recover from a file error
my($tmp);
print "Is this an input or output file ?(I, O)\n";
return if !query();
$tmp = uc($_);
print "Now the File Name:\n";
$tbl=1;
return if (!(&ans()));
$tbl=0;
if ($tmp eq 'O'){
$out_f = $answer;
&cap_file;}
else {
$in_f = $answer;}
$tbl;}#end of error_file

sub replace_record{#replace or insert a record
 my($tmp,$ct,$good,$pass,$yes);
 &socket if !$no_err;
print "Type Q or q to quit and $press";
for ($tmp = 1; $tmp <= $#rf; $tmp++){
if (($tmp eq '3' && $t_n eq 'user')&& $db eq 'mysql'){;}
else {
printf( "%d Enter the data for the field: %s: ", $tmp, $rf[$tmp]);
&query;}
if ($db eq 'mysql' && $t_n eq 'user' && $tmp le '3'){
$case_val=0;
 if ($tmp <3){
 $sql.= "'$_',";
 next;}
if ($tmp == 3){
 print "Would you like to set a password for this user [y/n]: ";
return if !&query;
$yes = uc($_);
if ($yes eq 'Y'){
$pass=&pass_new();
$sql.= "PASSWORD('$pass'),";
 } else {
 print "We won't set a password so the user doesn't have to use it\n";
$sql.= "'',";}
next;}#end of password
}#end of $tmp <= 3
loadtext() if $ft eq 'TEXT';
if ($rf[$tmp] =~/CHAR\(/ || $rf[$tmp] =~/char\(/ ||
$rf[$tmp] =~/ENUM\(/ || $rf[$tmp] =~/enum\(/){
$sql.= "'$_',";}
else {
$sql.= "$_,";}
}#end of for
chop($sql);
$sql.= ")";
print "$sql";
&ret;
$replace = "REPLACE INTO $t_n VALUES(";
$insert = "INSERT INTO $t_n VALUES(";
if ($mp eq 'A'){
$sql = "$insert$sql";}
else {
$sql = "$replace$sql";}
$tbl = 1;
&pd;
$sql="FLUSH PRIVILEGES" if $db eq 'mysql';
&pd if $db eq 'mysql';}#end of replace_record

sub environment{#environment variables
foreach $key(keys(%ENV)){
 printf("%-10.10s: $ENV{$key}\n", $key);}
}#end of environment

sub admin{#set the parameters for $0.pl
$in_f = $0;
&open_in_f($in_f);
if ($username ne "root"){
print "is the system administrator's login name as root `root'? (Y, N)";
&query();
if (uc($_) ne 'Y'){
print "Enter the login name of the super user for this machine:(as root) ";
die if !query();
$row[6] =~s/\"\"/\"$_\"/;
$root = $_;}
else {
$row[6] =~s/\"\"/\"root\"/;
$root = $_;}
}
else{
$row[12] =~s/\"\"/\"$username\"/;
$root=$username;}
print "Enter the mysql administrator's mysql user  name who controls mysql:\n
(16 characters maximum)\n";
die if !query();
$mysqlname = $_;
$row[7] =~s/\"\"/\"$_\"/;
$mysql = "mysql";
foreach $key(keys(%ENV)){
if ($key eq 'PATH'){
$field = $ENV{$key};
 printf("%-4.4s: $ENV{$key}\n", $key);}
}#end of foreach
@array = split(/:/, $field);
for ($ct = 0; $ct <= $#array; $ct++){
$mysqlpath = "$array[$ct]/";
chdir($mysqlpath);
print "$mysqlpath\n";
$mysqlpath = "" if !-x $mysql;
last if -x $mysql;}
if(!-x $mysql){
for (;;){
print "Please enter the path for $mysql including the trailing slash?\n";
$mysqlpath=&query();
last if -d $mysqlpath;}#end of for
}#end of if
print "$mysql exists in your path:\n" if -x $mysql;
for (;;){
print <<EOF;
$0 uses the data path to look for of .my.cnf if you are logged as root.
the default database path is:
/usr/local/var/ if mysql was a source build
or /usr/local/mysql/data/ if mysql was a binary build
is this correct?(B, S, N)
EOF
next if !query();
if (uc($_) eq 'S'){
$datapath = "/usr/local/var/";}
elsif (uc($_) eq 'B'){
$datapath = "/usr/local/mysql/data/";}
else {
print
"Enter the absolute path with the trailing / for the mysql database files:\n";
next if !query();
$datapath = $_;}
$row[11] =~s/\"\"/\"$mysqlpath\"/;
print <<EOF;
Enter the default database name for the program to open:
We suggest either mysql or test as your first database because you
need an open database for the socket or the pipe to run successfully.
EOF
next if !query();
$db = $_;
last if length($_);
last if -d $db && $username eq 'root';}#end of for
$row[8] =~s/\"\"/\"$_\"/;
$row[9] =~s/\"\"/\"$datapath\"/;
chdir($datapath);
print "The database directory $db is valid\n" if -d $db;
&set_path();
$row[10] =~s/\"\"/\"$userpath\"/;
$out_f = "$0.pl";
&check_exist;
for ($ct = 0; $ct <= $#row; $ct++){
print OUTFILE "$row[$ct]\n";}#end of for
close($OUTFILE);
$sql=chmod(0755, $out_f);
print "The file $userpath$out_f is now executable.\n" if -x $out_f;
print <<EOF;
The new working directory is:
$userpath
type M or m for the menulist at the menu prompts, or quit or Quit to exit $0.
This program will now contimue running with your new settings. Please use the
new file $out_f
for this user. Edit the file my-example.cnf wich is located where specified
in the mysql manual. You can copy it to~.my.cnf to save entering your mysql
password. If you are logged as root edit a copy of .my.cnf and place it in the
/etc or the $datapath directory. the line containg:

#password = mypassword
should be uncommented and changed with your mysql password. You can also add:

user = barryp
This saves typing the mysql user name each time. Replace barryp with your mysql
username. $out_f asks for your system user name and your system password.
http://www.hurontel.on.ca/~barryp/index.html
barryp\@hurontel.on.ca
gliddle\@hurontel.on.ca
Do you wish to display some help before you begin for the first time?(Y, N)
EOF
return if !&query();
if (uc($_) eq 'Y'){
&menu_help;}
`pwd`;
$sql = "";}#end of admin

sub check_exist{#check and open an output file
print "Replace $out_f?(Y, N)" if -e $out_f;
&query() if -e $out_f;
if (uc($_) eq 'Y'){ 
unlink $out_f;}
if ($mp ne '7'){
 unless(open(OUTFILE, ">$out_f")){
 warn("cannot open the output file $out_f\n");
&error_file;}
}
}#end of check_exist

sub query{#the input line
$_ = <STDIN>;
chomp($_);
if ($_ eq 'p' || $_ eq 'P'){
&case;
return if !query();}
if (length($_)){
if ($case_val==1){
tr/a-z/A-Z/;}
if ($case_val==2){ 
tr/A-Z/a-z/;}
if ($mp ne 'N' || $mp ne '3'){
unless( /^[0-9a-zA-Z!@#\\\~\$\%\^\&\*\(\)\+\ = \{\}\[\]\,\.\/\s\n_\?-]+$/){
warn("The input line is not allowed, please try again!\n>");
return if !query();}
}
}#end of if
if (uc($_) eq 'Q' && !$menucall){
return($_ = $sql = $mp = "");}
print "$_\n" if $case_val;
if (uc($_) eq 'QUIT'){
quit();
die("Thank you for using $0:\n");}
$_;}#end of query

sub password{#system username and password
my $password_ask;
$SIG{'INT'} = 'IGNORE';#prevent control+c from stopping program
#$SIG{'INT'} = 'DEFAULT';# control+c can now stop program
 $pgroup = getpgrp(0);
$username = getpwuid($ <);
print <<EOF;

Welcome  to $0! The name of the mysql monitor is $mysql. Type QUIT or
quit to exit at most prompts. Control-C is disabled for the duration of this
program. Type m and press enter for menu commands.
EOF
$password_ask=0; #set to 1 if you want the system username and password
if ($password_ask){
print
"Enter your user name for this machine, if you ar logged as root enter root:\n";
$case_val=2;
&case;#comment the portions of this function to satisfy your needs
die "Thank you for using $0\n" if !&query;
 $pgroup = getpgrp(0);
if ($username ne $_){
die "The user $_ is not allowed on this computer:\n";}
print "Enter your current password for this machine:\n";
$pwd =(getpwuid($username))[1];
 system "stty -echo";
 $passwd = <STDIN>;
 system "stty echo";
chomp($passwd);#comment if using shadow passwords or for security
if (crypt($passwd, $pwd) ne $pwd){
quit();
die("Incorrect password: goodbye!\n");}
}
&admin if $mysqlname eq ""; 
return($username,$passwd);}#end of password

sub case{#toggle automatic case conversion
if ($case_val==1){
$case_val = 2;
print "\nCASE CONVERSION IS now set to lowercase:\n";}
elsif ($case_val==2){
$case_val = 0;
print "\nCASE CONVERSION IS now off:\n";}
else {
$case_val = 1;
print "\nCase conversion is SET TO UPPERCASE:\n";}
$case_val;}#end of case

sub open_in_f{#open an input file
undef @row;
 unless(open(IN_FILE, "$in_f")){
 warn("cannot open the input file\n$in_f\n");
&error_file;}
print "loading $in_f.\n" if -f $in_f;
 @row = <IN_FILE>;
close(IN_FILE);
chomp(@row);
return($in_f,@row);}#end of open _in_f

#Display the subdirectories of the current directory and the menu options.
sub file_check{#what type of file
 print "Enter the name of the file to check:\n";
my $name = &ans();
if (-l $name){
lstat($name);
} else {
stat($name);}
 print "Testing flags for $name \n";#looking for wc
chdir "/usr/bin";
if (-x "wc"){
print " Lines Words Characters	Name\n";
$wc = "|wc $name";
unless(open(MH, "$wc")){
warn("Can't open wc with $tmp\n");}
close($MH);}
system "ls -l $name";
 print "\n is readable" if ( -r $name);
 print "\n is writable" if ( -w $name);
 print "\n is executable" if ( -x $name);
 print "\n is owned " if ( -o $name);
 print "\nReal User ID tests ";
 print "\n is readable" if ( -R $name);
 print "\n is writable" if ( -W $name);
 print "\n is executable" if ( -X $name);
$tmp = -O $name;
 print "\n is owned by group $tmp " if ( -O $name);
 print "\nReality Checks ";
 print "\n is a file " if (-f $name);
 print " that exists " if ( -e $name);
 print " has zero bytes " if ( -z $name);
if ($tmp = -s $name){
 print " has $tmp bytes in it\n" if ( -s $name);
 print "\n is a Text file " if (-T $name);}
 print "\n is a directory " if (-d $name);
 print "\n is a link " if (-l $name);
 print "\n is a socket " if (-S $name);
 print "\n is a pipe " if (-p $name);
 print "\n is a block device " if (-b $name);
 print "\n is a character device " if (-c $name);
 print "\n has setuid bit set " if (-u $name);
 print "\n has sticky bit set " if (-k $name);
 print "\n has gid bit set " if (-g $name);
 print "\n is open to terminal " if (-t $name);
 print "\n is a Binary file " if (-B $name);
print $press;
return("") if !query();
 return("");}#end of file_check

sub setpwd{# set a mysql password for a user
 my($user,$pass,$host);
 print "Setting a(new) password for a user.\n";
 $user = user();
 $pass = newpass($user);
 $host = hosts($user);
 print "#"x70;
 print "That was it ... here is an overview of what you gave to me:\n";
 print "The username : $user\nThe password for the user.\n";
# print "The password : $pass\n";
 print "The host : $host\n";
 print "#"x70;
 print "\nAre you sure you would like to implement this? (Y, N) ";
 return if !query();
 $no=$_;
 if ($no =~/n/i) {
 print "Okay .. that was it then.\n\n";
 return(0); }
 else {
 print "Okay ... let's go then.\n"; }
 $user = $dbh->quote($user);
 $host = $dbh->quote($host);
 if ($pass eq '') {
 $pass = "''";
 } else {
 $pass = "PASSWORD(". $dbh->quote($pass) . ")"; }
 my $sth = $dbh->prepare(
 "update user set Password = $pass where User = $user and Host = $host")
 || warn $dbh->errstr;
 $sth->execute || warn $dbh->errstr;
 $sth->finish;
 print "The password is now set for user $user.\n";}#end of setpwd

sub newuser{# ask for a new mysql user name
my($user);
for (;;){
 print "What username is to be created: ";
$answer=&ans();
 if ($answer) {
 $user = $answer;
 } else {
 print "You must type something ...\nTry again: ";
 next; }
 last; }
 print "The username = $user\n";
 $user;}#end of user

sub user{# ask for a user which is already in the user table
 my($user);
for (;;){
 print "For which user do you want to specify a password: ";
$answer=&ans();
 if ($answer) {
 my $sth = $dbh->prepare("select User from user where User = '$answer'") || warn $dbh->errstr;
 $sth->execute || warn $dbh->errstr;
 my @r = $sth->fetchrow_array;
 if ($r[0]) {
 $user = $r[0]; }
 else {
 print "sorry, user $answer isn't known in the user table.\nTry again: ";
 next; }
 } else {
 print "You must type something ...\nTry again: ";
 next; }
 last; }
 print "The new username = $user\n";
 $user;}#end of newuser

sub newpass{# ask for a new mysql password
 my($user) = @_;
 my($good,$pass,$yes);
 print "Would you like to set a password for $user [y/n]: ";
 $yes = <STDIN>;
 chomp($yes);
 if ($yes =~/y/) {
 $pass=&pass_new();
# print "The password for $user is $pass.\n";
 } else {
 print "We won't set a password so the user doesn't have to use it\n";
 $pass = ""; }
 $pass;}#end of newpass

sub newhosts{# ask for new hosts
 my($good,$host);
 print "We now need to know from what host(s) the user will connect.\n";
 print "Keep in mind that % means 'from any host' ...\n";
for (;;){
 print "The host please: ";
$answer=&ans();
 if ($answer) {
 $host .= ",$answer";
 print "Would you like to add another host [y/n]: ";
 $yes=uc(&query());
 if ($yes =~/y/i) {
 print "Okay, give us the host please: ";
 next; }
 else {
 print "Okay we keep it with this ...\n"; }
 } else {
 print "You must type something ...\nTry again: ";
 next; }
 last; }
 $host =~s/^,//;
 print "The following host(s) will be used: $host.\n";
 $host;}#end of newhosts

sub hosts{# ask for a host which is already in the user table
 my($user) = @_;
 my($good,$host);
 print "We now need to know which host for $user we have to change.\n";
 print "Choose from the following hosts: \n";
 $user = $dbh->quote($user);
 my $sth = $dbh->prepare("select Host,User from user where User = $user")
 || warn $dbh->errstr;
 $sth->execute || warn $dbh->errstr;
 while(my @r = $sth->fetchrow_array) {
 print " - $r[0] \n"; }
for (;;){
 print "The host please? (case sensitive): ";
$answer=&ans();
 if ($answer) {
 $sth = $dbh->prepare(
 "select Host,User from user where Host = '$answer' and User = $user")
 || warn $dbh->errstr;
 $sth->execute || warn $dbh->errstr;
 my @r = $sth->fetchrow_array;
 if ($r[0]) {
 $host = $answer;
 last; }
 else {
 print "You have to select a host from the list ...\nTry again: ";
 next; }
 } else {
 print "You have to type something ...\nTry again: ";
 next; }
 last; }
 print "The following host will be used: $host.\n";
 $host;}#end of hosts

sub quit{# a nice quit(first disconnect and then return
if ($no_err){
 $dbh->disconnect;
print "Disconnecting from $mysql:\n";
print "Now using the pipe:\n" if uc($_) ne 'QUIT';
return($no_err = 0,$choosenum=""); }
}#end of quit

sub q1{#mysql permisions
 my($end,$response);
&socket if $no_err==0;
 while(!$end) {
print <<EOF;
 Welcome to the permission setter $version for MySQL. Created by Luuk de Boer

 1. Set the password for a user.

 2. Add a database + user privileges for that database. The database must
not exist. - the user can do all except all admin functions

 3. Add user privileges for an existing database.
 - the user can do all except all admin functions

 4. Add user privileges for an existing database.
 - theuser can do all except all admin functions + no create/drop

 5. Add user privileges for an existing database.
 - the user can do only selects(no update/delete/insert etc.)

Type qUIT or quit to exit the program or an empty line or Q or Q  to return.

 Make your choice [1,2,3,4,5,Q,q]:
EOF
for (;;){
return if (!($response=&query()));
 if ($response =~/1|2|3|4|5/) {
 &setpwd if ($response == 1);
 &addall($response) if ($response =~/^[2345]$/);
 if ( !$response){
 print "sorry, hope we can help you next time with mysql permissions\n";
 $end = 1; }
 } else {
 print "Your answer was $response\n  and that's wrong .... Try again\n"; }
 last; }
 }
}#end of q1

sub socket{#toggle socket connection and pipe
chdir($userpath);
$version="1.3";
if (!$no_err){
if (! $DBI::errstr){
#use DBI;
#use Getopt::Long;
#use vars qw($dbh $hostname $opt_user $opt_password $opt_help $opt_host
# $opt_socket $opt_port $host $version);
$dbh=$host=$opt_user=$opt_password=$opt_help=$opt_host=$opt_socket="";
$opt_port=$log_file=0;
&read_my_cnf(); # Read options from ~/.my.cnf
GetOptions("user=s","password=s","help","host=s","socket=s","port=i","option=s");
&get_host();
$dbh=DBI->connect(
"DBI:mysql:mysql:host=$hostname:port=$opt_port:mysql_socket=$opt_socket",
$opt_user,$opt_password, {PrintError=> 0})
|| warn("Can't connect to the mysql server.\n The error: $DBI::errstr");}
$sql="USE $db";
$no_err=1;#this saves a false connection to the socket
$choosenum="or number";
print "The socket connection to $mysql was successful:\n";}
else {
$choosenum="";
quit();}
&pd;# send data through the pipe
return($choosenum,$no_err,$opt_user,$opt_password);}#end of socket

sub pass_new{#called by newpass and replace_record
 system "stty -echo";
 $case_val=0;
 for (;;){
 print "The password for this user please! ";
 $answer = &query();
 system "stty echo";
 print "\n";
 if ($answer) {
 system "stty -echo";
 print "Please type the password again: ";
 my $second = &query();
 system "stty echo";
 print "\n";
 if ($answer ne $second) {
 print "The passwords do not match.  We must begin again.\n";
 system "stty -echo";
 next; }
 else {
 $pass = $answer; }
 } else {
 print "You must type something ...\nTry again: ";
 next; }
 last; }#end of for
return$pass;}#end of pass_new

sub read_my_cnf{
if ($username ne 'root'){
print ".my.cnf was found in $ENV{'HOME'}:\n" if -e "$ENV{'HOME'}.my.cnf";
 unless(open(FH,$ENV{'HOME'} . "/.my.cnf")){
print "Could not open the file .my.cnf:\n";
return 1;}
}else {
chdir("/etc/");
if (-e ".my.cnf"){print "Found .my.cnf in /etc/:\n";}
else{
chdir($datapath);
print "Found .my.cnf in $datapath:\n" if -e ".my.cnf";}
 unless(open(FH, ".my.cnf")){
print "Could not open the file .my.cnf:\n";
return 1;}
}
 while (<FH>) {#print to STDOUT if mysql output commands are enabled
 print STDOUT ("$_") if (length($_) > 2 && $m_o == 1);
if (/^\[(client|perl)\]/i){
 while ((defined($_=<FH>)) && !/^\[\w+\]/) {
if (/^host\s*=\s*(\S+)/i) {
 $opt_host = $1; }
elsif (/^user\s*=\s*(\S+)/i){
 $opt_user = $1; }
elsif (/^password\s*=\s*(\S+)/i){
 $opt_password = $1; }
elsif (/^port\s*=\s*(\S+)/i){
 $opt_port = $1; }
elsif (/^socket\s*=\s*(\S+)/i) {
 $opt_socket = $1; }
 }
}
 }
 close(FH);
chdir($userpath);} #end of read_my_cnf

sub addall{#send user information through the socket
 my ($todo) = @_;
 my ($answer,$good,$db,$user,$pass,$host,$priv);
 if ($todo == 2) {
$db = newdatabase(); }
 else {
$db = database(); }
 $user = newuser();
 $pass = newpass();
 $host = newhosts();
 print "#"x70;
print <<EOF;
 gnThat was it ... here is an overview of what you gave to me:
 The database name : $db
 The username: $user
EOF
print "The password:\n";# print "The password : $pass\n";
 print "The hosts: $host\n";
 print "#"x70;
 print "Are you sure you would like to implement this? (Y, N) ";
 my $no = uc(&query());
 if ($_ eq 'N'){
 print "Okay that was it then .\n\n";
return(0); }
 else {
 print "Okay let's go then:\n"; 
 if ($todo == 2) {# create the database
my $sth = $dbh->do("create database $db") || $dbh->errstr; }
 if (($todo == 2) || ($todo == 3)) {
$priv = "'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'"; }
 elsif ($todo == 4) {
$priv = "'Y','Y','Y','Y','N','N','N','Y','Y','Y'"; }
 elsif ($todo == 5) {
$priv = "'Y','N','N','N','N','N','N','N','N','N'";
 } else {
print "Sorry, choice number $todo isn't known inside the program ..\n";
return;}
  my @hosts = split(/,/,$host);
  $user = $dbh->quote($user);
  $db = $dbh->quote($db);
  if ($pass eq '')  {
 $pass = "''";  }
  else  {
 $pass = "PASSWORD(". $dbh->quote($pass) . ")"; }
  foreach my $key (@hosts)  {
 my $key1 = $dbh->quote($key);
 my $sth = $dbh->prepare(
 "select Host,User from user where Host = $key1 and User = $user") 
 || warn $dbh->errstr;
 $sth->execute || warn $dbh->errstr;
 my @r = $sth->fetchrow_array;
 if ($r[0]) {
   print "WARNING! SKIPPING CREATE FOR USER $user AND HOST $key\n";
   print "Reason: The entry already exists in the user table.\n"; }
 else {
   $sth = $dbh->prepare(
   "insert into user (Host,User,Password) values($key1,$user,$pass)")
   || warn $dbh->errstr;
   $sth->execute || warn $dbh->errstr;
   $sth->finish; }
 $sth = $dbh->prepare(
 "INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Grant_priv,References_priv,Index_priv,Alter_priv) VALUES ($key1,$db,$user,$priv)")
 || warn $dbh->errstr;
 $sth->execute || warn $dbh->errstr;
 $sth->finish;  }#end of foreach
  $dbh->do("flush privileges") || print "Can't load privileges\n";
  print "Everything is inserted and mysql privileges have been reloaded.\n";}
}#end of addall

sub get_host{#check the host name
if ($opt_host eq ''){ 
$hostname="localhost";}
else {
 $hostname=$opt_host;}
&mysql_password;
return($opt_host,$hostname,);}#end of get_host

sub mysql_password{#mysql user name and password
if (!$no_err){
if (!$opt_user){
print "Enter your mysql user name:(up to 16 characters maximum)\n";
return if !($opt_user=&ans());}
if (!$opt_password){
print "Enter your mysql password(up to 16 characters maximum) or leave the\nfield blank:";
 system("stty -echo");
$opt_password = <STDIN>;
 system("stty echo");
print"\n";
chomp($opt_password);}
$mysqlword = " "; #if there is no password specified
$mysqlword = "-p" if $opt_password;}
return($opt_user,$opt_password);}#end of mysql_password

sub parameters{#must be root and logged as the mysql user with all privileges
if (($username eq "$root" || $opt_user eq "$mysqlname") ||
$opt_user eq "$mysqlname"){
my $tmp=$no_err;
print "Enter the new parameters for mysql or leave the field blank: `$parms'\n";
$no_err=0;
$answer=&ans();
$no_err=$tmp;
$parmstemp=$parms =$answer;}
else {
print "You must be root or a privileged user to change mysql parameters:\n";}
return($parms,$parmstemp);}#end of parameters

sub newdatabase{# ask for a new database name
 my($good,$ct,$answer);
for (;;){
 print "Which database would you like to create?  \n";
$sql="SHOW DATABASES";
&pd;
$answer=&ans();
for ($ct=1;$ct<=$#rf; $ct++){
if ($rf[$ct] eq $answer){
 print "sorry, this database name is already in use; try another name:\n:";
 $good = 1; 
last;}
else {
$good=0;}#end of else
}#end of for
 last if ($good == 0); }#end of for
 $db = $answer;
 print "The new database $db will be created and opened.\n";
 if ($mp eq 'I'){
$sql="CREATE DATABASE $db";
&pd;
$sql="USE $db";
&pd;
$sql="SHOW TABLES";}
 $db;}#end of newdatabase

sub dump_name{#dump a databaseor table
my($dn,$dbx,$quick);
print "Make a compact file `--quick' or slower large file or a table? (C, L, T)\n";
&query();
$tbl_n =$_;
$quick=" -a --add-drop-table --add-locks ";
$quick='--opt ' if uc($_) eq 'C';
$dbx=$db;
$sql = "show databases";
&pd;
if (uc($_) eq 'T'){
&table_open ($t_n);}
print "Enter the name $choosenum of the database to dump to a file:\n";
return if (!($db=&ans()));
$sql="USE $db";
&pd;
$dn = "$db.txt";
print "The database is $db\n";
print "The file name is $dn\n";
if (-e $dn){
print "The file $dn exists! Replace it?(Y, N)\n";
return if !query();
return if uc($_) eq 'N';
unlink($dn) if uc($_) eq 'Y';}
if (uc($tbl_n) eq 'T'){
$tbl_n=" $t_n";}
else {
$tbl_n="";}
print "Create data, table structure or both data and structure? (D, S, B)\n";
$quick= " -d$quick" if uc($_) eq 'S';
$quick= " -t$quick" if uc($_) eq 'D';
system(
"mysqldump $quick-u $mysqlname $mysqlword$opt_password $db$tbl_n>$dn\n");
print "$dn has been created in the directory:\n$userpath\n" if -e "$dn";
$db=$dbx;
$sql="USE $db";
&pd;}#end of dump_name

sub database{#open an available database
 my ($good,$answer);
for (;;){
print "\nWhich database name $choosenum would you like to select?\n";
$sql="SHOW DATABASES";
&pd;
$answer=&ans();
$good = 0;
if ($no_err){
for ($tmp=1;$tmp<=$#rf;$tmp++){
if ($rf[$tmp] eq "$answer"){
$good=1;
$db=$rf[$tmp];
last;}
}#end of for
 }else {
$good=1;}
last if $good == 1;}#end of for
 $db = $answer;
 print "The database $db will be used.\n";
if ($mp eq 'S' ||$mp eq '9') {
$sql="USE $db";
&pd;
$sql="SHOW TABLES";
&pd;}
 $db;}#end of database

sub set_path{#set a directory path
for (;;){
if($mp ne 'Y' || $mp eq 'Z' || $mp ne '3'){
print <<EOF;
Please make shure that you choose a read/write/execute directory so that the
output file may be made executable. You may move it to a directory in
your path such as ~/bin/.
EOF
}
print <<EOF;
Do you wish to use
$currdir
as your default user directory? (Y, N)
EOF
query();
if (uc($_) eq 'Y'){
$userpath=$currdir;}
else{
print "Enter the absolute path for your files with the trailing /:\n";
$tbl=1;
next if !&ans();
$userpath = $_;
$tbl=0;}
chdir($userpath) if -d $userpath;
print "The directory is executable.\n" if -x $userpath && $mp ne 'Y';
last if -d $userpath;}#end of loop
$userpath;}#end of set_path

sub send_ascii_mysql{#send large blocks of data through the pipe
&socket if $no_err;
$file=&mysqlfile($tmp);
&open_mysql;#read/write
open(FH, " $file") or warn "can't send $file: $!";
while(<FH>){
print MH "$_" if length($_)>2;}
close(MH) || warn "close: status = $?";
&socket if !$no_err;
$sql="FLUSH PRIVILEGES" if $db eq 'mysql';
&pd if $db eq 'mysql';}#end of send_ascii_mysql

sub mysqlfile{
&table_open($t_n) if $tmp eq 'D';
print"Are the files located in:\n$userpath: (Y,N) ";
&query();
&set_path if uc($_) ne 'Y';
print <<EOF;
mysql uses its default data directory
$datapath.
The database directory is appended.
EOF
for (;;){
print "Enter the file name to send to mysql or leave the line blank:\n";
$file=&ans();#could be a long file
$file="$userpath$file";
print "$file\n";
last if -e $file;}#end of for
$file;}#end of mysqlfile

sub send_greg_mysql{#send large blocks of data through the pipe
&socket if $no_err;
$file=&gregfile();
&open_mysql;#read/write
open(FH, " $file") or warn "can't send $file: $!";
while(<FH>){
print MH "$_" if length($_)>2;}
close(MH) || warn "close: status = $?";
&socket if !$no_err;
$sql="FLUSH PRIVILEGES" if $db eq 'mysql';
&pd if $db eq 'mysql';}#end of send_greg_mysql

sub gregfile{
print "Using the default database $db\n";
$sql="SHOW TABLES";
&pd;
for (;;){
print "Enter the file name to send to mysql or leave the line blank:\n";
return if (!($file=&ans()));#could be a long file
last if -e $file;}#end of for
$file;}#end of gregfile

sub send_outfile{#output a | delimited file 
print "Using the default database $db\n";
&table_open($t_n);
&socket if $no_err;
$out_f="$userpath$t_n.$ext";
&check_exist();
$sql="SELECT * FROM $t_n INTO OUTFILE '$out_f' FIELDS TERMINATED BY '|'";
&pd;
print "The file $out_f has been created.\n" if -e "$out_f";
&socket if !$no_err;}#end of send_outfile

sub out_ext{#set the output file extention for table output
print "Enter the extention for table output files without the leading period `$ext':\n";
$ext=&ans();}#end of out_ext

sub new_table($sql){#create a new table
my($index_total,$i_f_total,$tmp,$ct,$field_total,$default,$default_str,
$total,$i,$xt,$answer,$options,@fs);
@rf="";#used in pd()
print "warning: The mysql database is active!\n" if $db eq $mysql;
print <<EOF;

    If you wis to have an AUTO_INCREMENT field in your table, create the fields
here and use the`h' command to add an AUTO_INCREMENT field later, this
creates another index. Each primary index may have up to 16 fields.
You are allowed one primary index and several other indexes. The program allows
you the opertunity to create an AUTO_INCREMENT field `H' which must be indexed.
The AUTO_INVREMENT field will be placed as the last field in the table. If you 
make an error when creating the table fields, you are allowed to select a
field name by choosing 0 at the field name or field type promptwith each 
field. You may choose fields by their number when creating your indexes.
When your finished creating fields for your table, Please leave the line blank
when asked for a field name. This also applies to the fields in your indexes.
You will also be able to select the field type by number when creating fields.

   Would you like a default string for any of the fields in your table?(Y, N)
EOF
return if !query();
$default = "1" if uc($_) eq 'Y';
$fs[0]="CREATE TABLE $t_n(\n";
for ($tmp=1, $field_total=1; $tmp <=255; $tmp++, $field_total++){
$options="";
printf("%d: Please enter a field name or 0 to go back:",$tmp) if $tmp >1;
print "Please enter a field name:" if $tmp ==1;
$answer=&ans();
 $answer=~s/ +//g;
last if $answer eq "";
if ($answer == 0 && -d $answer){
print
"Enter the number of the field that you want to correct between 0 and $tmp:\n";
$ct=$tmp;
$tmp=query();
if ($tmp >$ct ||$tmp==0){
$tmp=$ct;}
$tmp--;
$field_total=$tmp;
next;}
$fs[$tmp]="$answer ";
$rf[$tmp]=$answer;
print <<EOF;
Type the name or number of one of the field types: The options are in brackets.

 1 TINYINT[(length)] [UNSIGNED] [ZEROFILL] 2 INT[(length)] [UNSIGNED] [ZEROFILL]
 3 SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
 4 MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
5 INTEGER[(length)] [UNSIGNED] [ZEROFILL]
 6 BIGINT[(length)] [UNSIGNED] [ZEROFILL]
7 REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
8 DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
9 FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
 10 DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
 11 NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]
12 CHAR(length) [BINARY] 13 VARCHAR(length) [BINARY]
14 DATE 15 TIME 16 TIMESTAMP 17 DATETIME
18 TINYBLOB 19 BLOB 20 MEDIUMBLOB 21 LONGBLOB
22 TINYTEXT 23 TEXT 24 MEDIUMTEXT 25 LONGTEXT
 26 ENUM(value1,value2,value3,...) 27 SET(value1,value2,value3,...)

Enter the field type name in either upper or lower case.
varchar char decimal float int enum etc: Parenthesys
are provided for you, when setting the field width. the field width is
requested in another question if required.
EOF
&query();
if (/\d/ && (($_>0) && ($_ < 28))){
$answer = $rt[$_];}
else {
$answer = $_;}
print "$answer is the field type you chose:\n";
$fs[$tmp].= "$answer";
$_=$answer;
if (/BLOB/ || /DATE/ || /TIME/ || /date/ || /time/ ||/blob/ || /TEXT/
|| /text/ || /INT/ || /int/){
print "This field requires no options.\n";
if ($default){
if (/BLOB/ || /TEXT/ || /blob/ ||/text/){
print "The default string is limited to 150 characters because each field
is sent as one line to allow for editing.";}
print "Enter the default string for this field\n";
return if !query();
$default_str = $_;}#end of default
$fs[$tmp].=" DEFAULT '$default_str' NOT NULL,\n";
next;}#end of if
elsif ($_ eq 'SET' || $_ eq 'set' || $_ eq 'ENUM' || $_ eq 'enum'){
print
"This field accepts several values, check the mysql database for examples:\n";}
elsif ($_ eq 'CHAR' || $_ eq '' || $_ eq 'VARCHAR' || $_ eq 'varchar'){
print "Do you wish to use the BINARY option for this field? (Y, N)";
&query();
$options="";
$options=" BINARY" if uc($_) eq 'Y';
$_="";
print
"Enter the number of characters for this field. (255 is the maximum allowed)\n";}
else {
print <<EOF;
Do you want to add an extended option for this field? Type the option as
specified in the brackets or leave the field blank. Please type one of the
special options such as UNSIGNED. The width and decimals are next.
EOF
$options=&query();
$options=" $options" if length($_)>0;
print <<EOF;
the parenthesys are provided for you. You only need to type the values.
E.G.
6,2
would return6 digits with 2 decimal places. 123456.78
The This is shown in the table as:
(6,2)
or as:
6
The table definition shows:
(6)

Now the field width ollowed by an optional `,' and a number for the decimals:
EOF
}
return if !query();
$fs[$tmp].="($_)$options";
if ($default){
print
"Enter the default string that goes inside the single quotes for this field\n";
return if !query();
$default_str = $_;}#end of default
$fs[$tmp].=" DEFAULT '$default_str' NOT NULL,\n";}#end of for and field input
print <<EOF;
Indexing of your table:

     The field names must exist. They cannot be duplicated in an index. you may
also type a field number instead. Blob and text  type fields may not be used
in any index. The sum of the field withs may not exceed 255 in the primary index
you cannot set the field with in a primary index. Field names may be in any
order you wish, the first field you choose is the primary field. If you wish to
add any extra indexes, you will be asked for them later where you may specify an
index width, 10 is reccommended as a maximum index field with for optimization.

     You may dump the table with the `Z' command and you
can replace it with the `3'  command if you make an error or change your mind.
the command sent to mysql is automatically saved in the capture array,
which you can save to file with the `b' command.You can use the `3' command
to send the file to mysql.

Leave the field blak when asked for a field name to terminate your index.
EOF
$tmp++;
$fs[$tmp]="PRIMARY KEY(";
for($i=1, $i_f_total=1; $i_f_total <=15; $i++, $i_f_total++){
for ($ct=1, $tx=1; $ct<=$#rf;$ct++, $tx++){
printf("%d:  %s\n",$ct, $fs[$ct]);
if ($tx %20 ==0){
$tx=0;
ret();}
}#end of for
print "Please enter a field name or number for your primary index?\n";
$answer=&ans();
last if $answer eq "";
$_=$answer;
if ($_ && /\d/ && $_ == $#rf){
$answer = $rf[$_];}
else {
$answer = $_;}
$fs[$tmp].="$answer,";}#end of for and primary index
chop $fs[$tmp];
$fs[$tmp].="),\n";#secondary indexes
$total=$field_total - $i_f_total;
$tmp++;
print <<EOF;
Each field name you choose becomes an index name.
They may be in any order you wish. You may not duplicate the index names in
your primary index. You may have  up to $total indexes.
EOF
for ($i = 1; $i <= $total; $i++, $tmp++){
for ($ct=1; $ct<=$#rf;$ct++, $tx++){
printf("%d:  %s\n",$ct, $fs[$ct]);
if ($tx %20 ==0){
$tx=0;
ret();}
}#end of for
print "Enter the field name or number of your index:\n";
$answer=&ans();
$_=$answer;
if ($_ && /\d/ && $_ == $#rf){
$answer = $rf[$_];}
else {
$answer = $_;}
print "Your answer is $answer:\n";
last if $answer eq "";
$fs[$tmp]="KEY index_$answer ($answer(";
printf(
"%d:  %s Now the width of the field $answer:",
$i, $fs[$tmp]);
&query;
$fs[$tmp].="$_)),\n";}#end of for
$tmp--;
chop $fs[$tmp];
chop $fs[$tmp];
$tbl = 1;
$fs[$tmp].=")";
for ($ct=0; $ct<=$#fs; $ct++){
$sql.="$fs[$ct]" if length($fs[$ct])>0;}
&pd;
$tbl=0;}#end of new_table

sub ans{#ask for a case sensitive request
my ($xt,$tp);
$xt=$case_val;
$tp="Numpers take priority in database, table and field names:\n";
$case_val=0;
print
"\nThis is a case sensitive request, your previous case setting will be restored.\n"
if $xt>=1;
$answer=&query();
$_=$answer;
 if ($no_err==1 && $tbl==0 && /\d/ && ($_<= $#rf && $_>0&& length($rf[$_])>0)){
 print $tp if $xt>=1;
 $answer = $rf[$_];}
$case_val=$xt;#return to the previous case setting
$answer;}#end of ans

sub table_open($t_n){#open a table
my($ct,$searchforskip,$search_for,$tmp,$enter,$data,$final,$alter,$field_q,$field);
$final = "( this action is final!)\n";
$enter = "Enter the name $choosenum of the table to ";
$alter = "ALTER TABLE ";
$tbl = 0;
$sql = "SHOW TABLES";
&pd;
return if $mp eq 'T';
print "$enter";
if ($mp eq '/' && $db ne "mysql"){ 
print "drop: $final";}
elsif ($mp eq 'D'){ 
print "describe: ";}
elsif ($mp eq 'Q'){ 
print "query: ";}
elsif ($mp eq 'R'){ 
print "replace a record: ";}
elsif ($mp eq 'A'){ 
print "insert a record: ";}
elsif ($mp eq 'W'){ 
print "count records: ";}
elsif ($mp eq 'G'){ 
print "optimize: ";}
elsif ($mp eq 'U'){
print "update: ";}
elsif ($mp eq '3'){ 
print "send to mysql: ";}
elsif ($mp eq 'H'){ 
print "aadd an AUTO_INCREMENT field: ";}
elsif ($mp eq '['){ 
print "delete a record from: $final ";}
elsif ($mp eq 'N'){ print "create: ";}
else { 
print "open: ";}
$t_n=&ans();
print "The table name is $t_n:\n";
if ($mp eq 'N'){
&new_table($sql);
return;}
$sql = "DESCRIBE $t_n";
$tbl=1 if $mp eq 'D';
 $tbl = 2 if $mp eq 'R' || $mp eq 'A';
if ($mp eq 'W'){
$sql = "SELECT COUNT(*) FROM $t_n";
return;}
&pd;
return if $mp eq 'D' || $mp eq '3';
if ($mp eq 'Y' && $db ne "mysql"){
print "Drop the table $t_n:(Y, N)\n";
return if !query();
if (uc($_) eq 'Y') {
$sql = "DROP TABLE $t_n IF EXISTS $t_n";
print $sql;
&pd;
print "The table $t_n has been dropped.\n";}
return;}
elsif ($mp eq 'Y' && $db eq "mysql"){
print "Cannot drop a table in the mysql database!\n";
return;}
elsif ($mp eq 'G'){
$sql = "optimize table $t_n IF EXISTS $t_n";
print $sql;
print "The table $t_n has been optimized.\n";
return;}
 elsif ($mp eq 'A' || $mp eq 'R'){ 
&replace_record;
return;}
elsif ($mp eq '1'){
&row_cryteria($t_n);
return;}
elsif ($mp eq '['){
print "Delete the following field: $final";}
elsif ($mp eq '{'){
print "Delete the following records: $final";}
print "Please enter a field name $choosenum to search:\n";
$tbl = 0;
return if !($field=&ans());
if ($mp eq 'H'){
print "adding the AUTO_INCREMENT field $field.\n";
$sql =
"$alter$t_n ADD $field INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD INDEX($field)";
return; }
elsif ($mp eq '[' &&$db ne "$mysql"){
$sql = "$alter$t_n drop $field";
print "Deleting the field $field from the table $t_n\n";
return;}
elsif ($mp eq '[' &&$db eq "$mysql"){
print
"Cannot delete the field $field from the table $t_n\n The database is $mysql:\n";
return;}
$tbl = 1;
print "please enter a portion of an ambiguuous search string:\n";
return if !query();
$search_for = $_;
if ($mp ge 'E' && $mp le 'F'){
&socket if $no_err;
if ($mp eq 'F'){
$sql = "DESCRIBE $t_n";
&pd;
print "Now enter the field name $choosenum to skip to:\n";
return if !($searchforskip=&ans());}#end of F
$sql = "DESCRIBE $t_n";
&pd;
$tbl = 0;
print "Please enter a terminating field name $choosenum to search:\n";
return if !($field_q=&ans());
$data = "select $distinct(";
for($ct = 0; $ct <= $#rf; $ct++){
last if $rf[$ct] eq $field;}
for(; $ct <= $#rf; $ct++){
$data.= " $rf[$ct],";
last if $rf[$ct] eq $field_u;
if ($mp eq 'F'){
for(; $ct <= $#rf; $ct++){
last if $rf[$ct] eq $searchforskip;}
$data.= " $rf[$ct],";}
}#end of for
chop($data);
$tbl = 1;
$sql = "$data) from $t_n where $field $like '%$search_for%'";
&pd;}#end of E F
if ($mp eq '{' && $dv eq "$mysql"){
print "Cannot delete the record from $t_n\ because the database is $mysql:\n";
return;}
elsif ($mp eq '{' && $dv ne "$mysql"){
$sql = "delete from $t_n where $field $like '%$search_for%'";
print "Deleting the record from $t_n\n";}#end of delete
elsif ($mp eq 'Q'){
if ($db eq 'mysql' && $t_n eq 'user' && $opt_user
eq "$root" && $field eq "Password"){
$search_for = "PASSWORD('$search_for'),";
$sql = "select $distinct * from $t_n where $field $like '$search_for'";}
else {
$sql = "select $distinct * from $t_n where $field $like '%$search_for%'";}
$tbl = 1;}#end of q
elsif ($mp eq 'U'){
$tbl = 0;
$sql = "DESCRIBE $t_n";
&pd;
print "enter a field name $choosenum to update\n";
return if !($field_q=&ans());
if ($fieldname eq uc($field_q) && $no_err){
loadtext();}
else{
print "Now the replacement data:\n";
return if !query();
$replace = $_;}
if ($db eq 'mysql' && $t_n eq 'user' && $opt_user
eq "$root" && $field eq "Password"){
$replace = "PASSWORD('$replace'),";}
$sql = "update $t_n set $field_u = \"$replace\" where $field = \"$search_for\"";
$tbl = 1;
&pd;}
}#end of table_open

sub dbf2mysql($t_n){
if (!$db){
&database;}
&socket if $no_err;
print "List field files and write them to disk ?(Y, N)\n";
return if !query();
$file_prompt = uc($_);
if ($file_prompt eq 'Y'){
print "Prompt for files ?(Y, N)\n";
return if !query();
$field_prompt = uc($_);
print "Send field structure to mysql?(Y, N)\n";
return if !query();
$mysql_field = uc($_);
&field_create;}
print "INsert records, Find records, Replace records, or quit?(I, F, R, Q)\n";
return if !query();
$record = uc($_);
if ($record eq 'F'){
&find_record;
} else {
&insert_record;}
$sql = "";#prevent duplication
@file_list = "";
&socket if !$no_err;
@row = "";}#end of dbf2mysql

 sub insert_record{#insert or replace records from text files
if ($record eq 'R' ||$record eq 'I'){
print "Send data to mysql?(Y, N, Q)\n";
return if !query();
$mysql_record = uc($_);
print "Enter the extention of the $dbf comma delimited text files\n";
&case if $toggle_case;
return if !query();
&case;
$wildcard = "*.$_";
@file_list = glob($wildcard);
$record_start = 0;
for($ct = 0; $ct <= $#file_list; $ct++){
$in_f = $file_list[$ct];
if ($field_prompt eq 'Y'){
print "$in_f\n";
&file_ask;
print "Enter the record number to start or 0 if you wang all the records?\n";
return if !query();
 s/\D//g;
$record_start = $_;}
&open_in_f($in_f);
$t_n = uc($in_f);
$t_n =~s/\.ASC//;
$out_f = "$t_n.MSC";
$replace_f = "$t_n.RSC";
&check_exist;
 unless(open(REPLACEFILE, ">$replace_f")){
 warn("cannot open the output file $replace_f\n");
&error_file;}
if (uc($field_prompt) eq 'Y'){
print "$replace_f and $out_f\n";}
print OUTFILE("use $db;\n");
print REPLACEFILE("use $db;\n");
$replace = "REPLACE INTO $t_n VALUES(";
$insert = "INSERT INTO $t_n VALUES(";
for($rn = $record_start; $rn <= $#row; $rn++){
$sql = $row[$rn];
chomp($sql);
$sql.= ");\n";
$sql =~s/\"/\'/g;
$sql =~s/",'/','/g;
$sql =~s/",/',/g;
$sql =~s/"/'/g;
$sql =~s /\0/ /g;
$sql =~s/(\w+)'(\w+)/$1 $2/g;
$sql =~s/(\w+) '(\w+)/$1 $2/g;
$sql =~s/(\w+)'(\w+)/$1`$2/g;
$rst = $sql;
$sql = "$insert$sql";
$rst = "$replace$rst";
if ($mysql_record eq 'Y'){
if (!$rn){
&open_mysql;
print M_F ("use $db;\n IF ESISTS $db;");}
if ($record eq 'I'){
print M_F ("$sql");}
if ($record eq 'R'){
print M_F ("$rst");}
}
print OUTFILE("$sql");
print REPLACEFILE("$rst");}#end of inner loop
print OUTFILE("\n");
print REPLACEFILE("\n");
close(OUTFILE);
close(REPLACEFILE);
close(M_F);}# end of main loop
}
}# end of insert_record

sub find_record{#find records in text file output
print "Enter the extention of the $dbf text files\n";
$answer=&ans();
$wildcard="*.$answer";
@file_list = glob($wildcard);
print "Enter your search text for the logged directory:\n";
$txt=&ans();
for($ct = 0; $ct <= $#file_list; $ct++){
$in_f = $file_list[$ct];
&open_in_f($row);
print "$in_f \n";
$t_n =~s/\.FLD//;
for($rn = 0; $rn <= $#row; $rn++){
$sql = $row[$t_n];
chomp($sql);
if ($sql =~/$txt/){
print "$sql\n";
print "Find the next matching record in the table $t_n?(Y or N)\n";
last if !query();
if (uc($_) eq 'Y'){
next;}
}
}#end of inner loop
}# end of main loop
}#end of find_record

sub field_create{#create the fields from the $dbf text files
print "Enter the extention of the field files\n";
&case if $toggle_case;
return if !query();
&case;
$wildcard="*.$_";
@file_list = glob($wildcard);
for($ct = 0; $ct <= $#file_list; $ct++){
$in_f = $file_list[$ct];
if ($field_prompt eq 'Y'){
print "$in_f\n";
&file_ask;}
&open_in_f($row);
$t_n = uc($in_f);
for($rn = 0; $rn <= $#row; $rn++){#remove the memo field
$fld = $row[$rn];
if ($fld =~/\,"M"\,/){
print "Removing the memo field from $in_f\n";
$fld = "";}
}#end of memo field loop
$t_n =~s/\.FLD//;
$out_f = "$t_n.fld";
&check_exist;
print OUTFILE("use $db;\nCREATE TABLE $t_n(\n");
if ($mysql_field eq 'Y'){
&open_mysql;
print M_F "use $db\nCREATE TABLE $t_n(\n";}
for($rn = 0; $rn <= $#row; $rn++){
$fld = $row[$rn];
if (length($fld)){#skip blank lines
$field_count = 0;# this is table specific for the field to be indexed
if ($t_n =~/C_INV/){
$field_count = 1;}
$fld =~s/\"//g;
$field = $fld;
$field =~s/,/ /g;
@array = split(/ +/, $field);
if ($rn == $field_count){
$primary_field = "PRIMARY KEY($array[0]));";}
$width = $array[2];#widen the character fields because of NULL
$fld =~s/\,C\,/ char(/;
if ($fld =~/char/){
$width++;
$fld =~s/\,0//;
$fld = "$fld) NOT NULL,";} 
$fld =~s/\,D\,8\,0/ date\,/;
$fld =~s/\,N\,/ decimal(/;
if ($fld =~/decimal/){
$fld = "$fld) NOT NULL,";}
$fld =~s/$array[2]/$width/;#change the field width
print OUTFILE("$fld\n");
if ($mysql_field eq 'Y'){
print M_F ("$fld");}
}#end of length
}#end of inner for
if ($mysql_field eq 'Y'){
print M_F ("$primary_field\n");}
print OUTFILE("$primary_field\n");
close(OUTFILE);
close(M_F);}#end of for
}#end of field_create

sub file_ask{#used by $dbf2mysql
print "Skip this file ?(Y, N)\n";
return if !query();
if (uc($_) eq 'Y'){
next;}
}#end of file_ask

sub ret{#an enter prompt
print $press;
&query;}#end of ret


sub loadtext{#TEXT type field
if ($no_err){
print<<EOF;
This field accepts large blocks of text.
The text file must conform to msql standards.
if you wish to have mysql escape characters to appear in your text, be sure to 
preceed them with a backslash `\', outherwise there will be aan error.
Leave the field blank when asked for a file name if you do not want to insert
any text. Enter a file name or leave the field blank?
EOF
load();
my $i=0;
$replace="";
for (; $i<=$#row; $i++){
$replace.="'" if length($in_f) && $i==0 && $mp ne 'U';
$replace.="$row[$i]\n";}#end of for
close($in_f);
if (length($in_f && $mp ne 'U')){
$replace.="'";
$sql.="$replace";}
else{
$sql.="''," if $mp eq 'R' || $mp eq 'A';}
}
else{
$replace="'" if $mp eq 'R' || $mp eq 'A';
for ($i = 0; $i <1000; $i++){
print "Type some text and end the entry with a blank line.\n";
last if !query();
$replace.= "$_\n";}#end of for
if (length($replace>2 && $mp ne 'U')){
$replace.="'";
$sql.="$replace";}
else{
$sql.="''," if $mp eq 'R' || $mp eq 'A';}
}
return($sql,$replace);}#end of loadtext

1;
