<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
<book><bookinfo>
<title>Geodetic Data Modeling System Internet Interface: Honors Thesis</title>
<authorgroup>

<author>
  <firstname>Michael</firstname>
  <surname>Still</surname>
  <affiliation><jobtitle>964076</jobtitle></affiliation>
</author>
</authorgroup>

<abstract><title>Abstract</title>
<para>
This document discusses the <command>GDMS Internet interface</command>. This interface allows remote access to the vast majority of the functionality available in the X Windows version of <command>GDMS</command>. The interface was developed in Perl, and uses the Common Gateway Interface (CGI) offered by most modern web servers to interact with the web browser.
</para>
</abstract>
</bookinfo>

<glossary><title>Glossary</title>
<para>
The following acronyms are used throughout this document.
</para>

<glossentry id="asp"><glossterm>ASP</glossterm>
<acronym>ASP</acronym>
<glossdef>
<para>
ASP stands for Active Server Pages. ASP is Microsoft's server side scripting language. Server side scripting languages embed program elements into the HTML pages, which are executed and then removed before the page is returned to the web browser.
</para>
</glossdef>
</glossentry><glossentry id="cgi"><glossterm>CGI</glossterm>
<acronym>CGI</acronym>
<glossdef>
<para>
CGI, or Common Gateway Interface, is a standard which defines methods by which web servers and server side executables may communicate. The main method of communication is the passing of the URL provided to the script as an environment variable (National Center for Supercomputing Applications 1996).
</para>
</glossdef>
</glossentry><glossentry id="gdms"><glossterm>GDMS</glossterm>
<acronym>GDMS</acronym>
<glossdef>
<para>
<command>GDMS</command>, the Geodetic Data Modeling System, is the name given to the undergraduate portion of my final year project. This is an X Windows based modeling package for geodetic data, and includes least squares, interpolation, windowing and fast Fourier transformation functionality.
</para>
</glossdef>
</glossentry><glossentry id="gif"><glossterm>GIF</glossterm>
<acronym>GIF</acronym>
<glossdef>
<para>
The Graphics Interchange Format (GIF) was co-developed by CompuServe Inc. and Unisys Corporation in the late 1980s and early 1990s. GIF is dependent on LZW compression (CompuServe 1990), which is now having it's patent enforced by Unisys (Anonymous 2002).
</para>
</glossdef>
</glossentry><glossentry id="html"><glossterm>HTML</glossterm>
<acronym>HTML</acronym>
<glossdef>
<para>
HyperText Markup Language is the <emphasis>lingua franca</emphasis> of the web. It is a content markup language based on SGML (World Wide Web Consortium 2002).
</para>
</glossdef>
</glossentry><glossentry id="jfif"><glossterm>JFIF</glossterm>
<acronym>JFIF</acronym>
<glossdef>
<para>
The file format commonly called JPEG is actually JPEG JFIF (JPEG File Interchange Format) &mdash; created by the Independent JPEG Group (Lilly 1996).
</para>
</glossdef>
</glossentry><glossentry id="jpeg"><glossterm>JPEG</glossterm>
<acronym>JPEG</acronym>
<glossdef>
<para>
JPEG stands for Joint Picture Expert Group, which is a group of the International Standards Organization. This group devised the JPEG compression format, which is used in the JFIF file format.
</para>
</glossdef>
</glossentry><glossentry id="lzw"><glossterm>LZW compression</glossterm>
<acronym>LZW</acronym>
<glossdef>
<para>
GIF is dependent upon LZW compression (CompuServe 1990), a compression algorithm which is named after it's developers Lempel, Ziv, and Welch (Nelson 1998).
</para>
</glossdef>
</glossentry><glossentry id="motd"><glossterm>MOTD</glossterm>
<acronym>MOTD</acronym>
<glossdef>
<para>
A MOTD is the Message Of The Day, a greeting message presented to users as they login to the <command>GDMS Internet interface</command>.
</para>
</glossdef>
</glossentry><glossentry id="php"><glossterm>PHP</glossterm>
<acronym>PHP</acronym>
<glossdef>
<para>
PHP, which stands for <quote>PHP: Hypertext Processor</quote> (AIMS Group, 2002), is an Open Source server side scripting language. Server side scripting languages embed program elements into the HTML pages, which are executed and then removed before the page is returned to the web browser.
</para>
</glossdef>
</glossentry><glossentry id="png"><glossterm>PNG</glossterm>
<acronym>PNG</acronym>
<glossdef>
<para>
Portable Network Graphics (PNG) was initially developed because of the patent problems with the GIF format described earlier in this section. The PNG format has since grown well past the feature set provided by GIF, and now rivals TIFF for completeness (Randers-Pehrson 1999).
</para>
</glossdef>
</glossentry><glossentry id="tiff"><glossterm>TIFF</glossterm>
<acronym>TIFF</acronym>
<glossdef>
<para>
TIFF (Tagged Image File Format) is a raster (bitmap) image format which was originally produced by Aldus and Microsoft. Aldus was later acquired by Adobe, who manage the TIFF specification to this day. At the time of writing, the current version of the TIFF specification is TIFF version 6.0 (Adobe 1992).
</para>
</glossdef>
</glossentry><glossentry id="url"><glossterm>URL</glossterm>
<acronym>URL</acronym>
<glossdef>
<para>
A Uniform Resource Locator is the <quote>address</quote> of a web page.
</para>
</glossdef>
</glossentry>

</glossary>

<chapter id="ch01"><title>Introduction</title>
<sect1><title>Motivation</title>
<para>
At the time that the <command>Geodetic Data Modeling System</command> (GDMS) implementation project was initiated, several of the potential users expressed a desire for the application to be available over the Internet. There are a variety of reasons that this type of functionality is enticing. The primary reason for <command>GDMS</command> is that it allows casual users to ability to analyze data, whilst not having to maintain their own copies of the datasets. A secondary reason is that it allows users who would normally use the X windows interface to the application to access data whilst <quote>in the field</quote>, or otherwise physically separated from their normal research location.
</para>

<para>
Initially, it was thought that a Internet interface to <command>GDMS</command> was outside the achievable scope of the project for 2002. However, as the year progressed, it became clear to me that implementing a Internet interface was indeed achievable, and would add genuinely useful functionality to the application. Hence this honors extension was undertaken.
</para>
</sect1>

<sect1><title>Outcome</title>
<para>
This document describes the design process and implementation of the <command>GDMS Internet interface</command>, a Perl application intended to operate under the Common Gateway Interface (CGI) offered by most modern web servers, including Apache, which is the web server in use within the University of Canberra Survey Laboratory. This application allows the on line use of almost all of the functionality available under the X windows <command>GDMS</command> system.
</para>
</sect1>
</chapter>

