#!/usr/bin/perl ####### Start of field definitions - System Config Parameters ######## ####### You will need to check and change these fields ######### ####### Do not change codes outside this section unless asked ####### # This parameter defines what character set you want your visitor's # browser to be set to when viewing your Html pages. # Default is "". Chinese GB = "gb2312". Chinese Big5 = "Big5". $charset = ""; # Field delimitor of your flat ASCII database file # Select only one of the following: "\t"(tab), "\|"(pipe), ","(comma) $delimitor = ","; # Maximum number of DB Fields $maxfields = 8; # Maximum number of matched records for display $maxdisplay = 200; # Max Records to be displayed per screen $maxdispscreen = 10; # "yes" if you want the search to match also non-alphanumeric characters # This will slow down the performance. Default setting is "no" $match_special_chars = "no"; # Pathname of directory in which your database is stored # Location of your database file has to be outside Html directories # NOTE: The last "/" is significant $database_dir = "../"; # Pathname of directory in which your Html templates are stored # NOTE: The last "/" is significant $template_dir = "../"; # Return URL link used by OK and error messages $return_url = "http://www.user-agents.org/index.shtml"; # URL of this cgi program ( free-search.cgi ) in your server $this_cgi_url = "/cgi-bin/free-search.cgi"; # These are the urls that are allowed to execute this program # eg. @valid = ('abc.com','def.com','xyz.net'); @valid = ('user-agents.org'); # Database items can be displayed on the search (summary) report # in alternate colors, eg. grey color for odd items, white color # for even items. $bgcolor0 = "#eeeeee"; $bgcolor1 = "#ffffff"; ####### End of field definitions #### # Parse Form Contents &parse_form; if ($ENV{'REQUEST_METHOD'} ne 'POST') { if (!$ARGV[0] && $ENV{'QUERY_STRING'} !~ /=/) { $in{'template'} = $ENV{'QUERY_STRING'}; $in{'opendb'} = 1; } elsif ($ARGV[0] && !$in{'template'}) { $in{'template'} = $ARGV[0]; $in{'opendb'} = 1; } } # Validate & execute command according to Action Type unless ( $in{'opendb'} || ($in{'action'} eq "showblank") || ($in{'action'} eq "searchdbdisplay")) { &error_not_a_command; } if ($in{'opendb'}) {&showblank} if ($in{'action'} eq "showblank") {&showblank} if ($in{'action'} eq "searchdbdisplay") {&search} sub parse_form { if ($ENV{'REQUEST_METHOD'} eq 'GET') { @pairs = split(/&/, $ENV{'QUERY_STRING'}); } elsif ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); } else { &error_form_method; } foreach $pair (@pairs){ if ($pair =~ /=/) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s///g; $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $in{$name} = $value; } } } sub search { &check_url_referer; &check_template; if ($in{'dbname'}) { &check_dbname; } else { &error_no_db_name; } if ($in{'maxdispscreen'} && # 050303 ($in{'maxdispscreen'} > 0 && $in{'maxdispscreen'} < 1000)) { # 050303 $maxdispscreen = $in{'maxdispscreen'}; # 050303 } # 050303 if ($in{'key2'} && ($in{'key2'} ne "")) { $in{'key'} = $in{'key2'}; } ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); if ($mday < 10) { $mday = "0$mday"; } $month = ($mon + 1); if ($month < 10) { $month = "0$month"; } $year = 1900 + $year; $us_date = "$month/$mday/$year"; $europe_date = "$mday/$month/$year"; open(DB,"$database_dir$dbname"); if ($in{'keywords'}) { if ($in{'keywords'} =~ /^[ ]+$/) { $in{'keywords'} = ""; } else { if ($in{'keywords'} =~ /\&\&/i && $in{'keywords'} =~ /\+\+/i) { # ds &error_invalid_operator_mix; # ds } # ds $keywords_operator = ""; # ds if ($in{'keywords'} =~ /\&\&/i) { # ds $in{'keywords'} =~ s/ *\&\& */&&/i; # ds @keywords = split(/\&\&/,$in{'keywords'}); # ds $keywords_operator = "and"; # ds } # ds elsif ($in{'keywords'} =~ /\+\+/i) { # ds $in{'keywords'} =~ s/ *\+\+ */++/i; # ds @keywords = split(/\+\+/,$in{'keywords'}); # ds } # ds else { # ds if ($in{'keywords_separator_is_comma'} =~ /^yes$/i) { # ds @keywords = split(/ *, */,$in{'keywords'}); # ds } # ds else { # ds @keywords = split(" +",$in{'keywords'}); # ds } # ds } # ds } } &set_content_type; undef @MATCH; undef @MATCHKEY; $mct = 0; open(DB,"$database_dir$dbname"); $keymatched = 0; while () { $row =$_; chop $row; if (!$row || $row =~ /^[ ]+$/) {next;} # Convert all \n in $row to -RET- $row =~ s/\n/ -RET- /g; $row =~ s/\r//g; if ($delimitor =~ /^\|$/i) { @dbfld = split(/\|/,$row); } else { @dbfld = split(/$delimitor/,$row); } $ctss=@dbfld; # if ($ctss < $xct) { # $howmany = $xct-$ctss; # $dbfld_ptr = $ctss; # 311203 # while ($howmany > 0) { # $dbfld[$dbfld_ptr] = ""; # $row .= $delimitor; # $dbfld_ptr++; # 311203 # $howmany--; # } # } ($key,$recpwd) = split(/ \| /,$dbfld[0]); if ($in{'key'}) { if ($in{'key'} eq $key) { $MATCH[$mct] = $row; $MATCHKEY[$mct] = $key; $mct++; $keymatched = 1; } } elsif ($in{'keywords'}) { $row1 = &replace_spc("$row"); $skip_record = 0; # ds foreach $keyword (@keywords) { &check_special_chars; if (!$in{'wordmatch-keywords'} || $in{'wordmatch-keywords'} !~ /y/i) { if ($row1 =~ /$keyword/i) { if ($keywords_operator eq "and") { # ds next; # ds } # ds else { # ds $MATCH[$mct] = $row; $MATCHKEY[$mct] = $key; $mct++; last; } # ds } # ds else { # ds if ($keywords_operator eq "and") { # ds $skip_record = 1; # ds last; # ds } # ds } } else { if ($delimitor =~ /^\|$/i) { if (($row1 =~ /\|$keyword /i) || ($row1 =~ / $keyword /i) || ($row1 =~ / $keyword\|/i) || ($row1 =~ / $keyword\|$/i) || ($row1 =~ /^$keyword /i) || ($row1 =~ /^$keyword\|$/i) || ($row1 =~ /^$keyword\|/i) || ($row1 =~ /\|$keyword\|/i) || ($row1 =~ /\|$keyword\|$/i)) { if ($keywords_operator eq "and") { # ds next; # ds } # ds else { # ds $MATCH[$mct] = $row; $MATCHKEY[$mct] = $key; $mct++; last; } # ds } # ds else { # ds if ($keywords_operator eq "and") { # ds $skip_record = 1; # ds last; # ds } # ds } } else { if (($row1 =~ /$delimitor$keyword /i) || ($row1 =~ / $keyword /i) || ($row1 =~ / $keyword$delimitor/i) || ($row1 =~ / $keyword$delimitor$/i) || ($row1 =~ /^$keyword /i) || ($row1 =~ /^$keyword$delimitor$/i) || ($row1 =~ /^$keyword$delimitor/i) || ($row1 =~ /$delimitor$keyword$delimitor/i) || ($row1 =~ /$delimitor$keyword$delimitor$/i)) { if ($keywords_operator eq "and") { # ds next; # ds } # ds else { # ds $MATCH[$mct] = $row; $MATCHKEY[$mct] = $key; $mct++; last; } # ds } # ds else { # ds if ($keywords_operator eq "and") { # ds $skip_record = 1; # ds last; # ds } # ds } } } } if ($keywords_operator eq "and" && $skip_record == 0) { # ds $MATCH[$mct] = $row; # ds $MATCHKEY[$mct] = $key; # ds $mct++; # ds } # ds } else { $MATCH[$mct] = $row; $MATCHKEY[$mct] = $key; $mct++; } if (($mct >= $maxdisplay) || ($keymatched == 1)) { last; } # print "$row"; } close(DB); unless ($mct) { ¬hing_found; } open(FL,"$template_dir$in{'template'}"); @nfile=; close(FL); # More than one record matched the keys foreach $line (@nfile) { # For each html line $linet=$line; # Replace eman="fn" by its actual value # One $line can contain only one eman="fn" if ($linet =~ /eman=\"f.*\"/i) { $linet =~ s/.*eman=\"//i; $linet =~ s/\".*//; chop($linet); $line =~ s/eman=\"$linet\"//i; } if ($linet =~ /\*\*matchcnt\*\*/i) { $line =~ s/\*\*matchcnt\*\*/$mct/i; } if ($linet =~ /\*\*usdate\*\*/i) { $line =~ s/\*\*usdate\*\*/$us_date/i; } if ($linet =~ /\*\*europedate\*\*/i) { $line =~ s/\*\*europedate\*\*/$europe_date/i; } if ($line !~ // && $start ne "1") { # $line is before or after the repeat/endrepeat section print "$line"; } elsif ($line !~ // && $start==1) { # $line is between repeat and endrepeat (including endrepeat) $repeated .= $line; } else { # $line is repeat line $start=1; } if ($line =~ //) { # $line is endrepeat, set $start ne 1 undef $start; $itemno = 0; if ($in{'nextstart'}) { $nextst = $in{'nextstart'}; $nextend = $nextst + $maxdispscreen - 1; } else { $nextst = 1; $nextend = $maxdispscreen; } # Now sort all the matched records $oddeven = 0; $match_reccnt = 0; foreach $match_rec (@MATCH) { # For each matched record $key = $MATCHKEY[$match_reccnt]; $match_reccnt++; $itemno++; if (($itemno >= $nextst) && ($itemno <= $nextend)) { if ($delimitor =~ /^\|$/i) { @fs = split(/\|/,$match_rec); } else { @fs = split(/$delimitor/,$match_rec); } ($key,$pwd) = split(/ \| /,$fs[0]); if ($in{'url_flds'}) { # 050402 undef @urlflds; # 050402 @urlflds = split (/,/,$in{'url_flds'}); # 050402 foreach $urlfld (@urlflds) { # 050402 $urlfld =~ s/^f//i; # 050402 $urlfld = $urlfld - 1; # 050402 if ($fs[$urlfld] && $fs[$urlfld] !~ /^http:\/\//i) { # 050402 $fs[$urlfld] = "http://" . $fs[$urlfld]; # 050402 } # 050402 } # 050402 } # 050402 # Assign field values in Matched Record to $TMP[f1,f2,..] $ctfs2=1; $fs2="f1"; foreach $val (@fs) { if ($delimitor =~ /\t/i) { $val =~ s/ _TAB_ /\t/g; # "tab" } if ($delimitor =~ /\|/i) { $val =~ s/ _PIPE_ /\|/g; # "pipe" } if ($delimitor =~ /\,/i) { $val =~ s/ _COMMA_ /,/g; # "," } $TMP{$fs2} = $val; $ctfs2++; $fs2 = "f" . "$ctfs2"; } # Extract and display matched keys $tline = $repeated; # Replace **dbname** **key** or **fn** by the actual value undef @temp; (@temp) = split(/\*\*/,$tline); $repeat_string =""; foreach $item (@temp) { # This If applies to all search actions if ($item eq "key") { $item =~ s/$item/$key/; } if ($item eq "pwd") { $item =~ s/$item/$pwd/; } if ($item eq "dbname") { $item =~ s/$item/$dbname/; } if ($item eq "usdate") { $item =~ s/$item/$us_date/; } if ($item eq "europedate") { $item =~ s/$item/$europe_date/; } if ($item eq "bgcolor") { if ($oddeven == 0) { $item =~ s/$item/$bgcolor0/; } else { $item =~ s/$item/$bgcolor1/; } } # This If applies to search and display actions only if ($item =~ /^f\d*$/) { $nitem = $TMP{$item}; $nitem =~ s/ *-RET- */ /g; $nitem =~ s/\/>/g; $nitem =~ s/\"/"/g; $nitem =~ s/^select$//gi; $nitem =~ s/\.\* _//g; $item =~ s/$item/$nitem/; } $repeat_string .= $item; } $ctfs2=1; $fs2="f1"; until ($ctfs2 > $maxfields) { $ctfsx = $ctfs2 - 1; $valx = $fs[$ctfsx]; if ($valx =~ /^0$/i || ($valx && $valx !~ /^select$/i)) { # if ($valx && $valx !~ /^select$/i) { $repeat_string =~ s///ig; } else { $repeat_string =~ s///ig; } $ctfs2++; $fs2 = "f" . "$ctfs2"; } print "$repeat_string"; undef %TMP; if (($itemno >= $mct) && ($nextst >= ( $maxdispscreen + 1 ))) { $prevst = $nextst - $maxdispscreen; print "\n\n\n"; } } else { if ($itemno > $nextend) { print "
\n"; # Change action URL for form statement below print "
\n"; foreach $entry (@pairs) { ($inname, $value) = split(/=/, $entry); if ($inname !~ /nextstart/i) { print "\n"; } } print "\n"; print "\n
\n"; print "
\n"; print "Current $nextst to $itemno\n"; print "
\n\n\n\n\n"; last; } } if ($oddeven == 0 ) { $oddeven = 1; } else { $oddeven = 0; } } } } } sub showblank { &check_template; open(FL,"$template_dir$in{'template'}"); @nfile=; close(FL); &set_content_type; # For each html line foreach $line (@nfile) { $linet=$line; # Replace eman="fn" by blank # One $line can contain only one eman="fn" if ($linet =~ /eman=\"f.*\"/i) { $linet =~ s/.*eman=\"//i; $linet =~ s/\".*//; chop($linet); $line =~ s/eman=\"$linet\"//i; } $line =~ s/\*\*f\d+\*\*//ig; # r10 print "$line"; } } sub return { print "Location: $ENV{'DOCUMENT_URI'}\n\n"; } sub check_url_referer { $referral_cnt = @valid; if ($referral_cnt > 0) { foreach $referer (@valid) { if ($ENV{'HTTP_REFERER'} =~ /$referer/i) { $good_ref = "yes"; last; } } if ($good_ref ne "yes") { &go_away; } } } sub error_no_db_name { &set_content_type; print "
ERROR: No database filename specified.
"; print "

