#!/usr/bin/perl -w # ---------------------------------------------------------------------------- # SimpleSubmit # Copyright (c) 2000 Jason M. Hinkle. All rights reserved. This script is # free software; you may redistribute it and/or modify it under the same # terms as Perl itself. # # For more information see: http://www.verysimple.com/scripts/ # # LEGAL DISCLAIMER: # This software is provided as-is. Use it at your own risk. The # author takes no responsibility for any damages or losses directly # or indirectly caused by this software. # @@@@ # (o o) # -------------------------------------------------------oOOo-(_)-oOOo-------- # All configuration settings can be found in submit.cfg. Make changes to the # variable below only if you have changed the name of your configuration file. # The config file path is relative from the current directory. my ($CONFIGFILE_NAME) = "submit.cfg"; # CONSTANTS: # (These are internal setting used by the software and will have no visible # effect on the output. Only make changes to these constants if you have a # specific reason.) my ($ID) = "SimpleSubmit"; my ($VERSION) = "3.14 BETA"; my ($FORMNAME_URL) = "url"; my ($FORMNAME_EMAIL) = "email"; my ($FORMNAME_CONFIRM) = "confirm"; my ($FORMNAME_ENGINES) = "engines"; my ($FORMNAME_INFO) = "info"; my ($CONFIGFILE_VALUEFIELD) = "Value"; my ($TABFILE_ENGINECODEFIELD) = "Code"; my ($TABFILE_ENGINECATEGORYFIELD) = "Category"; my ($TABFILE_ENGINEDESCRIPTIONFIELD) = "Description"; my ($TABFILE_ENGINESUBMITURLFIELD) = "SubmitUrl"; my ($TABFILE_ENGINEMETHODFIELD) = "Method"; my ($TABFILE_ENGINEVARMAPFIELD) = "Varmap"; my ($TABFILE_ENGINESTATICVARSFIELD) = "StaticVars"; my ($TABFILE_ENGINESUCCESSFIELD) = "Success"; my ($TABFILE_ENGINEDEFAULTFIELD) = "Default"; my ($EMAIL_IS_CONFIGURED); $|++; # FATAL ERROR CODES: # 000: trapped compilation or syntax error # 001: config file not found and/or not readable # 002: tab file not found and/or not readable # # ---------------------------------------------------------------------------- BEGIN { # ---------------------------------------------------------------------------- # send fatal errors and warnings to the browser instead of 500 server error. # this doesn't seem to catch everything. don't know why... $SIG{__WARN__} = \&Warn; $SIG{__WARN__} = \&Crash; # comment this line out to ignore runtime warnings $SIG{__DIE__} = \&Crash; # add the current directory to the @INC path. this seems to be necessary on # windows systems. my ($filePath,$directorySeparator); if ($ENV{'PATH_TRANSLATED'}) { $filePath = $ENV{'PATH_TRANSLATED'}; $directorySeparator = "\\" } elsif ($ENV{'SHELL'}) { $filePath = "./"; $directorySeparator = "/" } elsif ($ENV{'CMDLINE'}) { $filePath = ".\\"; $directorySeparator = "\\" } else { $filePath = $ENV{'SCRIPT_FILENAME'}; $directorySeparator = "/" } # get the full pathname to the current directory & add it to @INC my ($position) = rindex($filePath,$directorySeparator); $currentDirectory = substr($filePath,0,$position); push(@INC,$currentDirectory); } # ---------------------------------------------------------------------------- # Main # ---------------------------------------------------------------------------- # require libraries and create objects needed. use eval with single quotes # so that it is evaluated at run-time instead of compile time. otherwise, # a missing module will crash the script. the comment line after each one # is needed to force perl2exe to compile all modules into the executable. # first load only needed modules to output text, then load the rest once we have # printed the header. this will make the script appear to load more quickly. eval 'use strict'; #perl2exe_include strict.pm eval 'use vsPageVariables'; #perl2exe_include vsPageVariables.pm eval 'use vsSimpleDb'; #perl2exe_include vsSimpleDb.pm # create the PageVariables object my ($objPage) = new vsPageVariables; # create the new database object for the Config file my ($configFile) = $objPage->CurrentDirectory . $CONFIGFILE_NAME; # make sure the config file is readable or crash unless (-r $configFile) { &Crash("ConfigFile (" . $configFile . ") could not be opened for reading.","001"); } # create the new database object for the config file and open it my ($objConfigFile) = new vsSimpleDb(file => $configFile,delimiter => "\t",); $objConfigFile->OpenFile; # create the new database object for the TAB file my ($tabFile) = $objPage->CurrentDirectory . $objConfigFile->GetValue("TabFile",$CONFIGFILE_VALUEFIELD); # make sure the TAB file is readable or crash unless (-r $tabFile) { &Crash("TabFile (" . $tabFile . ") could not be opened for reading.","002"); } # set the page variables based on the config file settings $objPage->Title($objConfigFile->GetValue("Title",$CONFIGFILE_VALUEFIELD)); $objPage->BgColor($objConfigFile->GetValue("BgColor",$CONFIGFILE_VALUEFIELD)); $objPage->FontColor($objConfigFile->GetValue("FontColor",$CONFIGFILE_VALUEFIELD)); $objPage->FontFace($objConfigFile->GetValue("FontFace",$CONFIGFILE_VALUEFIELD)); $objPage->HeaderBgColor($objConfigFile->GetValue("HeaderBgColor",$CONFIGFILE_VALUEFIELD)); $objPage->HeaderFontColor($objConfigFile->GetValue("HeaderFontColor",$CONFIGFILE_VALUEFIELD)); $objPage->HeaderFile($objPage->CurrentDirectory . $objConfigFile->GetValue("HeaderFile",$CONFIGFILE_VALUEFIELD)); $objPage->FooterFile($objPage->CurrentDirectory . $objConfigFile->GetValue("FooterFile",$CONFIGFILE_VALUEFIELD)); # write the page header stuff $objPage->WritePageHeader; # now that we've printed the header, lets load the rest of the modules # and get ready to do whatever it is we are supposed to... eval 'use CGI'; #perl2exe_include CGI.pm eval 'use vsEmail'; #perl2exe_include vsEmail.pm eval 'use vsSimpleSubmit'; #perl2exe_include vsSimpleSubmit.pm eval 'use vsUtility'; #perl2exe_include vsUtility.pm # additional modules called elsewhere... #perl2exe_include vars.pm #perl2exe_include Socket.pm #perl2exe_include MIME::QuotedPrint.pm #perl2exe_include Time::Local.pm #perl2exe_include LWP::UserAgent.pm # create the new CGI object my ($objFormData) = new CGI; # create the Utility object my ($objUtility) = new vsUtility; # set the security stuff $objUtility->AuthorizedDomains($objConfigFile->GetValue("AuthorizedDomains",$CONFIGFILE_VALUEFIELD)); $objUtility->BannedDomains($objConfigFile->GetValue("BannedDomains",$CONFIGFILE_VALUEFIELD)); $objUtility->AuthorizedOnly($objConfigFile->GetValue("AuthorizedOnly",$CONFIGFILE_VALUEFIELD)); # check if email is enabled so we know to enable that option if ($objConfigFile->GetValue("ThankYouSendmail",$CONFIGFILE_VALUEFIELD) || $objConfigFile->GetValue("ThankYouSmtp",$CONFIGFILE_VALUEFIELD)) { $EMAIL_IS_CONFIGURED = 1; } # create the tabfile object my ($objTabFile) = new vsSimpleDb(file => $tabFile,delimiter => "\t",); # create the submit object and set some properties bases on the config values my ($objSubmit) = new vsSimpleSubmit; $objSubmit->TimeOut($objConfigFile->GetValue("TimeOut",$CONFIGFILE_VALUEFIELD)); $objSubmit->HideFailedDetails($objConfigFile->GetValue("HideFailedDetails",$CONFIGFILE_VALUEFIELD)); # count the urls submitted my ($numberOfUrls); my ($tempUrl) = $objFormData->param($FORMNAME_URL) || ""; if ($tempUrl) { my (@urls); if ($objUtility->InStr($objFormData->param($FORMNAME_URL),"\n")) { @urls = $objSubmit->StringToArray("\n",$objFormData->param($FORMNAME_URL)); } elsif ($objUtility->InStr($objFormData->param($FORMNAME_URL),",")) { @urls = $objSubmit->StringToArray(",",$objFormData->param($FORMNAME_URL)); } else { $numberOfUrls = 1; } $numberOfUrls = @urls; } # see what we are supposed to do and check if we have the appropriate input if (!$objFormData->param && !$objPage->BrowserMode) { &DoError("Usage: perl submit.cgi url=http://yoursite.com email=your\@email.com"); } elsif (!$objFormData->param) { &DoDefault; } elsif (!$objFormData->param($FORMNAME_URL)) { &DoError("Please Enter A Url"); } elsif ($objFormData->param($FORMNAME_URL) eq $FORMNAME_INFO) { &DoInfo(); } elsif (!$objFormData->param($FORMNAME_EMAIL)) { &DoError("Please Enter Your Email Address"); } elsif (!$objUtility->IsAuthorizedEmail($objFormData->param($FORMNAME_EMAIL))) { &DoError("The email address '" . $objFormData->param($FORMNAME_EMAIL) . "' is not authorized."); } elsif (!vsEmail->ValidAddress($objFormData->param($FORMNAME_EMAIL))) { &DoError("The email address '" . $objFormData->param($FORMNAME_EMAIL) . "' is not valid."); } elsif ($numberOfUrls> int($objConfigFile->GetValue("MaxUrls",$CONFIGFILE_VALUEFIELD))) { &DoError("A maximum of " . $objConfigFile->GetValue("MaxUrls",$CONFIGFILE_VALUEFIELD) . " URLs can be submitted at one time."); } else { # everything appears to be ok. er, let's get ready to rumble... my $resultLog = &DoSubmit; if ($resultLog) { # send email if specified in the config file and a confirm was requested by the visitor # "thankyou" is hard-coded in to provide backwards compatibility with version 2.0 &SendEmailMessage($resultLog) if (($objFormData->param($FORMNAME_CONFIRM) || $objFormData->param("thankyou")) && ($EMAIL_IS_CONFIGURED)); # write to logfile if specified in the config file &LogResults if ($objConfigFile->GetValue("LogFile",$CONFIGFILE_VALUEFIELD)); } } $objPage->WritePageFooter; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub DoDefault { # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # open the dat file $objTabFile->OpenFile; # enumerate all the records and add each engine my ($records,$fields); print "
\n"; return 1; } # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub DoError { # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ my ($message) = shift; $objPage->WriteHeader($objPage->Title); $objPage->WriteLine; $objPage->WriteLine($message); $objPage->WriteHeader; return 1; } # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub DoInfo { # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $objPage->WriteHeader("SimpleSubmit Version " . $VERSION); $objPage->WriteLine; my ($infoScreen) = ""; if (defined($objFormData->param($FORMNAME_INFO))) { $infoScreen = $objFormData->param($FORMNAME_INFO); } if ($infoScreen eq "") { $objPage->WriteLine($objPage->Bold("SimpleSubmit © 2000, Jason M. Hinkle")); $objPage->WriteLine("http://www.verysimple.com/scripts/"); $objPage->WriteLine; $objPage->WriteLine($objPage->Bold("SimpleSubmit borrows code from:")); $objPage->WriteLine("Tim Bunce (CGI.pm)"); $objPage->WriteLine("Milivoj Ivkovic (Mail::Sendmail.pm)"); $objPage->WriteLine("Martijn Koster & Gisle Aas (LWP.pm)"); $objPage->WriteLine("Matt Wright (various bits)"); $objPage->WriteLine("And many others too numerous to list..."); $objPage->WriteLine; if ($objPage->BrowserMode) { $objPage->WriteLine("Module Information"); $objPage->WriteLine("Directory Information"); $objPage->WriteLine("Authorization Information"); $objPage->WriteLine("Tabfile Information"); } else { $objPage->WriteLine($FORMNAME_INFO . "=2: Module Information"); $objPage->WriteLine($FORMNAME_INFO . "=3: Directory Information"); $objPage->WriteLine($FORMNAME_INFO . "=4: Authorization Information"); $objPage->WriteLine($FORMNAME_INFO . "=5: Tabfile Information"); } } elsif ($infoScreen eq "2") { $objPage->WriteLine($objPage->Bold("Module Information:")); $objPage->WriteLine("Perl Version " . $]); $objPage->WriteLine("CGI.pm Version " . CGI->VERSION); $objPage->WriteLine("LWP.pm Version " . LWP->VERSION); $objPage->WriteLine("Socket.pm Version " . Socket->VERSION); $objPage->WriteLine("vsEmail.pm Version " . vsEmail->Version); $objPage->WriteLine("vsPageVariables.pm Version " . vsPageVariables->Version); $objPage->WriteLine("vsSimpleDb.pm Version " . vsSimpleDb->Version); $objPage->WriteLine("vsSimpleSubmit.pm Version " . vsSimpleSubmit->Version); $objPage->WriteLine("vsUtility.pm Version " . vsUtility->Version); $objPage->WriteLine; $objPage->WriteLine($objPage->Underline("INC Path:")); my ($includepath); foreach $includepath (@INC) { $objPage->WriteLine($includepath); } } elsif ($infoScreen eq "3") { $objPage->WriteLine($objPage->Bold("Directory Information:")); $objPage->WriteLine("OS = " . $objPage->OS); $objPage->WriteLine("BrowserMode = " . $objPage->BrowserMode); $objPage->WriteLine("URI = " . $objPage->CurrentUri); $objPage->WriteLine("URL = " . $objPage->CurrentUrl); $objPage->WriteLine("CurrentDirectory = " . $objPage->CurrentDirectory); $objPage->WriteLine("DirectorySeparator = " . $objPage->DirectorySeparator); $objPage->WriteLine("FileName = " . $objPage->CurrentFileName); } elsif ($infoScreen eq "4") { $objPage->WriteLine($objPage->Bold("Authorization Information:")); $objPage->WriteLine("AuthorizedDomains: " . $objUtility->AuthorizedDomains); $objPage->WriteLine("BannedDomains: " . $objUtility->BannedDomains); $objPage->WriteLine("AuthorizedOnly: " . $objUtility->AuthorizedOnly); my ($referringUrl) = $objPage->ReferringUrl; $objPage->WriteLine("Referrer: " . $referringUrl); } elsif ($infoScreen eq "5") { $objPage->WriteLine($objPage->Bold("Tabfile Information:")); my ($records,%tabVersion,$versionItem); # open the .tab file $objTabFile->OpenFile; # get the record that contains the version info. (GetRecord returns a hash) %tabVersion = $objTabFile->GetRecord("#VERSION"); # enumerate all the version info foreach $versionItem (keys(%tabVersion)) { unless ($objUtility->LeftChars($tabVersion{$versionItem},1) eq "#") { $objPage->WriteLine($tabVersion{$versionItem}); } } # enumerate all the supported engines in the .tab file $objPage->WriteLine; $objPage->WriteLine($objPage->Underline("Supported Engines:")); foreach $records ($objTabFile->GetRows) { unless ($objUtility->LeftChars($records,1) eq "#") { $objPage->WriteLine($objTabFile->GetValue($records,$TABFILE_ENGINECODEFIELD)); } } } $objPage->WriteHeader; return 1; } # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub DoSubmit { # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ my ($submitResult, $tempTime); # pass the CGI object parameters to the submit object $objSubmit->AddCgiParameters($objFormData); # open the tab file $objTabFile->OpenFile; # see what engines to use and ready the submit object &ProcessEngines; # print out what time we started $tempTime = $objUtility->GetDate . " " . $objUtility->GetTime; $objPage->WriteLine($objPage->Bold("Started: " . $tempTime)); $submitResult = "Started: " . $objUtility->GetDate . " " . $objUtility->GetTime . "\n"; # print out all the paramenters just for fun my ($param); foreach $param ($objFormData->param) { unless ($param eq $FORMNAME_URL || $param eq $FORMNAME_ENGINES) { $objPage->WriteLine("" . $objPage->Bold($param . ": ") . $objFormData->param($param)); $submitResult .= $param . ": " . $objFormData->param($param) . "\n"; } } $objPage->WriteLine(); # check to see if multiple urls were specified. if so, then split them into an # array so we can loop through them. my ($url, @urls); if ($objUtility->InStr($objFormData->param($FORMNAME_URL),"\n")) { @urls = $objSubmit->StringToArray("\n",$objFormData->param($FORMNAME_URL)); } elsif ($objUtility->InStr($objFormData->param($FORMNAME_URL),",")) { @urls = $objSubmit->StringToArray(",",$objFormData->param($FORMNAME_URL)); } else { $urls[0] = $objFormData->param($FORMNAME_URL); } # submit each url one at a time to the specified engines foreach $url (@urls) { # get rid of possible line break character. chop $url if ($objUtility->RightChars($url,1) eq "\n" || $objUtility->RightChars($url,1) eq "\r"); if ($objUtility->IsAuthorizedDomain($url)) { $objSubmit->AddParameters(url => $url); $objPage->WriteHeader("Submitting: " . $url); $submitResult .= "\n" . "Submitting: " . $url . "\n";; # tell the submit object to do it $objSubmit->Submit; $submitResult .= $objSubmit->Results; $tempTime = $objUtility->GetDate . " " . $objUtility->GetTime; $objPage->WriteLine($objPage->Bold("Finished: " . $tempTime)); $objPage->WriteLine(); $submitResult .= "Finished: " . $objUtility->GetDate . " " . $objUtility->GetTime . "\n"; } else { $objPage->WriteHeader("The URL '" . $url . "' is not authorized."); $submitResult .= "\n" . "The URL '" . $url . "' is not authorized.\n";; } } return $submitResult; } # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub ProcessEngines { # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # if specific engines were submitted, use those, otherwise, use defaults my (@engines, $engine, $useDefaults); if ($objFormData->param($FORMNAME_ENGINES)) { @engines = $objFormData->param($FORMNAME_ENGINES); $useDefaults = 0; } else { @engines = $objTabFile->GetRows; $useDefaults = 1; } ### TO DO: check if an invalid engine is specified??? it currently just ignores it, ### but it should probably report that it is invalid in case fumbly tries something stoopid... # enumerate all the engines and add them to the submit object foreach $engine (@engines) { # support legacy forms...( $engine = "AltaVista" if ($engine eq "altavista"); $engine = "Excite" if ($engine eq "excite"); $engine = "Go" if ($engine eq "go"); $engine = "Google" if ($engine eq "google"); $engine = "HotBot" if ($engine eq "hotbot"); $engine = "InfoSeek" if ($engine eq "infoseek"); $engine = "Lycos" if ($engine eq "lycos"); $engine = "NorthernLight" if ($engine eq "northernlight"); $engine = "WhatYouSeek" if ($engine eq "whatyouseek"); # ) if (($objTabFile->GetValue($engine,$TABFILE_ENGINEDEFAULTFIELD) || !$useDefaults) && ($objUtility->LeftChars($engine,1) ne "#")) { $objSubmit->AddEngine( engineCode => $objTabFile->GetValue($engine,$TABFILE_ENGINECODEFIELD), engineSubmitUrl => $objTabFile->GetValue($engine,$TABFILE_ENGINESUBMITURLFIELD), engineMethod => $objTabFile->GetValue($engine,$TABFILE_ENGINEMETHODFIELD), engineVarmap => $objTabFile->GetValue($engine,$TABFILE_ENGINEVARMAPFIELD), engineStaticVars => $objTabFile->GetValue($engine,$TABFILE_ENGINESTATICVARSFIELD), engineSuccess => $objTabFile->GetValue($engine,$TABFILE_ENGINESUCCESSFIELD), ); # DEBUG: enumerate all the fields to see what we got # foreach $fields ($objTabFile->GetFields) { # $objPage->WriteLine("" . $records . "(" . $fields . ") = " . $objTabFile->GetValue($records,$fields)); #} } } return 1; } # ---------------------------------------------------------------------------- sub SendEmailMessage { # ---------------------------------------------------------------------------- my $results = shift || "Thank you for using SimpleSubmit: http://www.simplesubmit.com/"; $objPage->WriteHeader("Sending Confirmation"); print "Processing Email..."; # create the email object my ($objMessage) = new vsEmail( SendmailPath => $objConfigFile->GetValue("ThankYouSendmail",$CONFIGFILE_VALUEFIELD), SmtpServer => $objConfigFile->GetValue("ThankYouSmtp",$CONFIGFILE_VALUEFIELD), From => $objConfigFile->GetValue("ThankYouFrom",$CONFIGFILE_VALUEFIELD), To => $objFormData->param($FORMNAME_EMAIL), Subject => $objConfigFile->GetValue("ThankYouSubject",$CONFIGFILE_VALUEFIELD), HtmlMode => $objConfigFile->GetValue("ThankYouHtmlMode",$CONFIGFILE_VALUEFIELD), ); # get the thankyou file and use it if it is readable. otherwise, send the default my ($thankyouFile) = $objUtility->GetFile($objPage->CurrentDirectory . $objConfigFile->GetValue("ThankYouFile",$CONFIGFILE_VALUEFIELD)); if ($thankyouFile) { chop($results); $objMessage->Message($objUtility->Replace($thankyouFile,"\n"; print "Application Error: " . $errorType . "\n"; print "
\n"; print "
\n"; print "\n"; print "Click here for details..."; print "\n"; print "\n"; } else { # we are running at a command prompt print "Application Error:\n\n"; print $error; } exit; } # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub Warn { # add this line to the beginning of your program (preferrably inside BEGIN {} # and warning messages will be sent to this routine instead of crashing: # $SIG{__WARN__} = \&Warn; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ignore warnings - do nothing } # ---------------------------------------------------------------------------- END { # ---------------------------------------------------------------------------- # lets clean up before we leave... undef($objFormData) if defined($objFormData); undef($objPage) if defined($objPage); undef($objSubmit) if defined($objSubmit); undef($objTabFile) if defined($objTabFile); }