<chapter><title>Implementation rationale</title>
<sect1><title>Selection of the implementation technique</title>
<para>
A variety of implementation techniques were considered for the <command>GDMS Internet interface</command> before a final selection was made. This section documents the various alternatives that were considered, and then justifies the decision that was made.
</para>

<sect2><title>PHP: Hypertext Preprocessor</title>
<para>
There is some evidence that the name of PHP originally stood for <emphasis>Personal Home Page tools</emphasis> (Lerdorf 1995). PHP is an in-page scripting language which was originally developed by Rasmus Lerdorf (Lerdorf 1995). It is now maintained and extended by a on line team of developers lead by Rasmus Lerdorf (AIMS Group, 2002).
</para>

<para>
Because PHP is an in-page scripting language, the actual code to generate the HTML page viewed by the user of the web browser is actually stored within the HTML page on the servers secondary storage. A trivial example is:
</para>

<programlisting>
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;PHP Test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?php echo "Hello World&lt;p&gt;"; ?&gt;
&lt;/body&gt;
&lt;/html&gt;
</programlisting>

<para>
In this example, the tag starting with ?php is the script element. The output of this script is a simple HTML page saying <quote>Hello World</quote>.
</para>

<para>
The main advantage of in-page scripting is that the source code of the application is very tightly tied to the HTML presentation of the application's user interface. This means that when a user is editing a page, it is apparent what the given code does at the time that the page is created.
</para>

<para>
The main disadvantage of such as system is that it requires that the users who are editing the HTML appearance of an application must also understand the scripting language in which the application is implemented. This means that graphics designers and layout consultants require further training. The application is no longer a <emphasis>black box</emphasis> in which the HTML designer can simply be a user. A second drawback is that the inclusion of the scripting within the HTML pages is that it clutters the HTML representation of the user interface, making it much harder to read. This problem is compounded by poor in-page scripting support in many HTML editors, including Mozilla. These editors discard tags they don't comprehend at the time of editing the page, and this unfortunately includes tags such as PHP.
</para>

<para>
Developing the <command>GDMS Internet interface</command> in PHP would necessitate the users of the application running web servers with PHP modules installed (PHP Documentation Group, 2002). This is a extra level of configuration for systems administrators for little additional benefit.
</para>
</sect2>

<sect2><title>Active Server Pages</title>
<para>
Active Server Pages (ASP) is Microsoft's equivalent of PHP. Discussion of this alternative is deliberately brief, because ASP effectively has all the advantages and disadvantages of PHP, with the additional constraint that it only operates of Microsoft web server products running on Microsoft Operating Systems. This is not an acceptable constraint for the main target user of the application &mdash; the University of Canberra Survey Laboratory, who are not heavy users of Microsoft products.
</para>
</sect2>

<sect2><title>C or C++ Common Gateway Interface</title>
<para>
Another implementation alternative considered was to implement the system in either C or C++ using the Common Gateway Interface (CGI) subsystem offered by most web servers. This implementation technique has the advantage of the code for the <command>GDMS Internet interface</command> being in the same language as the <command>GDMS</command> application itself. However it has the disadvantage that parsing the incoming URLs is less trivial, as there is limited language support without the inclusion of non-standard application libraries (Kahan 2002).
</para>

<para>
C and C++ are not idiomatic methods of implementing CGI applications, and this would therefore increase the difficulty of maintaining the system for future students and administrators.
</para>
</sect2>

<sect2><title>Perl CGI</title>
<para>
Perl was originally developed by Larry Wall in 1987 (Perl Mongers, 1999) and is now developed by a team of Open Source developers. Perl is a shell script like scripting language, although it's syntax is much more powerful than that of shell script. Perl also has world class regular expression support as a standard, well integrated, feature. Perl has well integrated CGI support built into the language itself, and is optimized for the parsing of complex strings (such as the requests which are returned by a web browser to the <command>GDMS Internet interface</command> via the CGI apparatus).
</para>

<para>
Perl's inbuilt handling of CGI web interfaces makes it much easier to develop web applications than it would be in C or C++. For example, the following is a simple hello world application in Perl:
</para>

<programlisting>
# Import some modules
use strict;
use CGI;

# Declare variables because strict is enabled
my($result);

# Setup the CGI module, and output headers
$result = new CGI();
print $result->header;

print "Hello World";
</programlisting>

<para>
It can be seen from this example that Perl makes CGI programming trivial. This same program in C or C++ would have taken many more lines, and would have needed to include the hard coding of the required headers.
</para>

<para>
Perl is also extremely stable, well documented, and is already installed at most sites.
</para>
</sect2>

<sect2><title>Conclusion</title>
<para>
After consideration of all of the factors outlined above, Perl CGI was identified as the most suitable implementation language for the <command>GDMS Internet interface</command>.
</para>
</sect2>
</sect1>

<sect1><title>Presentation of the user interface</title>
<para>
In accordance with Internet user interface design best practice, the <command>GDMS Internet interface</command> presents a fully configurable user interface. This is implemented by providing extension tags above those which are available in the standard HTML specification (Raggett, Le Hors, &amp; Jacobs 1999).
</para>

<para>
The <command>GDMS Internet interface</command> follows the recommendations of the most recent HTML specification at the time of development for the insertion of scripting tags into HTML source files (Raggett, Le Hors, &amp; Jacobs 1999). Further documentation on the <command>GDMS Internet interface</command> tags available can be found in Appendix A of this document.
</para>
</sect1>

<sect1><title>Selection of an image format for graph display</title>
<para>
Much thought was expended on which image format to use for the plots displayed in the <command>GDMS Internet interface</command>. There are advantages and disadvantages to all the formats available at the time of writing this document. The following formats were considered for the <command>GDMS Internet interface</command>:
</para>

<sect2><title>Tagged Image File Format</title>
<para>
TIFF (Tagged Image File Format) is a raster (bitmap) image format which was originally produced by Aldus and Microsoft. Aldus was later acquired by Adobe, who manage the TIFF specification to this day. At the time of writing, the current version of the TIFF specification is TIFF version 6.0 (Adobe 1992). It should be noted that no significant development of the TIFF standard has occurred since that date.
</para>

<para>
The main advantage of the TIFF image format is that it is extremely mature. It has a large selection of options to ease the development of imaging software, for example the developer can use which ever endian representation is convenient for them, as well as such fundamental parameters as photometric interpretation, whether a high value is lighter or darker than a low value for a given colour sample within a pixel (Adobe 1992). There is also a stable, well supported Open Source application programmers interface available to manage creation and interpretation of images within the TIFF format (Warmerdam &amp; Welles 2002). The interface to this library does not frequently change, which is also an advantage for future portability of the <command>GDMS Internet interface</command>.
</para>

<para>
However, some of these advantages lead to the principal disadvantages that the TIFF format suffers from. Because the content of the file is so loosely specified, it is quite hard to write an application which can correctly decode all possible TIFF format images. This has resulted in there being only a few high quality TIFF viewing applications being available. The relative difficultly of implementing a TIFF decoder has also resulted in the web browser support for TIFF images being very poor (Bither 2002).
</para>

