LCC-win32: Drupal Cron
Under Construction! Please Visit Reserve Page. Page Will Be Available Shortly
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.
Requirement
Our program will periodically run the following system command line: <pre> udrive\usr\local\php\php.exe -n udrive\www\run_cron.php </pre> 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.
Proposed solution
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.
Restrictive
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.
Flexibility
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.
Implementation
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.
Code flow
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.
- Start
- Set defaults
- If no delay parameter use default
- If no path_to_drupal parameter use default
- If no path_to_php parameter use default
- Start loop
- Delay
- Run system command path_to_php\php.exe -n path_to_drupal\run_cron.php
- Go to Start loop
- End
Coding
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: <pre>
- 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.
} </pre>
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.
File existence
It is possible to create your own function to check the existence of a file the code would look similar to this: <pre> bool file_exists(const char * filename) {
FILE *fp; if (fp = fopen(filename, "r")) { fclose(fp); return true; } return false;
} </pre> 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: <pre> _access(path_to_drupal,0) </pre> It returns "0" if the file exists otherwise it returns "-1"
Command Window
If you use the standard system command to run php.exe <pre> system(cmd_string) </pre> 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: <pre> _System(cmd_string, SW_HIDE) </pre>
Creating a new LCC project
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
Create Project
- Start LCC
- Close any open projects: Project > Close click Yes to confirm
- Create project: Project > Create opens Definition of new project window
- Name of the new project: Enter drupal_cron
- Sources: Click Browse navigate to E:\lcc\projects click OK add \drupal_cron to give E:\lcc\projects\drupal_cron
- Output directory: Click in this window automatically updates to give E:\lcc\projects\drupal_cron\lcc
- Type of project: Radio button defaults to Console Application leave selected
- Click Create (button top right)
- Do you want to use the wizard to generate the application skeleton: Click Yes
- Application characteristics displayed: Click OK click OK to Lcc wizard pop-up
- Compiler settings displayed: Click Next
- Linker settings displayed: Click Next
- Debugger settings displayed: Click Finish
Project page drupal_cron.c will be displayed
Edit Code
- Delete everything in drupal_cron.c
- Copy the above code into drupal_cron.c
- File > Save
Test for errors
- Compiler > Make There should be no errors
- Compiler > Execute drupal_cron.exe Path to Drupal pop file not found - Indicates its working
- Create the following folder chain: E:\lcc\projects\drupal_cron\lcc\udrive\www
- In folder www create a blank file named run_cron.php
- Compiler > Execute drupal_cron.exe Path to PHP pop file not found - Indicates its working
Note: You can create a similar path to php and use a dummy file. The program is working lets create the final code.
Configuration
- Project > Configuration opens configuration window.
- Click Compiler tab and set the following:
- Check Optimise
- Check Eliminate unused assignments
- UnCheck Generate debug info
- Click Linker tab and set the following:
- Type of output: Click in Windows appl radio button
- Click OK Allow to rebuild OK, Ignore any errors click OK
Compile
- Compiler > Make
- Compiler > Compile drupal_cron.c
- Pick-up the finished program drupal_cron.exe in E:\lcc\projects\drupal_cron\lcc
- Copy this file to "Uniform Server"
Other files
To recap I have assumed Drupal has been installed in the root folder www.
Uniform Server
The folder "Uuiform Server" contains the following files:
- drupal_cron.exe
You can directly run this file if you have set the defaults to meet your requirements.
- drupal_cron.bat
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:
<pre> start drupal_cron.exe 1 udrive\www\run_cron.php udrive\usr\local\php\php.exe </pre> 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: <pre> start drupal_cron.exe 6 udrive\www\drupal\run_cron.php </pre>
- stop_drupal_cron.bat
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:
<pre> udrive\home\admin\program\pskill.exe drupal_cron.exe c </pre>
Drupal root folder
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: <pre> <? $dummy = file("http://localhost/cron.php%22); ?> </pre>
Alternative start and stop
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.
Summary
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 |