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

WhiteCap 6.7.1 - Visual plug-in for iTun...
WhiteCap is a sleek and sophisticated music visualizer and screensaver that features futuristic, wireframe mesh visuals with dynamic backgrounds and colors. WhiteCap contains thousands of visual... Read more
DiskMaker X 6.0 rc5 - Make a bootable OS...
DiskMaker X (was Lion DiskMaker) helps you to build a bootable drive from the official OS X installer app (the one you download from the Mac App Store). It detects the OS X Install program with... Read more
Lyn 1.9 - Lightweight image browser and...
Lyn is a fast, lightweight image browser and viewer designed for photographers, graphic artists, and Web designers. Featuring an extremely versatile and aesthetically pleasing interface, it delivers... Read more
MacFamilyTree 8.2.1 - Create and explore...
MacFamilyTree gives genealogy a facelift: modern, interactive, convenient and fast. Explore your family tree and your family history in a way generations of chroniclers before you would have loved.... Read more
LaunchBar 6.9 - Powerful file/URL/email...
LaunchBar is an award-winning productivity utility that offers an amazingly intuitive and efficient way to search and access any kind of information stored on your computer or on the Web. It provides... Read more
LaunchBar 6.9 - Powerful file/URL/email...
LaunchBar is an award-winning productivity utility that offers an amazingly intuitive and efficient way to search and access any kind of information stored on your computer or on the Web. It provides... Read more
MacFamilyTree 8.2.1 - Create and explore...
MacFamilyTree gives genealogy a facelift: modern, interactive, convenient and fast. Explore your family tree and your family history in a way generations of chroniclers before you would have loved.... Read more
Spotify - Stream music, crea...
Spotify is a streaming music service that gives you on-demand access to millions of songs. Whether you like driving rock, silky R&B, or grandiose classical music, Spotify's massive catalogue puts... Read more
VOX 2.8.26 - Music player that supports...
VOX just sounds better! The beauty is in its simplicity, yet behind the minimal exterior lies a powerful music player with a ton of features and support for all audio formats you should ever need.... Read more
beaTunes 5.0.1 - Organize your music col...
beaTunes is a full-featured music player and organizational tool for music collections. How well organized is your music library? Are your artists always spelled the same way? Any R.E.M. vs REM?... Read more

Latest Forum Discussions

See All