<para>
TIFF is therefore an inappropriate image format for use for the <command>GDMS Internet interface</command>, as good browser support in as many browsers as possible is vital.
</para>
</sect2>

<sect2><title>Graphics Interchange Format</title>
<para>
The Graphics Interchange Format (GIF) was co-developed by CompuServe Inc. and Unisys Corporation in the late 1980s and early 1990s. GIF is dependant on LZW compression (CompuServe 1990), which is now having it's patent enforced by Unisys (Anonymous 2002). The GIF format itself is quite limited, with a maximum palette size of 255 entries &mdash; in other words 255 distinct colours are available in each image.
</para>

<para>
Vendors are also dropping support for the GIF format because of the expense of licensing the Unisys LZW patent, for example, the Open Source <emphasis>libgif</emphasis> is no longer supported for the creation of GIF images (Raymond, 1998).
</para>

<para>
Despite all of these largely political issues, the GIF format is still well supported in all web browser versions, which would make it an ideal candidate for the <command>GDMS Internet interface</command> if it wasn't for the lack of a stable and reliable compression library.
</para>
</sect2>

<sect2><title>Joint Picture Experts Group File Interchange Format</title>
<para>
JPEG is an interesting image format because whilst the JPEG compression codec has been standardized by ISO, the actual on disc format commonly called JPEG is not part of the ISO standard. The file format commonly called JPEG is actually JPEG JFIF &mdash; created by the Independent JPEG Group (Lilly 1996).
</para>

<para>
JPEG support in web browsers is excellent, with support rapidly improving after 1996 (Lilly 1996). The biggest factor stopping the use of JPEG within the <command>GDMS Internet interface</command> is that the compression codec is lossy.
</para>

<sect3><title>Loss</title>
<para>
The JPEG compression algorithm is lossy &mdash; in other words, the act of compressing the image results in image data being discarded. This has the effect of noticeably reducing the clarity of the images &mdash; a characteristic which is especially noticeable with images which contain text at smaller point sizes. The use of such text is a feature of the <command>GDMS</command> graphing subsystem.
</para>

<para>
For example, JPEG compressing the following image results in the following output image:
</para>

<figure><title>The UC logo before JPEG compression</title>
<graphic format="eps" fileref="gen-tiff-figure4.eps">
</figure>

<figure><title>The UC logo after it has been JPEG compressed</title>
<graphic format="eps" fileref="gen-tiff-figure6.eps">
</figure>

<para>
This output is acceptible, because there is limited use of fine detail, and therefore limited loss of image clarity. The effects are much worse with an image which contains text at small point sizes:
</para>

<figure><title>A sample GDMS plot before JPEG compression</title>
<graphic format="eps" fileref="gen-tiff-figure5.eps">
</figure>

<figure><title>A sample GDMS plot after it has been JPEG compressed</title>
<graphic format="eps" fileref="gen-tiff-figure7.eps">
</figure>

</sect3>
</sect2>

<sect2><title>Portable Network Graphics</title>
<para>
Portable Network Graphics (PNG) was initially developed because of the patent problems with the GIF format described earlier in this section. The PNG format has since grown well past the feature set provided by GIF, and now rivals TIFF for completeness (Randers-Pehrson 1999).
</para>

<para>
The PNG support in many browsers is not perfect. However, browsers above version three for both Netscape and Microsoft Internet Explorer, and all versions of Mozilla have excellent support of PNG. There is an actively maintained and well supported Open Source programmers interface to the PNG format, in fact it is the reference implementation of the specification (Roelofs 2002), which reinforces it's stability.
</para>
</sect2>

<sect2><title>Conclusion</title>
<para>
Based on the factors outlined above, the PNG image format was selected for the <command>GDMS Internet interface</command>. This is because of it's excellent browser support in modern browsers, as well as it's mature and stable Open Source application programmers interface.
</para>
</sect2>
</sect1>

</chapter>


<chapter><title>Implementation</title>
<para>
This chapter discusses the actual application which was produced. The application is quite complex, with a series of pages being used to prompt the user and display information. The interaction of these different pages, each of which has a <quote>command</quote> associated with it, is shown in figure 3.2 below.
</para>

<para>
When the application starts, the command is not defined, as the user is unlikely to have specified one as part of the URL. This results in the <command>GDMS Internet interface</command> using the <emphasis>main</emphasis> command. The user is then presented with a welcome screen, which displays the message of the day. The message of the day in intended to be used to warn the users of the <command>GDMS Internet interface</command> of scheduled unavailability of the system, or new datasets having been added. There are no limits on the text that can be included in the message of the day however, so it could inform users of an impending Christmas party, or other equally unrelated events.
</para>

<figure><title>GDMS Internet interface welcome screen</title>
<graphic format="eps" fileref="gen-gdmsii-welcome.eps">
</figure>

<figure><title>GDMS Internet interface command interaction</title>
<graphic format="eps" fileref="gen-commands.eps">
</figure>

<para>
The message of the day is stored as a template named motd.html within the templates directory. See the configuration appendix of this document for more information about customizing this file.
</para>

<para>
The next operation that the user will perform is selecting a dataset to start processing. At this stage all other commands are disabled, because of a reliance on a dataset being available for processing. The user selects the <emphasis>open</emphasis> command, and a new page displaying a list of the available datasets is displayed. Once the user has selected one of the datasets from this list, a new page showing a plot of the selected dataset is displayed.
</para>

<figure><title>Selecting a dataset</title>
<graphic format="eps" fileref="gen-gdmsii-open.eps">
</figure>

<figure><title>A dataset plot in the north direction (time domain)</title>
<graphic format="eps" fileref="gen-gdmsii-plot.eps">
</figure>

<para>
It should be noted that at this time there is no way to configure the various graphing options offered by <command>GDMS</command> within the <command>GDMS Internet interface</command>. The recommended method for selecting the graphing style preferred by the users of the system is to run the <command>GDMS</command> X Windows application as the user id the web server runs as, and then copy the file ~/.cep to the same directory as the <command>GDMS Internet interface</command> executable. It should also be noted that at this time it is not possible to have individual graphing preferences for different users.
</para>

<para>
Now that the user has selected a dataset, the mathematical commands are now available. These may be selected from the same menu as the graphing commands, and include Least Squares regressions, windowing, interpolation, and Fast Fourier Transformations. All of the functionality available within the <command>GDMS</command> X Windows application is available for these mathematical operations.
</para> 

<para>
The <command>GDMS Internet interface</command> graphing subsystem also handles graphs in the frequency domain, in the same manner as the <command>GDMS</command> X Windows interface.
</para>

</chapter>



