#!/usr/bin/perl

my($curdir, $in_f, $out_f, %options, $rec, $code, $c_ct, $case_val, $file, $wct,
$str, $menucall, $dir);

use Cwd;
use Getopt::Long qw(GetOptions);

# Take an initial pass through our options, looking for one of the form
# -<number>.  We turn that into -w <number> for compatibility with the
# original old code.
for (my $i = 0; $i < @ARGV; $i++) {
    last if $ARGV[$i] =~ /^--$/;
    if ($ARGV[$i] =~ /^-(\d+)$/) {
        splice (@ARGV, $i++, 1, '-w', $1);
    }
}#end of for
$rec=0;
 $pgroup = getpgrp(0);
# Parse our options.  Use the same names as  per norm for simplicity.
$curdir=cwd();
$curdir.="\/";
print "$curdir\n";
Getopt::Long::config ('bundling');
$options{sentence} = 0;
GetOptions (\%options,
'wct=i', 'file=s', 'ign=s', 'rec|r', 'help|h', 'dir=s', 'str=s', 'sentence')
or exit 1;
usage () if $options{help};
$wct=$options{wct} if $options{wct};
$rec = 1 if $options{rec};
$code=$options{ign} if $options{ign} ne "";
$str=$options{str} if $options{str} ne "";
if ($options{dir}){
$curdir="$options{dir}/";
print "Changing to $curdir\n";
chdir($curdir);}
$file=$options{file};
print "Searching for $str\n" if $str ne "";
find_record () if $str || $options{file};
menu_list();
for (;;){#the main menu
$sql = $mp = "";
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 'M'){
&menu_list;}
elsif ($mp eq 'I'){
&ignore;}
elsif ($mp eq 'Q'){
&quit;}
elsif ($mp eq 'W'){
&word_file;}
elsif ($mp eq 'R'){
&recursive;}
 elsif ($mp eq 'N'){
 &find_record;}
elsif ($mp eq '5'){
&mysql_view;}
elsif ($mp eq ')'){
&file_check;}
elsif ($mp eq '?'){
&usage;}
elsif ($mp eq '('){
&set_path;}
 else {
 print "Invalid command `$mp':";}
}#end of main

sub menu_list{#the menu after pressing m
print <<EOF;
   ?  help                             )  check the statistics of a file  
   5  display a file                   (  change user path for files
   m  this menu                        n  new search string          
     v  view the capture array         q  quit the program
   r  toggle recursive searches        i  characters to ignore in searches
   w  word file for searches            p  toggle case conversion
EOF
}#end of menu_list

sub usage{#help for the program
print <<EOF;
strfind run in menu mode:
options: --help | -h this message and exit
--str="this is a string"
-r | --rec search recursively
--ign="hello" Ignore the string 'hello'.
--dir="/home" Start in the directory '/home'.
--file="words.txt"  A file to use for multiple searches.
--wct=2
use the second word in each line of the word file selected with --file.
Search for the string in text files in the current directory and below or change
to --dir.  The program will list the line number followed by the file name if
found. The next line contains the line found. The number of words is given if
used. The process number is $pgroup
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.
Character conversion is disabled for file names but it is activated
when the pathe or file name is completed.
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
quit() if $options{help};
}#end of usage

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 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(IN_FILE, ">$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/;}
}#end of length
if (uc($_) eq 'Q' && !$menucall){
return($_ = $sql = $mp = "");}
print "$_\n" if $case_val;
if (uc($_) eq 'QUIT'){
die("Thank you for using $0:\n");}
$_;}#end of query


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");
quit () if ($file ne "") || ($str ne "");
&error_file;}
print "loading $in_f.\n" if -f $in_f && !$str && ! $file;
 @row = <IN_FILE>;
