-
Usefull Library
While working on a semi complex redirection script I came accross a library that allows you to write C programs to cgi scripts.
I only know of a *nix version.
The library is called libcgicg1 and libcgicg1-dev
Only negetive I have been able to find is that it uses a shared library. Which means that if the server you are running the script on doesn't have the shared library you have to use the -static parameter for GCC which greatly increases the file size.
This post was purely informational. The script as it stands now is below.
Happy coding
Code:
#include <cgic.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#include <fcntl.h>
typedef struct sockaddr_in sockaddr_in;
typedef struct sockaddr sockaddr;
int ping_host (char *);
int cgiMain()
{
FILE *fp;
int ping_return;
char addy[20];
cgiHeaderContentType("text/html");
fprintf(cgiOut, "<HTML><HEAD><TITLE>Redirection Test</TITLE>");
if ( (fp=fopen("ip.dat", "r")) == NULL)
{
fprintf(cgiOut, "</HEAD>Could not open the file\n");
return 1;
}
fgets(addy, sizeof addy, fp);
if ( addy [ strlen(addy)-1] == '\n')
addy[strlen(addy)-1]='\0';
fclose(fp);
if ( (ping_return = ping_host(addy)) <= 0)
{
fprintf(cgiOut,"</HEAD><BODY>");
if (ping_return == 0)
fprintf(cgiOut, "Sorry but the server is not reachable at the moment");
if (ping_return == -1)
fprintf(cgiOut, "Unable to acquire a socket so unable to tell if the server is reachable or not");
fprintf(cgiOut, "</BODY></HTML>");
return 1;
}
fprintf(cgiOut, "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;URL=http://%s/\"></HEAD>", addy);
fprintf(cgiOut, "<BODY>Redirecting you to the server.<BR><BR><BR>");
fprintf(cgiOut, "This script was created with help from CGIC libraries\n");
fprintf(cgiOut, "<BR>%s...\n", addy);
fprintf(cgiOut, "</BODY></HTML>");
return 0;
}
int ping_host(char *addy)
{
sockaddr_in addr;
int sock, ret;
fd_set set;
struct timeval timeout = {10, 0};
if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
return -1;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
addr.sin_addr.s_addr = inet_addr(addy);
memset(&(addr.sin_zero), '\0', 8);
FD_ZERO(&set);
FD_SET(sock, &set);
fcntl(sock, F_SETFL, O_NONBLOCK);
if ( (ret = connect (sock, (sockaddr *)&addr, sizeof (sockaddr))) == -1)
{
if ( errno != EINPROGRESS )
return 0;
}
ret = select(sock+1, NULL, &set, NULL, &timeout);
close(sock);
if ( FD_ISSET(sock, &set) )
{
return 1;
}
return 0;
}