Hi all,
I'm new to C.
I have successfully written a small C program that acts as a "wrapper"
around cgi scripts. These scripts perform admin tasks such as backing up
etc. Obviously, The need for the "wrapper" was to get the scripts to run
with "root" privileges. So far so good. I simply create a "URL shortcut"
that some staff can double-click on to initiate the process.
However, because I am creating these automated tasks for management staff
of a company, I want to make sure that they don't go laucnching these tasks
twice or similar (2 or more similtaneous backup processes to the same drive
at the same time is not nice).
I thought the bast way to address this was just to grab a "process listing"
and use the available "regcomp and regexec" functions to check that there
is not already and instance of the designated script running. If so, baulk
and exit with a message.
The thing I don't understand; is that when testing this, any attempts to
run additional instances of the script using the c program don't work,
because the "new instance" will wait until the old process finishes, and
then start (which is not what I want).
BTW: I call it like this
http://some.internal.address/cgi-bin...?fw_backup.cgi
Could someone please point me in the right direction?
TIA
/* This program was created to get around the problem */
/* of having to do tasks that require root privileges */
/* but aren't possible when run as a simple cgi script. */
/* Set this binary to run suid and make sure it's owned */
/* by root, and you're good to go. */
/* Nick Sinclair 2005 GPL it's all yours. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <regex.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[], int ac, char *av[]){
/* Declare some variables */
FILE *cgi_file;
FILE *process_listing;
char line[130];
int counter = 0;
pid_t pid;
char *pattern = argv[1];
int regex_result;
regex_t re;
/* Let's do some sanity checks on the cgi script name */
/* Argument supplied at all? */
if (argc==1)
{ printf("\nNo CGI script name supplied - Freaking out and
exiting.\n\n");
exit(172);
}
/* Too many arguments? */
if (argc>2)
{ printf("\nToo many arguments supplied - Freaking out and
exiting.\n\n");
exit(172);
}
/* Does the file exist at all? */
cgi_file = fopen(argv[1], "r");
if (cgi_file==NULL)
{ printf("\nSupplied file cannot be read from or doesn't exist\n");
printf(" - Freaking out and exiting -\n\n");
exit(127);
}
/* Is the script already running - doh! */
regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB);
process_listing=popen("ps ax", "r");
while ( fgets( line, sizeof line, process_listing))
{
regex_result=regexec(&re, line, (size_t) 0, NULL, 0);
/* printf("Result = %d\n", regex_result); */
if (regex_result==0)
{
/* printf("%s", line); */
counter++;
}
}
pclose(process_listing);
regfree(&re);
if (counter>1)
{
printf("Script already running! - Freaking out and exiting.\n\n");
exit(172);
}
/* Set UID to 0 (root) */
setuid(0);
/* Now run the actual ".cgi" file */
/* pid=getpid(); */
execl("/usr/bin/bash", "bash", argv[1], (char *)0);
}