DOS CGI has one advantage over other CGI implementations: it's normally easier. You can perform some basic operations that take no programming skills whatsoever and no time at all to create. Say you have a form in which you want people to enter data, and you want to save all the forms you get into one big file that you can print out and review later. All you need to do is create two lines in a text file and an HTML page that you can send back to people after they submit the form. Using CGI is that easy, and you'll see just how to use it in this chapter.
When you move from the basic functions to the more advanced, a good quality about DOS CGI is that the methodology used isn't much different from any other platform on which you can use CGI. On the downside, DOS CGI is not without severe limitations in performance or flexibility because it's still constrained by how DOS deals with everything. Don't worry too much, though-programming CGI for DOS isn't everyone's first choice, but if it's what you need to work with, you don't need to suffer.
In covering DOS CGI's general use, you look at the following:
As I run through the examples here, you should note the development and server platform. All the DOS CGI examples shown in this chapter are run on a generic Intel-based machine, running Windows 3.1 and using Robert Denny's WinHTTPD version 1.4c. If you're using a different server package or running on a simulated version of DOS on a different type of machine, you should be very careful. Make sure that differences between what I use here and what you have available won't cause a conflict. The best place to check is at the command line (for basic functions), or you can check the server documentation.
Caution |
Not all servers support the DOS CGI interface. It was originally designed as a makeshift solution for servers that, due to the platform they were running on, could not perform the more advanced functions. Check your server documentation to ensure that DOS CGI is supported before you go ahead and try the examples shown. |
DOS CGI differs from conventional CGI in that DOS doesn't let the Web server store information into a large Standard Input (STDIN) buffer, like most other environments. This restriction creates a little problem. You can send information into the program through the Get method and make all the information part of the QUERY_STRING environment variable, but doing so limits how much information you can play with at any given time.
What DOS CGI does instead is make use of two special environment variables: CONTENT_FILE and OUTPUT_FILE. They allow CGI to create its own special buffers for information; but instead of holding the information in memory, these variables write it directly to a file.
Every piece of incoming data that's not an environment variable gets tossed into a temporary file, located somewhere on your machine. The CONTENT_FILE environment variable is the answer to the question "Now where is it?" because the system could have given the file any name it feels like. You don't have to worry about how the system generates the name for the file or where it decides to toss it-whatever the result, CONTENT_FILE tells you.
The Content File contains nothing more than the data from the POST operation, URL-encoded as one long string. For instance, the form Generic.htm, containing First Name, Last Name, and E-mail fields, produces a Content File that contains first=Bill&last=Schongar&[email protected] when run using a BAT file that does nothing more than print the Content File back to the screen. Listing 16.1 shows the source code for Generic.htm, and the resulting form is shown in Figure 16.1.
Figure 16.1 : Data entered in the generic form.
Listing 16.1. HTML source for a generic three-field form.
<title>Generic Forms Test - DOS CGI</title>
<h1>Generic Form</h1>
<form method=post action=/cgi-dos/generic.bat>
First Name: <input name=first> <br>
Last Name: <input name=last> <br>
Email: <input name=email> <br>
<input type=submit value="Go">
</form>
As you can see, all the information entered in the form has been neatly bundled up, just as you would expect with any other CGI implementation. Later in this chapter, you look at just what you can do with this information, because DOS itself often seems to lack built-in tools to handle it. Depending on what tools you use, you can do a great deal before you send anything back to the person waiting for it.
When you're ready to send something back to the user, you can use the OUTPUT_FILE environment variable. Just like Standard Output on other systems, the Output File is the place where the server expects to read data that comes back from the application. In the background, the server is twiddling its thumbs and occasionally checking the location it specifies in the OUTPUT_FILE environment variable. When something appears there, the server starts reading it in, line by line, and processing the data it contains.
Note that the server doesn't care how much you add to the file; it just cares when you stop. If you've got processes going on in the background that take awhile, you may want to think about sending information to the client just to get the user started. If you wait too long before sending anything back, the server and the client may think that the connection's been abandoned and therefore terminate the process with an error. You don't want that to happen.
Information you send to the Output File follows a basic format. You start with a header, to let the server and browser know what's coming, and then follow it up with your information. You can send back any type of header you want. The most common header to send back is either a Content-type header or a Location header for a file.
You don't have to be content with just what's available in the Content File. DOS CGI has a whole other range of environment variables available at its beck and call, including QUERY_STRING and REQUEST_METHOD.
DOS CGI programs can be created in a number of different programming languages. From the built-in system command languages to interpreted and compiled languages, a number of tools exist to help you get the job done. We'll look at the languages you're more likely to encounter, and see how and why they can be used.
Using batch (.BAT) and command (.CMD) files is the most basic way to implement DOS CGI programs. They're built into the DOS environment, and you can use them to access a variety of basic built-in functions and to call more advanced external functions, like another program. Their primary benefit is also their primary drawback-they're simple and you can't do much inside them. I'm not saying that they can't get the job done; it's all just a question of how many hoops you're willing to jump through to make them all work.
To do anything with a BAT or CMD file, you need to know a little bit about what makes them tick. As I've said all along, there's not much to them, and you need to know just few basic commands and concepts to get going.
Try this experiment. Go to a DOS prompt and type the following on the command line:
echo Hi, how are ya?
Then press Enter. What happens? You get back all the text that follows the echo command. It simply repeats what you tell it to by printing the text right back to the screen. You use this simple DOS command for printing text, like print in Perl or printf in C; it's the basis for almost all output of data in a BAT or CMD file.
Blank lines also come in handy in CGI programs. Whether you use them to make code in a file easier to read or to serve as a break so that the server knows to do something different, you need blank lines. The easy way to create a blank line with the echo command is just to put a period (.) right after it-no spaces, no other characters, just a period, like this:
echo.
If you put more characters after echo, it doesn't create a new line; it just functions like a normal echo command. With just that period following it, it does what you want it to do.
In the DOS world, environment variables such as CONTENT_FILE, OUTPUT_FILE, and REQUEST_METHOD are marked in a special manner: they're surrounded by percent signs (%). So, if you want to look at the content of the PATH environment variable on your system, from inside a BAT file, you use the following command:
echo %PATH%
When you run the BAT file from the DOS prompt, you get two lines: one is the command being entered by the BAT file, just as you would type it, and one is the result. This doesn't really matter when you're running a DOS CGI program-the server is interested in only what ends up in OUTPUT_FILE, or %OUTPUT_FILE% as you refer to it in your BAT file.
If you want to view a file or print several lines to the screen, you use the type command. It echoes plain text back to the screen until it reaches the end of the file-kind of an echo in an endless loop. If you send the server and browser a header that says plain text is coming and then use the type command to print a file to the Output File, everything that gets sent to the Output File appears line by line on the end user's screen.
When you want to send information somewhere else, that's called redirection. To tell a BAT file that you want to redirect information somewhere else, you have to use the symbols it understands. These two symbols are the greater-than sign (>) and two greater-than signs (>>) for most of the operations you need to worry about.
A greater-than symbol by itself (>) means "put everything on the left into the place on the right." So, in real life you might have "Orange Juice > Cup," meaning that you should take the orange juice and put it into the cup. This process assumes that you're going to get a new cup for the orange juice or that you're first going to dump out whatever is in the cup already. When you're dealing with BAT files, the same principle holds true-the command echo Hi, how are ya? > myfile.txt first empties the container (myfile.txt) and then shoves the text Hi, how are ya? into it. If you leave off the redirection, the text goes to the screen by default.
Two greater-than symbols (>>) still specify that information is redirected. But in this case, instead of replacing what was already there, the new information is added to it. This process is more like "Water >> Bucket," where you're adding more water instead of emptying the bucket. Getting much water moved would be really hard if you emptied the bucket every time. So, if you take the container myfile.txt, which you created before, and use the line echo Hi, how are ya? >> myfile.txt, you just increase the size of myfile.txt because you're adding the text to the file that already exists instead of replacing it.
Sometimes you want the program to perform different tasks, depending on a certain condition or comparison. The basic method of comparison is the IF statement. You can include several options in an IF statement, but two of the most useful tasks are string comparison (for checking environment variables) and file existence (for making sure that you don't try to send back a data file that doesn't exist). First, look at a line that compares two strings:
IF %REQUEST_METHOD%==POST goto DOSTUFF
Here, if the environment variable REQUEST_METHOD is POST, the program jumps to the section labeled DOSTUFF. Everything after the IF string1==string2 format is space for a command to take place; you can use copy a:\data.txt or delete c:\temp\filelock.txt, for example, or any other DOS-level command that you want.
The FOR command enables you to perform the same operation on many different things. It uses a replaceable variable, in which each element that it runs through puts data in the same variable and does a specific function to that variable every time the contents change. This command comes in handy. If you have 30 text files, for example, and you want to make them all into one big file called bigfile.txt, you can use the following line:
FOR %%f IN(c:\stuff\*.txt) DO type %%f >> c:\bigfile.txt
Later in this chapter, as you see different examples such as storing forms data in "BASIC and Its Cousins," you'll learn how the FOR command can be useful.
Because you're using DOS already, you might as well make use of built-in functions, like DIR, COPY, DELETE, and others that give you some useful functions without a lot of work. Say that you want to look through a file to find specific instances of a word and return them to a user. Most programs can do this task, though in some cases it would be laborious. UNIX users search this way all the time by using the grep command. Often, most people don't use DOS's FIND command to do the same thing. You see an example of this use shortly, but I wanted to add this important reminder: Don't despair that DOS can't do something until you've checked all your options.
Knowing what your program is receiving so that you can plan accordingly is vital to the success of any CGI program. You've seen the basics of a CONTENT_FILE dump before, but now you're going to see how easy it is to make the utility that performs the dump-just three lines. First, you need to set up a Content-type header to let the server and the browser know what kind of information you're sending. Next, you need to print a blank line, to separate the Content-type header from the rest of the content. Finally, you need to print out the whole Content File. Here's how you view the Content File as plain text output:
echo Content-type: text/plain > %OUTPUT_FILE%
echo. >> %OUTPUT_FILE%
type %CONTENT_FILE% >> %OUTPUT_FILE%
Now say that you want to store the Content File information in a big file so that you can go through it later, at your leisure. You also want to send something back to the users to let them know that you've received their information. This process is a simple variation on viewing the file-it's all in how you redirect output.
As I mentioned at the beginning of this chapter, this process takes just two lines and the HTML information you want to send back. First, you need to add the Content File to an existing file. Then you need to send back a file that you've made that contains any information or message you want to send. We'll look at them in pieces, starting with how you store content file data and send a fixed response:
type %CONTENT_FILE% >> myfile.txt
type message.txt > %OUTPUT_FILE%
These lines of code produce the following output, assuming that the file message.txt contains "Hi, how are ya?":
Content-type: text/html
Hi, how are ya?
As you can see, there's nothing to this process! Sure, this code is not the prettiest or most useful as it exists, but it checks that CGI is indeed running on your machine and gives you a base to build on for later.
This example is much more useful than just echoing back information that the user already knows about. This example enables you to take the QUERY_STRING environment variable (one word only), search through a text file, and then display the matches. And it takes no effort whatsoever on your part because you use the built-in DOS find command. All you need is the text file and about two minutes to type in the BAT program shown in Listing 16.2. You can use it for any kind of utility where you need a keyword search, such as a listing of projects, classes, or directions.
Listing 16.2. A DOS text search.
# Basic DOS text searching
# -Uses one-word QUERY_STRING to search
# Bill Schongar, July 1996
# First, we need the word we're looking for
set word=%QUERY_STRING%
# Now we search
find "%word%" c:\myfile.txt > c:\results.txt
# Send output
echo Content-type: text/html > %OUTPUT_FILE%
echo. >> %OUTPUT_FILE%
type c:\results.txt >> %OUTPUT_FILE%
But what if you have a variety of files you want to search through for the word? Then you use the FOR statement in the batch file and go through all the files, as shown in Listing 16.3.
Listing 16.3. A BAT file to search multiple text files.
# DOS CGI - Search multiple text files for keyword
# -Uses one-word QUERY_STRING to search
# Bill Schongar, July 1996
# First, we need the word we're looking for
set word=%QUERY_STRING%
# Now we search
for %%f IN (c:\files\*.txt) DO find "%word%" %%f > c:\results.txt
# Send output
echo Content-type: text/html > %OUTPUT_FILE%
echo. >> %OUTPUT_FILE%
type c:\results.txt >> %OUTPUT_FILE%
See? No problem. Even the most simplistic of languages, when combined with a few useful commands, can get the job done without much pain or effort.
Built into most DOS systems is either BASIC, QBasic, or some optional form thereof. These languages provide more advanced operations than can be had with regular BAT files, because you have more operations that you can perform. You can take advantage of being able to extract portions of strings, use variables more effectively, gain better control over file input and output-all the niceties that make what you can do more powerful.
The problem with BASIC isn't necessarily doing what you want to-though how easily you do it is another matter-but rather how you can use what you created after you're done creating it. Many BASIC implementations don't really have a concept of a runtime version of your program. They run from the editor, or they run from the command line and then spawn the editor, but they most often don't provide an easy way to say "Run this, but don't bring up the editor when you're done!" QBasic, one of the more common implementations of BASIC because it's built into MS-DOS, is guilty of this heinous problem. Its /run flag just says, "Oh, run first, editor second," not "Just run the program."
To get around this problem, you may be forced to compile the application into an EXE or COM file. If you have a variety of programming tools at your disposal, even old ones, you can normally find what you need hiding in and among them. The old Visual Basic for DOS, for instance, had a compiler that would do the job.
To give you an idea of some of the more useful jobs you can perform with a more advanced programming language, see Listing 16.4 for an example done in Qbasic.
Listing 16.4. Storing form data and returning information using QBasic.
REM DOS CGI Qbasic Form Processor
REM -Stores Firstname, Lastname and email
REM First, we need to get the filenames
infile$ = ENVIRON$("CONTENT_FILE")
REM infile$ = "c:\temp\mine.txt"
REM outfile$ = "c:\temp\yours.txt"
outfile$ = ENVIRON$("OUTPUT_FILE")
savefile$ = "c:\temp\save.txt"
REM Now we'll open up the content file
REM and read the line it contains
OPEN infile$ FOR INPUT AS #1
LINE INPUT #1, b$
REM Find out how long the string is
a = LEN(b$)
REM Now use a laborious method to check each character
REM and determine where to break into expected pairs
FOR i% = 1 TO a
c$ = MID$(b$, i%, 1)
IF c$ = "&" THEN
m% = m% + 1
marker(m%) = i%
END IF
NEXT i%
REM We're expecting three pairs, which means there
REM should be two markers. We'll use each marker
REM as a method of extracting the information before,
REM after, or in between them. That's what MID$ does.
REM There are going to be equal (=) signs in there,
REM but for the moment it doesn't matter. They can
REM be parsed out just like the & signs.
firstname$ = MID$(b$, 1, (marker(1) - 1))
lastname$ = MID$(b$, (marker(1) + 1), ((marker(2) - 1) - (marker(1))))
email$ = MID$(b$, (marker(2) + 1), (a - (marker(2))))
CLOSE #1
REM Now let's send some output back, customized
OPEN outfile$ FOR OUTPUT AS #2
PRINT #2, "Content-type: text/html"
PRINT #2, "
PRINT #2, "<title> Received</title>"
PRINT #2, "Thanks for filling out the form,"
PRINT #2, "<br> We'll email you something soon."
CLOSE #2
REM And we want to keep track of our visitors, so
REM we'll add them to a file
OPEN savefile$ FOR appeND AS #3
PRINT #3, "--------------------"
PRINT #3, "Visitor Data"
PRINT #3, "; firstname$
PRINT #3, "; lastname$
PRINT #3, "; email$
CLOSE #3
The program starts out by setting up some variables for referencing the Input File and the Output File, so that you don't have to keep typing the environment variable strings in over and over. As you can see from the comments (the lines beginning with REM), it then goes step by step through the data, running through a number of contortions to get the incoming data to be what we expect it to.
For some time, Perl was available only to folks in UNIX land. Then it slowly started gaining momentum and moving to other platforms, and the last platform to get it was good old 16-bit DOS. When you want to move beyond what you can easily do in BAT and CMD files, you can move up to Perl. The good thing about this migration is that Perl is enormously popular for creating CGI scripts, and things that you learn about the language itself will give you a jump start if you ever decide to go to a different environment. No matter where you end up programming, chances are very good that some variant of Perl will be there to make life easier.
Finding Perl for DOS can be hard. With version 5 of Perl storming out the gates and the mass migration to 32-bit platforms, the availability of a Perl 5 port for DOS is a very slim possibility. You can still find archives of Perl 4.036 for DOS by searching, but the sites that keep it in storage areas are getting fewer and farther between. At the time of writing the only site with an accessible copy of Perl 4.036 for MS-DOS was: ftp://ftp.ee.umanitoba.ca/pub/msdos/perl. Others may appear, so if you have problems with the above address, try a general search on "dos perl" on any of the major Web search engines.
Because Perl is an interpreted language that's not native to DOS, every time you go to run your Perl script, you have to start up a copy of PERL.EXE to do the interpreting. As you would expect, running this file sucks up more memory and slows down the process. This slowdown is one of the trade-offs you make for the additional power. Perl is also a more robust programming language and thus requires more of a learning curve to get it to do all the things you want it to do because it has so many more capabilities.
Another problem is that some of the Perl scripts and Perl libraries available are UNIX-centric. This means that if you see something really useful that you want to place on your site, you may have to do some significant tweaking to get it to work right, if there's any chance of it working at all. Remember, just because the Perl script thinks it can do the job doesn't mean that DOS is up to the challenge.
To continue with the trend of examples, look at the same form data storage routine created in Perl for DOS, as shown in Listing 16.5. As you can see, it has some equally strange commands if you're not used to it, but it's much better suited for this kind of task (because it takes care of splitting text strings based on special characters), and you don't need a compiler to run it.
Listing 16.5. Storing form data using Perl for DOS.
# Basic DOS CGI Form Handler, in Perl
# Bill Schongar, July 1996
# First, open file for data
$content=$ENV{'CONTENT_FILE'};
open(IncOMING,$content);
# Put all data from the file into one variable
while (<IncOMING>) {
$data=$data.$_;
}
close IncOMING;
# Now break the data up into the three components
# -First by the & sign, to separate pairs
# -Next by the = sign, to split name and value
($a,$b,$c) = split(/&/,$data);
($junk,$first) = split(/=/,$a);
($junk,$last) = split(/=/,$b);
($junk,$email) = split(/=/,$c);
# Now send some output
# -All print statements get redirected to OUTGOING,
# which is the OUTPUT_FILE
$output=$ENV{'OUTPUT_FILE'};
open(OUTGOING,">>$output");
print OUTGOING "Content-type: text/html \n\n";
print OUTGOING "<title>Input Received</title> <br>\n";
print OUTGOING "Thanks for giving us the information, $first. \n";
print OUTGOING "We'll send you some email later... \n";
close OUTGOING;
# Now store it all to a file
$store="c:\\temp\\storeme.txt";
open(STORAGE,">>$store");
print STORAGE "************ \n";
print STORAGE "Visitor Data \n";
print STORAGE "Name: $first $last \n";
print STORAGE "Email: $email \n";
close STORAGE;
This program results in much cleaner output, with much less work for everyone.
The top of the line for DOS CGI power and performance is C or C++. A compiled C/C++ executable (.EXE) doesn't need any outside help to be interpreted, it can do anything you could possibly want it to (with the exception of making DOS more efficient), and it's lightning fast. The disadvantage is that it's not easy, and as a result using C/C++ takes a lot more work to get the results you want.
If what you want is complex or really cool, then using C/C++ might be worth all the extra work. If you're absolutely desperate for performance, then you might consider using C/C++ for even basic operations, like the form dump you've been looking at in both BAT and Perl implementations. Be forewarned, however; doing the same amount of work takes a lot more effort, and saving the effort for something that you just can't do easier with something else is normally better.
To use C/C++, you first need a C compiler. If it's a couple years old really doesn't matter, as long as it produces good command-line runnable code. For instance, Visual C++ 1.0 is horrendously out of date, but you can find it for next to nothing (you can sometimes find it in books on C++ programming), and it produces fully working code. Being able to use older compilers is a definite benefit when you consider that you would end up spending several hundred dollars on a current copy of Visual C++ or any other well-known compiler.
Tip |
If you use Visual C++ or any other Windows-based compiler, be absolutely sure that you create your project as a command-line application, with no windows, no message boxes, and no real need of Windows controls. DOS CGI is somewhat limited in what it will do to let you communicate in its little shell, and you have to be kind to it. |
Using C as your programming language of choice opens up every possibility that DOS has to offer, and it also makes life very complex. Unless you've programmed in C before or really need to get the functionality, you might want to hold off until you've had a chance to play with C before you jump head first into DOS CGI programming with it. Because C is not a scripting language, you have to recompile each time you change something, and if you're just learning, recompiling is going to add up to a lot of time. After you learn the basics of file input/output and string handling, though, you've got enough knowledge to at least make a starting run at programming.
For implementation, C programming structure is much more like Perl or QBasic than the BAT methodology. You can use C's built-in functions to save overhead instead of running to external processes and dragging the system down too far.
People often shun DOS CGI because it's limited in how much it can do-not necessarily functionality wise, but just the amount of effort it dedicates to each task you want to perform. When you run a DOS CGI program, DOS has to allocate a certain region of resources to that particular processing task. This virtual machine (VM) puts a hard limit on just how many processes you can have running at once before you fill up environment space and memory, and DOS grinds to a halt because it's trying to pretend it can multitask. If what you're running is small and efficient and is over quickly, you may not have a problem. If what you're running is big and inefficient, like a huge QBasic program or Perl script, you've got a problem.
Most likely, you will never find a server that performs intense DOS CGI activity and survives for long. If you're running a personal Web site and expect a couple hundred hits per day, and maybe 10 percent of those folks will execute CGI requests, you don't really have a problem. Your site may be slower than some other sites, but that kind of load won't crush DOS CGI. If you're running a high-traffic or CGI-intense site (with internal CGI counters on every page, dynamic page creation, and so on), however, DOS CGI won't keep you afloat. I'm not saying that it doesn't want to, but there's a limit to how many processes it can spawn at once.
One of the speed problems is caused by the extra file input and output used for CONTENT_FILE and OUTPUT_FILE. Although memory buffers are fast, disk access isn't, especially if a lot of output is being written out. In addition, when you start reading in files left and right or processing them, more memory is taken up. You can reduce this problem by having a fast hard drive and lots of available memory, but the underlying drag will still be present no matter what you do.
As for functionality limitations, you're only up against what DOS can and cannot support in any language available to it. You have many options, as long as load isn't going to be an issue. But what happens when a function just isn't available, or you don't have the time or expertise to implement it in the language that supports it? Sometimes you need to dig further, and look at all the resources available to you.
If you've ever done a general search on any Web search engine, looking for information on DOS CGI, chances are you were disappointed by what you found. With the biggest segments of the Web server population on UNIX and 32-bit Windows, DOS doesn't get very many devotees. The other reason that you don't see too much on DOS is that DOS CGI programming, with the basic exceptions and limitations I've outlined, is just like programming for any other platform. All you have to know is how to modify things for your own use.
To convert CGI programs, here's the first rule of thumb: where you see STDIN, think CONTENT_FILE; where you see STDOUT, think OUTPUT_FILE. To see some of these variables, you really need to know a little bit about the languages and how they point to these variables. You can easily check for print statements of any kind (print, printf, and so on). Normally, these statements either point to a file handle, such as print MYFILE "Some text here \n"; in Perl or printf(MYFILE,"Some text here"); in C, or they point nowhere, such as print "Some text here \n"; in Perl. These print statements that go nowhere are almost always pointing to STDOUT, so you need to identify them and aim them back at OUTPUT_FILE. If these statements are already pointing to a file, chances are, they're using it for general storage, so you can keep them just the way they are and even use the file handle there originally.
Here's the second rule of thumb: Be sure DOS (and the language you intended to use) supports the functionality you're trying to use. If you see anything like ls, rsh, or grep, back away slowly. They are UNIX system commands, and only some of them have built-in equivalents on the DOS side. The easiest translation to is to change ls to a dir command, with possibly one or two other command-line parameters. But remember that many scripts are UNIX-centric and bear careful watching before you try to convert them over. If you don't recognize a command, type the command, followed by a space, a forward slash, and a question mark (/?), and see if any information comes up on it in DOS. If the system has no idea what you're talking about, you've hit a UNIX command.
Information that's available on CGI, any information, is valuable. It's not called the Common Gateway Interface just for fun-over 90 percent of what you see and read holds true to every platform, when taken in its most general sense. Everyone uses environment variables in one way or another. Headers don't change just because you're on a different system, and HTML code is still HTML code.
Good Web server software normally comes with a whole host of examples. For servers that support DOS CGI, this fact holds true as well. WinHTTPD contains several examples of batch files taking care of basic CGI tasks. You can use any one of them as a comparison to make sure that you're doing things right after you get going. Depending on your server software, additional tricks or features may be added in to make your life easier. Or you may find documentation about what to (or not to) do to get DOS CGI going. Be sure to look through all of it-you never know when two minutes of searching will save you two hours of frustration.
Chances are, you won't see as many books on the shelves of your favorite book store that deal with DOS programming nowadays as you would with just about any other topic. But basic references are still there. Many game companies still deal with DOS first, to avoid Windows overhead-and the folks who wrote DOOM certainly didn't create it using BAT files.
You should look for references that give you information that you need. DOS may seem limited, but people have made some pretty powerful applications in it over the years, and when it is used correctly (and with the right software), it can perform most any task, from dialing a modem to printing out user requests to accessing databases. You don't want information that deals with graphic interfaces unless you're planning to print out special information through another port to a printer or fax. You're really should be interested in C programming books that deal with communications and general data processing. Sometimes the public library is the last place you might expect to find the information you're looking for in the computer field-because most of the books are older than you need-in this case, however, the library should have information just about the right age for you to find what you're looking for. Sometimes time lags work in your favor.
If you're using DOS CGI, chances are you don't have a choice. Using DOS does place limits on how much space you can take up, what built-in functions are available, and just generally how far it'll do what you want it to, with all that extra file input and output. But don't give in to despair. Remember, DOS programs have been flourishing for years, and plenty of power and functionality is available out there; you can take advantage of it if you know where to look.