You must make sure a database filename is specified.

\n"; exit; } sub error_no_template_name { &set_content_type; print "
ERROR: No template filename specified.
"; print "

You must make sure a template filename is specified for your output.

\n"; exit; } sub error_not_a_command { &set_content_type; print "
ERROR: Not a valid command.
"; print "

The \"action\" command is not valid. This might have been caused by reloading a cgi program generated Web page.

Please go back to home page to continue.

\n"; exit; } sub nothing_found { print "
Sorry! Nothing found.
"; print "

No records match your search critera. Please press \"Back\" button and try again.

\n"; exit; } sub go_away { &set_content_type; print "
ERROR: Unauthorised Access.
"; print "

Request denied. You are attempting to access our server using an unauthorized form.

\n"; exit; } sub error_form_method { &set_content_type; print "
Error: Incorrect Form Request Method.
"; print "

You are not using \"method=get\" or \"method=post\" to submit your Form. Please contact Webmaster.

\n"; exit; } sub set_content_type { if ($charset eq "") { print "content-type: text/html\n\n"; } else { print "content-type: text/html\; charset=$charset\n\n"; } } sub check_special_chars { if ($keyword =~ /^\+*\\*\$*\%*\/*\!*\#*\@*\|*\&*\^*\~*\`*\(*\)*$/i) { next; } else { $keyword = &replace_spc("$keyword"); } } sub replace_spc { local($word) = shift(@_); if ($match_special_chars =~ /^yes$/i) { # DO NOT CHECK ^ AND . THEY ARE USED FOR OTHER PURPOSE $word =~ s/\+/SPC001/g; $word =~ s/\\/SPC002/g; $word =~ s/\$/SPC003/g; $word =~ s/\%/SPC004/g; $word =~ s/\//SPC005/g; $word =~ s/\#/SPC006/g; $word =~ s/\@/SPC007/g; if ($delimitor !~ /^\|$/i) { $word =~ s/\|/SPC008/g; } $word =~ s/\&/SPC009/g; $word =~ s/\~/SPC010/g; $word =~ s/\`/SPC011/g; $word =~ s/\(/SPC012/g; $word =~ s/\)/SPC013/g; $word =~ s/\[/SPC014/g; $word =~ s/\]/SPC015/g; $word =~ s/\{/SPC016/g; $word =~ s/\}/SPC017/g; $word =~ s/\/SPC019/g; } else { if ($delimitor =~ /\t/i) { $word =~ s/[^a-z0-9A-Z\t\^\ ]+/.*/g; } elsif ($delimitor =~ /\|/i) { $word =~ s/[^a-z0-9A-Z\|\^\ ]+/.*/g; } elsif ($delimitor =~ /\,/i) { $word =~ s/[^a-z0-9A-Z\,\^\ ]+/.*/g; } else { $word =~ s/[^a-z0-9A-Z\^\ ]+/.*/g; } } return $word; } sub check_dbname { if ($in{'dbname'} =~ /[^a-z0-9A-Z\ \_\-\.]+/) { &error_invalid_dbname; } else { $dbname = $in{'dbname'}; } } sub error_invalid_dbname { &set_content_type; print "
ERROR: Invalid database filename (dbname).
"; print "

