/**************************
* cgilib.h *
***************************/
typedef char *string;
typedef struct
{
string fieldName;
string value;
}oneField;
struct element {
oneField data;
struct element *next;
};
typedef struct element node;
typedef node *link;
link tokenize(string input_string);
string cgi_val(link head, string field);
void print_table(link head);
string next_word(char *, int *);
/**************************
* cgilib.c *
***************************/
#include "cgilib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Used to parse an input string, and returns a linked
* list of tokens. Maintained by alphabetical order of
* the field name, and the data stored in each node
* is a record representing one field
*/
link tokenize (string input_string)
{
int numOfSpaces;
string next;
oneField thisRecord;
/* used for head of linked list */
link head;
int counter = 0;
void insert(link*, oneField);
head = 0;
while(1)
{
numOfSpaces = 0;
next = next_word(input_string, &numOfSpaces);
/* next = the word which we will work with here */
if(counter == 0){
thisRecord.fieldName = (char *) calloc(strlen(next), sizeof(char));
strcpy(thisRecord.fieldName, next);
}else if(counter == 1){
thisRecord.value = (char *) calloc(strlen(next), sizeof(char));
strcpy(thisRecord.value, next);
insert(&head, thisRecord);
}else if(counter % 2 == 0){
thisRecord.fieldName = (char *) calloc(strlen(next), sizeof(char));
strcpy(thisRecord.fieldName, next);
}else{
thisRecord.value = (char *) calloc(strlen(next), sizeof(char));
strcpy(thisRecord.value, next);
insert(&head, thisRecord);
}
/* if the word returned by next_word was the last word
in the input string, then the element at that length
should be the null character, in which case we will
break from the loop */
counter++;
if(input_string[strlen(next)] == '\0')
break;
input_string += strlen(next) + numOfSpaces;
}
return head;
}
/*
* Steps through the linked list pointed to by the head
* and finds the node pointed to by the given field
*/
string cgi_val(link head, string field)
{
void toUpper(string);
link start = head;
while(head)
{
toUpper(head->data.fieldName);
toUpper(field);
if(!strcmp(head->data.fieldName, field))
{
return head->data.value;
}
head = head->next;
}
head = start;
return "ERROR! FIELD NAME NOT FOUND!";
}
/*
* Used to print the table
* Given: head of linked list
*/
void print_table(link head)
{
link start = head;
printf("\n%s%26s\n%s\n", "Field Name", "Value",
"----------------------------------------------");
while(head)
{
printf("%-20s%-40s\n", head->data.fieldName, head->data.value);
head = head -> next;
}
printf("----------------------------------------------\n");
head = start;
}
/*
* Used in order to put strings of any length in
* the linked list (dynamically generates the string)
*/
string next_word(char * pos, int *numOfSpaces){
/* count is the number of total characters in the string,
whereas trueCount counts special 3-digit characters as
only one 'true' character*/
int count = 0, trueCount = 0, i;
char * b = pos;
int forConvert;
string a;
char current;
if(pos[0] == '\0')
return NULL;
/* still check for spec. char in input */
while(((current = *b) != '=') && (current != '&') && (current != '\0')){
trueCount++;
count++;
b++;
if(current == '%')
trueCount = trueCount - 2;
}
a = (char *) calloc(trueCount + 1, sizeof(char));
/* check for spec chars */
for(i = 0; i < trueCount; i++)
{
if(*pos == '%')
{
pos++;
switch(*pos)
{
case '0': forConvert = 16*0;
break;
case '1': forConvert = 16*1;
break;
case '2': forConvert = 16*2;
break;
case '3': forConvert = 16*3;
break;
case '4': forConvert = 16*4;
break;
case '5': forConvert = 16*5;
break;
case '6': forConvert = 16*6;
break;
case '7': forConvert = 16*7;
break;
case '8': forConvert = 16*8;
break;
case '9': forConvert = 16*9;
break;
case 'A':
case 'a': forConvert = 16*10;
break;
case 'B':
case 'b': forConvert = 16*11;
break;
case 'C':
case 'c': forConvert = 16*12;
break;
case 'D':
case 'd': forConvert = 16*13;
break;
case 'E':
case 'e': forConvert = 16*14;
break;
case 'F':
case 'f': forConvert = 16*15;
break;
default:
printf("%c is not a proper hex number!\n", *pos);
exit(1);
}
pos++;
switch(*pos)
{
case '0': forConvert += 0;
break;
case '1': forConvert += 1;
break;
case '2': forConvert += 2;
break;
case '3': forConvert += 3;
break;
case '4': forConvert += 4;
break;
case '5': forConvert += 5;
break;
case '6': forConvert += 6;
break;
case '7': forConvert += 7;
break;
case '8': forConvert += 8;
break;
case '9': forConvert += 9;
break;
case 'A':
case 'a': forConvert += 10;
break;
case 'B':
case 'b': forConvert += 11;
break;
case 'C':
case 'c': forConvert += 12;
break;
case 'D':
case 'd': forConvert += 13;
break;
case 'E':
case 'e': forConvert += 14;
break;
case 'F':
case 'f': forConvert += 15;
break;
default:
printf("%c is not a proper hex number!(2)\n", *pos);
exit(1);
}
*numOfSpaces = *numOfSpaces + 2;
a[i] = forConvert;
}else if(*pos == '+'){
a[i] = ' ';
}else{
a[i] = *pos;
}
pos++;
}
a[trueCount] = '\0';
*numOfSpaces = *numOfSpaces + 1;
return a;
}
/***************************************************
****************************************************
****************************************************
***************************************************/
void insert(link *list_head, oneField a){
link p = *list_head, prev = NULL, new_node;
while(p && strcmp(a.fieldName, p->data.fieldName) > 0)
{
prev = p;
p = p->next;
}
new_node = malloc(sizeof(node));
new_node -> data = a;
new_node -> next = p;
if(prev)
prev -> next = new_node;
else
*list_head = new_node;
}
void toUpper(string a){
int i;
for(i = 0; i < strlen(a); i++){
a[i] = toupper(a[i]);
}
}
/**************************
* mainProgram.c *
***************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cgilib.h" /* It contains the function prototype of
"exit". */
string get_input(void)
{
string a;
int c;
int count = 0;
char file_name[20];
FILE *text;
printf("\n\nEnter the file name --> ");
gets(file_name);
text = fopen(file_name, "r"); /* open the file for reading */
if (!text)
{
printf("\n\nError: The file \"%s\" does not exist.\n",
file_name);
exit(1); /* terminate the program with an error */
}
while ((c = getc(text)) != EOF)
count++;
fclose(text);
a = (char *)calloc(count+1, sizeof(char));
text = fopen(file_name, "r");
if(!text)
{
printf("file not found!!!!\n");
exit(1);
}
fgets(a, count+1, text);
return a;
}
void main()
{
link a;
char inputField[31];
string inputString;
inputString = get_input();
a = tokenize(inputString);
print_table(a);
while(1){
printf("Enter a field name(Enter exit to Quit): ");
gets(inputField);
if(!strcmp(inputField, "exit")){
break;
}
printf("Value for specified field: %s\n", cgi_val(a,inputField));
}
}