/******************************************************************** // // Gate.cpp: implementation of the CGate class. // // kishan@hackorama.com http://www.hackorama.com // // Thu Nov 4 19:56:03 PST 1999 // *********************************************************************/ #include #include #include #include #include #include #include "gate.h" CGate::CGate() { //Get the submit stream from form gGetPost(); //process the posted data gProcessPost(); } CGate::CGate( char* posted_data ) { //this is for offline testing !! m_pBuff = new char[ strlen(posted_data) + 1 ]; strcpy( m_pBuff, posted_data ); //process the posted data gProcessPost(); } CGate::~CGate() { //give back everything to heap if(m_bMemAllocated){ for (int i = 0; i < m_memValues->numPairs ; i++){ delete [] m_pstrType[i]; delete [] m_pstrValue[i]; } delete[] m_pstrType; delete[] m_pstrValue; } delete m_memValues; delete[] m_pBuff; } void CGate::gGetPost() { //get the urlencode text stream from form submission char *endptr; int contentlength; const char *length = getenv("CONTENT_LENGTH"); if ( !length ){ gPrintError( 1 ); }else { contentlength=strtol(length, &endptr, 10); m_pBuff = new char[ (contentlength/sizeof(char))+1 ]; fread(m_pBuff, contentlength, 1, stdin); } } void CGate::gProcessPost() { m_bMemAllocated = 0; m_memValues = new mallocValues; //Find out how many pairs and max length for type and pair gGetLength(m_pBuff, m_memValues); //If there are some process it if ( m_memValues->numPairs ) { //Now allocate memory from heap gMemAlloc(m_memValues); //make type-value pairs of the stream gMakePairs(); //remove URL encoding gCleanUp(); } else { gPrintError( 2 ); } } void CGate::gGetLength(char* pBuff,struct mallocValues* memValues) { unsigned int x,y=0,z=0,i=0,j=0; unsigned int maxlengthofType = 0, maxlengthofValue = 0; for (x = 0; x < strlen(pBuff); x++) { switch (pBuff[x]){ case '=': { if( y >= maxlengthofType ) maxlengthofType = y; y = 0; i++; } break; case '&': { if( z >= maxlengthofValue ) maxlengthofValue = z; z = 0; j++; } break; default: if(j && i && (j==i)){ y++; }else if(i>j){ z++; } else{ y++; } break; } } memValues->maxlengthofType = maxlengthofType+1; memValues->maxlengthofValue = maxlengthofValue+1; memValues->numPairs = i; } void CGate::gMemAlloc(struct mallocValues* memValues) { int c = 0; m_pstrType = new char* [memValues->numPairs]; while ( c < memValues->numPairs ){ m_pstrType[c] = new char[memValues->maxlengthofType];c++; } c = 0; m_pstrValue = new char* [memValues->numPairs]; while ( c < memValues->numPairs ){ m_pstrValue[c] = new char[memValues->maxlengthofValue];c++; } m_bMemAllocated = 1; } void CGate::gMakePairs() { unsigned int x,y=0,z=0,i=0,j=0; for (x = 0; x < strlen(m_pBuff); x++) { switch (m_pBuff[x]){ case '=': m_pstrType[i][y] = '\0'; y = 0; i++; break; case '&': m_pstrValue[j][z] = '\0'; z = 0; j++; break; default: if(j && i && (j==i)){ m_pstrType[i][y] = m_pBuff[x];y++; }else if(i>j){ m_pstrValue[j][z] = m_pBuff[x];z++; } else{ m_pstrType[i][y] = m_pBuff[x];y++; } break; } } m_pstrValue[j][z] = '\0';//hack for the last value } void CGate::gCleanOne(char *pTheString) { unsigned int x,y; char* pstrTemp = new char[strlen(pTheString)+1]; pstrTemp[0] = '\0'; char hexstr[2]; for (x = 0, y = 0; x < strlen(pTheString); x++, y++) { switch (pTheString[x]){ // Convert all + chars to white space case '+': pstrTemp[x] = ' '; break; // Convert all %xy hex codes into ASCII case '%': // Copy the two bytes following the % strncpy(hexstr, &pTheString[x + 1], 2); // Skip over the hex x = x + 2; // Convert the hex to ASCII // Avoid altering URL delimiter sequence if( ((strcmp(hexstr,"26")==0)) || ((strcmp(hexstr,"3D")==0)) ){ pstrTemp[y]='%'; y++; strcpy(pstrTemp,hexstr); y=y+2; break; } pstrTemp[y] = (char)strtol(hexstr, NULL, 16); break; // make an exact copy of anything else default: pstrTemp[y] = pTheString[x]; break; } } pstrTemp[y] = '\0'; strcpy(pTheString, pstrTemp); delete[] pstrTemp; } void CGate::gCleanUp() { for(int i = 0; i < m_memValues->numPairs ; i++ ){ gCleanOne( m_pstrType[i] ); gCleanOne( m_pstrValue[i]); } } char* CGate::gGetValueFor(char *pstrType) { int i=0; while(i< m_memValues->numPairs ){ if(!(strcmp(m_pstrType[i],pstrType)) ){ return(m_pstrValue[i]); } i++; } return("NOMATCH"); } void CGate::gVerify() { cout << endl << "GATE: PRINTING OUT NAME VALUE PAIRS FOR VERIFYING" << endl; cout << endl; for(int i = 0; i < m_memValues->numPairs ; i++ ){ cout << "NAME[" << i << "] =" << m_pstrType[i] << " VALUE[" << i << "] = " << m_pstrValue[i] << endl; } } void CGate::gPrintHeader() { cout << "Content-type: text/html" << endl << endl; } void CGate::gPrintError(int type) { if( type == 1 ){ gPrintHeader(); cout << " GATE WARNING: You did not post any data for processing" << endl ; cout << " " << endl ; }else if ( type == 2 ){ gPrintHeader(); cout << " GATE ERROR: Looks like you entered wrong data" << endl ; cout << " " << endl ; } exit(0); } void CGate::gLog(char* pstrFile) { ofstream pFile( pstrFile, ios::app ); time_t now; now = time(NULL); if ( !pFile ) { //Could not open the log file ! //may be put an error message here ? }else{ pFile << "-------------------------------" << endl; pFile << "TIME: "<< ctime(&now) << endl; char *client_info; client_info = getenv("REMOTE_ADDR"); if(client_info) pFile << "IP: " << client_info << endl ; client_info = getenv("REMOTE_HOST"); if(client_info) pFile << "HOST: " << client_info << endl ; client_info = getenv("HTTP_USER_AGENT"); if(client_info) pFile << "BROWSER: " << client_info << endl ; client_info = getenv("HTTP_REFERER"); if(client_info) pFile << "REFERRED: " << client_info << endl ; client_info = getenv("HTTP_FROM"); if(client_info) pFile << "FROM: " << client_info << endl ; client_info = getenv("REMOTE_USER"); if(client_info) pFile << "USER: " << client_info << endl ; client_info = getenv("REMOTE_IDENT"); if(client_info) pFile << "ID: " << client_info << endl ; } }