TweetFollow Us on Twitter

CGIs in C
Volume Number:11
Issue Number:9
Column Tag:Internet Development

Writing CGI Applications in C

Inject Some Adrenaline into your World Wide Web
Server Applications.

By John O’Fallon,

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

For the last two months this column has been teaching you how to write CGI applications for WebSTAR using AppleScript. AppleScript is a wonderful environment for tying existing Apple event-aware applications (database engines, for example) to WebSTAR. It also provides an easy way to get your feet wet with CGI applications. Inevitably, though, there will come a time when you need a high-throughput, high-reliability CGI for your WebSTAR server. For that, we turn our attention to the C language.

Writing CGIs in C will be very comfortable for most experienced Macintosh programmers, and will provide all of the performance and reliability the most demanding servers need. In addition, when writing CGIs, you can get these benefits without the headaches that are often associated with C. For example, developing in C normally means spending a lot of time on the user interface. But CGI applications don’t typically need any significant interface, so all you need to worry about is the actual job that you are trying to accomplish.

If you aren’t already somewhat familiar with programming in C, you should stop right here and spend some quality time with a C programming primer. You don’t necessarily need to be a C ace to write a good CGI, but familiarity with the language, the basic libraries and the Macintosh ToolBox are essential. I will also assume that you already have some experience with WebSTAR and with the topic of CGI applications in general (if not, see the July and August issues for “CGI Applications in AppleScript”) as well as a basic knowledge of HTML. Now, on to the topic at hand.

Apple Events

CGIs exist for Apple events. You will be building an application whose sole purpose in life is to receive Apple events, look at what they’re asking for, do some processing, and send back some reasonable responses. So, to begin, we’ll start with an overview of just how Apple events are used to send and receive information. Please note that I haven’t read the Inside Macintosh chapter on Apple events in almost a year, so for the real deal, in all its glorious detail, look at Inside Mac, Volume VI, Chapter 6. [or Inside Macintosh: Interapplication Communication, Chapter 3 - Assoc. Ed. jaw]

Set It Up

All a CGI really needs to do is respond to Apple events that are originated by WebSTAR. Luckily for us, responding to Apple events turns out to be quite a bit easier than sending them.

Responding to Apple events starts by installing a series of event handlers. An event handler is a procedure that will be called to process a given event, based on the event class and event ID. Every event is defined by its class (an attribute representing a group of events) and its ID (within the group, the specific event that needs to occur).

Your CGI will install five (or possibly more) Apple event handlers. The first four events to be handled are the “core” events that all good Apple event aware applications support. These events are: open the application, open a document, print a document, and quit the application. The fifth event is the interesting one...

WebSTAR defines a single event class (WWW ) and event ID (sdoc) which is used to pass requests from WebSTAR to your application. Your CGI will install a handler to process events with these attributes. These attributes, and the procedure to be called when an event with that class and ID are received is just about all you need to know to install your event handler.

There is one other missing piece. In order for your CGI to run in native mode on PowerMacs, you’ll need to reference your Apple event handling procedure as a Universal Procedure Pointer. This is easy enough, and is illustrated in the procedure below, which installs event handlers for all five of our events.

void InstallAllEvents ()
OSErr MyErr;
AEEventHandlerUPP MyUPP;