<chapter><title>Conclusion</title>
<para>
Based on the discussion in previous chapters, Perl CGI with PNG images were selected for the implementation of the <command>GDMS Internet interface</command>. This has resulted in a easy to understand code base, which will aid in future expansion of the application. The <command>GDMS Internet interface</command> should also correctly function with all modern web servers, including the Apache web server which is used by the University of Canberra Survey Laboratory.
</para>

<para>
There is some scope for future improvement of the <command>GDMS Internet interface</command>. This includes:
</para>

<itemizedlist>
<listitem><para>A web aware method of configuring graphing preferences.</para></listitem>
<listitem><para>Per user graphing preferences.</para></listitem>
<listitem><para>Allowing zooming on the dataset graphs in the same manner that the <command>GDMS</command> X Windows application allows.</para></listitem>
<listitem><para>Caching of processed datasets where it makes sense. Graphs are already cached.</para></listitem>
<listitem><para>Implementation of features as they are added to the <command>GDMS</command> X Windows application.</para></listitem>
</itemizedlist>

<para>
Overall, the <command>GDMS Internet interface</command> is a stable and reliable light weight interface to the <command>GDMS</command> batch interface.
</para>
</chapter>



<chapter><title>References</title>
<sect1><title>References</title>
<para>
Adobe, 3 June 1992, 
<emphasis>TIFF Revision 6.0</emphasis>, 
[Online] http://partners.adobe.com/asn/developer/pdfs/tn/TIFF6.pdf
</para>
<para>
AIMS Group, 2002,
<emphasis>PHP CVS mailling list archive</emphasis>,
[Online] http://marc.theaimsgroup.com/?l=php-cvs
</para>
<para>
Anonymous, 2 February 2002,
<emphasis>The GIF Controversy: A Software Developer's Perspective</emphasis>, 
[Online] http://www.cloanto.com/users/mcb/19950127giflzw.html
</para>
<para>
Bither, B., [Last accessed] November 2002,
<emphasis>Benefits of the PNG Image Format</emphasis>,
[Online] Available: http://www.atalasoft.com/png.asp
</para>
<para>
CompuServe, 1990,
<emphasis>Graphics Interchange Format: Version 89a</emphasis>
[Online] http://www.w3.org/Graphics/GIF/spec-gif89a.txt
</para>
<para>
Kahan. J., 12 June 2002,
<emphasis>Libwww - the W3C Protocol Library</emphasis>,
[Online] http://www.w3.org/Library/
</para>
<para>
Lerdorf, R., 8 June 1995,
<emphasis>Personal Home Page Tools (PHP Tools)</emphasis>,
[Online] http://groups.google.com/groups?selm=3r7pgp$aa1@ionews.io.org
</para>
<para>
Lilly, C., 13 February 1996 [Last updated: 18 July 2001],
<emphasis>JPEG JFIF</emphasis>,
[Online] http://www.w3.org/Graphics/JPEG/
</para>
<para>
National Center for Supercomputing Applications, 8 March 1996,
<emphasis>The Common Gateway Interface</emphasis>,
[Online] http://hoohoo.ncsa.uiuc.edu/cgi/overview.html
</para>
<para>
Nelson, M., 1989,
<emphasis>Dr. Dobb's Journal October, 1989: LZW Data Compression</emphasis>,
[Online] http://dogma.net/markn/articles/lzw/lzw.htm
</para>
<para>
Perl Mongers, 1999,
<emphasis>Perl History</emphasis>,
[Online] http://www.perl.org/press/history.html
</para><para>
PHP Documentation Group, 2002,
<emphasis>PHP Manual</emphasis>,
[Online] http://www.php.net/manual/en/print/
</para><para>
Raggett, D., Le Hors, A., Jacobs, I., 24 December 1999 [last update], 
<emphasis>HTML 4.01 Specification</emphasis>, 
[Online] Available: http://www.w3.org/TR/html4/
</para>
<para>
Randers-Pehrson, G., July 1999,
<emphasis>PNG (Portable Network Graphics) Specification, Version 1.2</emphasis>,
[Online] http://www.libpng.org/pub/png/spec/png-1.2.pdf
</para>
<para>
Raymond, E. S., 8 July 1998,
<emphasis>The GIFLIB home page</emphasis>,
[Online] http://tuxedo.org/~esr/giflib/
</para>
<para>
Roelofs, G., 2002,
<emphasis>libpng</emphasis>,
[Online] http://www.libpng.org/pub/png/libpng.html
</para>
<para>
World Wide Web Consortium (w3c), 12 December 2002,
<emphasis>HyperText Markup Language (HTML) Home Page</emphasis>,
[Online] http://www.w3.org/MarkUp/
</para>
<para>
Warmerdam, F. and Welles, M., 24 January 2002 [last update],
<emphasis>The libtiff home page</emphasis>,
[Online] http://www.libtiff.org/
</para>

</sect1>
</chapter>






<appendix><title>GDMS Internet interface scripting elements</title>
<sect1><title>Introduction</title>
<para>
This appendix documents the various tags which are implemented by the <command>GDMS Internet interface</command> in addition to the standard HTML tags normally available. All of these tags are within the scripting name space provided by HTML 4.01 (Raggett, Le Hors, &amp; Jacobs 1999).
</para>

<sect2><title>commands</title>
<para>
This tag will display a menu of the commands available in the current context &mdash; for example, when the Internet interface first starts, it will list the open command. Commands which are not available, but are normally available will appear in a disabled style. This results in a list of commands which is consistent, and therefore reduces the potential for user confusion.
</para>

<para>
An example use is as follows:
</para>

<programlisting>
&amp;{commands};
</programlisting>

<para>
The display of the command menu is altered by the following configuration file entries:
</para>

<itemizedlist>
<listitem><para><emphasis>commandentry</emphasis>: this HTML snippet is used for enabled commands</para></listitem>
<listitem><para><emphasis>discommandentry</emphasis>: this HTML snippet is used for disabled commands</para></listitem>
</itemizedlist>

<para>
For example, these configuration entries ship by default with the <command>GDMS Internet interface</command>:
</para>

<programlisting>
# This line is simple HTML used for format the command entries,
# %s is the name of the command (including link HTML)
$commandentry = "&lt;tr&gt;&lt;td bgcolor=\"AAAAAA\"&gt;%s&lt;/td&gt;&lt;tr&gt;";

# This line is used for commands which aren't available...
$discommandentry = "&lt;tr&gt;&lt;td bgcolor=\"EEEEEE\"&gt;
  &lt;font color=\"777777\"&gt;%s&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;";
</programlisting>
</sect2>
<sect2><title>dataset</title>
<para>
This tag will display the name of the currently open dataset, if one is open. This might possibly be a descriptive string is processing has occurred on the dataset.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{dataset};
</programlisting>

