/* Website in C - mind@metalshell.com
*
* This code was meant to show the flexibility
* and speed of coding a site in C. [ Nobody Likes PHP! =) ]
*
* This example will show how to create a fully developed
* website in C, using mysql (optional).
*
* I did a speed test; Printing 2,000 lines containing 100 'A's
* per line using php and C; the results were: C (0.120s) PHP (0.605s)
*
* Note: I used a version of my own printing example to make
* the HTML output look alot nicer.. eprint() is optional.
*
* libmysqlclient.a: path may be different.
* To compile: gcc example.c -o example.cgi -lz /usr/lib/mysql/libmysqlclient.a
*
* to view VIA web browser: turn ExecCGI on in httpd.conf
* and move example.cgi to your html folder.
*/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
/* header path may be different */
#include "/usr/include/mysql/mysql.h"
/* To setup your mysql db so the example will work please
* open mysql; and paste the following:
*
* create database Cexample;
*
* use Cexample;
* create TABLE person (
* id mediumint(9) NOT NULL auto_increment,
* name char(40) NOT NULL,
* birth char(40) NOT NULL,
* addy char(40) NOT NULL,
* phone char(40) NOT NULL,
* PRIMARY KEY (id)
* );
*
* insert into person VALUES( NULL, 'John Doe', '01-20-66',
* 'N. Burboun ST.', '800-123-4567' );
*
* insert into person VALUES( NULL, 'Jane Doe', '12-09-72',
* 'S. Burboun ST.', '800-987-6543');
*
*/
/* edit USER, and PASS */
#define MySQL_HOST "localhost"
#define MySQL_USER "ChangeME"
#define MySQL_PASS "ChangeME"
#define MySQL_DATA "Cexample"
MYSQL_RES *res;
MYSQL_ROW row;
int TabMe = 0;
void eprint(int b, char *fmt, ...);
void ShowError(char *x, char *e);
void StartHtml();
void GetBirth(int x);
void GetAddress(int x);
void GetPhone(int x);
void GetShowAll(int x);
int StartQuery();
/* This structure is for our apache string parser
* when it parses for example id=1&0 our parser will
* execute GetBirth(0);
*/
struct
{
int id;
void (*func)(int);
}
DefExt[]=
{
{ 1, GetBirth },
{ 2, GetAddress },
{ 3, GetPhone },
{ 4, GetShowAll },
{ 0, NULL },
};
int main()
{
MYSQL mysql;
char query[100];
/* Initial start of our site's source */
printf("Content-Type: text/html\n\n");
/* Check to see if any arguments were passed through
* our program. If not show front page. */
if ((StartQuery()) == -1)
{
StartHtml();
if (!(mysql_connect(&mysql, MySQL_HOST, MySQL_USER, MySQL_PASS)))
ShowError(NULL, "MySQL SERVER down");
if (mysql_select_db(&mysql, MySQL_DATA))
ShowError(NULL, "MySQL database error");
snprintf(query, sizeof(query), "select * from person order by name");
if (mysql_query(&mysql,query))
ShowError(NULL, "MySQL server error");
res = mysql_store_result(&mysql);
while ((row = mysql_fetch_row(res)))
{
eprint( 0, "<font>%s - </font>\n", row[1]);
eprint( 0, "<a href=\"?id=1&%s\">Birth Day</a>\n", row[0]);
eprint( 0, "<font> - </font>\n");
eprint( 0, "<a href=\"?id=2&%s\">Address</a>\n", row[0]);
eprint( 0, "<font> - </font>\n");
eprint( 0, "<a href=\"?id=3&%s\">Phone</a>\n", row[0]);
eprint( 0, "<font> - </font>\n");
eprint( 0, "<a href=\"?id=4&%s\">Show All</a><br>\n", row[0]);
}
mysql_close(&mysql);
mysql_free_result(res);
eprint(-1, "</html>\n");
return 1;
}
eprint(-1, "</html>\n");
return 1;
}
int StartQuery()
{
int i, g, b;
char *x, *y, *z, *e;
(char *)y = malloc(100);
(char *)z = malloc(100);
(char *)e = malloc(100);
/* Apache will set QUERY_STRING=id=x&x */
x = getenv("QUERY_STRING");
/* If it doesn't exsist return a negative value
* to initialize our front page */
if (x == NULL || x[0] == 0) { return -1; }
/* Always perform checks on everything you write
* to prevent program flaws and or overflows */
if (strlen(x) >= 100)
{
ShowError(x, "Your request was too big");
return 0;
}
for (i = 0, b = 0, g = 0; i < strlen(x); i++)
{
if (g == 1)
{
if (i > 8)
{
ShowError(x, "Id too long");
return 0;
}
if (x[i] == '&')
{
if (x[i+1] == 0)
{
ShowError(x, "Missing field");
return 0;
}
g++;
b = 0;
continue;
} else {
z[b] = x[i];
b++;
continue;
}
}
if (g == 2)
{
e[b] = x[i];
b++;
continue;
}
if (x[i] == '=')
{
g++; b = 0;
if (!(strncmp(y, "id", 2)))
{
continue;
} else {
ShowError(x, "Invalid extention");
return 0;
}
}
y[b] = x[i];
b++;
}
if (strncmp(y, "id", 2) || z[0] == 0 || e[0] == 0)
{
ShowError(x, "Invalid extention");
return 0;
}
b = atoi(z); g = atoi(e);
for (i = 0; DefExt[i].id; i++)
{
if (DefExt[i].id == b)
{
StartHtml();
DefExt[i].func(g);
return 1;
}
}
ShowError(x, "Invalid ID");
return 1;
}
/* The mysql concept was derived from detour's mysql select
* example found at: http://www.metalshell.com/view/source/18/
*/
void GetMysql(char *query)
{
MYSQL mysql;
if (strlen(query) < 10)
ShowError(NULL, "MySQL query string too low");
if (!(mysql_connect(&mysql, MySQL_HOST, MySQL_USER, MySQL_PASS)))
{
fprintf(stderr,"mysql_connect() Failed: %s\n",mysql_error(&mysql));
ShowError(NULL, "MySQL SERVER down");
}
if (mysql_select_db(&mysql, MySQL_DATA))
ShowError(NULL, "MySQL database error");
if (mysql_query(&mysql,query))
ShowError(NULL, "MySQL server error");
res = mysql_store_result(&mysql);
row = mysql_fetch_row(res);
mysql_close(&mysql);
mysql_free_result(res);
}
void GetBirth(int x)
{
char query[100];
snprintf(query, sizeof(query), "select * from person where id = %i", x);
GetMysql(query);
eprint( 0, "<font> %s's Birth date is: %s</font>\n", row[1], row[2]);
}
void GetAddress(int x)
{
char query[100];
snprintf(query, sizeof(query), "select * from person where id = %i", x);
GetMysql(query);
eprint( 0, "<font> %s's Address is: %s</font>\n", row[1], row[3]);
}
void GetPhone(int x)
{
char query[100];
snprintf(query, sizeof(query), "select * from person where id = %i", x);
GetMysql(query);
eprint( 0, "<font> %s's Phone Number is: %s</font>\n", row[1], row[4]);
}
void GetShowAll(int x)
{
char query[100];
snprintf(query, sizeof(query), "select * from person where id = %i", x);
GetMysql(query);
eprint( 0, "<font> <b><u>%s</b></u> </font><br>\n", row[1]);
eprint( 0, "<font> Birth day: %s</font><br>\n", row[2]);
eprint( 0, "<font> Address : %s</font><br>\n", row[3]);
eprint( 0, "<font> Phone Num: %s</font><br>\n", row[4]);
}
void StartHtml()
{
eprint( 0, "<html>\n");
eprint( 1, "<head>\n");
eprint( 1, "<title> Website in C - Example </title>\n");
eprint(-1, "</head>\n\n");
}
/* Error printing */
void ShowError(char *x, char *e)
{
if (e == NULL) strcpy(e, "Unknown Error!");
/* Some prints resized to fit MS source code area */
eprint( 0, "<html>\n");
eprint( 1, "<head>\n");
eprint( 1, "<title>An Error Occured!</title>\n");
eprint(-1, "</head>\n\n");
eprint( 0, "<br><br><br><br><br><br><br>\n");
if (x != NULL)
{
eprint( 0, "<div align=center><font size=4>An error occured: \"%s\" ", e);
printf("While trying to process your request of \"%s\"</font></div>\n", x);
}else {
eprint( 0, "<div align=center><font size=4>An error occured: \"%s\" ", e);
printf("While trying to process your request.</font></div>\n");
}
eprint( 0, "<div align=center><font size=4>If this error keeps occuring please ");
printf("email the site admin</font></div>\n");
eprint(-1, "</html>\n");
exit(-1);
}
/* eprint - mind@metalshell.com [http://www.metalshell.com]
*
* Example:
* eprint( 0, "test1\n"); No Change (just print)
* eprint( 1, "test2\n"); Add a tab
* eprint( 1, "test3\n"); Add a tab
* eprint(-1, "test4\n"); Remove a tab
* eprint(-1, "test5\n"); Remove a tab
* eprint( 0, "test6\n"); No Change (just print)
*
* ;test1
* ;<tab>test2
* ;<tab><tab>test3
* ;<tab>test4
* ;test5
* ;test6
*/
void eprint(int b, char *fmt, ...)
{
va_list list;
char *p, *r;
int e, x;
if (b == -1) TabMe--;
if (b == 1) TabMe++;
for (x = 0; x < TabMe; x++) putc('\t', stdout);
va_start( list, fmt );
for ( p = fmt ; *p ; ++p )
{
if ( *p != '%' )
{
putc( *p, stdout );
} else {
switch ( *++p )
{
case 's':
{
r = va_arg( list, char * );
printf("%s", r);
continue;
}
case 'i':
{
e = va_arg( list, int );
printf("%i", e);
continue;
}
default:
{
if (!x)
putc( *p, stdout );
else
x = 0;
}
}
}
}
va_end(list);
fflush(stdout);
}
|