Please use only alphanumeric characters (space, dot, hyphen, underscore allowed) for your database filename.

\n"; exit; } sub check_template { if ($in{'template'}) { if ($in{'template'} =~ /[^a-z0-9A-Z\ \_\-\.]+/) { &error_invalid_template; } } else { &error_no_template_name; } } sub error_invalid_template { &set_content_type; print "
ERROR: Invalid template filename.
"; print "

Please use only alphanumeric characters (space, dot, hyphen, underscore allowed) for your template filename.

\n"; exit; } sub error_invalid_operator_mix { &set_content_type; print "
Error: Invalid Operator Mix
\n"; print "

You can only use either \"&&\" (the AND operator) or \"++\" (the OR operator) in your search box. Please press the \"Back\" button to try again.

\n"; print "

Back Home

\n"; exit; }
\n"; if ($nextst >= ( $maxdispscreen + 1 )) { $prevst = $nextst - $maxdispscreen; # Change action URL for form statement below print "
\n"; foreach $entry (@pairs) { ($inname, $value) = split(/=/, $entry); if ($inname !~ /nextstart/i) { print "\n"; } } print "\n"; print "\n
\n"; } print "
\n"; # Change action URL for form statement below print "
\n"; foreach $entry (@pairs) { ($inname, $value) = split(/=/, $entry); if ($inname !~ /nextstart/i) { print "\n"; } } $nextst2 = $nextend + 1; print "\n"; print "\n
\n"; print "
\n"; print "Current $nextst to $nextend\n"; print "