rnmcd Posted September 15, 2005 Posted September 15, 2005 I previously had a php script that ran from this cron job: lynx -dump http://www.mywebsite.com/admin/expire.php > /dev/null I learned that: Access to GET, wget, and lynx has been removed from the servers as a security measure. You would need to modify your script so it can be run without using these tools. <{POST_SNAPBACK}> TCH-David also mentioned that the php script could be run with this command in a cron job: >php -q /home/cpanelName/public_html/admin/expire.php > /dev/null Can anyone assist me with the changes that would need to be made to the following php script in order for it to run properly using the above cron job command? ><?PHP include("../include/common.php"); $sql="SELECT ".$config[table_prefix]."listingsDB.ID, ".$config[table_prefix]."listingsDB.expiration, ".$config[table_prefix]."UserDB.emailAddress, ".$config[table_prefix]."UserDB.user_name FROM ".$config[table_prefix]."listingsDB,".$config[table_prefix]."UserDB WHERE ".$config[table_prefix]."listingsDB.user_id=".$config[table_prefix]."UserDB.ID"; $recordSet=$conn->Execute($sql); while (!$recordSet->EOF) { $ID=make_db_unsafe($recordSet->fields[ID]); $expire=$recordSet->fields[expiration]; $email=make_db_unsafe($recordSet->fields[emailAddress]); $name=make_db_unsafe($recordSet->fields[user_name]); $expyear=substr($expire,0,4); $expmon=substr($expire,6,2); $expday=substr($expire,8,2); $test1=mktime(0,0,0,$expmon,$expday,$expyear); $year= date(Y); $mon=date(m); $day=date(d)+5; //variable for how many days before exp to send email $test=mktime(0,0,0,$mon,$day,$year); $year1=date(Y); $mon1=date(m); $day1=date(d)-10; //variable for how many days after expiration to delete $test2=mktime(0,0,0,$mon1,$day1,$year1); if ($test==$test1) { global $config, $lang; $message = $_SERVER[REMOTE_ADDR]. " -- ".date("F j, Y, g:i:s a")."\r\n\r\nHello $name,\r\n\r\n This is a reminder that your listing # $ID will expire on $expire and will no longer be visible. You may access your account (to renew, edit, or delete your ad) at this link: $config[baseurl]/admin/edit_my_listings.php?edit=$ID.\r\n\r\nExpired ads will be removed from your account 10 days after expiration.\r\n"; $header = "From: ".$config['admin_email']." <".$config['admin_email'].">\r\n"; $header .= "X-Sender: $config[admin_email]\r\n"; $header .= "Return-Path: $config[admin_email]\r\n"; mail("$email", "Listing Expiration", $message, $header); } if ($test1<=$test2) { echo $ID." ".$test."<br>".$test2."<br><br>"; $sql2="DELETE FROM ".$config[table_prefix]."listingsDB WHERE ID=$ID"; $rs=$conn->Execute($sql2); $sql3="DELETE FROM ".$config[table_prefix]."listingsDBElements WHERE listing_id=$ID"; $rs2=$conn->Execute($sql3); $sql = "SELECT file_name, thumb_file_name FROM " . $config[table_prefix] . "listingsImages WHERE (listing_id = $ID)"; $rs3 = $conn->Execute($sql); if ($rs3 === false) { log_error($sql); } while (!$rs3->EOF) { $thumb_file_name = make_db_unsafe ($recordSet->fields[thumb_file_name]); $file_name = make_db_unsafe ($recordSet->fields[file_name]); if (!unlink("$config[listings_upload_path]/$file_name")) { die("$lang[alert_site_admin]"); } if ($file_name != $thumb_file_name) { if (!unlink("$config[listings_upload_path]/$thumb_file_name")) { die("$lang[alert_site_admin]"); } } $rs3->MoveNext(); } $sql = "DELETE FROM " . $config[table_prefix] . "listingsImages WHERE (listing_id = $ID)"; $rs4 = $conn->Execute($sql); if ($rs4 === false) { log_error($sql); } } $recordSet->MoveNext(); } $sql5="SELECT ID, creation_date FROM ".$config[table_prefix]."listingsDB WHERE active='no'"; $rs5=$conn->Execute($sql5); while (!$rs5->EOF) { $ID=$rs5->fields[ID]; $creation=$rs5->fields[creation_date]; $expyear=substr($creation,0,4); $expmon=substr($creation,6,2); $expday=substr($creation,8,2); $test4=mktime(0,0,0,$expmon,$expday,$expyear); $year1=date(Y); $mon1=date(m); $day1=date(d)-5; //variable for how many days after creation but not active to delete $test5=mktime(0,0,0,$mon1,$day1,$year1); if ($test4<=$test5) { $sql12="DELETE FROM ".$config[table_prefix]."listingsDB WHERE ID=$ID"; $rs=$conn->Execute($sql12); if ($rs === false) { log_error($sql12); } $sql13="DELETE FROM ".$config[table_prefix]."listingsDBElements WHERE listing_id=$ID"; $rs2=$conn->Execute($sql13); $sql14 = "SELECT file_name, thumb_file_name FROM " . $config[table_prefix] . "listingsImages WHERE (listing_id = $ID)"; $recordSet = $conn->Execute($sql14); if ($recordSet === false) { log_error($sql14); } while (!$recordSet->EOF) { $thumb_file_name = make_db_unsafe ($recordSet->fields[thumb_file_name]); $file_name = make_db_unsafe ($recordSet->fields[file_name]); if (!unlink("$config[listings_upload_path]/$file_name")) { die("$lang[alert_site_admin]"); } if ($file_name != $thumb_file_name) { if (!unlink("$config[listings_upload_path]/$thumb_file_name")) { die("$lang[alert_site_admin]"); } } $recordSet->MoveNext(); } $sql15 = "DELETE FROM " . $config[table_prefix] . "listingsImages WHERE (listing_id = $ID)"; $recordSet = $conn->Execute($sql15); if ($recordSet === false) { log_error($sql15); } } $rs5->MoveNext(); } ?> Quote
TweezerMan Posted September 15, 2005 Posted September 15, 2005 At line 30 in the code you posted: >$message = $_SERVER[REMOTE_ADDR]. " -- ". ... ...the variable '$_SERVER[REMOTE_ADDR]' will not exist. Since it's just being used to construct a string, I'm not sure that there would be any harm in leaving it as it is though. I have a feeling that the real problems are in the file your script includes at line 2: >include("../include/common.php"); ...and possibly any files that common.php includes as well. You'd need to examine the code in common.php to see if there are any problems in its code. Quote
rnmcd Posted September 15, 2005 Author Posted September 15, 2005 (edited) So are you saying that if there are not any problems with includes then the script may run properly with cron command: >php -q /home/cpanelName/public_html/admin/expire.php > /dev/null May I ask what might make you think the includes could be the problem? I was under the impression that the problems were due to 'lynx' no longer being available for cron jobs. I also assumed (oops) that some change would need to be made to the script since I would no longer be using lynx. Edited September 15, 2005 by rnmcd Quote
TweezerMan Posted September 15, 2005 Posted September 15, 2005 So are you saying that if there are not any problems with includes then the script may run properly with cron command:>php -q /home/cpanelName/public_html/admin/expire.php > /dev/null <{POST_SNAPBACK}> Yes. Honestly, I would have already tested the script with that cron command (without the '> /dev/null' part) to see if there were indeed any problems or not. May I ask what might make you think the includes could be the problem? I was under the impression that the problems were due to 'lynx' no longer being available for cron jobs. <{POST_SNAPBACK}> If there are any issues, they can occur in any code that is run by the script. The code in included files is run just like the main script code, so there is nothing that would prevent an issue from being in an included file as opposed to the main script. The cron job you were previously trying to run started lynx, which in turn sends a request to the web server for your script. The fact that lynx is no longer available was a direct issue for your cron job. The reason you may need to make modifications to your script is due to the reason why whoever wrote the script required the use of lynx (or GET or wget). When a PHP script is run in the method I described, the PHP environment that the script will be running in is not the same. If a script depends on PHP variables that exist only when the script is called in a browser, the script won't work correctly when it is running outside of a web server environment (like it is when it is called with 'php -q'). A simple example of this: When a PHP script is run in a browser, the PHP variable $_SERVER['DOCUMENT_ROOT'] can be used to help determine the path to a script (for example, an included file). Since the script is running in a web server environment, PHP is able to get the location of DOCUMENT_ROOT from the web server. However, when that same script is called with 'php -q' in a cron job, the web server is not involved at all and does not exist in terms of this PHP environment. The PHP variable $_SERVER['DOCUMENT_ROOT'] will be empty. Script code that tries to use this variable to generate the path to a script file in this case will come up with an incorrect / incomplete path. Other PHP variables that have to do with an HTTP (browser) request are similarly affeted - variables such as $_SERVER['HTTP_REFERER'], $_SERVER['HTTP_QUERY_STRING'], and $_SERVER['REQUEST_URI'] also don't exist when a script is called with 'php -q' - because there is no browser request, no browser, no web server to get these variables from. Any modifications that might be need to made to your script would change the use of variables like these so your code uses variables that do exist in the PHP environment it is running in. I also assumed (oops) that some change would need to be made to the script since I would no longer be using lynx. <{POST_SNAPBACK}> They usually do, but it is not a certainty. It depends on the script code actually being run. The author of a script usually has a reason for requiring a script to be run with lynx/GET/wget in a cron job (it usually won't work as it is without it). Quote
TweezerMan Posted September 15, 2005 Posted September 15, 2005 Another example that might require a modification to a script: A difference in behavior between environments. When a script is called up in a browser, the web server automatically changes the 'current working directory' to the the directory where you script is located. This allows relative includes to work (such as './includes/myscript.php'). When a script is called in a cron job with 'php -q', neither cron nor PHP change the 'current working directory'. The initial current working directory for a cron job is your home directory - '/home/cpanelName'. A script with a relative include path would fail to find the file. To correct for this, the PHP script would need to be modified to 1) immediately perform a chdir(); at the beginning of the script to change the current working directory, or 2) use absolute file paths when specifying file and directory names. (#1 is usually an easier modification to perform.) Quote
rnmcd Posted September 15, 2005 Author Posted September 15, 2005 Yes. Honestly, I would have already tested the script with that cron command (without the '> /dev/null' part) to see if there were indeed any problems or not.If there are any issues, they can occur in any code that is run by the script. <{POST_SNAPBACK}> How do I run the cron command immediately? Do I just change the scheduled run to everyminute? Quote
TweezerMan Posted September 15, 2005 Posted September 15, 2005 I don't think setting it to run every minute is necessary. When I'm testing a script with a cron job, I set the cron job to run hourly, and when I'm ready to test it, set it to run 5 minutes or 10 minutes from now (taking the minutes from the current time, add 5 or 10 minutes, then set the cron job to run every hour at that minute). If I want to test again sooner than an hour, I just set the minutes portion of the cron job again. Quote
rnmcd Posted September 15, 2005 Author Posted September 15, 2005 (edited) The cron job ran and I recieved the following email: (I removed my cpanel_username) <br /><b>Warning</b>: session_start(): Cannot send session cookie - headers already sent in <b>/home/cpanel_username/public_html/include/main.php</b> on line <b>7</b><br /> <br /> <b>Warning</b>: session_start(): Cannot send session cache limiter - headers already sent (output started at /home/cpanel_username/public_html/include/main.php:7) in <b>/home/cpanel_username/public_html/include/main.php</b> on line <b>7</b><br /> It doesn't look like the expire.php script ran properly. Does the email provide any clues to what may have went wrong? Edited September 15, 2005 by rnmcd Quote
TweezerMan Posted September 15, 2005 Posted September 15, 2005 The script indeed did not run properly. The line number and file name in the error messages indicate where in the code you should start looking for the cause of the error. Before investing a lot of effort into trying to debug those errors, you might want to take a look at and try out a suggestion TCH-MikeJ made in another related thread. Quote
rnmcd Posted September 15, 2005 Author Posted September 15, 2005 I am looking into the method you suggested via TCH-MikeJ. But what could cause those error messages when the php script will run fine if I access the respective file? Is it due to the cron command? Quote
TweezerMan Posted September 15, 2005 Posted September 15, 2005 If the script runs fine when called in a browser, but has errors when run directly from the command line (cron job), it's a pretty safe bet that the script code has something in it that isn't correctly handling the different environment it's running in. Quote
rnmcd Posted September 16, 2005 Author Posted September 16, 2005 ... Before investing a lot of effort into trying to debug those errors, you might want to take a look at and try out a suggestion TCH-MikeJ made in another related thread. <{POST_SNAPBACK}> Here is TCH-MikeJ's suggestion: Command line curl was indeed disabled because it was being abused by vulnerable scripts just like the other command line programs were. A simple way to continue to use your cron.php file the way it's currently configured (the trial amember has cron.php encoded so I can't even see if it could be modified to work from a command line) is to use php to call the php page. Create a file in your account called something like "runcron.php": >#!/usr/local/bin/php <?php include('http://indiemanagers.com/amember/cron.php'); ?> Make sure the file is executable (permissions 755). Then change your cron job to run "/home/youraccount/runcron.php > /dev/null" (if it's in your top directory, for example). This will give you the same net effect as what you were doing before. We understand it's a little more of a pain to setup, but it's much less exploitable by random scripts searching for vulnerable websites. <{POST_SNAPBACK}> I think I have a basic understanding of TCH-MikeJ's suggestion. But the quandry is with my web developer. I showed him the code MikeJ listed and my web developer said that it would not work on my TCH hosted site because "the method described is for running cron when php is installed in cgi mode. PHP is not installed in CGI mode on your site." Is he correct in this? Quote
TweezerMan Posted September 16, 2005 Posted September 16, 2005 I think I have a basic understanding of TCH-MikeJ's suggestion. But the quandry is with my web developer. I showed him the code MikeJ listed and my web developer said that it would not work on my TCH hosted site because "the method described is for running cron when php is installed in cgi mode. PHP is not installed in CGI mode on your site." Is he correct in this? <{POST_SNAPBACK}> Basically, no. PHP is installed on TCH servers as both an Apache module (what most users deal with and what your developer is thinking of) *and* as a CGI/CLI binary. If the script does not work because there is no PHP CGI/CLI binary on your server, this would be an issue you should have the Help Desk correct. Quote
rnmcd Posted September 16, 2005 Author Posted September 16, 2005 I'm laughing because I know so little Is this all of the code that would need to be in the runcron.php file that MikeJ suggested? >#!/usr/local/bin/php <?php include('http://indiemanagers.com/amember/cron.php'); ?> What does the '#!/usr/local/bin/php' do? Quote
TweezerMan Posted September 16, 2005 Posted September 16, 2005 Actually, in your case, the runcron.php file should look like this: >#!/usr/local/bin/php <?php include('http://www.my-TCH-site.com/admin/expire.php'); ?> The URL to the script you were originally trying to run with lynx is what needs to go in the include line. I'd probably use #!/usr/bin/php in the first line of the script, but either one should work. What does the '#!/usr/local/bin/php' do? <{POST_SNAPBACK}> It specifies the location of the interpreter that will be loaded first (in this case, the PHP binary), which will then read and run your script. When a cron job starts, it starts as just a normal shell. It has no idea what language your script is in - PHP, Perl, Ruby, Python, etc. The first line is the path to a program that can read, understand, and execute your script. Quote
rnmcd Posted September 16, 2005 Author Posted September 16, 2005 Actually, in your case, the runcron.php file should look like this: >#!/usr/local/bin/php <?php include('http://www.my-TCH-site.com/admin/expire.php'); ?> <{POST_SNAPBACK}> Believe it or not, I actually used the correct URL! does it matter if there are single-quotes or double-quotes on each end of the URL? Quote
rnmcd Posted September 16, 2005 Author Posted September 16, 2005 (edited) Here is the email message I am receiving after running my cron job with the change we have discussed: /bin/sh: line 1: http://www.MyWebSite.com/admin/runcron.php: No such file or directory I am 100% sure that the file runcron.php is in the admin folder. Hmm. EDIT: I have since added: > /dev/nul to the end of cron command--I wasn't sure that it would be required. My NEW email error message after including > /dev/nul is: /bin/sh: line 1: /dev/nul: Permission denied I am sure the permissions on the runcron.php file is 755. What should it be for the expire.php file or does that matter? Edited September 16, 2005 by rnmcd Quote
TweezerMan Posted September 16, 2005 Posted September 16, 2005 does it matter if there are single-quotes or double-quotes on each end of the URL? <{POST_SNAPBACK}> In this instance, no, it does not matter whether you use single or double quotes to surround the URL. Here is the email message I am receiving after running my cron job with the change we have discussed: >/bin/sh: line 1: http://www.MyWebSite.com/admin/runcron.php: No such file or directory <{POST_SNAPBACK}> Try changing the first line of the runcron.php script to the following: >#!/usr/bin/php My NEW email error message after including > /dev/nul is: >/bin/sh: line 1: /dev/nul: Permission denied That should be '> /dev/null' - 2 L's in 'null'. Permissions on expire.php should be fine as long as they're at least 0644. Quote
rnmcd Posted September 16, 2005 Author Posted September 16, 2005 (edited) Nuts! I thought we had it. I had already changed the first line of the runcron.php script to: >#!/usr/bin/php When I added the 'missing' "L" to null I'm back to getting this email error message: >/bin/sh: line 1: http://www.[I]MYwebsite[/I].com/admin/runcron.php: No such file or directory Edited September 16, 2005 by rnmcd Quote
rnmcd Posted September 16, 2005 Author Posted September 16, 2005 If the script does not work because there is no PHP CGI/CLI binary on your server, this would be an issue you should have the Help Desk correct. <{POST_SNAPBACK}> Do you think the problem could be that there is not a PHP CGI/CLI binary on my server? Is there a way I can check? Quote
rnmcd Posted September 16, 2005 Author Posted September 16, 2005 (edited) By the way, here is the output that I get when I go to http://www.MYwebsite.com/admin/runcron.php: #!/usr/bin/php is that what I should see? Edited September 16, 2005 by rnmcd Quote
TweezerMan Posted September 16, 2005 Posted September 16, 2005 When I added the 'missing' "L" to null I'm back to getting this email error message: >/bin/sh: line 1: http://www.[I]MYwebsite[/I].com/admin/runcron.php: No such file or directory <{POST_SNAPBACK}> Your cron job needs to specify the local directory path to runcron.php, not the URL: >/home/cpanelName/public_html/admin/runcron.php > /dev/null Do you think the problem could be that there is not a PHP CGI/CLI binary on my server? Is there a way I can check? <{POST_SNAPBACK}> If there was no PHP binary on the server, you would receive an error message along the lines of 'Bad interpreter'. There is a PHP binary on your server. By the way, here is the output that I get when I go to http://www.MYwebsite.com/admin/runcron.php:is that what I should see? <{POST_SNAPBACK}> Well, maybe. The runcron.php script isn't really set up so you can browse to it, but whether you see anything else would depend on whether your expire.php script actually output anything. Quote
rnmcd Posted September 16, 2005 Author Posted September 16, 2005 Your cron job needs to specify the local directory path to runcron.php, not the URL: >/home/cpanelName/public_html/admin/runcron.php > /dev/null <{POST_SNAPBACK}> I was so close at one point...I had originally tried a directory path: /home/cpanelName/admin/runcron.php ---- but missed the 'public_html' So close but yet so far... But with your help we were able to get this figured out!!!! I truly appreciate your time David. Thank you for sticking with me for the last couple of days as I trudged through this. Quote
TweezerMan Posted September 16, 2005 Posted September 16, 2005 Glad to hear it's finally working! Quote
rnmcd Posted November 6, 2005 Author Posted November 6, 2005 (edited) Hello. The runcron.php file worked for awhile. I just noticed that it was no longer working. Is there a way to see if the cron job that executes runcron.php is working properly? Is there anything on the server side that may not be running cron jobs? By the way, the expire.php script does work when I run it manually by browsing to the expire.php page. Thanks. Edited November 6, 2005 by rnmcd Quote
rnmcd Posted November 6, 2005 Author Posted November 6, 2005 (edited) Hello. The runcron.php file worked for awhile. I just noticed that it was no longer working. Is there a way to see if the cron job that executes runcron.php is working properly? Is there anything on the server side that may not be running cron jobs? By the way, the expire.php script does work when I run it manually by browsing to the expire.php page. Thanks. I also took the "> /dev/null" out of the cron command. I did not receive any emails regarding the output. Does that mean the cron ran without problems or that it didn't run? The expire.php works when I navigate to runcron.php manually. Edited November 6, 2005 by rnmcd Quote
TweezerMan Posted November 6, 2005 Posted November 6, 2005 Is there a way to see if the cron job that executes runcron.php is working properly? You'd need to submit a ticket to the Help Desk and have them investigate it. Is there anything on the server side that may not be running cron jobs? There is a cron daemon that runs cron jobs on the server. If it's not running, cron jobs don't get run. I also took the "> /dev/null" out of the cron command. I did not receive any emails regarding the output. Does that mean the cron ran without problems or that it didn't run? Could be either one, unless you know that your script does produce output which should have resulted in an e-mail from cron. Quote
rnmcd Posted November 6, 2005 Author Posted November 6, 2005 ...There is a cron daemon that runs cron jobs on the server. If it's not running, cron jobs don't get run. .... So the cron daemon status can only be determined by tech support? Or can I check for myself if I know my server number? Quote
TweezerMan Posted November 6, 2005 Posted November 6, 2005 As far as I know, the Help Desk would have that for you. While it is possible that the cron daemon may not be running, I don't believe it is likely. If you submit a ticket to the Help Desk, you should tell them that your cron job does not appear to be running and ask them if they can determine why (don't just ask them if the cron daemon is running). Quote
rnmcd Posted November 6, 2005 Author Posted November 6, 2005 As far as I know, the Help Desk would have that for you. While it is possible that the cron daemon may not be running, I don't believe it is likely. If you submit a ticket to the Help Desk, you should tell them that your cron job does not appear to be running and ask them if they can determine why (don't just ask them if the cron daemon is running). What a coincidence. I had sent a help ticket before reading your last reply and I I did ask them if they could tell me why it was down (if it was). They wouldn't answer with anything more than, "rest assured the cron daemon for your and all TCH servers will be running." 5 minutes later my cron job email arrived. Oh well. Kind of disappointing that they wouldn't give me anymore information. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.