/*************************************************************/ /* */ /* Name: cgiForm.cpp */ /* */ /* Description: Program to process fields submitted from */ /* a HTML form. */ /* */ /*************************************************************/ #include /* for Socket data types */ #include /* for socket(), connect(), send(), and recv() */ #include /* for IP Socket data types */ #include /* for sockaddr_in and inet_addr() */ #include /* for atoi() */ #include /* for memset() */ #include /* for close() */ #include #include #include #include using namespace std; /* Create header of HTML page */ void header(string); /* Create footer of HTML page */ void footer(); /* Makes sure this request is a form submission */ int VerifyForm(); /* Read the data sent from the form */ void readData(int method, string &buf, int &len); /* Parses the submitted form data, filling the names[] and values[] arrays with useful information */ void ParseForm(string buffer, int length); /* Copies src to dst, unescaping any special characters in the process. dst must be at least as large as src in order to ensure that there is enough space. */ void UnescapeString(string &dst, const string &src); void DieWithError(char *errorMessage); /* External error handling function */ const int MAX_FIELDS = 100; // Max number of fields on form int numFields = 0; // Number of fields on form submitted string name[MAX_FIELDS]; // Array of field names string values[MAX_FIELDS]; // Array of fields values #define ECHOMAX 255 /* Longest string to echo */ int main() { ifstream input; string temp_ip; string myTitle = "Form Results"; int method; // method used to submit form values // 0 = post, 1 = get, -1 = not post or get string data; // data submitted from the form int len; // length of input data int sock; /* Socket descriptor */ struct sockaddr_in echoServAddr; /* Echo server address */ struct sockaddr_in fromAddr; /* Source address of echo */ short echoServPort; /* Echo server port */ int fromSize; /* In-out of address size for recvfrom() */ char *servIP; /* IP address of server */ char *echoString; /* String to send to echo server */ char temp_char; string temp_string; char echoBuffer[ECHOMAX+1]; /* Buffer for receiving echoed string */ int echoStringLen; /* Length of string to echo */ int respStringLen; /* Length of received response */ string temp; header(myTitle); input.open("ipaddress.txt"); input >> temp_ip; cout << temp_ip << endl; method = VerifyForm(); if (method == -1) { // get or post not used cout << "

Error

" << endl; cout << "You must submit a form using the GET or POST method!
" << endl; footer(); cout.flush(); return 0; } // end if VerifyForm // Read the data submitted from the form readData(method, data, len); // Parse the form values ParseForm(data, len); for (int i = 0; i < numFields; i++) cout << name[i] << " = " << values[i] << "
" << endl; servIP = (char *)temp_ip.c_str(); if(values[0] != "") { temp_string = "$"; temp_char = (char)(((string)values[0]).length()); temp_string += temp_char; temp_string += "$"; temp_string += values[0]; echoString = (char *)temp_string.c_str(); } else { echoString = (char *) values[1].c_str(); } cout << endl << "

" << echoString << "

" << endl; //echoStringLen = strlen(echoString); if ((echoStringLen = strlen(echoString)) > ECHOMAX) /* Check input length */ cout<< "Echo word too long" << endl; //DieWithError("Echo word too long"); echoServPort = 5224; /* 7 is the well-known port for the echo service */ /* Create a datagram/UDP socket */ if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) cout<< "socket failed" << endl; //DieWithError("socket() failed"); /* Construct the server address structure */ memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */ echoServAddr.sin_family = AF_INET; /* Internet addr family */ echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */ echoServAddr.sin_port = htons(echoServPort); /* Server port */ /* Send the string to the server */ if (sendto(sock, echoString, echoStringLen, 0, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) != echoStringLen) cout<<"sendto() sent a different number of bytes thanexpected"<< endl; /* Recv a response fromSize = sizeof(fromAddr); if ((respStringLen = recvfrom(sock, echoBuffer, ECHOMAX, 0, (struct sockaddr *) &fromAddr, &fromSize)) != echoStringLen) cout<< "recvfrom() failed" << endl; //DieWithError("recvfrom() failed"); if (echoServAddr.sin_addr.s_addr != fromAddr.sin_addr.s_addr) { fprintf(stderr,"Error: received a packet from unknown source.\n"); exit(1); } null-terminate the received data echoBuffer[respStringLen] = '\0'; printf("Received: %s\n", echoBuffer); Print the echoed arg */ close(sock); footer(); return 0; } // end function main void header(string title) { cout << "Content-Type: text/html" << endl << endl; cout << "" << endl; cout << "" << endl; cout << "" << title << "" << endl; cout << "" << endl; cout << "" << endl; return; } // end function header void footer() { cout << "" << endl; cout << "" << endl; cout << ""; cout.flush(); return; } // end function footer // Will make sure the submission is a form and uses POST method int VerifyForm() { char *form = "application/x-www-form-urlencoded"; // form submission char *pst = "POST"; // POST method char *gt = "GET"; char *method = getenv("REQUEST_METHOD"); // is it post method? if (strncmp(method, pst, 4) == 0) if (strcmp(getenv("CONTENT_TYPE"), form) != 0) // not a form submission return -1; else return 0; // is it get method? if (strncmp(method, gt, 3) == 0) return 1; return -1; } // end function VerifyForm void readData(int meth, string &buf, int &len) { char *contentLength; // CONTENT_LENGTH environment variable char *buffer; // Find length of data sent by form contentLength = getenv("CONTENT_LENGTH"); if (contentLength == NULL) len = 0; else len = atoi(contentLength); // Allocate space for buffer buffer = new char[len + 1]; if (!buffer) return; // unable to allocate memory if (meth == 0) { // post method cin.read(buffer, len); if (cin.gcount() < len) return; // read less than the desired number of characters } // end if meth == 0 else // get method buffer = getenv("QUERY_STRING"); buf = (string)buffer; return; } // end function readData void ParseForm(string buffer, int length) { string pos; // Current position in data int place = 0; // Current position int oldPlace = 0; // Previous position pos = buffer; cout << "Forms from field:
" << endl; cout << pos << "
" << endl; place = pos.find("=", oldPlace); // find first = while (place != -1) { UnescapeString(name[numFields], pos.substr(oldPlace, place - oldPlace)); oldPlace = place + 1; place = pos.find("&", oldPlace); // Find & if (place == -1) break; UnescapeString(values[numFields], pos.substr(oldPlace, place - oldPlace)); numFields++; oldPlace = place + 1; if (place == length) break; place = pos.find("=", oldPlace); } // end while place != -1 UnescapeString(values[numFields], pos.substr(oldPlace, place - oldPlace)); numFields++; return; } // end function parseForm void UnescapeString(string &dst, const string &src) { /* Loop over the characters in the string until we encounter the null character at the end, which tests false. */ for (int i = 0; i < src.length(); i++) { char c; c = src[i]; /* Handle spaces escaped as + signs */ if (c == '+') { c = ' '; } else if (c == '%') { /* Handle % escapes */ char hexdigits[3]; int ascii; i++; if (!src[i]) break; // Digits missing! Ignore escape hexdigits[0] = src[i]; i++; if (!src[i]) break; // Digits missing! Ignore escape hexdigits[1] = src[i]; hexdigits[2] = '\0'; // Add a terminating null... /* Now use the C standard library function sscanf() to read the hex value */ sscanf(hexdigits, "%x", &ascii); c = ascii; // And convert it back to a character } dst = dst + c; } } // end function UnescapeString void DieWithError(char *errorMessage) { perror(errorMessage); exit(1); }