This War of Mine gets a new ending and m...
This War of Mine just got a big new update, featuring free DLC that adds a new ending to the game, among other exciting changes. The update is celebrating the game's two-year release anniversary. Apart from the new ending, which will be quite... | Read more »
Summon eight new heroes in Fire Emblem H...
Nintendo keeps coming at us with Fire Emblem Heroes updates, and it doesn't look like that trend is stopping anytime soon. The folks behind the game have just announced the new War of the Clerics Voting Gauntlet, expected to start next Tuesday. [... | Read more »
The best deals on the App Store this wee...
iOS publishers are pulling out all the stops this week -- there's a huge number of seriously great games at discounted prices this week. Let's not waste any time and get right down to business. [Read more] | Read more »
The House of da Vinci (Games)
The House of da Vinci 1.0.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.0 (iTunes) Description: Enter The House of Da Vinci, a new must-try 3D puzzle adventure game. Solve mechanical puzzles, discover hidden... | Read more »
Solve the disappearance of history’s gre...
Blue Brain Games invites you to indulge in an immersive hands-on 3D puzzle adventure in similar vein to The Room series, with its debut release The House of Da Vinci. Set during the historic period of the Italian Renaissance (when Leonardo himself... | Read more »
Age of Rivals (Games)
Age of Rivals 3.3 Device: iOS Universal Category: Games Price: $.99, Version: 3.3 (iTunes) Description: Deep civilization-building strategy in a fast-paced card game! | Read more »
Panthera Frontier (Games)
Panthera Frontier 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: | Read more »
Angry Birds Evolution beginner's gu...
Angry Birds changes things up a fair bit in its latest iteration, Angry Birds Evolution. The familiar sling-shot physics mechanics are still there, but the game now features team-based gameplay, RPG elements, and a new top-down view. With all of... | Read more »
Sega Forever is for the retro game fans
Sega is launching a new retro games service titled Sega Forever, in a move that's sure to delight games enthusiasts with a bit of nostalgia. Sega's releasing five classic games for free. The titles include Sonic the Hedgehog, Phantasy Star II,... | Read more »
The Little Acre (Games)
The Little Acre 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: | Read more »

Price Scanner via

ABBYY TextGrabber 6 for iOS Implements Instan...
ABBYY has announced the release of TextGrabber 6.0.0, an important feature update to the company’s productivity app developed for iOS and Android devices. TextGrabber 6.0 now offers Real-Time... Read more
vPhone, First Smartphone That Can’t Be Lost,...
Austin, Texas based Hypori has introduced the vPhone, a virtual smartphone that affords every business user the benefits of separate work and personal phones, conveniently delivered on a single... Read more
Save this weekend with 2016 refurbished MacBo...
Apple has dropped prices on Certified Refurbished 2016 15″ and 13″ MacBook Pros by as much as $590 off original MSRP. An Apple one-year warranty is included with each model, and shipping is free: -... Read more
New 27-inch 3.4GHz iMac on sale for $1699, sa...
MacMall has the new 2017 27″ 3.4GHz iMac (MNE92LL/A) in stock and on sale for $1699 including free shipping. Their price is $100 off MSRP. Read more
Clearance 2016 MacBook Pros available for up...
B&H Photo has clearance 2016 13″ and 15″ MacBook Pros in stock today and on sale for up to $400 off original MSRP. Shipping is free, and B&H charges NY & NJ sales tax only: - 15″ 2.7GHz... Read more
Apple Ranks 9th In comScore Top 50 U.S. Digit...
comScore, Inc. has released its monthly ranking of U.S. online activity at the top digital media properties for May 2017 based on data from comScore Media Metrix Multi-Platform. * Entity has... Read more
10.5-inch iPad Pros available for up to $20 o...
B&H Photo has the new 2017 10.5″ iPad Pros available for up to $20 off MSRP including free shipping plus NY & NJ sales tax only: - 64GB iPad Pro WiFi: $649 - 256GB iPad Pro WiFi: $749 - 512GB... Read more
Three Off-The-Beaten-Track iOS Apps That Dese...
One of the great things about using iPads and iPhones is the vast selection of apps available for most anything you want or need to do. The three outlined in this article have been in my core app... Read more
Apple No. 1 Spot In Gartner Top 100 Vendors i...
Gartner, Inc. has unveiled the top global 100 vendors in IT in 2016 based on their revenue across IT (excluding communication services) and component market segments. In the Gartner Global Top 100:... Read more
Clearance iMacs available for up to $300 off...
B&H Photo has clearance 21″ and 27″ Apple iMacs available starting at $949, each including free shipping plus NY & NJ sales tax only: - 27″ 3.3GHz iMac 5K: $1999 $300 off original MSRP - 27″... Read more

Jobs Board

*Apple* News Product Marketing Mgr., Publish...
…organizational consensus on strategy and vision for publisher tools, authoring, and Apple News Format.Carries this strategy and vision across the organization to Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Security Data Analyst - *Apple* Information...
…data sources need to be collected to allow Information Security to better protect Apple employees and customers from a wide range of threats.Act as the subject matter Read more
Lead *Apple* Solutions Consultant - Apple I...
…integrity, and trust.Success Metrics/Key Performance Indicators:Quantitative* Year over Year growth in Apple Product and Beyond the Box sales in the assigned Point of Read more
*Apple* Solutions Consultant till v%u00E5r...
…ethics, integrity, and trust.Success Metrics/Key Performance Indicators:QuantitativeYear over Year growth in Apple Product and Beyond the Box sales in the assigned Point Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.