<para>
The dataset name is the portion of the filename before the extensions .dat1, .dat2, and .dat3 are applied. For example <emphasis>mb_AUCK_GPS</emphasis> is a dataset name.
</para>
</sect2>
<sect2><title>datasets</title>
<para>
This tag will display a list of the datasets available in the dataset directory.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{datasets};
</programlisting>

<para>
The dataset directory is configured with the following configuration file entry:
</para>

<programlisting>
# This line defines where the datasets are stored
$datasets = "/home/httpd/gdms-datasets/";
</programlisting>

<para>
There are also several configuration options which alter the appearance of the list of datasets available. These are:
</para>

<itemizedlist>
<listitem><para><emphasis>selectstart</emphasis>: this is used for any output which should appear at the beginning of the list. This could include HTML tags for the creation of the required list markup (for example tables).</para></listitem>
<listitem><para><emphasis>selectentry</emphasis>: this configuration item is used for each entry in the list. The special text <command>%s</command> is replaced by the HTML for the entry itself.</para></listitem>
<listitem><para><emphasis>selectend</emphasis>: this is used for any HTML required to finalize the list.</para></listitem>
</itemizedlist>

<programlisting>
# This is used for selection lists (for instance datasets)
$selectstart = "List start";
$selectentry = "&lt;LI&gt;%s";
$selectend = "List end";
</programlisting>
</sect2>
<sect2><title>eastplot</title>
<para>
This tag will insert the HTML and required URL for the East direction plot from the current dataset. The output of the tag will be empty if there is no currently selected dataset. The plots are 24 bit colour PNG images, as discussed in the implementation methodology section of this document.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{eastplot};
</programlisting>
</sect2>
<sect2><title>interpparams</title>
<para>
This tag will output the HTML form required for the entry of interpolation processing parameters. The user will then select <quote>OK</quote> on this web form, and the interpolation operation will occur.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{winparams};
</programlisting>
</sect2>
<sect2><title>lsparams</title>
<para>
This tag will output the HTML form required for the entry of Least Squares processing parameters. The user will then select <quote>OK</quote> on this web form, and the Least Squares regression will occur.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{lsparams};
</programlisting>
</sect2>
<sect2><title>lsreweightdir</title>
<para>
This tag converts to the direction in which the user is being prompted for a Least Squares re weighting matrix.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{lsreweightdir};
</programlisting>
</sect2>
<sect2><title>lsselect</title>
<para>
This tag will output the HTML form required for the selection of the Least Squares output. This is because each Least Squares operation produces two datasets, the data (with a Least Squares line and indication of the effect of re weighting), and the residuals dataset.
</para>

<para>
Note that if the user wants to open both datasets, then they can use the <quote>Open in new window</quote> or equivalent functionality in their web browser.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{lsselect};
</programlisting>
</sect2>
<sect2><title>matrices</title>
<para>
This tag will output the HTML that represents the list of re weighting matrices which are available. Note that matrices must end in the extension .mat to be listed.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{matrices};
</programlisting>
</sect2>
<sect2><title>motd</title>
<para>
This tag will display a welcome message to the user &mdash; the Message Of The Day (MOTD). This can be used to inform users of new datasets now being available, planned system outages, and other such informational messages.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{motd};
</programlisting>
</sect2>
<sect2><title>northplot</title>
<para>
This tag will insert the HTML and required URL for the North direction plot from the current dataset. The output of the tag will be empty if there is no currently selected dataset. The plots are 24 bit colour PNG images, as discussed in the implementation methodology section of this document.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{northplot};
</programlisting>
</sect2>
<sect2><title>upplot</title>
<para>
This tag will insert the HTML and required URL for the Up direction plot from the current dataset. The output of the tag will be empty if there is no currently selected dataset. The plots are 24 bit colour PNG images, as discussed in the implementation methodology section of this document.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{upplot};
</programlisting>
</sect2>
<sect2><title>winparams</title>
<para>
This tag will output the HTML form required for the entry of windowing processing parameters. The user will then select <quote>OK</quote> on this web form, and the windowing operation will occur.
</para>

<para>
An example usage is:
</para>

<programlisting>
&amp;{winparams};
</programlisting>
</sect2>

</sect1>
</appendix>

<appendix><title>Source code</title>
<programlisting>
#!/usr/bin/perl

# GDMS web broker
# Copyright (C) Michael Still             2002
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#  
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#  
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

# This is the broker between the GDMS code and the CGI server. It's 
# role is to parse templates, execute requests, and cache results for 
# speedy processing next time that request is seen...
use strict;
use CGI;

my($result, $command, $TEMP);

# Variables set by the config file
my($templates, $datasets, $matrices, $commandentry, $discommandentry, 
   $selectstart, $selectentry, $selectend, $plotcache, $tmpdir, 
   $rooturl, $ploturl, $gdms, $temp);

# Setup the CGI module
$result = new CGI();

# Read in the config file
eval `cat gdms.config` or die 
    "GDMSweb $$: Could not read config file: $@";
$temp = $gdms;
$temp =~ s/\/.*$//;

# Determine what page we are accessing
$command = $result-&gt;param('command');
if($command eq ""){
    $command = "main";
}

# Some pages just do some processing and then immediately redirect to 
# another page. I need to deal with these before I can display the 
# page headers
print STDERR "GDMSweb $$: Processing $command\n";
print STDERR "GDMSweb $$: Dataset is permanent\n" 
    if($result-&gt;param('intype') eq "");
print STDERR "GDMSweb $$: Dataset is temporary\n" 
    if($result-&gt;param('intype') ne "");
 
