-                         CGI PROGRAMMING NOTES -                         =====================   A This file contains suggestions for writing Perl CGIs for use with  CRINOID.   CRINOID CGI STYLE GUIDE  =======================   @ First off, try your script from an interactive prompt, using the "-w" (warnings) flag:    $ PERL -w myscript.cgi  C Anything that gets complained about, fix. That will solve about 80%  of the potential problems.  F For efficiency, you'd like to be able to re-run scripts multiple timesH after they've been loaded.  You can tell CRINOID to do this by including the statement:       $CRINOID::Reuse = 1;  G in your script.  But beware, your script has to be "well behaved" to be  able to be reused.    * The Well-Behaved Script #1: Initialization* ------------------------------------------  G Perl with the -w flag should catch uninitialized variables for you, but F in general uninitialized variables are a much more serious concern for CRINOID CGI scripts.   If you have a script like:  )     print "Content-type: text/plain\n\n"; 3     print "first time? ",($x ? "NO" : "YES"), "\n";   D Then you're using the fact that $x is false (undefined, even), which- will not be the case if the script is re-run.   I There *are* times when it's useful to bend the rules about initialization G a bit, particularly when you have a largeish amount of static data that < you don't want to re-initialize each time the script is run:       if (!defined(@MyArray)) { %         @MyArray = (1, 1, 2, 3, 5, 8,                  ...           );      }       , The Well-Behaved Script #2: Variable Scoping, --------------------------------------------C Wherever possible put your variables in "my" or "local"; this helps D keep the memory use from rerunning scripts within reasonable bounds.  , This is also just good programming practice.    / The Well-Behaved Script #3: Close what you Open / ----------------------------------------------- : Any files (and dirs) you open in your script will *NOT* beC automatically closed for you.  You need to close them explicitly in ? your script.  In particular watch out that you close files when ! you encounter an error condition.   > Failing to close files, and then rerunning the script with the3 files already open, can be a real pain to diagnose.   A There are some exceptions: you should NOT close STDIN, STDOUT and 1 STDERR.  These are dealt with in the server code.      Watch where you are, part 1  --------------------------- ? The default directory when your script is run may very well NOT ? be the directory where the script is located....in fact, it's a  good idea for the scripts in:          MYDISK:[USER.WWW-CGI]  to have the default set to: 1         MYDISK:[USER.WWW-TEMPFILES]  (or similar) C when they are run, so that they can't inadvertantly mess up another < script, or create a file that might be runnable as a script.  = Setting the "HomeDir" in your OYSTER.CONFIG will chdir to the 4 the directory you select before running your script.   Watch where you are, part 2  --------------------------- L If you do not set the "HomeDir" in your OYSTER.CONFIG, the default directoryM will be the same as the top-level script directory (as the previous example):          MYDISK:[USER.WWW-CGI] 3 even when the script is actually in a subdirectory: (         MYDISK:[USER.WWW-CGI.KEWL]STUFF.  G This latter case also illustrates the interaction between PATH_INFO and  the script directory.   7         http://host/cgi/~user/kewl/stuff/more/path/info    will run the script (         MYDISK:[USER.WWW-CGI.KEWL]STUFF.; (if it exists!) with the PATH_INFO set to  "more/path/info"    But if you had a script:-         MYDISK:[USER.WWW-CGI.KEWL.STUFF]MORE. 7 then IT will be run, with PATH_INFO set to "path/info".   G The search for scripts is done "deepest first" until a script is found.   @ If you set the parameter "NoDescend" in your OYSTER.CONFIG, thenA the search will be confined to the uppermost CGI directory and no   subdirectories will be searched.  F If you keep your scripts with a suffix like ".pl" or ".cgi" then lowerD directory levels can't be searched, since (on VMS) a directory named3 "myscript.pl" isn't part of a valid directory-spec.   G Also on the topic of "searching for a script", note that the "Suffixes" G parameter in OYSTER.CONFIG lets you confine valid script names to those . that have one of a specified set of filetypes.     SCRIPT COMMAND LINE OPTIONS: ----------------------------F Recent changes to SCRIPT.PM (v0.4-1) allows _some_ command flags to beB used in CGI scripts.  In particular, the first line of your script should look like:        #!  perl    [options]   B Just as for a "normal" Perl script.  The parsing of the options isE done "manually" (i.e., by OYSTER s/w, not by Perl) and only a limited F subset of options are understood.  Also, the parser doesn't understand# combining single-character options.    Options available:          -w      turn on warnings!         -Dfff   debug flags 'fff' *         -Idir   put 'dir' on the @INC list  D Of these, I expect that -I will be the most useful, so that your CGIA scripts can put any custom modules in a directory of your choice. 