LCC-win32: Drupal Cron: Difference between revisions

From The Uniform Server Wiki
Jump to navigation Jump to search
(New page: {{Uc nav lcc-win32}} '''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 ...)
 
No edit summary
Line 1: Line 1:
=[http://upezobyxez.co.cc Under Construction! Please Visit Reserve Page. Page Will Be Available Shortly]=
{{Uc nav lcc-win32}}
{{Uc nav lcc-win32}}
'''LCC Drupal Cron''' (Portable Cron)
'''LCC Drupal Cron''' (Portable Cron)
Line 7: Line 8:
== Requirement ==
== Requirement ==
Our program will periodically run the following system command line:
Our program will periodically run the following system command line:
<pre>
&lt;pre&gt;
udrive\usr\local\php\php.exe -n udrive\www\run_cron.php
udrive\usr\local\php\php.exe -n udrive\www\run_cron.php
</pre>
&lt;/pre&gt;
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.
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.


Line 53: Line 54:
== Coding ==
== 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:
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>
&lt;pre&gt;
#include <stdheaders.h>
#include &lt;stdheaders.h&gt;
#include <windows.h>
#include &lt;windows.h&gt;
#include <io.h>
#include &lt;io.h&gt;


int main(int argc,char *argv[])
int main(int argc,char *argv[])
Line 62: Line 63:
   //== Variables
   //== Variables
   int delay;                    // Delay required
   int delay;                    // Delay required
   char path_to_drupal[80]="";  // relative pat to Drupal
   char path_to_drupal[80]=&quot;&quot;;  // relative pat to Drupal
   char path_to_php[80]="";      // relative path to php
   char path_to_php[80]=&quot;&quot;;      // relative path to php
   char error_message[200]="";  // error message string
   char error_message[200]=&quot;&quot;;  // error message string
   char cmd_string[200]="";      // command line string
   char cmd_string[200]=&quot;&quot;;      // command line string


   //== Default values
   //== Default values
   int default_delay=600000;    // 1000ms gives 1s delay
   int default_delay=600000;    // 1000ms gives 1s delay
                                 // 600000 = 10 mins
                                 // 600000 = 10 mins
   char default_path_to_drupal[80]="udrive\\www\\run_cron.php";
   char default_path_to_drupal[80]=&quot;udrive\\www\\run_cron.php&quot;;
   char default_path_to_php[80]="udrive\\usr\\local\\php\\php.exe";
   char default_path_to_php[80]=&quot;udrive\\usr\\local\\php\\php.exe&quot;;


   //== Set variables according to parameter supplied ===================
   //== Set variables according to parameter supplied ===================
Line 103: Line 104:
   {
   {
strcat(error_message, path_to_drupal);
strcat(error_message, path_to_drupal);
strcat(error_message, "\n\n File not found\n\n No action taken");
strcat(error_message, &quot;\n\n File not found\n\n No action taken&quot;);
MessageBox (NULL, error_message , "Path to Drupal", 0);
MessageBox (NULL, error_message , &quot;Path to Drupal&quot;, 0);
return 1;                        // Give up its not going to work
return 1;                        // Give up its not going to work
   }
   }
Line 111: Line 112:
   {
   {
strcat(error_message, path_to_php);
strcat(error_message, path_to_php);
strcat(error_message, "\n\n File not found\n\n Noaction taken");
strcat(error_message, &quot;\n\n File not found\n\n Noaction taken&quot;);
MessageBox (NULL, error_message , "Path to PHP", 0);
MessageBox (NULL, error_message , &quot;Path to PHP&quot;, 0);
return 1;                        // Give up its not going to work
return 1;                        // Give up its not going to work
   }
   }
Line 120: Line 121:
  //== Build command string ==============================
  //== Build command string ==============================
  strcat(cmd_string, path_to_php);
  strcat(cmd_string, path_to_php);
  strcat(cmd_string, " -n ");        // Prevents ini read
  strcat(cmd_string, &quot; -n &quot;);        // Prevents ini read
  strcat(cmd_string, path_to_drupal);
  strcat(cmd_string, path_to_drupal);
  //== End Build command string ==========================
  //== End Build command string ==========================
Line 134: Line 135:
             // process exrernally killed.
             // process exrernally killed.
}
}
</pre>
&lt;/pre&gt;


'''''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.
'''''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.
Line 144: Line 145:


It is possible to create your own function to check the existence of a file the code would look similar to this:
It is possible to create your own function to check the existence of a file the code would look similar to this:
<pre>
&lt;pre&gt;
bool file_exists(const char * filename)
bool file_exists(const char * filename)
{
{
     FILE *fp;
     FILE *fp;
     if (fp = fopen(filename, "r"))
     if (fp = fopen(filename, &quot;r&quot;))
     {
     {
         fclose(fp);
         fclose(fp);
Line 155: Line 156:
     return false;
     return false;
}
}
</pre>
&lt;/pre&gt;
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:
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>
&lt;pre&gt;
_access(path_to_drupal,0)
_access(path_to_drupal,0)
</pre>
&lt;/pre&gt;
It returns "0" if the file exists otherwise it returns "-1"
It returns &quot;0&quot; if the file exists otherwise it returns &quot;-1&quot;


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
=== Command Window ===
=== Command Window ===
If you use the standard system command to run php.exe
If you use the standard system command to run php.exe
<pre>
&lt;pre&gt;
system(cmd_string)
system(cmd_string)
</pre>
&lt;/pre&gt;
a command window opens until the program executions ends. Although relatively fast it produces an annoying black screen flash.
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:
Ideally the program should be run in a hidden window hence the use of this function:
<pre>
&lt;pre&gt;
_System(cmd_string, SW_HIDE)
_System(cmd_string, SW_HIDE)
</pre>
&lt;/pre&gt;


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
Line 182: Line 183:
=== Create Project ===
=== Create Project ===
# Start LCC
# Start LCC
# Close any open projects:  '''Project > Close''' click '''Yes''' to confirm
# Close any open projects:  '''Project &gt; Close''' click '''Yes''' to confirm
# Create project: '''Project > Create''' opens '''Definition of new project''' window
# Create project: '''Project &gt; Create''' opens '''Definition of new project''' window
## Name of the new project: Enter '''drupal_cron'''
## 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'''
## Sources: Click '''Browse''' navigate to E:'''\lcc\projects''' click '''OK''' add '''\drupal_cron''' to give '''E:\lcc\projects\drupal_cron'''
Line 201: Line 202:
# Delete everything in '''drupal_cron.c'''
# Delete everything in '''drupal_cron.c'''
# '''Copy''' the above code into '''drupal_cron.c'''
# '''Copy''' the above code into '''drupal_cron.c'''
# '''File > Save'''
# '''File &gt; Save'''


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
=== Test for errors ===
=== Test for errors ===
# '''Compiler > Make''' There should be no errors
# '''Compiler &gt; Make''' There should be no errors
# '''Compiler > Execute drupal_cron.exe''' Path to Drupal pop file not found - Indicates its working
# '''Compiler &gt; 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'''
# Create the following folder chain: E:\lcc\projects\drupal_cron\lcc\'''udrive\www'''
# In folder www create a blank file named '''run_cron.php'''
# 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   
# '''Compiler &gt; 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.   
Note: You can create a similar path to php and use a dummy file.   
Line 216: Line 217:
'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
=== Configuration ===
=== Configuration ===
# '''Project > Configuration''' opens configuration window.
# '''Project &gt; Configuration''' opens configuration window.
# Click Compiler tab and set the following:
# Click Compiler tab and set the following:
## '''Check''' Optimise
## '''Check''' Optimise
Line 227: Line 228:
'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
=== Compile ===
=== Compile ===
# Compiler > Make
# Compiler &gt; Make
# Compiler > Compile drupal_cron.c
# Compiler &gt; Compile drupal_cron.c
# Pick-up the finished program '''drupal_cron.exe''' in '''E:\lcc\projects\drupal_cron\lcc'''
# Pick-up the finished program '''drupal_cron.exe''' in '''E:\lcc\projects\drupal_cron\lcc'''
# Copy this file to "Uniform Server"
# Copy this file to &quot;Uniform Server&quot;


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
Line 237: Line 238:


=== Uniform Server ===
=== Uniform Server ===
The folder "Uuiform Server" contains the following files:
The folder &quot;Uuiform Server&quot; contains the following files:


*'''drupal_cron.exe'''
*'''drupal_cron.exe'''
Line 248: Line 249:
For example create '''drupal_cron.bat''' and add this line:
For example create '''drupal_cron.bat''' and add this line:


<pre>
&lt;pre&gt;
start drupal_cron.exe 1 udrive\www\run_cron.php udrive\usr\local\php\php.exe
start drupal_cron.exe 1 udrive\www\run_cron.php udrive\usr\local\php\php.exe
</pre>
&lt;/pre&gt;
The above would have no effect since the parameters passed are the defaults.
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:
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>
&lt;pre&gt;
start drupal_cron.exe 6 udrive\www\drupal\run_cron.php  
start drupal_cron.exe 6 udrive\www\drupal\run_cron.php  
</pre>
&lt;/pre&gt;


*'''stop_drupal_cron.bat'''
*'''stop_drupal_cron.bat'''
Line 262: Line 263:
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:
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>
&lt;pre&gt;
udrive\home\admin\program\pskill.exe drupal_cron.exe c
udrive\home\admin\program\pskill.exe drupal_cron.exe c
</pre>
&lt;/pre&gt;


=== Drupal root folder ===
=== Drupal root folder ===
Drupal's root folder (where file cron.php is located) must contain the following PHP script file.
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:
Create a new file '''run_cron.php''' and add the following line:
<pre>
&lt;pre&gt;
<? $dummy = file("http://localhost/cron.php"); ?>
&lt;? $dummy = file(&quot;http://localhost/cron.php&quot;); ?&gt;
</pre>
&lt;/pre&gt;


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''

Revision as of 10:21, 24 November 2010

Under Construction! Please Visit Reserve Page. Page Will Be Available Shortly

MPG UniCenter

MPG UniCenter

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.

Top

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.

Top

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.

Top

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.

Top

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

Top

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>

  1. include <stdheaders.h>
  2. include <windows.h>
  3. 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.

Top

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"

Top

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>

Top

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

Top

Create Project

  1. Start LCC
  2. Close any open projects: Project > Close click Yes to confirm
  3. Create project: Project > Create opens Definition of new project window
    1. Name of the new project: Enter drupal_cron
    2. Sources: Click Browse navigate to E:\lcc\projects click OK add \drupal_cron to give E:\lcc\projects\drupal_cron
    3. Output directory: Click in this window automatically updates to give E:\lcc\projects\drupal_cron\lcc
    4. Type of project: Radio button defaults to Console Application leave selected
    5. Click Create (button top right)
  4. Do you want to use the wizard to generate the application skeleton: Click Yes
  5. Application characteristics displayed: Click OK click OK to Lcc wizard pop-up
  6. Compiler settings displayed: Click Next
  7. Linker settings displayed: Click Next
  8. Debugger settings displayed: Click Finish

Project page drupal_cron.c will be displayed

Top

Edit Code

  1. Delete everything in drupal_cron.c
  2. Copy the above code into drupal_cron.c
  3. File > Save

Top

Test for errors

  1. Compiler > Make There should be no errors
  2. Compiler > Execute drupal_cron.exe Path to Drupal pop file not found - Indicates its working
  3. Create the following folder chain: E:\lcc\projects\drupal_cron\lcc\udrive\www
  4. In folder www create a blank file named run_cron.php
  5. 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.

Top

Configuration

  1. Project > Configuration opens configuration window.
  2. Click Compiler tab and set the following:
    1. Check Optimise
    2. Check Eliminate unused assignments
    3. UnCheck Generate debug info
  3. Click Linker tab and set the following:
    1. Type of output: Click in Windows appl radio button
    2. Click OK Allow to rebuild OK, Ignore any errors click OK

Top

Compile

  1. Compiler > Make
  2. Compiler > Compile drupal_cron.c
  3. Pick-up the finished program drupal_cron.exe in E:\lcc\projects\drupal_cron\lcc
  4. Copy this file to "Uniform Server"

Top

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>

Top

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.

Top

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.

Top


Ric