home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Visual Database / Visual Foxpro 6.0 (Ent. Edition) / Vf6ent Extractor.EXE / TOOLS / INETWIZ / SERVER / MYCGI.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-26  |  5.9 KB  |  215 lines

  1. #include <io.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <windows.h>
  5. #include <winbase.h>
  6. #include <time.h>
  7. #include <direct.h>
  8. #include <sys/timeb.h>
  9.  
  10. #define TEMP_PREFIX_LENGTH 8        // Length of temporary file prefix excluding null terminator
  11. #define DATA_BUFFER_LENGTH 1000        // Length of data buffer.
  12.  
  13. #define MAX_FILE_ATTEMPTS        10  // Number of times to attempt creating temp file.
  14. #define ACK_RETRY_MILLISECONDS 250  // Number of milliseconds for each retry attempt to read ACK file.
  15. #define ACK_TIMEOUT_SECONDS     60  // Number of seconds until attempts to read ACK file time out.
  16.  
  17. #define SERVER_INACCESSIBLE_TITLE_LOC    "Server Inaccessible"
  18. #define SERVER_INACCESSIBLE_TEXT_LOC    "Communication with the server is not possible at this time."
  19. #define SERVER_TIMEOUT_TITLE_LOC    "Server Timeout" 
  20. #define SERVER_TIMEOUT_TEXT_LOC        "The server timed out. It is probably too busy to fulfill your request."
  21. #define SERVER_NODATA_TITLE_LOC    "Server Error"
  22. #define SERVER_NODATA_TEXT_LOC    "A server error occurred.  No return data was sent."
  23.  
  24. void errorform( char *errorstring, char *errortitle );
  25.  
  26. void main( int argc, char *argv[] ) 
  27. {
  28.  
  29.     char tmpPrefix[TEMP_PREFIX_LENGTH+1];
  30.     char tmpFolder[] = "\\temp";
  31.     char tmpName[_MAX_PATH];
  32.  
  33.     char *t1         = NULL;
  34.     char *tempbuffer = NULL;
  35.  
  36.     char datFileName[_MAX_PATH];
  37.     char ackFileName[_MAX_PATH];
  38.     char atnFileName[_MAX_PATH];
  39.  
  40.     FILE *datFile    = NULL;
  41.     FILE *atnFile    = NULL;
  42.     FILE *tempFile   = NULL;
  43.     struct _timeb timebuffer;
  44.  
  45.     
  46.     char buffer[DATA_BUFFER_LENGTH];
  47.     int cont_len, bytesread, fileattempts;
  48.     time_t begintout, chktout;
  49.     char **envptr;
  50.     fpos_t pos;
  51.  
  52.     // Turn stdin buffering off
  53.     setvbuf( stdin, NULL, _IONBF, 0 );
  54.  
  55.     // Create server.app compatible temporary folder.
  56.     // Note:  Server.app is looking for files in <current drive>:\temp,
  57.     // not in the actual system temporary folder.
  58.     _mkdir( tmpFolder );
  59.  
  60.     // Seed random number generator and zero fileattempts counter.
  61.     _ftime( &timebuffer );
  62.     srand( ((timebuffer.time & 0xFF)<<10) | timebuffer.millitm );
  63.     fileattempts = 0;
  64.  
  65.     for (;;) 
  66.     {
  67.  
  68.         fileattempts++;
  69.  
  70.         // If we've tried MAX_FILE_ATTEMPTS times, give error message.
  71.         if ( fileattempts > MAX_FILE_ATTEMPTS ) 
  72.         {
  73.             errorform( SERVER_INACCESSIBLE_TEXT_LOC, SERVER_INACCESSIBLE_TITLE_LOC );
  74.             goto CleanupAndExit;
  75.         }
  76.  
  77.         // Create random file name. Format is "VF" plus unique 4 digit hex number
  78.         // representing the processid, plus 2 digit random number (in case multiple
  79.         // machines are running the CGI scripts).
  80.         sprintf( tmpPrefix, "VF%04X%02X", (DWORD) GetCurrentProcessId(), rand() & 0xFF);
  81.  
  82.         // Build temporary file name.
  83.         sprintf( tmpName, "%s\\%s", tmpFolder, tmpPrefix );
  84.  
  85.         // Create the names for the three files.
  86.         sprintf( datFileName, "%s.dat", tmpName );
  87.         sprintf( ackFileName, "%s.ack", tmpName );
  88.         sprintf( atnFileName, "%s.atn", tmpName );
  89.  
  90.         // Create data file.
  91.         datFile = fopen( datFileName, "a" );
  92.  
  93.         // Make sure data file didn't already exist.
  94.         if ( NULL != datFile ) 
  95.         {
  96.             // Seek to the end of the file.
  97.             fseek( datFile, 0, SEEK_END );
  98.             if( 0 == fgetpos( datFile, &pos ) ) 
  99.             {
  100.                 // We know fgetpos was successful, now check position.
  101.                 // If pos is zero, we know we have a new file and can break out of loop.
  102.                 if ( 0 == pos ) break;
  103.             }
  104.             fclose( datFile );
  105.         }
  106.         
  107.     }
  108.  
  109.     // We could check REQUEST_METHOD here, but what would be the point?
  110.     // If CONTENT_LENGTH is NULL, we won't read the stdin, otherwise we will.
  111.     // This is entirely for POST method requests.
  112.     t1 = getenv( "CONTENT_LENGTH" );
  113.     if ( NULL != t1 ) 
  114.     {
  115.         cont_len = atoi( t1 );
  116.  
  117.         tempbuffer = (char *) malloc( sizeof(char) * cont_len );
  118.         if ( NULL == tempbuffer )
  119.         {
  120.             goto CleanupAndExit;
  121.         }
  122.  
  123.         bytesread = fread( tempbuffer, sizeof(char), cont_len, stdin );
  124.         if ( 0 != bytesread )
  125.             fwrite( tempbuffer, sizeof(char), bytesread, datFile );
  126.  
  127.         free( tempbuffer );
  128.     }
  129.  
  130.     // This part reads all of the environment variables and sends
  131.     // them along in the DAT file as well. All ampersand delimited.
  132.     envptr = environ;
  133.     while ( NULL != *envptr )
  134.     {
  135.         fputs( "&", datFile );
  136.         fputs( *envptr, datFile );
  137.         envptr++;
  138.     }
  139.     fclose( datFile );
  140.  
  141.     // Create ATN File
  142.     atnFile = fopen( atnFileName,"w" );
  143.     if ( NULL == atnFile ) 
  144.     {
  145.         errorform( SERVER_INACCESSIBLE_TEXT_LOC , SERVER_INACCESSIBLE_TITLE_LOC );
  146.         goto CleanupAndExit;
  147.     }
  148.  
  149.     fclose( atnFile );
  150.  
  151.     _flushall();
  152.  
  153.     // Wait for Server to ACK
  154.     time( &begintout );
  155.     do
  156.     {
  157.         tempFile = fopen( ackFileName, "r" );
  158.         if ( NULL != tempFile ) break;    // Break before sleep if successful.
  159.         time( &chktout );
  160.         Sleep( ACK_RETRY_MILLISECONDS );
  161.     //if _access() can't find the file, then the query is currently being processed.  
  162.     //Keep looping for another ACK_TIMEOUT_SECONDS.
  163.     } while ( ( NULL == tempFile ) && (( difftime( chktout, begintout ) < ACK_TIMEOUT_SECONDS ) 
  164.         || ((_access(atnFileName,0) == -1) && ( difftime( chktout, begintout ) < (2*ACK_TIMEOUT_SECONDS) ))));
  165.  
  166.     if ( NULL != tempFile )
  167.     {
  168.         fclose( tempFile );
  169.     }
  170.     else
  171.     {
  172.         errorform( SERVER_TIMEOUT_TEXT_LOC , SERVER_TIMEOUT_TITLE_LOC);
  173.         goto CleanupAndExit;
  174.     }
  175.  
  176.     // Send the Data file to stdout.
  177.     datFile = fopen( datFileName, "r" );
  178.     if ( NULL == datFile ) 
  179.     {
  180.         errorform( SERVER_NODATA_TEXT_LOC , SERVER_NODATA_TITLE_LOC);
  181.         goto CleanupAndExit;
  182.     }
  183.     else 
  184.     {
  185.         // Return results to web server.
  186.         while ( !feof( datFile ) )
  187.         {
  188.             if ( NULL != fgets( buffer, DATA_BUFFER_LENGTH, datFile ) )
  189.                 printf( "%s", buffer );
  190.         } 
  191.         fclose( datFile );
  192.     }
  193.  
  194. CleanupAndExit:
  195.  
  196.     // Close all file handles.
  197.     _fcloseall();
  198.  
  199.     // Remove temporary files.
  200.     remove( ackFileName );
  201.     remove( datFileName );
  202.     remove( atnFileName );
  203.  
  204.     return;
  205.  
  206. }
  207.  
  208. void errorform( char *errorstring, char *errortitle )
  209. {
  210.     printf( "Content-Type: text/html\n\n" );
  211.     printf( "<head><title>%s</title></head>\n", errortitle );
  212.     printf( "<body>\n<h1>%s</h1>\n", errortitle );
  213.     printf( "%s<hr>\n</body>", errorstring );
  214. }
  215.