if($command eq "lsprocess"){
    $temp = "$rooturl?dataset=".$result-&gt;param('dataset')."-ls".
    $result-&gt;param('reweight');

    # If we are using manual reweighting, then we need to get more 
    # information
    if($result-&gt;param('reweight') ne "auto"){
    $temp = $temp."&amp;command=lsreweight&amp;dir=north";
    }
    else{
    $temp = $temp."&amp;command=lsselect&amp;data=".
        $result-&gt;param('dataset')."-ls".
        $result-&gt;param('reweight')."-data&amp;residuals=".
        $result-&gt;param('dataset')."-ls".
        $result-&gt;param('reweight')."-residuals";
    
    # Do the processing here
    performLs("auto");
    }

    $temp = $temp."&amp;intype=temp";

    # And now bounce of to the real page
    print STDERR "GDMSweb $$: Redirecting after automatic LS to: $temp\n";
    print $result-&gt;redirect($temp);
    exit;
}
elsif($command eq "lsprocesstwo"){
    $temp = "$rooturl?dataset=".$result-&gt;param('dataset')."-ls".
    $result-&gt;param('reweight');

    $temp = $temp."&amp;command=lsselect&amp;data=".$result-&gt;param('dataset').
    "-ls".$result-&gt;param('reweight')."-data&amp;residuals=".
    $result-&gt;param('dataset')."-ls".
    $result-&gt;param('reweight')."-residuals";
    
    # Do the processing here
    performLs($result-&gt;param('lsargs'));

    $temp = $temp."&amp;intype=temp";

    # And now bounce of to the real page
    print STDERR "GDMSweb $$: Redirecting after manual LS to: $temp\n";
    print $result-&gt;redirect($temp);
    exit;
}
elsif($command eq "windowprocess"){
    $temp = "$rooturl?dataset=".$result-&gt;param('dataset')."-win".
    $result-&gt;param('wtype')."&amp;command=plot";
    $temp = $temp."&amp;intype=temp";

    # Do the processing here
    performWindow();

    # And now bounce of to the real page
    print STDERR "GDMSweb $$: Redirecting after window to: $temp\n";
    print $result-&gt;redirect($temp);
    exit;
}
elsif($command eq "interpprocess"){
    $temp = "$rooturl?dataset=".$result-&gt;param('dataset')."-interp".
    $result-&gt;param('itype')."&amp;command=plot";

    $temp = $temp."&amp;intype=temp";

    # Do the processing here
    performInterpolation();

    # And now bounce of to the real page
    print STDERR "GDMSweb $$: Redirecting after interpolation to: $temp\n";
    print $result-&gt;redirect($temp);
    exit;
}
elsif($command eq "fftprocess"){
    $temp = "$rooturl?dataset=".$result-&gt;param('dataset').
    "-fft&amp;command=plot";

    $temp = $temp."&amp;intype=temp";

    # Do the processing here
    performFFT();

    # And now bounce of to the real page
    print STDERR "GDMSweb $$: Redirecting after FFT to: $temp\n";
    print $result-&gt;redirect($temp);
    exit;
}

# Determine if the GDMS script for this page exists already
print $result-&gt;header;
print processTemplate("$templates/$command.html");
exit;