close(IN_FILE);
chomp(@row);
$in_f eq "" if ! -f $in_f;
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 $name\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 ans{#ask for a case sensitive request
my ($xt,$tp);
$xt=$case_val;
$case_val=0;
print
"\nThis is a case sensitive request, your previous case setting will be restored.\n"
if $xt>=1;
$answer=&query();
$_=$answer;
$case_val=$xt;#return to the previous case setting
$answer;}#end of ans

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

sub find_record{#find records in text files
my(@w_l, $wildcard, @dir_list, @file_list, $ct, $rn, $tmp,$i,$x, $str_count,
$num, @array, $f, $d_count, $f_count);

$in_f=$file if $file ne "" && -f $in_f;
if (($file ne "") &&(-T $in_f)){
$wct -- if $wct ne "";
$wct=0 if $wct eq "";
open_in_f($in_f);
if ($in_f ne "" && -f $in_f){
for ($rn = 0, $num =0; $rn <=$#row; $rn++){
$sql=$row[$rn];
@array = split(/ +/, $sql);
next if $#array <$wct;
if (($wct >= 0) && ($wct<= $#array)){
if (length($array[$wct]) > 0){
$w_l[$num]=$array[$wct];
$num++;}
}
else {
for ($x=0; $x <= $#array; $x++){
if (length($array[$x]) > 0){
$w_l[$num]=$array[$x];
$num++;}#end of if
}#end of for
}#end of else
}#end of for
}#end of if
$num =$#w_l;
$num++;
print "$num searches per line.\n";}#end of if
$str_count=0;
$wildcard="*";#this must b * for recursive searches
if (($str eq "") && ($file eq "")){
print "Enter your search string  for the logged directory:\n";
return if !query();
$w_l[0] = $_;}
else {
$w_l[0]=$str;}
$i=$num=$x=0;
$userpath=$curdir if $rec;
for (;;){
$d_count++;
@file_list = glob($wildcard);
for($ct = 0; $ct <= $#file_list; $ct++){
$in_f = $file_list[$ct];
if ((-d $in_f) && $rec == 1){#recursive
$dir_list[$i]="$userpath$in_f/";
$i++;
$f=$i;
next;}
if (-T $in_f){
&open_in_f($in_f);
$f_count ++;
for($rn = 0; $rn <= $#row; $rn++){
$sql = $row[$rn];
next if $sql eq "";
next if (($code ne "") && $row[$rn] =~ /$code/);
for ($num=0; $num<=$#w_l; $num++){
if ($sql =~/$w_l[$num]/){
print "$userpath\n" if $rec  == 1 && $i == $f;
$f++;
$tmp=($rn+1);
print "line $tmp $in_f\n";
print "$sql\n";
$str_count++;
last;}#end of if
}#end of if
}#end of for
}#end of if
}# end of file loop
if (! $rec){
last;}
else {
last if $x == $i;
$userpath=$dir_list[$x];
chdir($dir_list[$x]) if ($i > $x);
$x++ if ($i > $x);}#end of if
}#end of directory loop
print "$str_count strings found in $f_count files, $d_count directories.\n" if $str_count;
chdir($curdir);
quit() if $str || $file;}#end of find_record

sub quit{
die "Thank you for using $0.\n";}#end of quit

sub set_path{#set a directory path
for (;;){
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;
last if -d $userpath;}#end of loop
$userpath;}#end of set_path

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 recursive{#toggle recursive search -r
if ($rec==1){
$rec = 0;
print " recursive search is disabled.\n";}
else {
$rec = 1;
print "Recursive search is now active.\n";}
$rec;}#end of recursive

sub ignore{
print "Enter your string of characters to be ignored in searches:\n";
return if !query();
$code =  &ans();}#end of ignore

sub word_file{#parse a word file and fill @word_list
print "Enter the number of the word on each line to search or 0 for none.\n";
$wct=&query();
$wct =~ /\d/;
print "Enter the path and file name of a file to use for search words:\n";
$file= &ans();
find_record() if $file ne "";}#end of word_file

1;
