/******************************************************************************
* Programmer: Peter C. Y. Leung
* Subject: Sena Limo Service Reservations Form
* HTML: http://www.senalimo.com/reservations/index.html
* File: reservations_lo.c (orginal), reservations.c (upload file)
* For: Estevam Sena, Sena Limo Service
* Date: June 29, 2003
* Updated: May 27, 2004
*
* This program gets data from FORM_HTML for reservations information. Then
* the program will forword all information by E-mail to a pager and mail
* account The program is based on the post_query.c code and is required to
* complie with util.c.
*
* The Reciver address 1 is changed form 4156095521@mobile.att.net to
* estevamsenalimo@comcast.net
*****************************************************************************/
#include
#include
#include
#include
#define FORM_FIELDS 7 // Number of form elements
#define MAX_ENTRIES 100 // Max size of entry and fdata
#define FORM_PATH "index.html" // Form calls this form
#define FILE_PATH "debug.txt" // File to save
#define EMAIL_DEBUG_PATH "email_debug.txt" // Email ASCI debug file
#define EMAIL_BINARY "/usr/sbin/exim" // Exim location
#define EMAIL_SENDER "Sena Limo Service WebApp " // Sender Name
#define EMAIL_RECEIVER "estevamsenalimo@comcast.net" // Reciver address
#define EMAIL_RECEIVER1 "joshuat@bersama.com" // Reciver address
#define EMAIL_RECEIVER2 "pleung@cryptomail.org" // Reciver address
#define EMAIL_RECORD_RECEIVER "res@senalimo.com" // Reciver address
#define USER_ID 4303 // User id
#define GROUP_ID 100 // Group id
#define MODE_CH 0640 // Change to me
#define PASS_REMOVE "PASS_REMOVE" // Code name to signal remove
#define PASS_REPLACE "PASS_REPLACE" // Code name to signal replace
#define PASS_REPLACE_FILE "" // Replace with this file
#define NP_MESSAGE "* This field is required ... please enter information here ... \n"
// Additional not pass message
typedef struct {
char *name;
char *val;
} entry;
typedef struct {
int req; // Is this field required? 0 = No, 1 = Yes.
int pass; // Is this field has value? 0 = No, 1 = Yes.
char *name; // Field name.
char *file; // Default value to data file.
char *fileh; // Heading of the data file.
char *html; // Field value.
char *phtml; // Passed value to html.
char *fhtml; // Failed value to html.
} fdata;
char *makeword(char *line, char stop);
char *fmakeword(FILE *f, char stop, int *len);
char x2c(char *what);
void unescape_url(char *url);
void plustospace(char *str);
/************************ Printing error HTML message ************************/
void printER(const char *error) {
printf("%c%cSena Limo Service - ",10,10);
printf("Sedans and Limousine Services %c%c",10,10);
printf("%c%cSena Limo Service %c",10,10,10);
printf("Phone: (415)609-5521 * Fax: (510)223-7645 %c",10);
printf(" %c",10);
printf("Reservations Form is encountering problems right now, ");
printf("with error message: %s. Please come back later ",error);
printf("for the Reservations Form",34,FORM_PATH,34);
printf(" to make reservations.
%cFor problems ",10);
printf("related to the Reservations Form page, please contact webmaster@",34,34);
printf("senalimo.com .
%c%c",10,10);
}
/***************** Checking for POSTING and ENCODING type ********************/
void checkEnv() {
char htmlin[128];
FILE *inp;
if(strcmp(getenv("REQUEST_METHOD"),"POST") ||
strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded")) {
if((inp = fopen(FORM_PATH,"r")) == NULL) {
printER(strcat("Cannot load ",FORM_PATH));
} else {
while(fgets(htmlin,127,inp)) printf("%s",htmlin);
fclose(inp);
}
exit(1);
}
}
/****************** Initializing fields and file data ************************/
void initData(fdata *data) {
int n;
for(n = 0; n <= FORM_FIELDS; n++) {
data[n].pass = 0;
data[n].html = "";
data[n].fileh = "";
data[n].file = "";
data[n].phtml = "";
data[n].fhtml = "";
}
data[0].req = 1;
data[0].name = "NAME";
data[0].fileh = "Name";
data[0].fhtml = " ";
data[1].req = 1;
data[1].name = "PHONE_AREA";
data[1].fileh = "Phone";
data[1].fhtml = " ";
data[2].req = 1;
data[2].name = "PHONE_NUM";
data[2].fhtml = " ";
data[3].req = 0;
data[3].name = "EMAIL";
data[3].fileh = "E-Mail";
data[3].fhtml = "Not Provided.";
data[4].req = 0;
data[4].name = "VECHICLE";
data[4].fileh = "Vechicle";
data[4].file = "Not Provided";
data[4].fhtml = "Not decided at this time.";
data[5].req = 0;
data[5].name = "SCHEDULE";
data[5].fileh = "Schedule";
data[5].file = "Not Provided";
data[5].fhtml = "Not set at this time.";
data[6].req = 0;
data[6].name = "TYPE";
data[6].fileh = "Type";
data[6].file = "Others";
data[6].fhtml = "Others";
data[7].req = 0;
data[7].name = "ADDINST";
data[7].fileh = "Additional Instruction";
data[7].file = "Not Provided";
data[7].fhtml = "No additional instuction at this time.";
}
/******************** Checking fields in HTML Form ***************************/
void checkField(const char *name, const char *val, fdata *data, int *passed) {
int n;
size_t sl;
for(n = 0; n <= FORM_FIELDS; n++) {
if(!strcmp(name,data[n].name)) {
if(strcmp(val,"")) {
sl = strlen(val) + 1;
if((data[n].file = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory in CheckField");
exit(1);
}
if((data[n].html = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory in CheckField");
exit(1);
}
strcpy(data[n].file,val);
strcpy(data[n].html,val);
data[n].pass = 1;
} else if(data[n].req) {
*passed = 0;
}
break;
}
}
}
/************ Replacing return and tab character with space ******************/
char *replaceSpace(const char *lw) {
int n, m = 0, rp = 1; //rp replace
char *temp;
size_t sl;
sl = strlen(lw) + 1;
if((temp = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory in replaceSpace");
exit(1);
}
for(n = 0; lw[n]; n++) {
if(lw[n] == '\n' || lw[n] == '\r' || lw[n] == '\t') {
if(rp) {
temp[n-m] = ' ';
rp = 0;
} else {
m++;
}
} else {
temp[n-m] = lw[n];
rp = 1;
}
}
temp[n-m] = '\0';
return(temp);
}
/******************** Saving data to file FILE_PATH **************************/
int saveData(const fdata *data) {
int n;
FILE *outp;
if(fopen(FILE_PATH,"r") == NULL){
outp = fopen(FILE_PATH,"w");
for(n = 0; n <= FORM_FIELDS; n++)
if(strcmp(data[n].fileh,""))
fprintf(outp,"%s%c",data[n].fileh,9);
fclose(outp);
}
outp = fopen(FILE_PATH,"a");
fprintf(outp,"%c",10);
for(n = 0; n <= FORM_FIELDS; n++) {
if(strcmp(data[n].fileh,"")) {
if(!strcmp(data[n].fileh,"Zip Code") ||
!strcmp(data[n].fileh,"Phone") || !strcmp(data[n].fileh,"Fax")) {
fprintf(outp,"%s - %s%c",data[n].file,data[n+1].file,9);
} else if(!strcmp(data[n].fileh,"Comments")) {
fprintf(outp,"%s%c",replaceSpace(data[n].file),9);
} else {
fprintf(outp,"%s%c",data[n].file,9);
}
}
}
// Add comment here for non-Unix file system
/*
chown(FILE_PATH,USER_ID,GROUP_ID);
chmod(FILE_PATH,MODE_CH);
*/
// End of comment
return(1);
}
/****************** Making Replacement FORM_FIELD Code ***********************/
char *makeRC(const char *fname, const char type) {
char *temp;
size_t sl;
sl = strlen(fname) + 16; //15
if((temp = (char *)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory makeRC");
exit(1);
}
strcpy(temp,"\n");
break;
case 'e':
sl += 8; // 8
if((temp = (char*)realloc(temp,sizeof(char) * sl)) == NULL) {
printER("Out of memory in makeRC");
exit(1);
}
strcat(temp," END-->\n");
break;
default:
printER("Error in Making Replacement Code");
exit(1);
}
return(temp);
}
/*************************** Making TD code **********************************/
char *makeTD(const char *data, const char *colspan, char *hdata) {
char *temp;
size_t sl;
if(strcmp(colspan,"0")) {
sl = strlen(data) + strlen(colspan) + 24; // 23
if((temp = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory in makeTD");
exit(1);
}
strcpy(temp,"\t\t");
} else {
sl = strlen(data) + 13; // 12
if((temp = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory in makeTD");
exit(1);
}
strcpy(temp,"\t\t ");
}
strcat(temp,data);
strcat(temp," \n");
strcat(hdata,temp);
free(temp);
return(hdata);
}
/*********************** Making Require TD code ******************************/
char *makeRTD(const char *fhtml, char *hdata) {
char *temp;
size_t sl;
sl = strlen(fhtml) + strlen(NP_MESSAGE) + 11; // 10
if((temp = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory in makeRTD");
exit(1);
}
strcpy(temp,"\t\t");
strcat(temp,fhtml);
strcat(temp," ");
strcat(temp,NP_MESSAGE);
strcat(hdata,temp);
free(temp);
return(hdata);
}
/************************* Making hidden code ********************************/
char *makeHC(const char *name, char *val, char *hdata) {
int n;
char *temp, *tempv;
size_t sl;
for(n = 0; val[n]; n++) if(val[n] == '\"') val[n] = '\'';
sl = strlen(name) + strlen(val) + 42; // 41
if((temp = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory in makeHC");
exit(1);
}
strcpy(temp," ");
strcat(hdata,temp);
free(temp);
return(hdata);
}
/*********** Making passed desh code for zip, phone and fax ******************/
char *makePDSC(const char *bname, const char *ename, char *hdata) {
char *temp;
size_t sl;
sl = strlen(bname) + strlen(ename) + 16; // 15
if((temp = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory in makePDSC");
exit(1);
}
strcpy(temp,"\t\t ");
strcat(temp,bname);
strcat(temp," - ");
strcat(temp,ename);
strcat(temp," \n");
strcat(hdata,temp);
free(temp);
return(hdata);
}
/************ Making failed desh code for zip, phone and fax *****************/
char *makeFDSC(const char *bname, const char *ename, char *hdata) {
char *temp;
size_t sl;
sl = strlen(bname) + strlen(ename) + strlen(NP_MESSAGE) + 14; //13
if((temp = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory in makeFDSC");
exit(1);
}
strcpy(temp,"\t\t");
strcat(temp,bname);
strcat(temp," - ");
strcat(temp,ename);
strcat(temp," ");
strcat(temp,NP_MESSAGE);
strcat(hdata,temp);
free(temp);
return(hdata);
}
/****************** Replacing return character with BR ***********************/
char *replaceBR(const char *lw) {
int i, n, m=0, rp=1;
char *tag=" ", *temp;
size_t sl;
sl = strlen(lw) + 1;
if((temp = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory replaceBR");
exit(1);
}
for(n = 0; lw[n]; n++) {
if(lw[n] == '\n' || lw[n] == '\r' || lw[n] == '\f') {
if(rp) {
sl += 4;
if((temp = (char*)realloc(temp,sizeof(char) * sl)) == NULL) {
printER("Out of memory in replaceBR");
exit(1);
}
for(i = 0; tag[i]; i++) {
temp[m++] = tag[i];
}
rp = 0;
}
} else {
temp[m++] = lw[n];
rp = 1;
}
}
temp[m] = '\0';
return(temp);
}
/************************* Making comments out code **************************/
char *makeCom(const char *hform, const char *data, char *hdata) {
char *temp, *BRtemp;
size_t sl;
BRtemp = replaceBR(data);
sl = strlen(hform) + strlen(BRtemp) + 25; // 24
if((temp = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory in makeCom");
exit(1);
}
strcpy(temp,"\t\t ");
strcat(temp,hform);
strcat(temp,BRtemp);
strcat(temp," \n");
strcat(hdata,temp);
free(temp);
return(hdata);
}
/********************* Formating HTML table elements *************************/
char *formatHTML(const fdata *data, const int cf, const int passed,
char *hdata) {
char *temp;
size_t sl;
sl = strlen(data[cf].phtml)+strlen(data[cf].name)+strlen(data[cf].html) + 1000;
if((temp = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory replaceBR");
exit(1);
}
strcpy(temp,"\0");
if(!strcmp(data[cf].name,"MAILS_PERMIT") ||
!strcmp(data[cf].name,"SALES_PERMIT")) {
if(data[cf].pass) {
if(!passed) {
makeHC(data[cf].name,data[cf].html,temp);
}
makeTD(strcat(temp,data[cf].phtml),"2",hdata);
} else {
makeTD(data[cf].fhtml,"2",hdata);
}
} else if(!strcmp(data[cf].name,"PHONE_AREA")) {
if(data[cf].pass && data[cf+1].pass) {
if(!passed) {
makeHC(data[cf].name,data[cf].html,temp);
makeHC(data[cf+1].name,data[cf+1].html,temp);
}
makePDSC(strcat(temp,data[cf].html),data[cf+1].html,hdata);
} else {
makeFDSC(data[cf].fhtml,data[cf+1].fhtml,hdata);
}
} else if(!strcmp(data[cf].name,"FAX_AREA")) {
if(data[cf].pass && data[cf+1].pass) {
if(!passed) {
makeHC(data[cf].name,data[cf].html,temp);
makeHC(data[cf+1].name,data[cf+1].html,temp);
}
makePDSC(strcat(temp,data[cf].html),data[cf+1].html,hdata);
} else if(!data[cf].pass && !data[cf+1].pass) {
strcat(hdata,"\t\tNA \n");
} else {
makePDSC(data[cf].html,data[cf+1].html,hdata);
}
} else if(!strcmp(data[cf].name,"ZIP_CODE")) {
if(data[cf].pass && data[cf+1].pass) {
if(!passed) {
makeHC(data[cf].name,data[cf].html,temp);
makeHC(data[cf+1].name,data[cf+1].html,temp);
}
makePDSC(strcat(temp,data[cf].html),data[cf+1].html,hdata);
} else if(data[cf].pass) {
if(!passed) {
makeHC(data[cf].name,data[cf].html,temp);
}
makeTD(strcat(temp,data[cf].html),"0",hdata);
} else {
makeFDSC(data[cf].fhtml,data[cf+1].fhtml,hdata);
}
} else if(!strcmp(data[cf].name,"ADDINST")) {
if(data[cf].pass) {
if(!passed) {
makeHC(data[cf].name,data[cf].html,temp);
}
makeCom(temp,data[cf].html,hdata);
} else {
makeTD(data[cf].fhtml,"0",hdata);
}
} else if(data[cf].req) {
if(data[cf].pass) {
if(!passed) {
makeHC(data[cf].name,data[cf].html,temp);
}
makeTD(strcat(temp,data[cf].html),"0",hdata);
} else {
makeRTD(data[cf].fhtml,hdata);
}
} else if(!data[cf].req) {
if(data[cf].pass) {
if(strlen(data[cf].phtml)) {
if(!passed) {
makeHC(data[cf].name,data[cf].html,temp);
}
makeTD(strcat(temp,data[cf].phtml),"0",hdata);
} else {
if(!passed) {
makeHC(data[cf].name,data[cf].html,temp);
}
makeTD(strcat(temp,data[cf].html),"0",hdata);
}
} else {
makeTD(data[cf].fhtml,"0",hdata);
}
}
free(temp);
return(hdata);
}
/********************* Finding end of the Replacement Code *******************/
int findEndRC(const char *endcode, const char *htmlin) {
size_t sl;
if(!strcmp(htmlin,endcode))
return(0);
else
return(3);
}
/******************** Making DReplacement code output ************************/
char *makeRCout(char *hdata) {
char *temp, htmlin[128];
size_t sl;
FILE *inp;
sl = 128;
if((temp = (char*)malloc(sizeof(char) * sl)) == NULL) {
printER("Out of memory makeRC");
exit(1);
}
if((inp = fopen(PASS_REPLACE_FILE,"r")) != NULL) {
while(fgets(htmlin,127,inp)) {
strcat(temp,htmlin);
sl += 128;
if((temp = (char*)realloc(temp,sizeof(char) * sl)) == NULL) {
printER("Out of memoery makeDRC");
exit(1);
}
}
fclose(inp);
} else {
strcpy(temp,"\t\t");
strcat(temp,"Your reservation is forwarded to our representative.");
strcat(temp," \n");
}
strcat(hdata,temp);
free(temp);
return(hdata);
}
/************************* Making ASCII output ********************************/
char *makeASCII(const fdata *data, char *adata) {
int n;
strcat(adata,"Someone has made a reservation from your website.\n\n");
for(n = 0; n <= FORM_FIELDS; n++) {
if(strcmp(data[n].fileh,"")) {
if(!strcmp(data[n].name,"ZIP_CODE") ||
!strcmp(data[n].name,"PHONE_AREA") || !strcmp(data[n].name,"FAX_AREA")) {
if(data[n].pass && data[n+1].pass) {
strcat(adata,data[n].fileh);
strcat(adata,": ");
strcat(adata,data[n].file);
strcat(adata," - ");
strcat(adata,data[n+1].file);
strcat(adata,"\n");
n = n + 1;
}
} else if(!strcmp(data[n].name,"ADDINST")) {
if(data[n].pass) {
strcat(adata,data[n].fileh);
strcat(adata,": ");
strcat(adata,replaceSpace(data[n].file));
strcat(adata,"\n");
}
} else {
if(data[n].pass) {
strcat(adata,data[n].fileh);
strcat(adata,": ");
strcat(adata,data[n].file);
strcat(adata,"\n");
}
}
}
}
return(adata);
}
/************************* Making HTML output ********************************/
char *makeHTML(const char *htpath, const fdata *data, const int passed) {
int replacetag=0;
long n, cfield;
char *hdata, htmlin[128], prout[128], begincode[80], endcode[80];
size_t sl;
FILE *inp, *prinp;
if((hdata = (char*)malloc(sizeof(char) * 500000)) == NULL) {
printER("Out of memory only makeHTML");
exit(1);
}
strcpy(hdata,"\0");
if((inp = fopen(htpath,"r")) == NULL) {
printER("Cannot load file in makeHTML");
exit(1);
} else {
while(fgets(htmlin,127,inp)) {
switch (replacetag) {
case 0:
for (n = 0; n <= FORM_FIELDS; n++) {
strcpy(begincode,makeRC(data[n].name,'b'));
if(!strcmp(htmlin,begincode)) {
strcpy(endcode,makeRC(data[n].name,'e'));
replacetag = 1;
cfield = n;
break;
}
}
if(passed) {
if(!strcmp(htmlin,makeRC(PASS_REMOVE,'b'))) {
strcpy(endcode,makeRC(PASS_REMOVE,'e'));
replacetag = 3;
} else if(!strcmp(htmlin,makeRC(PASS_REPLACE,'b'))) {
strcpy(endcode,makeRC(PASS_REPLACE,'e'));
replacetag = 2;
}
}
if(replacetag==0) strcat(hdata,htmlin);
break;
case 1:
formatHTML(data,cfield,passed,hdata);
replacetag = findEndRC(endcode,htmlin);
break;
case 2:
makeRCout(hdata);
replacetag = findEndRC(endcode,htmlin);
break;
case 3:
replacetag = findEndRC(endcode,htmlin);
break;
default:
printER("Error in table creation!");
}
}
fclose(inp);
}
return(hdata);
}
/****************** Sending E-mail message of Html Data **********************/
int sendMail(const char *mreceiver, const char *hdata) {
char buf[81], *msender, *msubject, *mreply, *temp;
FILE *outp;
msender = EMAIL_SENDER;
msubject = "Reservation From the Website";
// Add comment from here for CGI running on system without Sendmail
if((temp = (char*)malloc(sizeof(char) * 1000)) == NULL) {
printER("Out of memory only sendMail");
exit(1);
}
strcpy(temp,"\0");
strcat(temp,EMAIL_BINARY);
strcat(temp," ");
strcat(temp,mreceiver);
// sprintf(buf,"%s",EMAIL_BINARY); for Unix Sendmail
sprintf(buf,"%s",temp);
outp = popen(buf, "w");
fprintf(outp,"From: %s\n",msender);
fprintf(outp,"To: %s\n",mreceiver);
fprintf(outp,"Subject: %s\n",msubject);
fprintf(outp,"Content-Type: text/plain\n");
fprintf(outp,"%s",hdata);
pclose(outp);
free(temp);
// End of the comment
// Remove comment from here for writting E-mail message to file
/*
outp = fopen(mreceiver,"w");
fprintf(outp,"%s\n",EMAIL_BINARY);
fprintf(outp,"From: %s\n",msender);
fprintf(outp,"To: %s\n",mreceiver);
fprintf(outp,"Subject: %s\n",msubject);
fprintf(outp,"Content-Type: text/plain\n");
fprintf(outp,"%s",hdata);
fclose(outp);
*/
// End of the comment
return(1);
}
/****************************** Main Program *********************************/
void main(int argc, char *argv[]) {
entry entries[MAX_ENTRIES];
fdata data[MAX_ENTRIES];
register int x;
int cl,sl,spassed=1;
char *adata, *hdata;
printf("Content-type: text/html%c%c",10,10);
checkEnv();
initData(data);
cl = atoi(getenv("CONTENT_LENGTH"));
for(x = 0; cl && (!feof(stdin)); x++) {
entries[x].val = fmakeword(stdin,'&',&cl);
plustospace(entries[x].val);
unescape_url(entries[x].val);
entries[x].name = makeword(entries[x].val,'=');
checkField(entries[x].name,entries[x].val,data,&spassed);
}
if(spassed) {
if((adata = (char*)malloc(sizeof(char) * 500000)) == NULL) {
printER("Out of memory only makeASCI");
exit(1);
}
strcpy(adata,"\0");
makeASCII(data,adata);
spassed = sendMail(EMAIL_RECORD_RECEIVER,adata);
spassed = sendMail(EMAIL_RECEIVER,adata);
spassed = sendMail(EMAIL_RECEIVER1,adata);
spassed = sendMail(EMAIL_RECEIVER2,adata);
}
printf("%s",makeHTML(FORM_PATH,data,spassed));
}
/**************************** End of File ************************************/