MyUPP = NewAEEventHandlerProc(HandOpenApp);
MyErr = AEInstallEventHandler
MyUPP = NewAEEventHandlerProc(HandOpenDoc);
MyErr = AEInstallEventHandler (kCoreEventClass,kAEOpenDocuments,MyUPP,0,FALSE);
MyUPP = NewAEEventHandlerProc(HandPrintDoc);
MyErr = AEInstallEventHandler (kCoreEventClass,kAEPrintDocuments,MyUPP,0,FALSE);
MyUPP = NewAEEventHandlerProc(HandQuitApp);
MyErr = AEInstallEventHandler (kCoreEventClass,kAEQuitApplication,MyUPP,0,FALSE);
MyUPP = NewAEEventHandlerProc(HandClientRequest);
MyErr = AEInstallEventHandler (WWW '','sdoc',MyUPP,0,FALSE);
if (MyErr != noErr) {
 SysBeep (2);
    // Well behaved apps would do more than beep!

The parameter passed to NewAEEventHandlerProc is simply the name of the C procedure that will be called when an Apple event is received for the defined class and ID.

Watch For It

Now that the Apple Event Manager knows about your event handler, and knows the Apple event class and ID it can handle, you need to start watching for events. This is done in your main event loop, by adding support for high-level events.

In addition to mouse clicks, key presses, etc., your CGI application will receive high level events from the system, via WaitNextEvent. When an Apple event is sent to your application, WaitNextEvent will respond with the kHighLevelEvent constant in the ‘what’ field of the EventRecord. When a high level event is received in your main event loop, it is up to your application to dispatch it to the Apple Event Manager, which will in turn call your event handler. The code is simple, and looks like this:

while (QuitApp==FALSE) {
// Go through the event loop as long as we aren’t supposed to quit
 WaitNextEvent (everyEvent, &Action, 0L, 0L);
    // Ask the OS for an event
 switch (Action.what) {
 case mouseDown: // They clicked the mouse...
 HandleMouseDown (Action.where);
 case keyDown:   // They pressed a key...
 HandleKeyDown ((int)Action.message,(int)Action.modifiers);
 case kHighLevelEvent:
    // We have an Apple event... so let the OS...
    // dispatch it (see Inside Mac).
 MyErr = AEProcessAppleEvent (&Action);
 if (MyErr != noErr) {
 SysBeep (2);
    // Well behaved apps do more than beep!

Handle It

The Apple Event Manager will take the event and look for an installed handler that accepts events of the given class and ID. When it finds an appropriate handler, it will execute it. In the example above, the procedure name was HandClientRequest, so this is the procedure that will be executed.

WebSTAR is very generous about the information that it supplies to your CGI, so your first task when you receive an event is to pull out the variables that are passed to you. There are quite a few variables, and StarNine adds new ones fairly regularly, so there is no way to cover them all here. Check your WebSTAR technical documentation for a complete description of the parameters. The documentation will tell you what information the parameter holds, and what its name is. The name, like the Apple event class and ID, is a 4 byte constant.

To pull a parameter out of an Apple event, you use the AEGetParamPtr routine. You specify the name of the parameter, and AEGetParamPtr will copy the data into a buffer and tell you how long it is. I normally use the length variable to cap the buffer and make it into a C string. Here are a few examples:

    // '----' - direct parameter
MyErr=AEGetParamPtr (TheRequest,'----',typeChar,&ReqType,(Ptr)PostArg_Direct,1023,
PostArg_Direct[ReqSize] = '\0';
    // 'addr' - client address
MyErr=AEGetParamPtr (TheRequest,'addr',typeChar,&ReqType,(Ptr)PostArg_Address,255,
PostArg_Address[ReqSize] = '\0';
    // 'Agnt' - user agent
MyErr=AEGetParamPtr (TheRequest,'Agnt',typeChar,&ReqType,(Ptr)PostArg_Client,255,
PostArg_Client[ReqSize] = '\0';
    // 'post' - post arguments
MyErr=AEGetParamPtr (TheRequest,'post',typeChar,&ReqType,(Ptr)PostArg_Post,
PostArg_Post[ReqSize] = '\0';

Let’s take a closer look at each of these requests.

• The first parameter, TheRequest, is a pointer to the Apple event sent from WebSTAR. This tells the Apple Event Manager what event we’re processing (and so, where to pull the parameter from).

• The second parameter is the four byte name of the parameter, as defined by WebSTAR.

• The third parameter is the parameter data type. The Apple Event Manager supports an extensive list of data types, with a complete set of coercion routines. WebSTAR, however, is nice and consistent, always sending parameters as good old typeChar.

• The fourth parameter, ReqType, allows the Apple Event Manager to tell the CGI what data type the parameter is, but I ignore this field, since I know that the Apple event is coming from WebSTAR and that it’s always a typeChar.

• The fifth parameter is a buffer to receive the data, followed by the maximum length of data to be copied into the buffer. Make sure that your buffer is big enough to hold as much data as you say you can hold. Also, we’ll be adding a null to the end of the string, so make sure you have a byte to spare for that.

• The last parameter is a ‘Size’ variable to receive the length that was actually copied into our buffer.

Choosing sizes for your buffers is somewhat arbitrary, and is done on a field by field basis. POST arguments, for example, can be up to 24k in length. Often, it makes sense to accept this much data, but in many cases, where you know the HTML form will be asking only for a few short fields, you can get away with substantially less. Also, in this example, we accept up to 255 characters for both the client address and for the user agent (the name of the browser). Both of these are probably more than long enough; I could most likely get away with 64 bytes for each, or less.

Finish It

Let’s take a second to recap... We detected our Apple event and dispatched it to the Apple Event Manager. The Apple Event Manager passed it off to our handling procedure, which read in the parameters it needed from WebSTAR. Next, the CGI went off and did its thing, and now it finally is time to respond to WebSTAR.

We’ll talk about processing the request and how to build the response string in a few minutes, but first, let’s finish with the Apple events. The last bit of Apple event processing we need to do is send the response. This is done quite easily with the AEPutParamPtr routine.

The nice thing about responding to Apple events is that the Apple Event Manager knows you are going to respond, so it builds the response event for you, before your handler even gets called. Once your handler finishes, it sends the event back to WebSTAR too. All this leaves for you to do is to copy your results into the event before you finish. Here is how that looks:

MyErr=AEPutParamPtr (TheReply,keyDirectObject,typeChar,

TheReply is the Apple event that was created for us by the Apple Event Manager for sending our response. keyDirectObject is a constant which represents what can be thought of as the main parameter of the Apple event (which is the response text, of course). typeChar simply tells the Apple Event Manager that the data is a string. PostArg_Response is a pointer to our response text, and ReqSize is the length, in bytes, of our response.

Whew! We’ve done all the work we need to do in order to communicate with WebSTAR. It’s quite a process, but the Apple event code also happens to be pretty static; the code presented here can be used almost verbatim in just about any CGI you would care to create, so now that we’ve done the work of communicating with WebSTAR, we can move on to actually doing our job.

Parsing the Post

Many CGIs function based on user-input, which comes from an HTML form. Forms are easy to build, and the browser handles all the editing controls for you, so your CGI won’t know the user is filling out a form until they are done and press a “submit” button. The upside to this is that all you have to do is process the data, forgetting almost entirely about the user interface. The downside is that there is a lack of control during the editing process.

In any event (well, actually in an sdoc event), when the user submits the form, it’ll come to you as an ASCII string. The string will list the field names as they appeared on the HTML form with the associated user-entered data. The field names are separated from the field data by an equal sign (=) and then ampersands (&) are used to separate the various field=data pairs. At the same time, any special characters in the field data (such as & and =) are encoded with a percent sign (%) and the character’s ASCII code in hex.

Maybe an example will be clearer. For a simple form that asked the user for their name, job title, and e-mail address, you might get the following post data:


Notice the instances of %20. These are encoded spaces (a space has an ASCII value of 0x20). Other characters like colons, slashes, etc. would give us similar encoded values. When your CGI receives this text string, the first thing it will need to do is decode those ASCII values. This is a fairly easy task and looks like this:

Replace Special Chars

/* REPLACESPECIALCHARS replaces instances of percent signs (%)   */
/* followed by an ASCII char value with the actual character.            */

void ReplaceSpecialChars (char *TheText)
int i;
int j;
int AsciiChar;

i = 0;
j = 0;
while (TheText[i] != '\0') {// Search the entire text block
 switch (TheText[i]) {
 case '%':// if the char is a percent sign, look at the next char
 if ((TheText[i+1] >= 'A') && (TheText[i+1] <= 'F')) {
 AsciiChar = TheText[i+1] - 'A' + 10; 
 // convert A thru F to 10 thru 15
 else {
 AsciiChar = TheText[i+1] - '0'; // Convert all others to 0 to 9
 AsciiChar = AsciiChar * 16;
    // That was the high order of a hex number, so mult by 16 to
    // find the decimal value. Now do the low order char...
 if ((TheText[i+2] >= 'A') && (TheText[i+2] <= 'F')) {
 AsciiChar += (TheText[i+2] - 'A' + 10);
    // Convert A thru F to 10 thru 15 (and add it to the high order value)
 else {
 AsciiChar += (TheText[i+2] - '0');
    // Convert all others to 0 to 9 (and add it to the high order value)
 if ((AsciiChar >= 0) && (AsciiChar < 256)) {
    // if we got a valid value, replace the ASCII char
 if (AsciiChar == 10) {
 else {
 TheText[j] = AsciiChar;  // Copy the char into the string
 i += 2;
    // Now that we have converted 'em, skip the extra characters
 else {
 TheText[j] = TheText[i];
    // False alarm, nothing to convert, just copy the char (shouldn't happen)
 case '+':
 TheText[j] = ' '; // Spaces are coded as plus signs
 case '&':
 TheText[j] = DELIM_CHAR; 
    // Replace the default delimiter with something more uncommon
 case 10:
 j--;   // Strip out linefeeds, Macs don't use them
 TheText[j] = TheText[i]; // A normal character, just copy it
TheText[j] = '\0';     // make sure the string is capped

While the routine decodes the ASCII values, it also replaces the ampersands that delimit the fields. I did this because an ampersand is actually a fairly common character for people to use, and will confuse things mightily if it appears in the text and is used as our delimiter. So DELIM_CHAR is simply defined as something more obscure. The omega ( ) works well - it is rare but can be typed easily and is quickly recognizable.

You will also notice that the routine converts both plus signs (+) and the %20 ASCII encodings into spaces. This is because some browsers (notably NetScape and Mosaic) encode spaces as plus signs, and we’d like to stay compatible with as many browsers as possible (not to mention the fact that most people use these two browsers).

For the last step, we need a way of extracting the text for any given field. All we need to do is scan through the text looking for the field name followed by an equal sign. When we find that, we simply copy the user entered data into a buffer. Here is a simple routine to do just that:

/* GETFIELDDATA searches PostArg_Post for the specified field   */
/* name and returns the text entered by the user.                           */
/*************** *************************************************/

int GetFieldData (char *PostString, char *FieldName, int MaxLength, char 
int i,StrLen,Found,Position;

StrLen = 0; // First, find out how long the field name is
while (FieldName[StrLen] != '\0') StrLen++;
Found = FALSE;   // Assume we haven't found anything
Position = 0;
while ((Found == FALSE) && (PostString[Position] != '\0')) {
    // look til we find something or we hit the end
 Found = TRUE;   // We can hope, can't we?
 for (i = 0 ; i < StrLen ; i++)  // if any character at all doesn't match
 if (PostString[Position+i] != FieldName[i]) {
 Found = FALSE;   // then no deal, and stop trying
 i = StrLen;
if (Found) {// OK... Great... We found our field
 Position += (i - 1);// Start looking for the delimitting '='
 while (PostString[Position] != '=') Position++;   
 Position++;// Skip over the '='
 i = 0; // Almost done, just copy the string
 while ((PostString[Position+i] != '\0') &&
 (PostString[Position+i] != DELIM_CHAR) && (i < MaxLength)) {
 TextBuff[i] = PostString[Position+i];
 // Copy the user entered text into the buffer
 TextBuff[i] = '\0'; // Cap the C string
 return (TRUE);
else {
 TextBuff[0] = '\0'; // Return a NULL string
 return (FALSE);

There are other ways of extracting this information from the POST string, but this is a handy routine that is easy to get started with.

The Equivalent of “Hello World!”

So, let’s write a CGI that will be the equivalent of the ever-popular “Hello World!”. We’ll create a simple HTML form with two input fields and a “submit” button. When the user clicks “submit”, our CGI will take the words in the two input fields, stick them together, and respond with some HTML text that shows the user what we did. We start with the HTML form...

<TITLE>Hello World! Test</TITLE>
Enter a word in each of the fields below...

<P><B>Field 1:</B> <INPUT TYPE="text" NAME="Field1" SIZE="32" MAXLENGTH="32">

<P><B>Field 2:</B> <INPUT TYPE="text" NAME="Field2" SIZE="32" MAXLENGTH="32">

<P><INPUT TYPE=submit VALUE="Submit Form">

Last month, Jon Wiederspan went into some detail about how forms work, and they are very well documented in many places on the Web, so I won’t go into detail about what is going on here. There are, however, two important things to notice. First, the ACTION parameter of the FORM command is “/HelloWorld.cgi”. This is simply the file name of the CGI application we are going to write. The application name must end with either “.cgi” or “.acgi” to be recognized as a CGI application by WebSTAR. (Actually, you can reconfigure the file extension definitions within WebSTAR to recognize other extensions, but we won’t get into that here.)

The other thing to notice is the field definitions. They are both text fields and are named Field1 and Field2 (creative, eh?). The field names defined in the HTML file will be important when we go to parse the POST argument in the CGI.

Now for the CGI code. All of the code listed so far will be needed, as well as other standard Macintosh application stuff for initializing menus, windows, etc. The core of the program will be the HandleClientRequest routine, and will look like this:


pascal OSErr HandClientRequest (AppleEvent *TheRequest, 
 AppleEvent *TheReply, long Reference)
OSErr MyErr;
DescType ReqType;
Size ReqSize;
char Post[1024];
char Response[1024];
char Field1[64];
char Field2[64];

    // Get the post data
MyErr=AEGetParamPtr (TheRequest,'post', typeChar,&ReqType,
 (Ptr)Post, BUFFER_SIZE,&ReqSize);
PostArg_Post[ReqSize] = '\0'; // and cap it as a C string
ReplaceSpecialChars (Post); // Replace the special characters
GetFieldData (Post, "Field1", 64, Field1); // Get the user entered data
GetFieldData (Post, "Field2", 64, Field2); // out of the post string
sprintf (Response,
 Field1, Field2); // Build the HTML response string
ReqSize = strlen (Response);// Get the # of chars in the response string
MyErr=AEPutParamPtr (TheReply,keyDirectObject,

return (MyErr);

This example is a bit over-simplified, but works for our test. For one thing, in a real CGI, you would probably want to allocate more memory to both the post string and the response string.

The first thing that happens in our application is a high level event is received from the OS. Our main event loop passes it off to the Apple Event Manager, which calls this routine. When HandClientRequest gets the request, it pulls the POST argument out of the Apple event and then parses out the user entered data using GetFieldData. After that, all it has to do is put the user’s words into a simple HTML response and stick the resulting string into the reply Apple event. Piece of cake.


We wrote “HelloWorld.cgi” as a CGI, but we might want to make it an ACGI (Asynchronous CGI). The difference here is simply in the filename of the finished application. This example program will run as either a CGI or an ACGI just fine; the difference is in what WebSTAR does when it sends the event to us.

If the application ends with “.cgi”, then WebSTAR creates the Apple event, sends it off to our application, and waits for a result. All server activity stops cold while the CGI does its thing. With an ACGI, WebSTAR sends the event and goes merrily on its way serving other connections. This sounds like a better solution, and often is, but not always.

For example, our “HelloWorld.cgi” should be left as a CGI. It is so fast that it won’t really cause a delay on the server, and making it an ACGI would just add overhead that we have no need to incur. So plain old CGIs can be safely used when the CGI is doing something very fast. ACGIs should always be used when processing might take a bit longer, so that other connections don’t get hung up waiting for the application to finish.

But if the application is running asynchronously, you ask, what happens when WebSTAR sends us a new event while we’re processing another? Simple. While our CGI is processing an event, the main event loop isn’t running, so Apple events aren’t being processed and will build up in a queue until we are ready to handle them. So even though WebSTAR is processing connections asynchronously, the CGI is processing them one at a time. This isn’t a problem unless the CGI is going to spend a large amount of its time sitting idle (say, waiting for results from a client/server database engine running on another machine). In this case, processing incoming requests synchronously can become a big problem.


We really have three classes of CGIs, and we use each depending on the situation at hand.

• When your CGI will be very fast, make it a CGI. “Very fast” means that it probably works strictly within memory and doesn’t have to wait for disk I/O or other slow processes.

• When your CGI is fast, but can take a second or two to run, use an ACGI. ACGIs can also safely be used when processing will take a long time to run but is fairly uncommon. If the CGI isn’t run very often, the requests will rarely pile up in the Apple event queue.

• When your CGI may take longer than a few seconds, and when it will be accessed frequently, you have little choice but to make it threaded or else it will become a processing bottleneck for the entire server.

Writing threaded applications simply means that the program uses the Thread Manager to execute multiple instances of parts of your program simultaneously. Without going into the details of the Thread Manager, here is how a CGI can use threads to perform its job for multiple simultaneous connections.

1) Receive the Apple event in the main event loop.

2) Suspend the Apple event

3) Spawn a thread and pass all connection information (post string, etc.) to the new thread.

4) The main event loop yields to any active thread.

5) The thread performs its task. At key intervals (usually when waiting for slow processes) the thread yields to other active threads (including the main event loop).

6) When the thread has built its response, it resumes the Apple event and replies.

7) The thread disposes itself.

The Thread Manager implements “Lightweight” concurrent processing, so switching between thread contexts is extremely fast. You will notice very little performance degradation by making your CGI threaded. Also, you’ll find that making the Thread Manager calls are relatively straightforward, but there are a couple of “gotchas”. First, you can not allocate or release memory within a thread context. Your main event loop should do all of this and then pass the handles or pointers to each thread. You will also need to watch your use of global variables closely. Global variables are available to threads, but they are common to all threads running. So using globals can be very handy, but make sure you don’t rely on a global variable for storing data within a thread or you may find the threads are writing over each others’ data.

Other Special Considerations

Being a server-based application, your CGI will need to pay special attention and be a good citizen. Here are just a few tips:

1) Release the CPU as often as possible, and for a decent amount of time. In general, your main event loop won’t be doing much when your CGI is idle, so all you really need to do is use a large value for the “sleep ticks” in your WaitNextEvent call. Sleep ticks apply only to idle events, so you will be notified immediately when an Apple event comes in anyway.

2) Don’t use modal dialog boxes. Many servers will be unattended, and modal dialogs are a sure way to hang the server. If you get errors, write an entry into a log file, or display the error on your status window (if you have one) and beep.

3) CGIs are limited to 32K for the return file size, so if your application is running as a CGI, you won’t be able to send huge return strings. The limit on ACGIs is much higher, and is dependent on when Apple events starts generating memory errors. I haven’t done exhaustive research on this, but it does vary from machine to machine. Most servers handle 60K replies just fine, but some will crash when you try to pass this much data. I wouldn’t recommend trying to send any more than 50 to 60K just to be on the safe side.

4) When a CGI isn’t already running, WebSTAR will launch it when it is needed, so some CGIs quit after every time they are executed. This causes a few seconds of delay while the CGI launches, but may not be an issue if the CGI is executed only very rarely. The other problem with launching CGIs on the fly is that you may encounter problems starting up. Out of memory errors and other startup problems may cause modal dialog boxes to be displayed, which may cause the server to halt.

Advanced Topics

Well, now you have plenty to get started building Web-based applications in C. There is more to learn, though, once you have had a few successes. For one thing, StarNine is constantly coming out with enhancements that make CGIs easier to use and more powerful. By the time you’ve read this, there will undoubtedly be new capabilities available to CGIs, but here are a few of the things that you will want to learn more about once you feel comfortable with the basic principals:

1) A URL that activates a CGI, as we have said, normally includes the name of the CGI. WebSTAR now supports “actions”, which allows you to define filename extensions that will trigger your CGI. So, for example, if your CGI performs a database search, you could map the CGI to a filename suffix of “.srch”. Any URL that references a file ending with “.srch” would be passed to your CGI. The file being referenced by the CGI doesn’t need to actually exist, in fact, it probably won’t. The URL will simply be passed to your CGI and you will decide what to do with it. Very powerful stuff.

2) You can also now define a “Pre-processor” and a “Post-processor” for WebSTAR. The pre-processor is a CGI that gets every request before WebSTAR processes it. The CGI can choose to process the request itself or pass it back to WebSTAR for normal processing. The post-processor gets information about the request after WebSTAR is done processing it, which can be used to implement new logging methods or set off alarms for certain activity.

3) WebSTAR will not only send Apple events when incoming requests need to be processed, but will also respond to them. You can use Apple events to extract and update many of the configuration options in WebSTAR, as well as perform other interesting jobs. That means that your CGI can manipulate WebSTAR itself. Note that, in order to do this, you must be using an ACGI. Otherwise, WebSTAR stops and waits for the CGI to reply, and can’t respond to events.

4) Finally, WebSTAR supports “server push” by allowing a CGI to return data to the client in multiple Apple events. This can be handy for applications where the data is being returned on a timed basis (like reports every minute) or where the data is being gathered very slowly (as in searching a large database). This is also a way to get around the file size limitation, because while each event can contain only 60k or so of data, you can use multiple chunks to send an arbitrarily large amount of data back to the user.

Wrapping Up

Now that you know how C CGIs work, you’ll want to get started. The fastest way is to visit my Web site, where you’ll find “Responder”. To get to the Maxum Web site, point your browser at “”. [It’s at all the usual source code sites, listed on page 2, as well. -jtk]

Responder is a very simple CGI that includes source code and a CodeWarrior project that will get you started very quickly. There is at least one other C CGI available so you might want to look around to find what will work best for you. Responder is a bare-bones shell that is very easy to understand, and it will make sense to you, having just read this article, since most of the code listed here has been clipped from Responder.

Have fun!


Community Search:
MacTech Search:

Software Updates via MacUpdate

Tomb of the Mask guide - How to increase...
Tomb of the Mask is a great endless arcade game from Happymagenta in which quick reflexes and a persistent attitude can go a long way toward earning a top score. Check out these tips to see if you can give yourself an edge on the leaderboards. [... | Read more »
Smooth Operator! (Games)
Smooth Operator! 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: Smooth Operator is a weird, weird two-player kissing game. Squeeze in for 2 player fun on a single iPad, creating awkward... | Read more »
Sinless: Remastered (Games)
Sinless: Remastered 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: | Read more »
_PRISM Guide - How to solve those puzzle...
_PRISM is a rather delightful puzzle game that’s been tailor made for touch screens. While part of the fun is figuring things out as you go along, we thought we’d offer you a helping hand at getting in the right mindset. Don’t worry about messing... | Read more »
Set off on an adventure through the Cand...
Like match three puzzlers? If so, Jelly Blast, the innovative iOS and Android game which launched last year, is worth a look. Jelly Blast sees you head off on an epic adventure through the Candy Kingdom with your friends Lily, Mr. Hare, and Mr.... | Read more »
Ellipsis - Touch. Explore. Survive. (...
Ellipsis - Touch. Explore. Survive. 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: | Read more »
Ys Chronicles II (Games)
Ys Chronicles II 1.0.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.0 (iTunes) Description: After a hard fight to recover the six sacred books in Ys Chronicles I, Adol is back for a sequel! | Read more »
FINAL FANTASY Ⅸ 1.0.4 Device: iOS Universal Category: Games Price: $16.99, Version: 1.0.4 (iTunes) Description: ==========●Special sale price for the FINAL FANTASY IX release! ●20% off from February 10 to February 21, 2016... | Read more »
Tennis Club Story (Games)
Tennis Club Story 1.03 Device: iOS Universal Category: Games Price: $4.99, Version: 1.03 (iTunes) Description: Aim for the ace position of tennis club prestige in this simulation! Your leadership decides if players make it to the big... | Read more »
Juggernaut Wars guide - How to use skill...
Juggernaut Warsis a brand new auto-RPG on iOS and Android that challenges you to build a team of heroes, send them out into various different missions to defeat waves of heroes, and level them up to increase their power. The actual combat itself... | Read more »

Price Scanner via

Sale! B&H Photo offers 12-inch Retina Mac...
B&H Photo has 12″ Retina MacBooks on sale for $300 off MSRP for a limited time. Shipping is free, and B&H charges NY tax only: - 12″ 1.1GHz Gray Retina MacBook: $999 $300 off MSRP - 12″ 1.... Read more
App Annie Reveals Future of the App Economy:...
App Annie, a San Francisco based mobile app data and insights platform, has launched its first comprehensive app economy forecast. This new offering will provide brands, agencies, investors and app... Read more
Apple restocks Certified Refurbished Mac mini...
Apple has restocked Certified Refurbished 2014 Mac minis, with models available starting at $419. Apple’s one-year warranty is included with each mini, and shipping is free: - 1.4GHz Mac mini: $419 $... Read more
What iPad Pro Still Needs To Make It Truly Pr...
I love my iPad Air 2. So much that I’m grudgingly willing to put up with its compromises and limitations as a production tool in order to take advantage of its virtues. However, since a computer for... Read more
21-inch 3.1GHz 4K on sale for $1399, $100 off...
B&H Photo has the 21″ 3.1GHz 4K iMac on sale $1399 for a limited time. Shipping is free, and B&H charges NY sales tax only. Their price is $100 off MSRP: - 21″ 3.1GHz 4K iMac (MK452LL/A): $... Read more
Apple price trackers, updated continuously
Scan our Apple Price Trackers for the latest information on sales, bundles, and availability on systems from Apple’s authorized internet/catalog resellers. We update the trackers continuously: - 15″... Read more
Save up to $240 with Apple Certified Refurbis...
Apple is now offering Certified Refurbished 12″ Retina MacBooks for up to $240 off the cost of new models. Apple will include a standard one-year warranty with each MacBook, and shipping is free. The... Read more
Apple refurbished 13-inch Retina MacBook Pros...
Apple has Certified Refurbished 13″ Retina MacBook Pros available for up to $270 off the cost of new models. An Apple one-year warranty is included with each model, and shipping is free: - 13″ 2.7GHz... Read more
Apple refurbished Time Capsules available for...
Apple has certified refurbished Time Capsules available for $120 off MSRP. Apple’s one-year warranty is included with each Time Capsule, and shipping is free: - 2TB Time Capsule: $179, $120 off - 3TB... Read more
13-inch 2.5GHz MacBook Pro (refurbished) avai...
Apple has Certified Refurbished 13″ 2.5GHz MacBook Pros available for $829, or $270 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 13″ 2.5GHz MacBook Pros... Read more

Jobs Board

Infrastructure Engineer - *Apple* /Mac - Rem...
…part of a team Requires proven problem solving skills Preferred Additional: Apple Certified System Administrator (ACSA) Apple Certified Technical Coordinator (ACTC) Read more
Lead Engineer - *Apple* OSX & Hardware...
Lead Engineer - Apple OSX & Hardware **Job ID:** 3125919 **Full/Part\-Time:** Full\-time **Regular/Temporary:** Regular **Listed:** 2016\-02\-10 **Location:** Cary, Read more
Simply Mac *Apple* Specialist- Service Repa...
Simply Mac is the largest premier retailer of Apple products in the nation. In order to support our growing customer base, we are currently looking for a driven Read more
Infrastructure Engineer - *Apple* /Mac - Rem...
…part of a team Requires proven problem solving skills Preferred Additional: Apple Certified System Administrator (ACSA) Apple Certified Technical Coordinator (ACTC) Read more
Lead Engineer - *Apple* OSX & Hardware...
Lead Engineer - Apple OSX & Hardware **Job ID:** 3125919 **Full/Part\-Time:** Full\-time **Regular/Temporary:** Regular **Listed:** 2016\-02\-10 **Location:** Cary, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.