home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks96 / troz.cgi.sit / troz.cgi / MyCGIProcess.c next >
Text File  |  1996-06-22  |  12KB  |  434 lines

  1. /*****
  2.  *
  3.  *    Troz CGI
  4.  *
  5.  *    MyCGIProcess.c
  6.  *
  7.  *
  8.  *
  9.  *    by Grant Neufeld
  10.  *
  11.  *    Copyright ©1996 by Grant Neufeld
  12.  *
  13.  *    http://arpp.carleton.ca/grant/
  14.  *    gneufeld@ccs.carleton.ca
  15.  *    grant@acm.org
  16.  *
  17.  *****/
  18.  
  19. #include "MyConfiguration.h"
  20. #if kCompileWithCGICode
  21.  
  22. #include <string.h>
  23. #include <Threads.h>
  24. #include <QCAPI.h>
  25.  
  26. #include "globals.h"
  27.  
  28. #include "CGI.h"
  29. #include "CustomHandlers.h"
  30. #include "DebugUtil.h"
  31. #include "LogUtil.h"
  32. #include "MemoryUtil.h"
  33. #include "ProcessUtil.h"
  34.  
  35.  
  36. #include "otherprocs.h"
  37.  
  38.  
  39.  
  40. /***  LOCAL CONSTANTS  ***/
  41.  
  42. #define krtTrozType                'troZ'
  43.  
  44. #define krsTrozHTTPHeader        10101
  45. #define krsTrozHTMLFirstChunk    10102
  46. #define krsTrozHTMLSecondChunk    10103
  47.  
  48. #define krsTrozPinkyHTML        10110
  49. #define krsTrozQuickCamHTML        10111
  50.  
  51.  
  52. /***  LOCAL VARIABLES  ***/
  53.  
  54. Handle    vTrozHTTPHeader;
  55. Handle    vTrozHTMLFirstChunk;
  56. Handle    vTrozHTMLSecondChunk;
  57. int        vTrozHTTPHeaderSize;
  58. int        vTrozHTMLFirstChunkSize;
  59. int        vTrozHTMLSecondChunkSize;
  60.  
  61. Handle    vTrozPinkyHTML;
  62. int        vTrozPinkyHTMLSize;
  63.  
  64. Handle    vTrozQuickCamHTML;
  65. int        vTrozQuickCamHTMLSize;
  66.  
  67. UInt16    vTrozRandomRate;
  68.  
  69. FSSpec    vTrozQuickCamFile;
  70.  
  71.  
  72. /***  LOCAL FUNCTIONS  ***/
  73.  
  74. Boolean    TrozShouldWeNarf    ( CGIHdl );
  75. OSErr    TrozUseQuickCam        ( CGIHdl );
  76.  
  77.  
  78. /***  CUSTOM CGI FUNCTION  ***/
  79.  
  80. /* This function is where the CGI is actually processed.
  81.     You should replace its contents with your own.
  82.     You need to allocate (*theCGIHdl)->responseData using MemoryNewHandle.
  83.     Put an HTTP header at the beginning of (*theCGIHdl)->responseData.
  84.     Put your data immediately following the last character of the HTTP header.
  85.     (*theCGIHdl)->responseData will be automatically deallocated by the CGI handler.
  86.     You should set (*theCGIHdl)->responseSize to be the size of the responseData,
  87.      including null terminator if you have one. */
  88. void
  89. CustomCGIProcess ( CGIHdl theCGIHdl )
  90. {
  91.     Boolean    processEvent;
  92.     Handle    returnData;
  93. //    short    returnDataSize;
  94.     OSErr    theErr;
  95. //    char *    theOriginalURL;
  96. //    short    theOriginalURLSize;
  97. //    short    scriptNameSize;
  98. //    short    serverNameSize;
  99.     SInt8    savedHandleState;
  100. //    long    returnDataPostion;
  101. //    short    extraBytesForHandle;
  102.     
  103.     /* debugging check to ensure that theCGIHdl is not NULL */
  104.     my_assert ( theCGIHdl != NULL,
  105.         "\pCustomCGIProcess: theCGIHdl is NULL" );
  106.     
  107.     //••• need to test to ensure that the needed CGIHdl fields are present
  108.     
  109.     /* Test to see if the event should be processed */
  110.     processEvent = TrozShouldWeNarf ( theCGIHdl );
  111.     if ( processEvent )
  112.     {
  113.         /* the event met the test requirements, so process it */
  114.         if ( Random() % 2 )
  115.         {
  116.             /* at random, use the QuickCam instead */
  117.             theErr = TrozUseQuickCam ( theCGIHdl );
  118.             if ( theErr == noErr )
  119.             {
  120.                 returnData = CGINewHandle ( theCGIHdl, vTrozQuickCamHTMLSize + 1, &theErr );
  121.                 if ( returnData != NULL )
  122.                 {
  123.                     savedHandleState = HGetState ( returnData );
  124.                     HLock ( returnData );
  125.                     
  126.                     strcpy ( *returnData, *vTrozQuickCamHTML );
  127.                     QCBlockBoundsCheckNow ();
  128.                     
  129.                     HSetState ( returnData, savedHandleState );
  130.                     
  131.                     (*theCGIHdl)->responseSize = vTrozQuickCamHTMLSize + 1;
  132.                     (*theCGIHdl)->responseData = returnData;
  133.                 }
  134.             }
  135.         }
  136.         else
  137.         {
  138.             theErr = 1;
  139.         }
  140.         
  141.         if ( theErr != noErr )
  142.         {
  143.             /* determine the size of the intended url string */
  144. //            savedHandleState = HGetState ( (Handle)theCGIHdl );
  145. //            HLock ( (Handle)theCGIHdl);
  146. //            scriptNameSize = strlen ( (char *)(*theCGIHdl)->script_name );
  147. //            serverNameSize = strlen ( (char *)(*theCGIHdl)->server_name );
  148. //            HSetState ( (Handle)theCGIHdl, savedHandleState );
  149.             
  150.     //        returnDataSize = vTrozHTTPHeaderSize + serverNameSize + scriptNameSize +
  151.     //            vTrozHTMLFirstChunkSize + scriptNameSize + vTrozHTMLSecondChunkSize;
  152.             
  153.             returnData = CGINewHandle ( theCGIHdl, vTrozPinkyHTMLSize + 1, &theErr );
  154.     //        returnData = CGINewHandle ( theCGIHdl, returnDataSize + 1, &theErr );
  155.             if ( returnData != NULL )
  156.             {
  157.                 savedHandleState = HGetState ( returnData );
  158.                 HLock ( returnData );
  159.                 
  160.                 strcpy ( *returnData, *vTrozPinkyHTML );
  161.                 QCBlockBoundsCheckNow ();
  162.                 
  163.     #if 0
  164.                 returnDataPostion = nil;
  165.                 
  166.                 /* write out the http header */
  167.                 strcpy ( *returnData, *vTrozHTTPHeader );
  168.                 QCBlockBoundsCheckNow ();
  169.                 returnDataPostion += vTrozHTTPHeaderSize;
  170.                 /* write out the server name */
  171.                 strcpy ( *returnData + returnDataPostion, (*theCGIHdl)->server_name );
  172.                 QCBlockBoundsCheckNow ();
  173.                 returnDataPostion += serverNameSize;
  174.                 /* write out the script name */
  175.                 strcpy ( *returnData + returnDataPostion, (*theCGIHdl)->script_name );
  176.                 QCBlockBoundsCheckNow ();
  177.                 returnDataPostion += scriptNameSize;
  178.                 /* write out the first html chunk */
  179.                 strcpy ( *returnData + returnDataPostion, *vTrozHTMLFirstChunk );
  180.                 QCBlockBoundsCheckNow ();
  181.                 returnDataPostion += vTrozHTMLFirstChunkSize;
  182.                 /* write out the Original URL, in relative form */
  183.                 strcpy ( *returnData + returnDataPostion, (*theCGIHdl)->script_name );
  184.                 QCBlockBoundsCheckNow ();
  185.                 returnDataPostion += scriptNameSize;
  186.                 /* write out the second (and last) html chunk */
  187.                 strcpy ( *returnData + returnDataPostion, *vTrozHTMLSecondChunk );
  188.                 QCBlockBoundsCheckNow ();
  189.     #endif            
  190.                 
  191.                 /* null terminate the text */
  192.     //            (*returnData)[returnDataSize] = nil;
  193.     //            QCBlockBoundsCheckNow ();
  194.                 
  195.                 HSetState ( returnData, savedHandleState );
  196.                 
  197.                 (*theCGIHdl)->responseSize = vTrozPinkyHTMLSize + 1;
  198.                 (*theCGIHdl)->responseData = returnData;
  199.                 
  200.                 /* you should try to make use of giving time,
  201.                     especially in for and while loops or where you have to wait for
  202.                     some other process to return data or finish a task. */
  203.     //            ProcessGiveTime ( nil );
  204.             }
  205.         }
  206.     }
  207. } /* CustomCGIProcess */
  208.  
  209.  
  210. /* This is where we determine whether to interrupt the user's access with
  211.     a Pinky troZ! attack */
  212. Boolean
  213. TrozShouldWeNarf ( CGIHdl theCGIHdl )
  214. {
  215.     Boolean    weShouldNarf;
  216.     short    scriptNameLength;
  217.     long    stringDiff;
  218.     SInt16    randomValue;
  219.     
  220.     weShouldNarf = false;
  221.     
  222.     //••• should deal appropriately with absent CGIHdl fields - IE. default to true for them
  223.     
  224.     if ( ((*theCGIHdl)->method == HTTP_get) || ((*theCGIHdl)->method == HTTP_conditionalGet) )
  225.     {
  226.         /* test if action is preprocessor or ACTION */
  227. //        •••
  228. //        if ( • )
  229. //        {
  230.             scriptNameLength = strlen ( (*theCGIHdl)->script_name );
  231.             
  232.             /* test if last charcter of script_name is '/' */
  233.             if ( ((*theCGIHdl)->script_name)[scriptNameLength - 1] == '/' )
  234.             {
  235.                 stringDiff = nil;
  236.             }
  237.             else if ( scriptNameLength > 6 )
  238.             {
  239.                 /* test if script_name ends in ".html" */
  240.                 stringDiff = strcmp ( ".html", (*theCGIHdl)->script_name + scriptNameLength - 5 );
  241.             }
  242.             
  243.             if ( stringDiff == nil )
  244.             {
  245.                 /* get a random to choose whether to narf */
  246.                 randomValue = Random() % vTrozRandomRate;
  247.                 if ( randomValue == nil )
  248.                 {
  249.                     weShouldNarf = true;
  250.                 }
  251.             }
  252. //        }
  253.     }
  254.     
  255.     return weShouldNarf;
  256. } /* TrozShouldWeNarf */
  257.  
  258.  
  259. OSErr
  260. TrozUseQuickCam ( CGIHdl theCGIHdl )
  261. {
  262.     OSErr    theErr;
  263.     
  264.     theErr = SaveJPEGFromQuickCam ( vTrozQuickCamFile, 32 );
  265.     
  266.     return theErr;
  267. }
  268.  
  269.  
  270. /* this function will be called after the cgi result has been returned.
  271.     It will contain the same CGIHdl that was used for the CustomCGIProcess.
  272.     This function's prototype is defined in "CGI.h" */
  273. void
  274. CustomCGIPostProcess ( CGIHdl theCGIHdl )
  275. {
  276. } /* CustomCGIPostProcess */
  277.  
  278.  
  279. /***  CUSTOM CGI INITIALIZATION  ***/
  280. #pragma segment Startup
  281.  
  282. /* Put any of the initialization you need done, here.
  283.     This function will be called once: in-between the startup
  284.     sequence and the main event loop.
  285.     Return true if the initialization was successful, otherwise false.
  286.     An initialization failure will result in the application quitting. */
  287. Boolean
  288. CustomCGIStartup ( void )
  289. {
  290.     OSErr    theErr;
  291.     SInt8    savedHandleState;
  292.     Str255    theFileName;
  293.     
  294.     /* get the FSSpec for the file to store the JPEG quickcam grab in */
  295.     GetIndString ( theFileName, 10001, 3 );
  296.     theErr = FSMakeFSSpec ( gProcessFSSpec.vRefNum, gProcessFSSpec.parID, theFileName, &vTrozQuickCamFile );
  297.     
  298.     /* Load in the default blocks of text to return */
  299.     
  300.     /* the pinky html */
  301.     vTrozPinkyHTML = Get1Resource ( krtTrozType, krsTrozPinkyHTML );
  302.     if ( vTrozPinkyHTML == NULL )
  303.     {
  304.         return false;
  305.     }
  306.     savedHandleState = HGetState ( vTrozPinkyHTML );
  307.     HLock ( vTrozPinkyHTML );
  308.     vTrozPinkyHTMLSize = strlen ( (char *)(*vTrozPinkyHTML) );
  309.     HSetState ( vTrozPinkyHTML, savedHandleState );
  310.     
  311.     /* the QuickCam html */
  312.     vTrozQuickCamHTML = Get1Resource ( krtTrozType, krsTrozQuickCamHTML );
  313.     if ( vTrozQuickCamHTML == NULL )
  314.     {
  315.         return false;
  316.     }
  317.     savedHandleState = HGetState ( vTrozQuickCamHTML );
  318.     HLock ( vTrozQuickCamHTML );
  319.     vTrozQuickCamHTMLSize = strlen ( (char *)(*vTrozQuickCamHTML) );
  320.     HSetState ( vTrozQuickCamHTML, savedHandleState );
  321.     
  322.     /* the HTTP Header */
  323.     vTrozHTTPHeader = Get1Resource ( krtTrozType, krsTrozHTTPHeader );
  324.     if ( vTrozHTTPHeader == NULL )
  325.     {
  326.         return false;
  327.     }
  328.     savedHandleState = HGetState ( vTrozHTTPHeader );
  329.     HLock ( vTrozHTTPHeader );
  330.     vTrozHTTPHeaderSize = strlen ( (char *)(*vTrozHTTPHeader) );
  331.     HSetState ( vTrozHTTPHeader, savedHandleState );
  332.     
  333.     /* the first HTML chunk */
  334.     vTrozHTMLFirstChunk = Get1Resource ( krtTrozType, krsTrozHTMLFirstChunk );
  335.     if ( vTrozHTMLFirstChunk == NULL )
  336.     {
  337.         return false;
  338.     }
  339.     savedHandleState = HGetState ( vTrozHTMLFirstChunk );
  340.     HLock ( vTrozHTMLFirstChunk );
  341.     vTrozHTMLFirstChunkSize = strlen ( (char *)(*vTrozHTMLFirstChunk) );
  342.     HSetState ( vTrozHTMLFirstChunk, savedHandleState );
  343.     
  344.     /* the second HTML chunk */
  345.     vTrozHTMLSecondChunk = Get1Resource ( krtTrozType, krsTrozHTMLSecondChunk );
  346.     if ( vTrozHTMLSecondChunk == NULL )
  347.     {
  348.         return false;
  349.     }
  350.     savedHandleState = HGetState ( vTrozHTMLSecondChunk );
  351.     HLock ( vTrozHTMLSecondChunk );
  352.     vTrozHTMLSecondChunkSize = strlen ( (char *)(*vTrozHTMLSecondChunk) );
  353.     HSetState ( vTrozHTMLSecondChunk, savedHandleState );
  354.     
  355.     vTrozRandomRate = 3;
  356.     GetDateTime ( (unsigned long *)(&(qd.randSeed)) );
  357.     
  358.     return true;
  359. } /* CustomCGIStartup */
  360.  
  361.  
  362. /***  CUSTOM CGI CLEAN UP  ***/
  363. #pragma segment Main
  364.  
  365. /* This function is called at quitting time. Put any cleanup you need to do in it.
  366.     Return true if you are succeful.
  367.     Return false if you are unable to quit for some reason (this generally only
  368.     applies when the user cancels)
  369.     allowUserInteract specifies whether you can make user interface calls.
  370.     However, CGIs generally should not rely on any user interface calls, so don't
  371.     depend on them. */
  372. Boolean
  373. CustomCGIQuit ( Boolean allowUserInteract )
  374. {
  375. #pragma unused (allowUserInteract)
  376.     return true;
  377. }/* CustomCGIQuit */
  378.  
  379.  
  380. /***  WSAPI SUPPORT  ***/
  381. #if kCompilingForWSAPI
  382.  
  383. #define kFileCreatorTypeAny        '*   '
  384.  
  385. /* See the WSAPI documentation for further details on the use of
  386.     WSAPI_RegisterAction and WSAPI_RegisterSuffix. */
  387. WSAPI_ErrorCode
  388. CustomCGIWSAPIRegister ( WSAPI_CommandPBPtr commandPtr )
  389. {
  390.     WSAPI_ErrorCode    theErr;
  391.     
  392.     /* return plug-in name and abilities, register actions and suffixes. */
  393.     
  394.     /* your code must make at least one of the following WSAPI Register
  395.         calls or there's no way for WebSTAR to pass CGI requests to your plug-in */
  396.     
  397.     /* in this example, we're registering "GRANTSCGI" as an action.
  398.         You should always use the kMyCGIName constant (don't forget to properly
  399.         set it in "MyConfiguration.h". */
  400.     theErr = WSAPI_RegisterAction ( commandPtr, "TROZCGI", kMyCGIName );
  401.     if ( theErr != WSAPI_I_NoErr )
  402.     {
  403.         /* PlugIn Action didn't register. Notify user.
  404.             May want to take some action other than just
  405.             displaying this message */
  406.         WSAPI_DisplayMessage ( commandPtr, "TROZCGI: Couldn't register the action." );
  407.     }
  408.     
  409.     /* in this example, we're registering ".TROZC" as a suffix mapping for
  410.         the "GRANTSCGI" action (registered above). We're also registering it
  411.         for files that have the TEXT filetype and CGI? as their creator type.
  412.         If you don't care about particular file or creator types, then just
  413.         use '*   ' (defined as kFileCreatorTypeAny directly above this function). */
  414.     theErr = WSAPI_RegisterSuffix ( commandPtr, "TROZCGI", ".TROZ",
  415.         'TEXT', 'troZ', "text/html") );
  416.     if ( theErr != WSAPI_I_NoErr )
  417.     {
  418.         /* PlugIn Suffix didn't register. Notify user.
  419.             May want to take some action other than just
  420.             displaying this message */
  421.         WSAPI_DisplayMessage ( commandPtr, "TROZCGI: Couldn't register the suffix." );
  422.     }
  423.     
  424.     return theErr;
  425. } /* CustomCGIWSAPIRegister */
  426.  
  427.  
  428. #endif /* kCompilingForWSAPI */
  429.  
  430.  
  431. #endif    /* kCompileWithCGICode */
  432.  
  433. /*** EOF ***/
  434.