|
lcc-win32: Introduction | Compile unidelay | Drupal Cron |
| lcc-win32 C compiler. |
LCC Drupal Cron (Portable Cron)
On the previous page I covered a simple delay program this page expands on that to produce a portable cron application targeted at Drupal. I covered how to use unidelay.exe to produce a generic cron application on this page it is worth reading for background information.
Our program will periodically run the following system command line:
udrive\usr\local\php\php.exe -n udrive\www\run_cron.php
It runs php.exe in CLI mode (switch -n prevents php.ini file being read), which in turn runs script run_cron.php located in the server web root folder www. This script contains a single line which runs Drupal’s cron.php script.
The above line can be hard-coded within a delay loop. Assumes a fixed time; a user will always install Drupal in the root folder www and location of the PHP executable will never change.
Hard coding makes the program very restrictive, suppose a user wishes to have a different delay or decides to install Drupal in a sub-folder named drupal or some other folder. The location of PHP executable is unlikely to change but is possible.
Remember we have the ability to pass parameters to our program making it much more flexible. If the above hard-coded variables are made defaults they can be overridden using parameters.
Order of parameters passed to our program is important, what will a user most likely want to change. I would go for delay followed by path to Drupal the least likely will be the path to PHP unless a user has redesigned Uniform Server. However including it as a parameter increases flexibility.
The command line to run our program looks similar to the following:
drupal_cron.exe delay path_to_drupal path_to_php
You will notice I have given the program and parameters a name these can be used later within the program as variables.
I will place one restriction; our program shall be located in folder “Uniform Server” or any folder above both php and drupal folders. This means the paths are relative to the location of our program. Makes it both easier to program and for a user to correctly name the paths.
This should be a flow diagram however a few words can express the intended idea and logic. It can be a pain, keep it short.
From the above you can start coding. I tend to add loads of comments in the hope when re-read in the future I will understand it. Its all a mater of personal style the following is one coding solution:
#include <stdheaders.h>
#include <windows.h>
#include <io.h>
int main(int argc,char *argv[])
{
//== Variables
int delay; // Delay required
char path_to_drupal[80]=""; // relative pat to Drupal
char path_to_php[80]=""; // relative path to php
char error_message[200]=""; // error message string
char cmd_string[200]=""; // command line string
//== Default values
int default_delay=600000; // 1000ms gives 1s delay
// 600000 = 10 mins
char default_path_to_drupal[80]="udrive\\www\\run_cron.php";
char default_path_to_php[80]="udrive\\usr\\local\\php\\php.exe";
//== Set variables according to parameter supplied ===================
if(argc==1){ // No parameters
delay = default_delay; // hence use defaults
strcat(path_to_drupal, default_path_to_drupal);
strcat(path_to_php, default_path_to_php);
}
if(argc==2){
delay = default_delay * (int)atoi(argv[1]); // New delay required
strcat(path_to_drupal, default_path_to_drupal); // All other use
strcat(path_to_php, default_path_to_php); // defaults
}
if(argc==3){
delay = default_delay * (int)atoi(argv[1]); // New delay required
strcat(path_to_drupal, argv[2]); // New drupal path
strcat(path_to_php, default_path_to_php); // Use default
}
if(argc==4){
delay = default_delay * (int)atoi(argv[1]); // New delay required
strcat(path_to_drupal, argv[2]); // New drupal path
strcat(path_to_php, argv[3]); // New php path
}
//== End set vars =====================================================
//== Check if files exists ============================================
if( _access(path_to_drupal,0) !=0 ) // File not found alert user
{
strcat(error_message, path_to_drupal);
strcat(error_message, "\n\n File not found\n\n No action taken");
MessageBox (NULL, error_message , "Path to Drupal", 0);
return 1; // Give up its not going to work
}
if( _access(path_to_php,0) !=0 ) // File not found alert user
{
strcat(error_message, path_to_php);
strcat(error_message, "\n\n File not found\n\n Noaction taken");
MessageBox (NULL, error_message , "Path to PHP", 0);
return 1; // Give up its not going to work
}
//== End Check if files exists ============================================
//== Build command string ==============================
strcat(cmd_string, path_to_php);
strcat(cmd_string, " -n "); // Prevents ini read
strcat(cmd_string, path_to_drupal);
//== End Build command string ==========================
//== Infinite loop, run process hidden =====================
while (1){ //loop forever
_System(cmd_string, SW_HIDE); // Run hidden child process
sleep(delay); // Delay for specified time
}
//== End Infinite loop, run process hidden ===================
return 0; // Exit! Will never reach this point beause
// process exrernally killed.
}
Note: If you are looking for particular functions check out LCC standard library. Click Help link (top right ) from the drop down menu you will find various help files including the standard library.
The code is self-explanatory however there are a few things worthy of note.
It is possible to create your own function to check the existence of a file the code would look similar to this:
bool file_exists(const char * filename)
{
FILE *fp;
if (fp = fopen(filename, "r"))
{
fclose(fp);
return true;
}
return false;
}
This may in certain situations produce unreliable results hence its far better to use a function specifically designed for this task hence the reason for using this function:
_access(path_to_drupal,0)
It returns "0" if the file exists otherwise it returns "-1"
If you use the standard system command to run php.exe
system(cmd_string)
a command window opens until the program executions ends. Although relatively fast it produces an annoying black screen flash.
Ideally the program should be run in a hidden window hence the use of this function:
_System(cmd_string, SW_HIDE)
On the previous page I used different names for the project folder and executable it makes it slightly easier to create a new project if the names are identical. I will be creating the following project drupal_cron
Project page drupal_cron.c will be displayed
Note: You can create a similar path to php and use a dummy file. The program is working lets create the final code.
To recap I have assumed Drupal has been installed in the root folder www.
The folder "Uuiform Server" contains the following files:
You can directly run this file if you have set the defaults to meet your requirements.
Alternatively you can start drupal_cron.exe using a batch file and pass parameters to it. For example create drupal_cron.bat and add this line:
start drupal_cron.exe 1 udrive\www\run_cron.php udrive\usr\local\php\php.exe
The above would have no effect since the parameters passed are the defaults.
If you want to change the delay to 1 hour and installed Drupal to sub-folder www\drupal the batch file now looks like this:
start drupal_cron.exe 6 udrive\www\drupal\run_cron.php
If you want to manually stop drupal_cron.exe without relaying on turning your PC off create a batch file named stop_drupal_cron.bat and add the following line:
udrive\home\admin\program\pskill.exe drupal_cron.exe c
Drupal's root folder (where file cron.php is located) must contain the following PHP script file. Create a new file run_cron.php and add the following line:
<? $dummy = file("http://localhost/cron.php"); ?>
An alternative to using separate batch files to start and stop drupal_cron.exe is to add the appriate line of code to the end of Uniform Server's start and stop files.
Note: At the bottom of each file you will see :END add the one liner below this.
If you have never considered using Drupal now you have a good excuse to try it. You can install it on a separate Uniform Server fire it up and have a play. Add your new compiled script and check it works.
Real point of the above is to provide real working code that can be compiled with lcc. At first sight it looks difficult to use, this invariably is down to knowing where to start. I hope this page and the pervious ones have pointed you in the right direction. I have noticed over the years fancy programming language come and go but C remains there in a prominent position.
| | Ric |