######################################################################
# Find the template file, and then parse it
sub processTemplate(@args){
    my($file) = @_;
    my($pre, $post, $cmd, $output, $len, $line);

    # This local usage is used to make the TEMPLATE filehandle local 
    # to this subroutine...
    local *TEMPLATE;
    print STDERR "GDMSweb $$: Processing template file: $file\n";

    $output = "";
    if(!open TEMPLATE, "&lt; $file"){
    print STDERR "GDMSweb $$: $file not found\n";
    open TEMPLATE, "&lt; $templates/commandnotfound.html";
    }
    while(&lt;TEMPLATE&gt;){
    # Repeatedly process a line until there are not more template 
    # commands
    $line = $_;
    $len = -1;

    while($len != length($line)){
        $len = length($_);

        $_ = $line;
        if(/(.*)&amp;{([^%]*)};(.*)/){
        $pre = $1;
        $cmd = $2;
        $post = $3;
        
        if($cmd eq "commands"){
            # List the available commands
            $line = $pre.getCommands().$post;
        }
        elsif($cmd eq "dataset"){
            my($tempdescription);

            # The name of the current dataset
            if($result-&gt;param('dataset') ne ""){
            if($result-&gt;param('intype') ne "temp"){
                open TEMP, ("head -1 $datasets/".
                    $result-&gt;param('dataset').
                    ".dat1 |");
            }
            else{
                open TEMP, ("head -1 $tmpdir/".
                    $result-&gt;param('dataset').
                    ".dat1 |");
            }
            
            $tempdescription = "";
            while(&lt;TEMP&gt;){
                chomp;
                $tempdescription = "Filename: &lt;i&gt;".
                $result-&gt;param('dataset')."&lt;/i&gt;&lt;BR&gt;".
                $_;
            }
            close TEMP;
            $line = $pre.$tempdescription.$post;
            }
            else{
            $line = $pre.$post;
            }
        }
        elsif($cmd eq "datasets"){
            # List the datasets in the dataset directory
            my($temptotal, $tempfile);
            $temptotal = "";

            open TEMP, "find $datasets -type f -name \"*.dat1\" |";
            while(&lt;TEMP&gt;){
            my($linecount);
            $tempfile = $_;
            $tempfile =~ s/$datasets\/*//;
            $tempfile =~ s/.dat1\n$//;

            $linecount = `cat $datasets/$tempfile.dat1 | wc -l`;
            $temptotal = $temptotal.
                substHTML($selectentry, 
                      "&lt;a href=\"$rooturl?".
                      "command=plot&amp;".
                      "dataset=$tempfile\"&gt;".
                      $tempfile."&lt;\/a&gt; ".
                      "($linecount lines)");
            }
            close TEMP;
            
            $line = $pre.$temptotal.$post;
        }
        elsif($cmd eq "motd"){
            # Output a message of the day
            $line = $pre.processTemplate("$templates/motd.html").
            $post;
        }
        elsif($cmd eq "northplot"){
            # A plot in the X;
            $line = $pre.generateAndLink("x").$post;
        }
        elsif($cmd eq "eastplot"){
            # A plot in the Y direction
            $line = $pre.generateAndLink("y").$post;
        }
        elsif($cmd eq "upplot"){
            # A plot in the Z direction
            $line = $pre.generateAndLink("z").$post;
        }
        elsif($cmd eq "lsparams"){
            # Output a HTML form for the parameters of a LS 
            # regression
            $line = $pre.generateForm("lsprocess", 
                          $result-&gt;param('dataset'), 
                          "$templates/lsparams.html").
                          $post;
        }
        elsif($cmd eq "lsselect"){
            $line = $pre."&lt;a href=\"$rooturl?dataset=".
            $result-&gt;param('data').
            "&amp;command=plot&amp;intype=temp\"&gt;Data&lt;/a&gt;&lt;br&gt;".
            "&lt;a href=\"$rooturl?dataset=".
            $result-&gt;param('residuals').
            "&amp;command=plot&amp;intype=temp\"&gt;Residuals&lt;/a&gt;".
            $post;
        }
        elsif($cmd eq "lsreweightdir"){
            $line = $pre.$result-&gt;param('dir').$post;
        }
        elsif($cmd eq "winparams"){
            # Output a HTML form for the parameters of a 
            # windowing operation
            $line = $pre.generateForm("windowprocess", 
                          $result-&gt;param('dataset'), 
                          "$templates/winparams.html").
                          $post;
        }
        elsif($cmd eq "interpparams"){
            # Output a HTML form for the parameters of a
            # interpolation operation
            $line = $pre.generateForm("interpprocess", 
                          $result-&gt;param('dataset'), 
                          "$templates/interpparams.html").
                          $post;
        }
        elsif($cmd eq "matrices"){
            # List the datasets in the dataset directory
            my($temptotal, $next);
            $temptotal = "";

            if($result-&gt;param('dir') eq "north"){
            $next = "command=lsreweight&amp;dir=east";
            }
            elsif($result-&gt;param('dir') eq "east"){
            $next = "command=lsreweight&amp;dir=up";
            }
            else{
            $next = "command=lsprocesstwo&amp;lsreweight=manual";
            }

            open TEMP, "find $matrices -type f -name \"*.mat\" |";
            while(&lt;TEMP&gt;){
            chomp;
            s/$matrices//;

            $temptotal = $temptotal.
                substHTML($selectentry, 
                      "&lt;a href=\"$rooturl?$next&amp;lsargs=".
                      $result-&gt;param('lsargs').
                      "$matrices/$_,\"&gt;$_&lt;\/a&gt;");
            }
            close TEMP;
            
            $line = $pre.$temptotal.$post;
        }
        }
    }
    
    # And now we can print out the resultant line
    $output = $output.$line;
    }

    return $output;
}

# Determine what commands should be available at this time
sub getCommands(@args){
    my($output, $temp);

    $output = "";
    # If there is no current dataset
    if($result-&gt;param('dataset') eq ""){
    # Dataset open
    $output = $output.substHTML($commandentry, 
                    "&lt;a href=\"$rooturl?command=open\"&gt;Open&lt;\/a&gt;");
    
    # Maths
    $output = $output.substHTML($discommandentry, 
                    "Least squares");
    $output = $output.substHTML($discommandentry, "Windowing");
    $output = $output.substHTML($discommandentry, "Interpolation");
    $output = $output.substHTML($discommandentry, "FFT");
    }
    else{
    # Datset open
    $output = $output.substHTML($commandentry, 
                    "&lt;a href=\"$rooturl?command=open\"&gt;Open&lt;\/a&gt;");

    # Maths
    $temp = "&lt;a href=\"$rooturl?command=ls&amp;dataset=".
        $result-&gt;param('dataset');
    $temp = $temp."&amp;intype=temp" 
        if($result-&gt;param('intype') ne "");
    $temp = $temp."\"&gt;Least squares&lt;/a&gt;";
    $output = $output.substHTML($commandentry, $temp);

    $temp = "&lt;a href=\"$rooturl?command=window&amp;dataset=".
        $result-&gt;param('dataset');
    $temp = $temp."&amp;intype=temp" 
        if($result-&gt;param('intype') ne "");
    $temp = $temp."\"&gt;Windowing&lt;/a&gt;";
    $output = $output.substHTML($commandentry, $temp);

    $temp = "&lt;a href=\"$rooturl?command=interp&amp;dataset=".
        $result-&gt;param('dataset');
    $temp = $temp."&amp;intype=temp" 
        if($result-&gt;param('intype') ne "");
    $temp = $temp."\"&gt;Interpolation&lt;/a&gt;";
    $output = $output.substHTML($commandentry, $temp);

    $temp = "&lt;a href=\"$rooturl?command=fftprocess&amp;dataset=".
        $result-&gt;param('dataset');
    $temp = $temp."&amp;intype=temp" 
        if($result-&gt;param('intype') ne "");
    $temp = $temp."\"&gt;FFT&lt;/a&gt;";
    $output = $output.substHTML($commandentry, $temp);
    }

    return $output;
}

# Substitute into the HTML stub from the config file
sub substHTML(@args){
    my($html, $insert) = @_;
    my($temp);

    $temp = $html;
    $temp =~ s/%s/$insert/;
    return $temp;
}

# This subroutine deals with generating plots as required and then 
# outputs the HTML needed to link to that image
sub generateAndLink(@args){
    my($dir) = @_;
    my($file, $unique);
    local *COMMANDS;

    # Generate the filename
    $unique = "$$-".time()."-".rand();
    $file = "$plotcache/".$result-&gt;param('dataset')."-$dir.png";

    if(! -f $file){
    # We need to generate the image
    print STDERR "GDMSweb $$: Plot cache miss for ".
        $result-&gt;param('dataset')." ($dir)\n";
    open COMMANDS, "&gt; $tmpdir/gdms-$unique.cmd" or 
        die "Could not open temporary file $tmpdir/gdms-$unique.cmd\n";

    # Open the dataset. It might be in a temporary location
    if($result-&gt;param('intype') ne "temp"){
        print COMMANDS "open $datasets/".
        $result-&gt;param('dataset')."\n";
    }
    else{
        print COMMANDS "open $tmpdir/".
        $result-&gt;param('dataset')."\n";
    }

    print COMMANDS "plot $dir $file\n";
    close COMMANDS;

    # Execute the gdms main program with this command script
    `$gdms -b $tmpdir/gdms-$unique.cmd`;
    print STDERR "GDMSweb $$: GDMS execute return code is $?\n";
    }
    
    # Now link to that image
    return "&lt;img src=\"$ploturl/".$result-&gt;param('dataset').
    "-$dir.png\"&gt;";
}

# Generate a HTML form for the required paramers
sub generateForm(@args){
    my($command, $dataset, $passedform) = @_;
    my($resultstring, $DUMPFILE);

    # Start the form
    $resultstring = "&lt;form method=\"post\" action=\"$rooturl\" ";
    $resultstring = $resultstring.
    "enctype=\"application/x-www-form-urlencoded\"&gt;";
    $resultstring = $resultstring.
    "&lt;input type=\"hidden\" name=\"command\" value=\"$command\" /&gt;";
    $resultstring = $resultstring.
    "&lt;input type=\"hidden\" name=\"dataset\" value=\"$dataset\" /&gt;";
    if($result-&gt;param('intype') ne ""){
    print STDERR "Continuing temporary tag\n";
    $resultstring = $resultstring.
        "&lt;input type=\"hidden\" name=\"intype\" value=\"temp\" /&gt;";
    }

    $resultstring = $resultstring.processTemplate("$passedform");
    
    # End the form
    $resultstring = $resultstring."&lt;BR&gt;&lt;BR&gt;&lt;div align=\"center\"&gt;";
    $resultstring = $resultstring.
    "&lt;input type=\"submit\" name=\"commit\" value=\" OK \" /&gt;&lt;/div&gt;&lt;/form&gt;";

    return $resultstring;
}

# Create a dataset in the temp location which is the output of a LS 
# regression
sub performLs(){
    my($lsargs) = @_;
    my($unique);
    local *COMMANDS;

    print STDERR "GDMSweb $$: Performing LS regression\n";
    $unique = "$$-".time()."-".rand();
    open COMMANDS, "&gt; $tmpdir/gdms-$unique.cmd" or 
    die "Could not open temporary file $tmpdir/gdms-$unique.cmd\n";
    
    # Open the dataset. It might be in a temporary location
    if($result-&gt;param('intype') ne "temp"){
    print COMMANDS "open $datasets/".$result-&gt;param('dataset')."\n";
    }
    else{
    print COMMANDS "open $tmpdir/".$result-&gt;param('dataset')."\n";
    }
    
    print COMMANDS "ls $lsargs $tmpdir/".$result-&gt;param('dataset')."-ls".
    $result-&gt;param('reweight')."-data $tmpdir/".
    $result-&gt;param('dataset')."-ls".
    $result-&gt;param('reweight')."-residuals\n";
    close COMMANDS;
    
    # Execute the gdms main program with this command script
    `$gdms -b $tmpdir/gdms-$unique.cmd`;
    print STDERR "GDMSweb $$: GDMS return code is $?\n";
}

# Create a dataset in the temp location which is the output of a 
# windowing operation
sub performWindow(){
    my($unique);
    local *COMMANDS;

    print STDERR "GDMSweb $$: Performing window operation\n";
    $unique = "$$-".time()."-".rand();
    open COMMANDS, "&gt; $tmpdir/gdms-$unique.cmd" or 
    die "Could not open temporary file $tmpdir/gdms-$unique.cmd\n";
    
    # Open the dataset. It might be in a temporary location
    if($result-&gt;param('intype') ne "temp"){
    print COMMANDS "open $datasets/".$result-&gt;param('dataset')."\n";
    }
    else{
    print COMMANDS "open $tmpdir/".$result-&gt;param('dataset')."\n";
    }
    
    print COMMANDS "window ".$result-&gt;param('wtype')." ".
    $result-&gt;param('wsize')." ".$result-&gt;param('woverlap').
    " $tmpdir/".
    $result-&gt;param('dataset')."-win".$result-&gt;param('wtype')."\n";
    close COMMANDS;
    
    # Execute the gdms main program with this command script
    `$gdms -b $tmpdir/gdms-$unique.cmd`;
    print STDERR "GDMSweb $$: GDMS return code is $?\n";
}

# Create a dataset in the temp location which is the output of 
# interpolation operation
sub performInterpolation(){
    my($unique);
    local *COMMANDS;

    print STDERR "GDMSweb $$: Performing interpolation\n";
    $unique = "$$-".time()."-".rand();
    open COMMANDS, "&gt; $tmpdir/gdms-$unique.cmd" or 
    die "Could not open temporary file $tmpdir/gdms-$unique.cmd\n";
    
    # Open the dataset. It might be in a temporary location
    if($result-&gt;param('intype') ne "temp"){
    print COMMANDS "open $datasets/".$result-&gt;param('dataset')."\n";
    }
    else{
    print COMMANDS "open $tmpdir/".$result-&gt;param('dataset')."\n";
    }
    
    print COMMANDS "interp ".$result-&gt;param('itype')." ".
    $result-&gt;param('isamplerate')." $tmpdir/".
    $result-&gt;param('dataset')."-interp".$result-&gt;param('itype')."\n";
    close COMMANDS;
    
    # Execute the gdms main program with this command script
    `$gdms -b $tmpdir/gdms-$unique.cmd`;
    print STDERR "GDMSweb $$: GDMS return code is $?\n";
}

# Create a dataset in the temp location which is the output of the FFT
sub performFFT(){
    my($unique);
    local *COMMANDS;

    print STDERR "GDMSweb $$: Performing FFT\n";
    $unique = "$$-".time()."-".rand();
    open COMMANDS, "&gt; $tmpdir/gdms-$unique.cmd" or 
    die "Could not open temporary file $tmpdir/gdms-$unique.cmd\n";
    
    # Open the dataset. It might be in a temporary location
    if($result-&gt;param('intype') ne "temp"){
    print COMMANDS "open $datasets/".$result-&gt;param('dataset')."\n";
    }
    else{
    print COMMANDS "open $tmpdir/".$result-&gt;param('dataset')."\n";
    }
    
    print COMMANDS "fft $tmpdir/".
    $result-&gt;param('dataset')."-fft\n";
    close COMMANDS;
    
    # Execute the gdms main program with this command script
    `$gdms -b $tmpdir/gdms-$unique.cmd`;
    print STDERR "GDMSweb $$: GDMS return code is $?\n";
}
</programlisting>
<para><emphasis>Code: gdms.pl</emphasis></para>
</appendix>

<appendix><title>Installation</title>
<para>
To install the <command>GDMS Internet interface</command>, simply place it within your web servers CGI executable directory. Then work through the various options listed in the configuration file, and ensure that they are correct for your system. The most commonly incorrect settings are the paths to locations such as the temporary directory. These may be set to anything you desire, with the limitation that the plots directory <emphasis>must</emphasis> be accessible to the web server, as the images are served directly from this folder.
</para>

<para>
Note that no compilation of the <command>GDMS Internet interface</command> is required, as Perl is an interpreted language.
</para>

<para>
It is also important to ensure that all permissions are set correctly on the new directories to ensure that the web server remains secure. Consult your local system administrator for assistance.
</para>

</appendix>











<appendix><title>A sample configuration file</title>
<para>
This appendix details a sample configuration file for the <command>GDMS Internet interface</command>. This file should be stored in the same directory as the <command>GDMS</command> CGI script. It should also be noted that the <quote>.cep</quote> configuration file that would normally reside in a user's home directory should also be in the same directory as the <command>GDMS</command> CGI script.
</para>

<para>
The easiest way to create a suitable <quote>.cep</quote> configuration file is to run <command>GDMS</command> as any user, configure it so that you are happy with the graph output, and then copy that .cep file to the right location. Don't forget to update the permissions so that the user the web server is running as has read and write permissions on the file.
</para>

<para>
The same gdms.config file is as follows:
</para>

<programlisting>
###############################################################################
# Directories
###############################################################################

# This line defines where the templates are stored
$templates = "/home/httpd/gdms-templates/";

# This line defines where the datsets are stored
$datasets = "/home/httpd/gdms-datasets/";

###############################################################################
# HTML configuration
###############################################################################

# This line is simple HTML used for format the command entries, %s is the name
# of the command (including link HTML)
$commandentry = "&lt;tr&gt;&lt;td bgcolor=\"AAAAAA\"&gt;%s&lt;/td&gt;&lt;tr&gt;";

# This line is used for commands which aren't available...
$discommandentry = "&lt;tr&gt;&lt;td bgcolor=\"EEEEEE\"&gt;&lt;font color=\"777777\"&gt;%s&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;";

# This is used for selection lists (for instance datasets)
$selectstart = "List start";
$selectentry = "&lt;LI&gt;%s";
$selectend = "List end";

###############################################################################
# Caching configuration
###############################################################################

# This is the location of the plot cache -- it can get quite big
$plotcache = "/home/httpd/html/gdms-plots/";
$ploturl = "/gdms-plots/";

# Location for temporary files
$tmpdir = "/home/httpd/gdms-temp/";

###############################################################################
# Other
###############################################################################

# This is the root URL
$rooturl = "/cgi-bin/gdms.pl";

# This is the full path to the GDMS application
$gdms = "/home/httpd/gdmsbatch";
</programlisting>
<para><emphasis>Code: gdms.config</emphasis></para>
</appendix>
</book>

