How to Set Up a Simple Database

with mSQL and CGI Interfaces

L. Fini
Osservatorio Astrofisico di Arcetri


Summary

In the following pages we describe a simple database used to maintain a list of the computers and related devices in use at the Osservatorio Astrofisico di Arcetri. The system is based on mSQL (a database engine provided with an SQL interface) and on HTML FORMS which fire CGI procedures on a Web server. Through the interface it is possible to search the database and add/modify data.

The latter operations are protected by a username/password mechanism.

The whole system is an assembling of various Web tools and may be of interest as a template to set up other similar applications.


Introduction

The use of Web based tool to implement client/server applications is gaining increasing success: it has even generated a new word (intranet) for applications designed for the internal use of an organization.

The main reason for such a success is due to the fact that one may concentrate the implementation efforts to the actual application while the user interface is provided by ready to use browsers.

Moreover the Web based applications are intrinsically oriented to the net and can be accessed by a variety of different clients thanks to the standard protocol HTTP.

In the following pages we describe a simple application for the management of a small database used to maintain an archive of the computing devices used at the Osservatorio di Arcetri and the Dipartimento di Astronomia e Scienza dello Spazio. The interest of it is mainly as a tutorial for the implementation of similar services.

Note: In the source code and examples all text is in English except for data to be displayed to users which is in italian. This should not prevent a full understanding of the system.

The application consists mainly of the definition of user interfaces to the various database operations needed for database management: searching, creating, modifying and deleting records.

The database engine is mSQL (briefly described below) and user interfaces are implemented as CGI procedures written in lite, the native development language provided by mSQL.

Note: For a description of CGI techniques see the on line manual: http://www.arcetri.astro.it./CC/HTMLHelp/.

What is mSQL

As the mSQL FAQ puts it:

mSQL is mini SQL, a light weight database engine developed by David J. Hughes <bambi@hughes.com.au> at Bond University, Australia. It has been designed to provide fast access to stored data with low memory requirements. As its name implies mSQL offers a subset of SQL as its query interface. Although it only supports a subset of SQL, everything it supports is in accordance with the ANSI SQL specification.

Further information can be found at the mSQL Home page:

http://www.Hughes.com.au.

The full manual is available in the distribution and on-line at the Osservatorio di Arcetri:

http://www.arcetri.astro.it/CC/mSQLman.

The Database Engine

The heart of mSQL is a process (msql2d) running on the server machine which operates on the database: a set of disk files on some disk of the server.

msql2d processes queries written in SQL received from a net link and replies with queries results.

Some auxiliary programs are also provided:

The system also includes libraries for various languages to implement specialized interfaces plus a specific language interpreter lite.

Lite is an interpreted language somewhat similar to perl, although much more limited than the latter, but with the advantage of being quite lighter and specifically designed to interface to mSQL.

The mSQL system, in fact, also provides an application (w3-msql) which is run as a CGI program on the HTTP server. w3-msql can parse files containing both usual HTML code and lite code. The HTML code is output as such to the client, while lite code is interpreted and executed. In this way CGI programs of any kind can be easily implemented.

The whole system described here has been implemented by means of this technique.

How the Database Inventario is Structured

The database consists of a number of ``tables'' managed by the mSQL server. Here follows the structure as displayed by relshow:

Database = Inventario

  +---------------------+
  |       Table         |
  +---------------------+
  | AuthList            |
  | Ditte               |
  | Enti                |
  | Tipi                |
  | Oggetti             |
  | Obsoleti            |
  +---------------------+

Here follows a description of each table:

Tables must be created initially with msqladmin, then data may be added, modified and deleted via SQL commands.

System architecture

Database management operations are divided into two groups: the first group includes database searching and browsing operations and is available to every user; the second group includes database modification operations and is reserved to authorized users. The second group is protected by an authentication mechanism described below.

 
Figure 1: Overall structure  

All the procedures are executed under the control of w3-msql. In the following sections each operation defined is described in deeper details.

Figure 1 shows the overall structure of the system. In the figure (and in all the following figures) every block represents an HTML/lite procedure resulting in an HTML page shown to the user, each arrow represents a URL link which fires the next step (for the sake of clarity only main links are shown, auxiliary links such as those used to access to help pages are not included).

index.html is the main page with links to the various parts of the system: Inventario.html, for searching; showrel.html to show the structure of the database; oldinv.html, to browse the database of obsolete devices; priv/index.html, to authenticate privileged users.

Searching

  The interface to perform searches into the database and show resulting records is shown in figure 2.

 
Figure 2: Searching interface  

The procedure is divided into the following steps:

1.
The initial procedure (Inventario.html) shows two FORMs to be used to enter the search specification: the first provides a simplified way to specify the search expression, the second one accepts a search expression in full SQL syntax.

When the "SUBMIT" button is activated form data are sent to the following step (either simplesrc.html for the simplified search or fullsrc.html for the complete one.

2.a
The procedure simplesrc.html receives the query data assembles the corresponding SQL command end sends the query to the server waiting for the reply. The reply is then formatted so that it is displayed as a checklist with one record per line.

2.b
The procedure fullsrc.html receives the query, adds a few tokens to complete the SQL command and sends the query to the server waiting for the reply. The reply is formatted as explained above.

3.
The procedure recdetails.html, gets a list of selected records and displays then in full details.

Display the database structure

The interface for database structure displaying is very simple: it is a single procedure showrel.html which simply displays the structure of tables in the database.

Data Entry and Update

The procedures needed for data entry and update are more complex because they must be protected against unauthorized use and because much programming is necessary to implement various forms of checking on the data.

In every applicable case, in fact, we present data entry fields as menus instead of fillable fields in order to force the use of standardized terms.

Every operation which modifies the database is executed only after a confirmation, and this implies a further step in the procedure.

 
Figure 3: Record Modify Interface 

We have three kind of operations which modify the database:

In figure 3 the overall structure of the modify operations is shown. Here follow a detailed description of the authentication step which is preliminary to each operation and of the operations themselves.

Authentication

The use of modification procedures is subject to the authentication of the user requesting the access. This is done by the procedure: priv/index.html which shows a FORM with two fields: username and password. User data are sent to the following step which performs the following checks:

  1. Checks username and password against the Unix password file, If the check is successful goes to check 2.
  2. Checks the username against the list of authorized users stored in table AuthList. If the check is successful goes to step 3.
  3. Checks the database LOCK file. If this file exists then someone else is modifying the database and the access is denied.

    NOTE: This locking mechanism is very rough but enough for this particular application.

    If no LOCK file exists, goes to step 4.

  4. Create a LOCK file containing a time stamp and an authorization code. The authorization code is transmitted throughout the next steps to be checked again when the database will be actually modified.

If any of the above checks fails the access to the following operations is denied.

Adding a New Record

As shown in figure 3 the insertion of a new record is performed in four steps:

1.
The procedure preselect.html displays a menu with possible device types; the user selects one of them.

2.
Procedure insertdb.html shows a FORM with various fill-in fields to describe the device. Some of these fields are in the form of single choice menus.

NOTE: Although this feature is not used here, the splitting of data input into two steps allows in the future to present different input FORMs at step 2, depending on the type of device selected at step one.

3.
The procedure confinsert.html checks the correctness of data input by the user (e.g.: some fileds must be necessarily filled). If the check is successful assembles the SQL query to insert the record into the database and requests a confirmation to the user.

4.
The procedure doinsert.html actually updates the database and sends an acknowledgment to the user.

Modifying a Record

The structure of the modify operation is similar to the insertion operation, except for the fact that the input FORM displayed is filled-in with data read from the existing record.

So the input step is preceded by a search operation very similar to the one described in section 4.1.

1.
The procedure Inventario.html displays the two alternate search FORMs.

2.
The search procedure selected at step 1 performs the search and shows the list of devices with checkboxes.

3.
The procedure recdetail.html displays the selected record in full detail with three buttons:

3.a.
CANCEL: to abort the request.

3.b.
MODIFY: to modify the record.

3.c.
DELETE: to delete the record.

To proceed with record modification the button MODIFY must be pressed.

4.
The procedure operations.html displays an input FORM with fields initialized with data read from the selected record.

5.
The procedure confupdate.html builds the SQL request and asks for confirmation.

6.
The procedure doupdate.html checks the authorization code against the code stored into the LOCK file and, if successful, updates the database.

Deleting a Record

In order to maintain knowledge of devices which are no more in use when deleting a record the record is actually moved into a database for "obsolete" devices.

The operation steps as shown in figure 3 are as follows:

1-3.
The first three steps are the same as described above for the modify procedure. When the record is displayed the button DELETE must be pressed.

4.
The procedure operations.html asks for confirmation.

5.
The procedure dodelete.html checks the authorization code against the code stored into the LOCK file and, if successful, deletes the record from the current database and writes it into the "obsolete" database.

End of Maintenance Operations

when the maintenance operations are finished, it is necessary to exit the procedure by selecting the proper link.

This operation fires the procedure endmaint.html, which deletes the LOCK file thus allowing some other user to access the update procedures.

NOTE: In order to avoid that the database can remain locked forever if a user simply exits his/her browser without following the proper exit procedure, an expiration mechanism has been implemented. Upon a request to access the privileged section, if the LOCK file is inactive since more than 30 minutes, it is deleted anyway allowing the new user to access the update procedures.

Implementation Notes

lite Libraries

When implementing the above procedures we have often used subprograms in precompiled libraries. The lite language in fact, provides support for precompiled libraries which can be included into other procedures with two advantages: 1) efficiency: the compilation step is not done at run-time; 2) Code protection: the code of the subprogram cannot be read by the user.

dblib.lite

This library gathers general procedures (mSQL functions, auxiliary functions) which may be useful for the implementation of similar applications.

invlib.lite

This library contains procedures specifically designed for this particular application (display formats, path of particular files, procedures related to the specific structure of the database, etc.)

Source Code

All the procedures described in this report together with the related libraries are included in the following pages in the approximate order and organization in which they ire quoted n the text.

Starting Procedures

index.html

<! THIS FILE IS GENERATED AUTOMATICALLY. DO NOT EDIT >
<! YOU MUST EDIT THE SOURCE FILE index.src INSTEAD   >
<! file generated from config: cfgDbg on 25/1/98 12:14:25 >

<html>
<head><title>Inventario Apparecchi di calcolo (mSQL)</title></head>

<! /* L. Fini -- Jan 1988                                        */ >

<body>


<center>

<h3>Osservatorio di Arcetri<br>
Dipartimento di Astronomia e Scienza dello Spazio</h3>


<h1>Inventario Apparecchi di Calcolo</h1>
</center>

<!++       Inizio zona da includere   >
<hr>

<blockquote>

<dl>
<dt><h2><a href=/cgi-bin/w3-msql/lfini/Inventario.html?DEBUG=1&DB=Inventario>Inventario corrente</a></h2>
<dd>
Accesso all'inventario corrente.

<dt><h2><a href=/cgi-bin/w3-msql/lfini/gen/showrel.html?DEBUG=1&DB=Inventario>Struttura</a> del database</h2>
<dd>
Mostra la struttura del database e delle tabelle.
</dl>

<hr>
<hr>
<h3> Le seguenti operazioni sono riservate al personale addetto</h3>
<dl>

<dt><h2><a href=/cgi-bin/w3-msql/lfini/priv/index.html?DEBUG=1&DB=Inventario>Modifiche</a></h2>
<dd>
Variazione di dati, inserimento nuove schede, eliminazione dall'inventario.

<dt><h2><a href=/cgi-bin/w3-msql/lfini/priv/oldinv.html?DEBUG=1&DB=Inventario&PRIV=1>Accesso</a> agli apparecchi disinventariati</h2>
<dd>
Ricerche sul database degli strumenti dismessi.
</dl>
</blockquote>
<!--       Fine zona da includere   >
</body>
</html>

oldinv.html

<html>
<head><title>Inventario Apparecchi di calcolo (mSQL)</title></head>
<body>

<!
load "../invlib.lib";


header(1,"<h1>Apparecchi Disinventariati</h1>");

$w3=w3path();
$Debug=(int)$DEBUG;

$tb = tbold();

if($Debug==1) {
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>   Table: </b>$tb\n");
    echo("DBG><b>  w3path: </b>$w3\n");
    echo("DBG><b>    PRIV: </b>$PRIV\n");
    echo("</pre>\n");
}

srcform($DB,$tb,"", "", "", $Debug);

>

</body>
</html>

showrel.html

<html>
<head><title>showrel.html - show database structure</title></head>
<body>

<!
load "../invlib.lib";   /* Osservatorio di Arcetri. Library management       */
load "../dblib.lib";    /* This module shows the structure of the database   */

            /* L.Fini. Nov 1997                                  */

header(0,"<h1>Visualizzazione struttura del database</h1>");

$tipi[1]="int";
$tipi[2]="char";
$tipi[6]="text";

$tb = tbcurr();
$to = tbold();
$Debug=(int)$DEBUG;
if($Debug==1) {
    $euid=geteuid();
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>   Table: </b>$tb\n");
    echo("DBG><b>    EUID: </b>$euid\n");
    echo("</pre>\n");
}
                    /* Get field list and build query   */
$flds = fields($DB,$tb);
$nflds= # $flds;

echo("Il database delle apparecchiature di calcolo &egrave; costituito da una\n");
echo("tabella principale di nome <b>$tb</b> contenente le schede descrittive\n");
echo("delle apparecchiature in uso ed una secondaria di nome <b>$to</b> per\n");
echo("le apparecchiature dismesse.<p> Entrambe le tabella hanno la seguente\n");
echo("struttura:\n");

echo("<blockquote>\n");
echo("<table border=2>\n");
echo("<tr><th>Nome campo<th>&nbsp;Tipo&nbsp;<th>Lungh.</tr>\n");

$i=0; 
while( $i < $nflds) {
    $fdata=split($flds[$i],",");
    $fname=$fdata[0];
    $ftype=(int)$fdata[1];
    $fleng=(int)$fdata[2];

    if($ftype>0) {
        $t=$tipi[$ftype];
        if($t=="") {
            $t=(char)$ftype;
        }
        echo("<tr><td> $fname <td> $t <td>&nbsp; $fleng</tr>\n");
    }
    $i = $i + 1;
}


>

</table>
</blockquote>

<hr>

Il database utilizza altre tabelle ausiliarie, descritte nel seguito:

<h3>Lista degli utenti autorizzati a modificare il database:</h3>

<blockquote>
<table border=2>
<tr><th>Username<th>Full name</tr>

<!

$sock=opendb($DB);

$q="select * from AuthList";

$ret= msqlQuery($sock, $q);
if ($ret < 0) {
    echo("<h2>Errore da msqlQuery</h2>");
    echo("<b>Query: </b> $q <br>");
    echo("<b>ErrMsg: </b> $ERRMSG<p>\n");
    msqlClose($sock);
    exit(1);
}
$res=msqlStoreResult();
msqlClose($sock);

$loop=1;
while($loop>0) {
    $row = msqlFetchRow($res);
    if ( # $row == 0) {
        $loop=0;
    } else {
        echo("<tr><td> $row[0] <td> $row[1] </tr>\n");
    }
}

>

</table>
</blockquote>

<h2>Lista degli Enti proprietari</h2>

<blockquote>
<table border=2>
<tr><th>&nbsp;&nbsp;&nbsp; Ente &nbsp;&nbsp;&nbsp; <th></tr>

<!

$sock=opendb($DB);

$q="select * from Enti order by item";

$ret= msqlQuery($sock, $q);
if ($ret < 0) {
    echo("<h2>Errore da msqlQuery</h2>");
    echo("<b>Query: </b> $q <br>");
    echo("<b>ErrMsg: </b> $ERRMSG<p>\n");
    msqlClose($sock);
    exit(1);
}
$res=msqlStoreResult();
msqlClose($sock);

$loop=1;
while($loop>0) {
    $row = msqlFetchRow($res);
    if ( # $row == 0) {
        $loop=0;
    } else {
        echo("<tr><td> $row[0] </tr>\n");
    }
}

>

</table>
</blockquote>

<h2>Lista delle Ditte</h2>

<blockquote>
<table border=2>
<tr><th>&nbsp;&nbsp;&nbsp; Ditta &nbsp;&nbsp;&nbsp; <th></tr>

<!

$sock=opendb($DB);

$q="select * from Ditte order by item";

$ret= msqlQuery($sock, $q);
if ($ret < 0) {
    echo("<h2>Errore da msqlQuery</h2>");
    echo("<b>Query: </b> $q <br>");
    echo("<b>ErrMsg: </b> $ERRMSG<p>\n");
    msqlClose($sock);
    exit(1);
}
$res=msqlStoreResult();
msqlClose($sock);

$loop=1;
while($loop>0) {
    $row = msqlFetchRow($res);
    if ( # $row == 0) {
        $loop=0;
    } else {
        echo("<tr><td> $row[0] </tr>\n");
    }
}

>

</table>
</blockquote>



</body>
</html>

Inventario.html

<html>
<head><title>Inventario Apparecchi di calcolo (mSQL)</title></head>
<body>

<!
load "invlib.lib";  /* Osservatorio di Arcetri. Inventory management     */
            /* this module displays a record search FORM         */

            /* L.Fini. Oct 1997                                  */

$Debug=(int)$DEBUG;
$db = dbcurr();
$tb = tbcurr();

header(0,"<h2>Ricerca schede</h2>");

srcform($db, $tb, "", "", "", $Debug);
>

</body>
</html>

Searching Procedures

simplesrc.html

<html>
<head><title>simplesrc.html - perform a search. Simplified syntax</title></head>

<!
load "../dblib.lib";    /* Osservatorio di Arcetri. Inventory management     */
load "../invlib.lib";   /* This module performs a search on the database     */
            /* after building a valid mSQL search command based  */
            /* on a few of simple specifications.                */

            /* The search expression is the logical AND of case  */
            /* insensitive string matching in any point of the   */
            /* fields: author, title, borrower etc.              */

            /* L.Fini. Oct 1997                                  */

header(0,"<h2>Risultati Ricerca</h2>");

$w3=w3path();
$Debug=(int)$DEBUG;

if($Debug==1) {
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>   Table: </b>$TB\n");
    echo("DBG><b>  w3path: </b>$w3\n");
    echo("DBG><b>  INIZIO: </b>$INIZIO\n");
    echo("DBG><b>  FORMAT: </b>$FORMAT\n");
    echo("DBG><b>    PRIV: </b>$PRIV\n");
        echo("DBG><b>    USER: </b>$USER\n");
        echo("DBG><b>   FULLN: </b>$FULLN\n");
    echo("</pre>\n");
}

$q = "select " + fdlist(1) + " from " + $TB + " where " ;

$n=0;

if($INIZIO != "") {
    $q = $q + "numero >= " + (char)$INIZIO;
    $n=1;
    $and = " AND ";
} 
if($TIPO != "") {
    $q = $q + $and + "tipo CLIKE '%" + $TIPO + "%'";
    $n=1;
    $and = " AND ";
}

if($ENTE != "") {
    $q = $q + $and + "ente CLIKE '%" + $ENTE + "%'";
    $n=1;
    $and = " AND ";
}
if($COLLOC != "") {
    $q = $q + $and + "collocazione = " + $COLLOC;
    $n=1;
    $and = " AND ";
}
if($RESP != "") {
    $q = $q + $and + "responsabile CLIKE '%" + $RESP + "%'";
    $n=1;
    $and = " AND ";
}
if($MATR != "") {
    $q = $q + $and + "matricola CLIKE '%" + $MATR + "%'";
    $n=1;
    $and = " AND ";
}
if($INV != "") {
    $q = $q + $and + "inventario CLIKE '%" + $INV + "%'";
    $n=1;
    $and = " AND ";
}
if($MOD != "") {
    $q = $q + $and + "modello CLIKE '%" + $MOD + "%'";
    $n=1;
    $and = " AND ";
}

if($n==0) {
    echo("<h2>Non hai specificato una stringa di ricerca!</h2>");
    exit(0);
}

$q = $q + " order by numero";

if((int)$LIMIT >0 ) {
    $q = $q + " limit " + $LIMIT;
}

$res= searchq($DB,$q,$Debug);

$nr=msqlNumRows($res);
echo("<h3>Trovate $nr schede</h3><hr>\n");

shrthdr($DB,$TB,$FORMAT,$Debug);    /* Stampa header per visualizzazione */

$totval=0;
$loop=1;

while($loop>0) {
    $row = msqlFetchRow($res);
    if ( # $row == 0) { 
        $loop=0;
    } else {
        $totval = $totval + viewshort($row,$FORMAT,$Debug);
    }
}

shrtftr($PRIV,$USER,$FULLN,$FORMAT,$totval);

>

</body>
</html>

fullsrc.html

<html>
<head><title>fullsrc.html - perform a search. Full mSQL syntax</title></head>
<body>

<!
load "../dblib.lib";    /* Osservatorio di Arcetri. Inventory management     */
load "../invlib.lib";   /* This module gets an msql search expression from   */
            /* a form and performs a search with the given       */
            /* espression. The output is formatted on a few      */
            /* lines and allows to select a record to be shown   */
            /* in full details.                                  */

            /* L.Fini. Nov 1997                                  */

header(0,"<h1>Risultati ricerca</h1>");

$w3 = w3path();

$Debug=(int)$DEBUG;
if($Debug==1) {
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>   Table: </b>$TB\n");
    echo("DBG><b>  w3path: </b>$w3\n");
    echo("DBG><b>  FORMAT: </b>$FORMAT\n");
    echo("DBG><b>    PRIV: </b>$PRIV\n");
        echo("DBG><b>    USER: </b>$USER\n");
        echo("DBG><b>   FULLN: </b>$FULLN\n");
    echo("</pre>\n");
}

if($SPEC == "") {
    echo("<h2>Deve essere specificato un  comando di ricerca</h2>\n");
    echo("<h3>Vedi: <a href=$w3/help.html>aiuto</a></h3>\n");
    exit(0);
}

$q = "select " + fdlist(1) + " from " + $TB + " where " + $SPEC;

$res= searchq($DB,$q, $Debug);

$nr=msqlNumRows($res);

echo("<h3>Trovate $nr schede</h3><hr>\n");

$loop=1;
$totval=0;
shrthdr($DB,$TB,$FORMAT,$Debug);    /* Stampa header per visualizzazione */

while($loop>0) {
    $row = msqlFetchRow($res);
    if ( # $row == 0) { 
        $loop=0;
    } else {

        $totval = $totval + viewshort($row,$FORMAT,$Debug);

        viewshort($row,$FORMAT,$Debug);
    }
}

shrtftr($PRIV,$USER,$FULLN,$FORMAT,$totval);

>

</body>
</html>

recdetail.html

<html>
<head><title>recdetail.html - Show a record in full detail</title></head>
<body>
<html>

<!
load "../dblib.lib";    /* Osservatorio di Arcetri. Library management       */
load "../invlib.lib";   /* L.Fini. Oct 1997                                  */

            /* This shows the full content of a record           */

funct privmode(char $db,
               char $Rowid,
               char $Priv,
               char $User,
               char $Fulln,
               char $Debug)
{
$w3=w3path();

echo("</pre><form action=$w3/priv/operations.html>\n");
echo("<b>Operazioni consentite</b>:<blockquote> \n");
echo("<input type=hidden name=DB value=$db>\n");
echo("<input type=hidden name=ROWID value=$Rowid>\n");
echo("<input type=hidden name=PRIV value=$Priv>\n");
echo("<input type=hidden name=USER value=$User>\n");
echo("<input type=hidden name=FULLN value=\"$Fulln\">\n");
echo("<input type=hidden name=DEBUG value=$Debug>\n");
echo("<input type=submit name=OPER value=MODIFICA> : ");
echo("Modifica informazioni nella scheda<br>\n");
echo("<input type=submit name=OPER value=ELIMINA> : ");
echo("Elimina apparecchiatura dall'Inventario<br>\n");
echo("<input type=submit name=OPER value=ANNULLA> : ");
echo("Annulla modifica e torna alla selezione funzioni<br>\n");
echo("</blockquote></form>\n");
}


header(0,"<h1>Dettaglio schede</h1>");

$Debug=(int)$DEBUG;
$rwtype = typeof($ROWID);
if($Debug==1) {
    echo("<pre>\n");
    echo("DBG><b>   Rowid: </b>");
    if($rwtype=="array") {
        $i=0; $n = # $ROWID;
        while($i<$n) {
            echo("$ROWID[$i],");
            $i++;
        }
    } else {
        echo($ROWID);
    }
    echo("\n");
    echo("DBG><b>    PRIV: </b>$PRIV\n");
        echo("DBG><b>    USER: </b>$USER\n");
        echo("DBG><b>   FULLN: </b>$FULLN\n");
    echo("</pre>\n");
}

if(# $ROWID == 0) {
    printf("<h2>Nessuna scheda selezionata!</h2>\n");
    exit(0);
}


$i=0; $n = # $ROWID;

if($rwtype=="array") {
    while($i<$n) {
        $row = viewrec($DB,$TB,(int)$ROWID[$i],$PRIV,$Debug);
        if($PRIV != "") {
            privmode($DB,$ROWID[$i],$PRIV,$USER,$FULLN,$DEBUG);
        }
        $i++;
    }
} else {
    $row = viewrec($DB,$TB,(int)$ROWID,$PRIV,$Debug);
    if($PRIV != "") {
        privmode($DB,$ROWID,$PRIV,$USER,$FULLN,$DEBUG);
    }
}

>

</body>
</html>

Data Entry Procedures

priv/index.html

<html>
<head><title>index.html - Access to privileged functions</title></head>
<body>

<!
load "../invlib.lib";   /* Osservatorio di Arcetri. Library management       */
load "../dblib.lib";    /* L.Fini. Oct 1997                                  */

            /* This module request username and password for     */
            /* user authentication                               */

header(1,"<h1>Accesso ad operazioni sul database</h1>");

$www=w3path();
$html=htmlpath();
$Debug=(int)$DEBUG;
if($Debug==1) {
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>  w3path: </b>$www\n");
    echo("DBG><b>htmlpath: </b>$html\n");
    echo("</pre>\n");
}


echo("<h3>Per procedere occorre identificarsi con <i>username</i> e <i>password</i>:</h3>\n");
echo("<form action=./privindex.html method=post>\n");
echo("<input type=hidden name=DB value=$DB>\n");
echo("<blockquote><h4><pre>\n");
echo("Username: <input type=text name=id size=10><br>\n");
echo("Password: <input type=password name=id size=10> &nbsp;&nbsp; ");
echo("<input type=submit value=INVIO>");
if($Debug==1) {
    echo("<input type=hidden name=DEBUG value=1>\n");
}

echo("</h4></blockquote>\n");
echo("</form>\n");

>

</body>
</html>

privindex.html

<html>
<head><title>privindex.html - Check user identification</title></head>
<body>

<! 

load "../invlib.lib";   /* Osservatorio di Arcetri. Gestione inventario      */
load "../dblib.lib";    /* L.Fini. Oct 1997                                  */

            /* This module checks username and password and      */
            /* creates the lock file with authorization token    */

            /* Then displays a selection of allowed operations   */


header(1,"<h1>Selezione operazione sul database</h1>");

$w3=w3path();
$Debug=(int)$DEBUG;
if($Debug==1) {
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>  w3path: </b>$w3\n");
    echo("DBG><b>    PRIV: </b>$PRIV\n");
    if($PRIV != "") {
        echo("DBG> Iteration\n");
        echo("DBG><b>    USER: </b>$USER\n");
        echo("DBG><b>   FULLN: </b>$FULLN\n");
    } else {
        echo("DBG> First entry\n");
        echo("DBG><b>Username: </b>$id[0]\n");
    }
    echo("</pre>\n");
}


if($PRIV=="") {             /* here the first time it's called   */
    $User=$id[0];
    $passw=$id[1];

    $pwf=getpwnam($User);

    if(# $pwf != 7) { Fail($DB,403); }  /* cannot get user password  */

    $sign=strseg($pwf[1],0,1);

    $cpw=crypt($passw,$sign);

    if($cpw != $pwf[1]) { Fail($DB,104); }  /* illegal password          */

    $cmd="select name from AuthList where username = '$User'";
    $res=searchq($DB,$cmd,$Debug);

    $row = msqlFetchRow($res);

    if(# $row == 0) { Fail($DB,105); }  /* User not in authorization */
                        /* list                      */

    $Fulln=$row[0];

    $file=w3userdir() + "/" + $DB + ".lock";    /* make filename     */

    if(test("f",$file) == 1) {  /* Lock file exists. Get user name   */
        $fd=open($file,"<");
        $usr=readln($fd);
        $usr=chop($usr);
        $fuln=readln($fd);
        $fuln=chop($fuln);
        $rtm=readln($fd);
        $rtm=readln($fd);
        $rtm=chop($rtm);
        $tm = (int)$rtm;
        $life=time() - $tm;
        close($fd);
        if($Debug==1) {
            echo("<pre>\n");
            echo("DBG> Lockfile --\n");
            echo("DBG>      User: $usr\n");
            echo("DBG> Full Name: $fuln\n");
            echo("DBG>  Timelock: $rtm \n");
            echo("DBG>      Life: $life sec\n");
            echo("</pre>");
        }
        if(# $rtm>0) {
            if($usr != $User) { /* database in use by someone */

                if($life > 1800) {  /* But time expired   */
                    unlink($file);
                } else {
                    echo("<H3>Data base occupato da: $line</h3>\n");
                    echo("<H4>Riprova piu' tardi</h4>\n");
                    exit(0);
                }
            }
            
        } else {
            if(test("f",$file)==1) {
                fatal("<H3>Internal locking error</h3>\n");
            }
        }
    }
} else {            /* Here when called after previous operation */
    ChkPriv($DB,$PRIV,$USER,$FULLN);
    $User=$USER;
    $Fulln=$FULLN;
}

$Priv=resetlock($DB,$User,$Fulln);
$pargs=privargs($DB,$Priv,$User,$Fulln,$DEBUG);
echo("<blockquote>\n");
echo("<h3>\n");
echo("<ul>\n");
echo("<li> <a href=$w3/priv/updatedb.html?$pargs>Modifica/Cancellazione</a> di schede esistenti<p>\n");

echo("<li> <a href=$w3/priv/preselect.html?$pargs>Inserimento </a>di nuove schede<p>\n");
echo("<li> <a href=$w3/priv/modtables.html?$pargs>Modifica</a> tabelle ausiliarie<p>\n");
echo("<li> <a href=$w3/priv/endmaint.html?$pargs>Fine</a> procedure<p>\n");
echo("</ul>\n");
echo("</h3>\n");
echo("</blockquote>\n");

>

</body>
</html>

preselect.html

<html>
<head><title>preselect.html - Seleziona tipo record</title></head>
<body>

<!
load "../invlib.lib";   /* Osservatorio di Arcetri. Library management       */
load "../dblib.lib";    /* L.Fini. Oct 1997                                  */

            /* This module displays a FORM for device type       */
            /* selection.                                        */

header(1,"<h1>Preselezione tipo apparecchio</h1>");

$w3=w3path();
$html=htmlpath();
$Debug=(int)$DEBUG;
if($Debug==1) {
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>  w3path: </b>$w3\n");
    echo("DBG><b>htmlpath: </b>$html\n");
    echo("DBG><b>    PRIV: </b>$PRIV\n");
    echo("DBG><b>    USER: </b>$USER\n");
    echo("DBG><b>   FULLN: </b>$FULLN\n");
    echo("</pre>\n");
}
                    /* Get field list and build query   */

echo("<form method=POST action=$w3/priv/insertdb.html>\n");
echo("<h3>Scegliere il tipo di Apparecchiatura e premere ");
echo("<input type=hidden name=DB value=$DB>\n");
echo("<input type=submit value=Invio>.</h3>\n");
echo("<input type=hidden name=PRIV value=$PRIV>\n");
echo("<input type=hidden name=USER value=$USER>\n");
echo("<input type=hidden name=FULLN value=\"$FULLN\">\n");
echo("<input type=hidden name=DEBUG value=$Debug>\n");
echo("<blockquote><b>\n");

selecttable($DB,"Tipi",10,"TIPO","",$Debug);

echo("</b></blockquote>\n");
echo("</form>");
>
</body>
</html>

insertdb.html

<html>
<head><title>insertdb.html - Insert new records</title></head>
<body>

<!
load "../invlib.lib";   /* Osservatorio di Arcetri. Library management       */
load "../dblib.lib";    /* L.Fini. Oct 1997                                  */

            /* This module generates the data entry FORM.        */


header(1,"<h1>Modulo inserimento dati</h1>");
$w3=w3path();
$html=htmlpath();
$tb=tbcurr();
$Debug=(int)$DEBUG;
if($Debug==1) {
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>  w3path: </b>$w3\n");
    echo("DBG><b>htmlpath: </b>$html\n");
    echo("DBG><b>    Tipo: </b>$TIPO\n");
    echo("DBG><b>    PRIV: </b>$PRIV\n");
    echo("DBG><b>    USER: </b>$USER\n");
    echo("DBG><b>   FULLN: </b>$FULLN\n");
    echo("</pre>\n");
}
                    /* Get field list and build query   */

$Num = getnext($DB,$tb,"numero", $Debug);


echo("<form method=POST action=$w3/priv/confinsert.html>\n");
echo("<input type=hidden name=DB value=$DB>\n");
echo("<h3>Inserire i dati richiesti e premere ");
echo("<input type=hidden name=PRIV value=$PRIV>\n");
echo("<input type=hidden name=USER value=$USER>\n");
echo("<input type=hidden name=FULLN value=\"$FULLN\">\n");
echo("<input type=hidden name=DEBUG value=$Debug>\n");
echo("<input type=submit value=Invio>.</h3>\n");
echo("<table>");

echo("<table>");

echo("<tr valign=center><td><b>Numero</b> ");
echo("<td><input type=hidden name=NUM value=$Num>$Num</tr>\n");
echo("<tr valign=center><td><b>Tipo</b> ");
echo("<td><input type=hidden name=TIPO value=\"$TIPO\">$TIPO</tr>\n");

echo("<tr valign=center><td><b>Costruttore </b> ");
echo("<td>");
selecttable($DB,"Ditte",5,"COST","",$Debug);
echo("</tr>\n");

echo("<tr valign=center><td><b>Venditore </b> ");
echo("<td>");
selecttable($DB,"Ditte",5,"VEND","",$Debug);
echo("</tr>\n");

echo("<tr valign=center><td><b>Modello</b> ");
    echo("<td><input type=text size=40 name=MOD></tr>\n");

echo("<tr valign=center><td><b>Descrizione </b> ");
    echo("<td><input type=text size=40 name=DESC></tr>\n");

echo("<tr valign=center><td><b>Matricola </b> ");
    echo("<td><input type=text size=25 name=MATR></tr>\n");

echo("<tr valign=center><td><b>Valore </b> ");
    echo("<td><input type=text size=10 name=VAL> (Lire)</tr>\n");

echo("<tr valign=center><td><b>Ente </b> ");
echo("<td>");
selecttable($DB,"Enti",1,"ENTE","Oss.Arcetri",$Debug);
echo("</tr>\n");

echo("<tr valign=center><td><b>N. Inventario </b> ");
    echo("<td><input type=text size=15 name=INV></tr>\n");

echo("<tr valign=center><td><b>Collocazione </b> ");
    echo("<td><input type=text size=4 name=COLL> (N. stanza come da ");
    echo("<a href=$html/mappe/Mappe.html>mappe</a>))</tr>\n");

echo("<tr valign=center><td><b>Responsabile </b> ");
    echo("<td><input type=text size=15 name=RESP></tr>\n");

$tm = time();
$yr=unixtime2year($tm);
$mo=unixtime2month($tm);
$dy=unixtime2day($tm);

echo("<tr valign=center><td><b>Data </b> ");
    echo("<td><input type=text size=2 value=$dy name=DD> / ");
    echo("<input type=text size=2 value=$mo name=MM> / ");
    echo("<input type=text size=4 value=$yr name=YY></tr>\n");

echo("<tr valign=center><td><b>Nome di rete </b> ");
    echo("<td><input type=text size=15 name=NRET></tr>\n");

echo("<tr valign=center><td><b>Principale </b> ");
    echo("<td><input type=text size=15 name=PRIN></tr>\n");


echo("<tr valign=center><td><b>Commenti </b> ");
    echo(" <td><textarea cols=60 rows=3 name=COMM></textarea></tr>\n");


echo("</table></form>\n");
>
</body>
</html>

confinsert.html

<html>
<head><title>confinsert.html - Confirm insertion</title></head>
<body>

<!
load "../invlib.lib";   /* Osservatorio di Arcetri. Library management       */
load "../dblib.lib";    /* This module ask for confirmation of record        */
            /* insertion                                         */

            /* L.Fini. Oct 1997                                  */


funct lacking(char $fname, int $c)
{
if($c<1) {
echo("<h2>Dati di ingresso incompleti</h2>\n");
echo("<h3>Mancano le seguenti informazioni obbligatorie:</h3><blockquote>\n");
}
echo("<h4>$fname</h4>\n");
}

header(1,"<h1>Conferma inserimento scheda</h1>");

$w3=w3path();
$html=htmlpath();
$tb = tbcurr();
$Debug=(int)$DEBUG;
if($Debug==1) {
   echo("<pre>\n");
   echo("DBG><b>Database: </b>$DB\n");
   echo("DBG><b>   Table: </b>$tb\n");
   echo("DBG><b>  w3path: </b>$w3\n");
   echo("DBG><b>htmlpath: </b>$html\n");
   echo("DBG><b>    PRIV: </b>$PRIV\n");
   echo("DBG><b>    USER: </b>$USER\n");
   echo("DBG><b>   FULLN: </b>$FULLN\n");
   echo("</pre>\n");
}
                    /* Get field list and build query   */
$c=0;

if($TIPO == "") { lacking("Tipo",$c); $c=1; }
if($COST == "") { lacking("Costruttore",$c); $c=1; }
if($VEND == "") { lacking("Venditore",$c); $c=1; }
if($MOD == "") { lacking("Modello",$c); $c=1; }
if($VAL == "") { lacking("Valore",$c); $c=1; }
if($ENTE == "") { lacking("Ente",$c); $c=1; }
if(($DD == "")||($MM == "")||($YY == "")) { lacking("Data",$c); $c=1; }
if($COLL == "") { lacking("Collocazione",$c); $c=1; }
if($RESP == "") { lacking("Responsabile",$c); $c=1; }

$pargs=privargs($DB,$PRIV,$USER,$FULLN,$DEBUG);

if($c==1) {
    echo("</blockquote><hr>\n");
    echo("Puoi usare il bottone <b>Back</b> del browser per tornare alla pagina\n");
    echo("precedente ed aggiungere le informazioni mancanti.\n");
    exit(0);
}

echo("<b>Se non voui proseguire puoi \n");
echo("<a href=$w3/priv/privindex.html?$pargs>tornare</a> alla selezione delle operazioni<p>\n");

$q = "insert into " + $tb + " values (\n ";

$tm = time();

$yr=unixtime2year($tm);
$mo=unixtime2month($tm);
$dy=unixtime2day($tm);

$catdate=encdata($dy,$mo,$yr);

$q = $q + $NUM + ",\n ";
$q = $q + chrEncode($TIPO) + ",\n ";
$q = $q + chrEncode($COST) + ",\n ";
$q = $q + chrEncode($VEND) + ",\n ";
$q = $q + chrEncode($MOD) + ",\n ";
$q = $q + chrEncode($DESC) + ",\n ";
$q = $q + chrEncode($MATR) + ",\n ";
$q = $q + chrEncode($VAL) + ",\n ";
$q = $q + chrEncode($ENTE) + ",\n ";
$q = $q + chrEncode($INV) + ",\n ";
$q = $q + chrEncode($COLL) + ",\n ";
$q = $q + chrEncode($RESP) + ",\n ";
$q = $q + chrEncode((char)$catdate) + ",\n ";
$q = $q + chrEncode($NRET) + ",\n ";
$q = $q + chrEncode($PRIN) + ",\n ";
$q = $q + chrEncode($COMM) + ",\n ";
$q = $q + chrEncode($FULLN) + ",\n ";
$q = $q + chrEncode((char)$catdate) + "\n)\n";

$q = dblEncode($q);

echo("<h2>Query:</h2><blockquote><h3><pre>\n");
echo($q);
echo("</pre></h3></blockquote>\n");
echo("<form method=POST action=$w3/priv/doinsert.html>\n");
echo("<input type=hidden name=DB value=$DB>\n");
echo("<input type=HIDDEN name=DEBUG value=$Debug>\n");
echo("<input type=HIDDEN name=PRIV value=$PRIV>\n");
echo("<input type=HIDDEN name=USER value=$USER>\n");
echo("<input type=HIDDEN name=FULLN value=\"$FULLN\">\n");
echo("<input type=HIDDEN name=ROWID value=$ROWID>\n");
echo("<input type=HIDDEN name=QUERY value=\"$q\">\n");
echo("Per inserire il record premere:");
echo("<input type=SUBMIT value=CONFERMA>\n");
echo("</form>\n");

echo("<h3>Se non vuoi inserire il record ");
echo("<a href=$w3/priv/privindex.html?$pargs>torna</a> alla selezione funzioni.</h3>\n");
>
</body>
</html>

doinsert.html

<html>
<head><title>doinsert.html - Actually insert a record</title></head>
<body>
<!
load "../invlib.lib";   /* Osservatorio di Arcetri. Inventory management     */
load "../dblib.lib";    /* L.Fini. Oct 1997                                  */

            /* This module performs an insertion into the        */
            /* database.                                         */

            /* Input variables:                                  */

            /* $QUERY:  operation to perform (mSQL syntax)       */

header(1,"<h1>Inserimento scheda</h1>");
$Debug=(int)$DEBUG;
$w3=w3path();
if($Debug==1) {
    $uid=geteuid();
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>     UID: </b>$uid\n");
    echo("DBG><b>  w3path: </b>$w3\n");
    echo("DBG><b>   QUERY: </b>$QUERY\n");
    echo("DBG><b>    PRIV: </b>$PRIV\n");
    echo("DBG><b>    USER: </b>$USER\n");
    echo("DBG><b>   FULLN: </b>$FULLN\n");
    echo("</pre>\n");
}

ChkPriv($DB,$PRIV,$USER,$FULLN);

$ret=plaincmd($DB,$QUERY,$Debug);

if($ret>=0) {
    echo("<h3>Nuovo record correttamente inserito</h3>\n");
} else {
    echo("<h3>Il record NON &egrave; stato inserito !</h3>\n");
}

$pargs=privargs($DB,$PRIV,$USER,$FULLN,$DEBUG);
echo("<blockquote>\n");
echo("<h3>Torna alla pagina <a href=$w3/priv/privindex.html?$pargs>selezione funzioni</a></h3>\n");
echo("</blockquote>\n");

>

</body>
</html>

Data Update Procedures

operations.html

<html>
<head><title>operations.html - Perform operations on database</title></head>
<body>
<!
load "../invlib.lib";   /* Osservatorio di Arcetri. Library management       */
load "../dblib.lib";    /* L.Fini. Oct 1997                                  */

            /* This module gets operation request (MODIFY, or    */
            /* DELETE) and prepares the related query            */



                    /************************************/
funct modify(char $db,          /* Modify a record                  */
             int $Rowid,
             char $Priv,
             char $User,
             char $fulln,
             int $Debug)
{
$w3=w3path();
$tb=tbcurr();
                    /* Get field list and build query   */
$flds = fields($db,$tb);
$nflds= # $flds;

$i=0; 
$nnflds=0;
$q = "select"; $s=" ";
while( $i < $nflds) {
    $fdata=split($flds[$i],",");
    if(($fdata[0] != "redazione")&&($fdata[0] != "data_red")) {
        $fname[$i]=$fdata[0];
        $ftype[$i]=(int)$fdata[1];
        $fleng[$i]=(int)$fdata[2];

        $q = $q + $s + $fdata[0];
        $s=",";
        $nnflds=$nnflds + 1;
    }
    $i=$i + 1;
}

$row = getrec($db,$tb,$Rowid,$Debug,$q);

$pargs=privargs($db,$Priv,$User,$fulln,(char)$Debug);
echo("<b>Per interrompere la modifica tornare alla pagina\n");
echo("<a href=$w3/priv/privindex.html?$pargs>");
echo(" selezione funzioni</a>.</b><hr>\n");

echo("<form method=POST action=$w3/priv/confupdate.html>\n");
echo("<b>Modificare i dati nei campi sottostanti e quindi premere ");
echo("<input type=submit value=Invio>.</b><p>\n");
echo("<input type=hidden name=DB value=$db>\n");
echo("<input type=hidden name=ROWID value=$Rowid>\n");
echo("<input type=hidden name=PRIV value=$Priv>\n");
echo("<input type=hidden name=USER value=$User>\n");
echo("<input type=hidden name=FULLN value=\"$fulln\">\n");
echo("<input type=hidden name=DEBUG value=$Debug>\n");

echo("<table>");

echo("<tr valign=center><td><b>_rowid:</b> ");
echo("<td>$Rowid<br>\n");

$i=0;
while( $i<$nnflds) {
    if($ftype[$i] > 0) {
        printf("<input type=hidden name=NAMES value=\"%s\">\n",$fname[$i]);
        printf("<input type=hidden name=TYPES value=%d>\n",$ftype[$i]);
        printf("<input type=hidden name=LENGS value=%d>\n",$fleng[$i]);
        printf("<tr valign=center><td><b>%s:</b> ",$fname[$i]);
    }
    if($ftype[$i]==6) {
        printf(" <td><textarea cols=60 rows=3 name=VALUES>$row[$i]</textarea><br>\n");
    }
    if($ftype[$i] == 1) {
        if($fname[$i]=="numero"){
                echo("<td> $row[$i]<input type=hidden name=VALUES value=\"$row[$i]\"><br>\n");
        } else {
                echo("<td><input type=text size=10 name=VALUES value=\"$row[$i]\"><br>\n");
        }
    } 
    if($ftype[$i] == 2) {
            $sz=(int)$fleng[$i];
            echo("<td><input type=text size=$sz name=VALUES value=\"$row[$i]\"<br>\n");
    }
    $i = $i + 1;
}

echo("</table></form>");
return(1);
}

                    /************************************/
funct delete(char $db,          /* deletes a record (Actually moves */
             int $Rowid,        /* it into the "Obsolete" table)    */
             char $Priv,
             char $User,
             char $fulln,
             int $Debug)
{
$w3=w3path();
$tb=tbcurr();
$tbold=tbold();
$row = getrec($db,$tb,$Rowid,$Debug,"");    /* Get record               */
$flds = fields($db,$tb);            /* Get field list           */

if(# $row<2) {
    return(0);
}


$tm = time();
$yr=unixtime2year($tm);
$mo=unixtime2month($tm);
$dy=unixtime2day($tm);
$catdate=encdata($dy,$mo,$yr);

$d = "DELETE FROM " + $tb + 
     " WHERE _rowid=" + (char)$Rowid + "\n";    /* prepare delete query     */

$s = " ";
$i=0; 
$nflds= # $flds;

$q = "INSERT INTO " + $tbold + " VALUES\n(\n";  /* prepare insertion query  */
while( $i < $nflds) {
    $fdata=split($flds[$i],",");
    $val=$row[$i];
    if($fdata[0] == "redazione") {
        $val=$fulln;
    }
    if($fdata[0] == "data_red") {
        $val=(char)$catdate;
    }
    if($fdata[0] != "_rowid") {
        if((int)$fdata[1]==1) {
            $q = $q + $s + $val;
        } else {
            $q = $q + $s + chrEncode($val);
        }
        $s=",\n ";
    }
    $i=$i + 1;
}

$q = $q + "\n)\n";

$q = dblEncode($q);

$pargs=privargs($db,$Priv,$User,$fulln,(char)$Debug);
echo("<b>Per interrompere la cancellazione tornare alla pagina\n");
echo("<a href=$w3/priv/privindex.html?$pargs>");
echo(" selezione funzioni</a>.</b><hr>\n");

echo("<form method=POST action=$w3/priv/dodelete.html>\n");
echo("<b>Se vuoi eleminare la seguente scheda dall'inventario premi ");
echo("<input type=submit value=CONFERMA>.</b><p>\n");
echo("<input type=hidden name=DB value=$db>\n");
echo("<input type=hidden name=ROWID value=$Rowid>\n");
echo("<input type=hidden name=PRIV value=$Priv>\n");
echo("<input type=hidden name=USER value=$User>\n");
echo("<input type=hidden name=FULLN value=\"$fulln\">\n");
echo("<input type=hidden name=DEBUG value=$Debug>\n");
echo("<input type=hidden name=QUERY1 value=\"$d\">\n");
echo("<input type=hidden name=QUERY2 value=\"$q\">\n");

$row = printrec($row);

echo("</form>");

return(1);
}



$w3=w3path();
$Debug=(int)$DEBUG;
if($Debug==1) {
    echo("<pre>\n");
    echo("DBG><b> Database: </b>$DB\n");
    echo("DBG><b>   w3path: </b>$w3\n");
    echo("DBG><b>    Rowid: </b>$ROWID\n");
    echo("DBG><b>Operation: </b>$OPER\n");
    echo("DBG><b>     PRIV: </b>$PRIV\n");
    echo("DBG><b>     USER: </b>$USER\n");
    echo("DBG><b>    FULLN: </b>$FULLN\n");
    echo("</pre>\n");
}

$Rowid=(int)$ROWID;

if($ROWID == "") {
    echo("<h2>Internal error: No record selected.!</h2>\n");
    exit(0);
}

$stat=0;

if($OPER=="MODIFICA") {
    header(1,"<h1>Modifica scheda</h1>");
    $stat=modify($DB,$Rowid,$PRIV,$USER,$FULLN,$Debug);
}

if($OPER=="ELIMINA") {
    header(1,"<h1>Elimina scheda</h1>");
    $stat=delete($DB,$Rowid,$PRIV,$USER,$FULLN,$Debug);
}

if($OPER=="ANNULLA") {
    header(1,"<h1>Operazione Annullata</h1>");
    $pargs=privargs($DB,$PRIV,$USER,$FULLN,(char)$Debug);
    echo("<h3>Torna alla pagina ");
    echo("<a href=$w3/priv/privindex.html?$pargs>");
    echo(" selezione funzioni</a>.</h3><hr>\n");
    $stat=1;

}

if($stat != 1) {
    header(1,"<h1>Richiesta illegale: $OPER</h1>");
}

>

</body>
</html>

confupdate.html

<html>
<head><title>confupdate.html - Requires confirmation for modif. op.</title></head>
<body>

<!
load "../invlib.lib";   /* Osservatorio di Arcetri. Inventory management     */
load "../dblib.lib";    /* L.Fini. Oct 1997                                  */

            /* This module receives a modification requests,     */
            /* build the UPDATE SQL query and asks for confir-   */
                        /* mation                                            */

            /* Input variables:                                  */

            /* $ROWID: _rowid of record to modify                */
            /* $NAMES: array of field names                      */
            /* $TYPES: array of field types                      */
            /* $LENGS: array of field lengths                    */
            /* $VALUE: array of field values                     */

header(1,"<h1>Conferma aggiornameto scheda</h1>");
$w3=w3path();
$html=htmlpath();
$tb = tbcurr();
$Rowid=(int)$ROWID;
$Debug=(int)$DEBUG;
if($Debug==1) {
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>   Table: </b>$tb\n");
    echo("DBG><b>  w3path: </b>$w3\n");
    echo("DBG><b>htmlpath: </b>$html\n");
    echo("DBG><b>   Rowid: </b>$Rowid\n");
    echo("DBG><b>    PRIV: </b>$PRIV\n");
    echo("DBG><b>    USER: </b>$USER\n");
    echo("DBG><b>   FULLN: </b>$FULLN\n");
    echo("</pre>\n");
}

if((char)$ROWID == "") {
    printf("<h2>Internal error: No record selected.!</h2>\n");
    exit(0);
}

$tm = time();
$yr=unixtime2year($tm);
$mo=unixtime2month($tm);
$dy=unixtime2day($tm);

$moddate=encdata($dy,$mo,$yr);

$nflds=# $NAMES;

$q = "update " + $tb + " set\n\n";
$s=" ";

$i=0;
while($i<$nflds) {
    if((int)$TYPES[$i]==1) {        /* Campo numerico                  */
        $v=(int)$VALUES[$i];
        $q=$q + $s + $NAMES[$i] + "=" + (char)$v;
    } else {                /* Campo alfanumerico              */
        $q=$q + $s + $NAMES[$i] + "=" + chrEncode($VALUES[$i]);
    }
    $i=$i + 1; $s = ",\n ";
}

$q = $q + $s + "redazione=" + chrEncode($FULLN) + 
               ",\n data_red=" + chrEncode((char)$moddate) +
               "\n\nwhere _rowid=" + $ROWID;

$q = dblEncode($q);

echo("<h2>Query:</h2><blockquote><h3><pre>\n");
echo($q);
echo("</pre></h3></blockquote>\n");
echo("<form method=POST action=$w3/priv/doupdate.html>\n");
echo("<input type=hidden name=DB value=$DB>\n");
echo("<input type=HIDDEN name=ROWID value=$ROWID>\n");
echo("<input type=HIDDEN name=PRIV value=$PRIV>\n");
echo("<input type=HIDDEN name=USER value=$USER>\n");
echo("<input type=HIDDEN name=FULLN value=\"$FULLN\">\n");
echo("<input type=HIDDEN name=DEBUG value=$Debug>\n");
echo("<input type=HIDDEN name=QUERY value=\"$q\">\n");

echo("Per confermare la modifica premere: ");
echo("<input type=SUBMIT value=CONFERMA>\n");
echo("</form>\n");

$pargs=privargs($DB,$PRIV,$USER,$FULLN,$DEBUG);
echo("<h3>Annulla modifica e ");
echo("<a href=$w3/priv/privindex.html?$pargs>torna</a> alla selezione funzioni</h3>\n");
>

</body>
</html>

doupdate.html

<html>
<head><title>doupdate.html - Actually update a record</title></head>
<body>

<!
load "../invlib.lib";   /* Osservatorio di Arcetri. Inventory management     */
load "../dblib.lib";    /* L.Fini. Oct 1997                                  */

            /* This module performs an UPDATE operation on the   */
            /* database.                                         */

            /* Input variables:                                  */

            /* $QUERY:  operation to perform (mSQL syntax)       */
            /* $ROWID:  _rowid of the record (for double check)  */

header(1,"<h1>Aggiornamento scheda</h1>");
$Debug=(int)$DEBUG;
$w3=w3path();
if($Debug==1) {
    $uid=geteuid();
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>     UID: </b>$uid\n");
    echo("DBG><b>  w3path: </b>$w3\n");
    echo("DBG><b>   ROWID: </b>$ROWID\n");
    echo("DBG><b>   QUERY: </b>$QUERY\n");
    echo("DBG><b>    PRIV: </b>$PRIV\n");
    echo("DBG><b>    USER: </b>$USER\n");
    echo("DBG><b>   FULLN: </b>$FULLN\n");
    echo("</pre>\n");
}

ChkPriv($DB,$PRIV,$USER,$FULLN);

$ret=plaincmd($DB,$QUERY, $Debug);

if($ret>=0) {
    echo("<h3>La scheda &egrave; stata aggiornata</h3>\n");
} else {
    echo("<h3>L' operazione NON &Egrave; STATA ESEGUITA</h3>\n");
}

$pargs=privargs($DB,$PRIV,$USER,$FULLN,$DEBUG);
echo("<blockquote>\n");
echo("<h3><a href=$w3/priv/privindex.html?$pargs>");
echo("Torna </a> alla selezione funzioni</h3>\n");
echo("</blockquote>\n");
>

</body>
</html>

Delete Procedures

dodelete.html

<html>
<head><title>dodelete.html - Actually delete a record</title></head>
<body>

<!
load "../invlib.lib";   /* Osservatorio di Arcetri. Inventory management     */
load "../dblib.lib";    /* L.Fini. Oct 1997                                  */

            /* This module performs a delete query               */
            /* (The query is built elsewhere and is sent as an   */
                        /* argument)                                         */

            /* Input variables:                                  */

            /* $QUERY:  operation to perform (mSQL syntax)       */
            /* $ROWID:  _rowid of the record (for double check)  */

header(1,"<h1>Eliminazione scheda dall'inventario</h1>");

$Debug=(int)$DEBUG;
$w3=w3path();
if($Debug==1) {
    $uid=geteuid();
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$DB\n");
    echo("DBG><b>     UID: </b>$uid\n");
    echo("DBG><b>  w3path: </b>$w3\n");
    echo("DBG><b>   ROWID: </b>$ROWID\n");
    echo("DBG><b>  QUERY1: </b>$QUERY1\n");
    echo("DBG><b>  QUERY2: </b>$QUERY2\n");
    echo("DBG><b>    PRIV: </b>$PRIV\n");
    echo("DBG><b>    USER: </b>$USER\n");
    echo("DBG><b>   FULLN: </b>$FULLN\n");
    echo("</pre>\n");
}

ChkPriv($DB,$PRIV,$USER,$FULLN);

$ret=plaincmd($DB,$QUERY1, $Debug);
if($ret<0) {
    echo("<h3>Il record non &egrave; stato cancellato</h3>\n");
} else {
    echo("<h3>Il record &egrave; stato cancellato</h3>\n");
    $ret=plaincmd($DB,$QUERY2, $Debug);
    if($ret<0) {
        echo("<h3>Il record NON &Egrave; STATO TRASFERITO !!</h3>\n");
    } else {
        echo("<h3>Il record &egrave; stato trasferito</h3>\n");
    }
}

$pargs=privargs($DB,$PRIV,$USER,$FULLN,$DEBUG);
echo("<blockquote>\n");
echo("<h3>Torna alla pagina <a href=$w3/priv/privindex.html?$pargs>selezione funzioni</a></h3>\n");
echo("</blockquote>\n");

>

</body>
</html>

Libraries

invlib.lite

/* THIS FILE IS GENERATED AUTOMATICALLY. DO NOT EDIT */
/* YOU MUST EDIT THE SOURCE FILE invlib.src INSTEAD   */
/* file generated from config: cfgDbg on 26/1/98 9:18:51 */


                                /* L. Fini -- Jan 1988                    */

                /******************************************/
funct w3path()          /* Returns full file path as seen by      */
                /* w3-msql                                */
{
return("/cgi-bin/w3-msql/lfini");
}

                /******************************************/
funct htmlpath()        /* Returns file path as seen by the http  */
{               /* server                                 */
return("http://www.arcetri.astro.it/~lfini/nINV");
}

                /******************************************/
funct w3userdir()       /* Returns the path of the "w3user" own   */
{               /* directory (to store the lockfile)      */
return("/tmp");
}

                /******************************************/
funct dbcurr()          /* Returns the name of the database       */
{               /*                                        */
return("Inventario");
}
                /******************************************/
funct tbold()           /* Returns the name of the obsolete device*/
{               /* table                                  */
return("Obsoleti");
}
                /******************************************/
funct tbcurr()          /* Returns the name of the current device */
{               /* table                                  */
return("Oggetti");
}


                /******************************************/
funct fdlist(int $sel)      /* Returns a list of main table fields    */
                /* If: sel=(-1) doesn't include add-on    */
                /*     fields                             */
                /* If: sel=0 includes add-on fields       */
                /* If: sel=1 includes the _rowid field    */
{
if($sel==(-1)) {
    $r= "numero,tipo,costruttore,venditore,modello,descrizione,matricola,valore,ente,inventario,collocazione,responsabile,data,nome_di_rete,principale,commenti";
}
if($sel==0) {
    $r= "numero,tipo,costruttore,venditore,modello,descrizione,matricola,valore,ente,inventario,collocazione,responsabile,data,nome_di_rete,principale,commenti" + "," + "redazione,data_red";
}
if($sel==1) {
    $r= "_rowid," + "numero,tipo,costruttore,venditore,modello,descrizione,matricola,valore,ente,inventario,collocazione,responsabile,data,nome_di_rete,principale,commenti" + "," + "redazione,data_red";
} 
return($r);
}



                /******************************************/
funct fmtnorm() {       /* Returns format string for short list 1 */
return("%-3s %-8s %-10s %-8s %-6s %-4s  %4s %2d/%2d/%4d %-12s\n");
}

                /******************************************/
funct fmtval() {        /* Returns format string for short list 2 */
return("%-3s %-8s %-16s %-10s %5s %6d %-6s %2d/%4d %s\n");
}


                /******************************************/
funct header(int $s,        /* Prints out an HTML header with a sub-  */
             char $subtit)  /* title.                                 */
{               /* If s=1 also prints "privileged op"     */
                /*        warning                         */
echo("<center>\n");
echo("<h3>Osservatorio di Arcetri<br>\n");
echo("Dipartimento di Astronomia e Scienza dello Spazio</h3>\n");
echo("<h2>Inventario Apparecchi di Calcolo</h2>\n");
echo($subtit);
if($s==1) {
    echo("<h3>L'uso di queste procedure &egrave; riservato al personale autorizzato</h3>\n");
}
echo("</center><hr><br>\n");
}


                /******************************************/
funct shrthdr(char $db,     /* Prints out the header for short record */
              char $tb,     /* listing                                */
              char $fmt,
              int $Debug)
{
echo("<form method=post action=recdetail.html>\n");
echo("<input type=hidden name=DB value=$db>\n");
echo("<input type=hidden name=TB value=$tb>\n");
echo("<input type=HIDDEN name=DEBUG value=$Debug>\n");

if($fmt == "N") {
    $hd1 = "<pre><b>" +
           "  Numero   Costruttore         Matrico. Ente   Num. Colloc.\n";
    $hd2 = "       Tipo         Modello             Prop.  Inv.         Data     Nome rete</b>\n";
} 
if($fmt == "V") {
    $hd1 = "<pre><b>" +
           " Numero    Costruttore                           Num. Valore Ente           Nome\n";
    $hd2 = "       Tipo         Modello          Matricola   Inv.  x1000 Prop.   Data   di rete</b>\n";
}

echo($hd1);
echo($hd2);
}


                /******************************************/
funct shrtftr(char $Priv,   /* Prints out the footer for short record */
              char $User,   /* listing                                */
              char $Fulln,
              char $fmt,
              int $totval)
{
if($fmt == "V") {
    printf("\n<b>Valore totale (Lire x 1000) ......................... %6d\n",$totval);
}
echo("</pre>\n");

echo("<hr>\n");
echo("Per visualizzare i dati completi, seleziona uno o pi&ugrave; record\n");
echo("e premi: <input type=submit value=INVIO>\n");
if($Priv != "") {
    echo("<input type=HIDDEN name=PRIV value=$Priv>\n");
    echo("<input type=HIDDEN name=USER value=$User>\n");
    echo("<input type=HIDDEN name=FULLN value=\"$Fulln\">\n");
}
echo("</form>\n");
}


                /******************************************/
funct viewshort(char $row,  /* Prints out a single record in short    */
                char $FORMAT,   /* format                                 */
                int  $Debug)    /* FORMAT may be one of "N" (normal form.)*/
{               /*        or "V" (format with value)      */
$w3=w3path();

printf("<input type=checkbox name=ROWID value=%d>%4d ",(int)$row[0],(int)$row[1]);
$data=dcdata($row[13]);

if(# $row[2]>3) { $row[2]=strseg($row[2],0,2); }
if(# $row[3]>8) { $row[3]=strseg($row[3],0,7); }

if($FORMAT=="N") {
    $fmt=fmtnorm();
    if(# $row[5]>10)  { $row[5]=strseg($row[5],0,9); }
    if(# $row[7]>8)   { $row[7]=strseg($row[7],0,7); }
    if(# $row[9]>6)   { $row[9]=strseg($row[9],0,5); }
    if(# $row[10]>4)  { $row[10]=strseg($row[10],0,3); }
    if(# $row[11]>4)  { $row[11]=strseg($row[11],0,3); }
    if(# $row[14]>12) { $row[14]=strseg($row[14],0,11); }

    printf($fmt,$row[2], $row[3], $row[5],
           $row[7],$row[9], $row[10],$row[11], 
           $data[0], $data[1], $data[2], $row[14]);
    $val1000=0;
}
if($FORMAT=="V") {
    $fmt=fmtval();
    $val1000 = ((int)$row[8] + 500) / 1000; 
    if(# $row[5]>16) { $row[5]=strseg($row[5],0,15); }
    if(# $row[7]>10) { $row[7]=strseg($row[7],0,9); }
    if(# $row[6]>6)  { $row[6]=strseg($row[6],0,5); }
    if(# $row[9]>6)  { $row[9]=strseg($row[9],0,5); }
    if(# $row[10]>4) { $row[10]=strseg($row[10],0,3); }

    printf($fmt,$row[2],        /* tipo                   */
           $row[3], $row[5],        /* costruttore, modello   */
           $row[7], $row[10],       /* matricola, inventario  */
           $val1000, $row[9],       /* valore, ente           */
           $data[1], $data[2],      /* data                   */
           $row[14]);           /* nome di rete           */
}
return($val1000);
}


                /******************************************/
funct viewrec(char $db,     /* Prints out a record in full format     */
              char $tb,     /* reads the record from the database     */
              int $Rowid,
              char $Priv, 
              int $Debug)
{
$row = getrec($db,$tb,$Rowid,$Debug,"");
if(# $row > 0) {
    printrec($row);
}
}



                /******************************************/
funct printrec(char $row)   /* Prints out a record in full format     */
                        /* Record data are in array $row          */
{
$html=htmlpath();

$data=dcdata($row[13]);
$rdat=dcdata($row[18]);

$i=0;

printf("<center><font size=+1>\n");
printf("<h2>Record N. %s</h2></center>\n",$row[1]);
printf("<pre>");
printf("             Tipo:<b> %s</b>\n",$row[2]);
printf("      Costruttore:<b> %s</b>\n",$row[3]);
printf("        Venditore:<b> %s</b>\n",$row[4]);
printf("          Modello:<b> %s</b>\n",$row[5]);
printf("      Descrizione:<b> %s</b>\n",$row[6]);
printf("        Matricola:<b> %s</b>\n",$row[7]);
printf("           Valore:<b> %s</b>\n",$row[8]);
printf("Ente Proprietario:<b> %s</b>\n",$row[9]);
printf("  Num. Inventario:<b> %s</b>\n",$row[10]);
printf("     Collocazione:<b> %s</b>  ",$row[11]);
echo("(Vedi: <a href=$html/mappe/Mappe.html>mappe</a>)\n");
printf("     Responsabile:<b> %s</b>\n",$row[12]);
printf("             Data:<b> %2d/%2d/%4d</b>\n",$data[0],$data[1],$data[2]);
printf("     Nome_di_rete:<b> %s</b>\n",$row[14]);
printf("       Principale:<b> %s</b>\n",$row[15]);
printf("         Commenti:<b> %s</b>\n",$row[16]);
printf("Scheda redatta da:<b> %s (%2d/%2d/%4d)</b>\n",$row[17],$rdat[0],$rdat[1],$rdat[2]);

printf("<hr></pre>\n");

return(1);
}

                /******************************************/
funct srcform(char $db,     /* Prints out the FORM for record search  */
              char $tb,     /* inventario                             */
              char $Priv,   /*                                        */
              char $User,   /*                                        */
              char $Fulln,  /*                                        */
              int $Debug)   /*                                        */
{
$w3=w3path();
if($Debug==1) {
    echo("<pre>\n");
    echo("DBG><b>Database: </b>$db\n");
    echo("DBG><b>   Table: </b>$tb\n");
    echo("DBG><b>  w3path: </b>$w3\n");
    echo("DBG><b>    PRIV: </b>$Priv\n");
    echo("DBG><b>    USER: </b>$User\n");
    echo("DBG><b>   FULLN: </b>$Fulln\n");
    echo("</pre>\n");
}


echo("<form method=POST action=$w3/gen/simplesrc.html>\n");
echo("<h2>Ricerca Semplice &nbsp; &nbsp; &nbsp; &nbsp; \n");
echo(" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\n");
echo(" <input type=submit value=trova></h2>\n");

echo("<input type=hidden name=DEBUG value=$Debug>\n");
echo("<input type=hidden name=DB value=$db>\n");
echo("<input type=hidden name=TB value=$tb>\n");
if($Priv != "") {
    echo("<input type=hidden name=PRIV value=$Priv>\n");
    echo("<input type=hidden name=USER value=$User>\n");
    echo("<input type=hidden name=FULLN value=\"$Fulln\">\n");
}
echo("<pre>\n");
echo("<strong>dal Numero:</strong><input type=text size=5 value=1 name=INIZIO>");
echo("   <strong>Num.schede:</strong><input type=text size=5 value=30 name=LIMIT>");
echo("      <strong>Matricola:<input type=text size=10 name=MATR>\n");

echo("      <strong>Tipo:</strong><input type=text size=5 name=TIPO> ");
echo("        <strong>Ente:</strong><input type=text size=10 name=ENTE>");
echo("   <strong>Invent.:</strong><input type=text size=5 name=INV>\n");
echo("    <strong>Stanza:</strong><input type=text size=5 name=COLLOC>");
echo("     <strong>Respons.:</strong><input type=text size=10 name=RESP>");
echo("   <strong>Modello:</strong><input type=text size=10 name=MOD>\n\n");

echo("</pre>\n");

echo("Tipo di stampa: <input type=radio name=FORMAT checked value=N>Normale\n");
echo("<input type=radio name=FORMAT value=V>Con valore\n");
echo("</form>\n");

echo("<hr>\n<form method=POST action=$w3/gen/fullsrc.html>\n");

echo("<input type=hidden name=DEBUG value=$Debug>\n");
echo("<input type=hidden name=DB value=$db>\n");
echo("<input type=hidden name=TB value=$tb>\n");

echo("<h2>Ricerca completa</h2>\n");

echo("Specificare un comando di ricerca mSQL (<a href=$w3/gen/help.html>aiuto</a>).\n");
echo("Quindi premere &lt;return&gt;.\n");
echo("<input type=text size=80 name=SPEC><br>\n");
echo("Tipo di stampa: <input type=radio name=FORMAT checked value=N>Normale\n");
echo("<input type=radio name=FORMAT value=V>Con valore\n");
echo("</form>\n");
}

dblib.lite

/* dblib.lite    Vers. 1.0  -- L.Fini, Jan 1998                              */

/* Utility functions for database manipulation                               */





                /*********************************************/
funct chrEncode(char $str)  /* Returns msqlencoded and quoted string     */
{
$r= "'" + msqlEncode($str) + "'";
return($r);
}

                /*********************************************/
funct dblEncode(char $str)  /* converts '"' into &quot;                  */
{
$spl = split($str,"\"");
$n=# $spl;
$i=0;
$q=""; $r="";
while($i<$n) {
    $r = $r + $q + $spl[$i];
    $i = $i + 1;
    $q = "&quot;";
}
return($r);
}
        

                /******************************************/
funct privargs(char $db,    /* Builds arguments for a URL to call     */
               char $Priv,  /* privindex.html with method GETS        */
               char $User,
               char $Fulln,
               char $Debug)
{
$prv=urlEncode($Priv);
$usr=urlEncode($User);
$fln=urlEncode($Fulln);
$dbn=urlEncode($db);

$str="DEBUG=" + $Debug + "&DB=" + $dbn;
if($Priv != "") {$str = $str +  "&PRIV=" + $prv; }
if($User != "") {$str = $str +  "&USER=" + $usr; }
if($Fulln != "") {$str = $str + "&FULLN=" + $fln; }

return($str);

}

                /******************************************/
funct writechk(char $file,  /* Writes the check file (lockfile)       */
               char $uname, /* Username                               */
               char $fulln, /* Ful name of user                       */
               char $priv,  /* Authorization token                    */
               int  $tm)    /* Time                                   */
{
umask(077);         /* make it readable by myself only        */
$fd=open($file,">");

if($fd<0) {
        echo("<H3>Cannot open file $file (Err: $ERRMSG)</h3>\n");
        exit(0);
}

fprintf($fd,"%s\n",$uname);
fprintf($fd,"%s\n",$fulln);
fprintf($fd,"%s\n",$priv);
fprintf($fd,"%d\n",$tm);

close($fd);

}


                /******************************************/
funct resetlock(char $db,   /* Write a new lockfile                   */
                char $uname,
                char $fulln)
{
$file=w3userdir() + "/" + $db + ".lock";    /* Generate the filename  */
$tm=time();
srandom($tm);
$rd=random();
$priv=crypt((char)$rd,"LF");            /* Generate authorization token   */

writechk($file,$uname,$fulln,$priv,$tm);    /*   write Author. file   */
return($priv);
}


                /******************************************/
funct Fail(char $db,        /* Return an error message and code       */
           int $code)           /* when access to privileged functions is */
{               /* denied                                 */
$w3=w3path();
echo("<h2>Accesso al database '$db' negato ! (codice:$code)</h2>\n");
echo("<blockquote><h3><a href=$w3/priv/index.html?DB=$db>Ritorna</a>");
echo(" al controllo di accesso</h3></blockquote>\n");
exit(0);
}



                /******************************************/
funct ChkPriv(char $db,     /* Check authorization code               */
              char $priv,
              char $uname,
              char $fulln)
{
$w3=w3path();
$file=w3userdir() + "/" + $db + ".lock";    /* Generate the filename  */

if(test("f",$file) == 0) {
    Fail($db,401);      /* lock file doesn't exist                */
}

$fd=open($file,"<");

if($fd<0) {
    Fail($db,402);      /* Cannot read from lock file              */
}

$runame=readln($fd); $runame=chop($runame);
$rfulln=readln($fd); $rfulln=chop($rfulln);
$rpriv=readln($fd);  $rpriv=chop($rpriv);
$rtm=readln($fd);    $rtm=chop($rtm);

close($fd);

if(($priv != $rpriv)||($uname != $runame)) {
    if($uname != $runame) {
        echo("<h2>Database currently locked by: $fulln</h2>\n");
        Fail($db,101);  /* Database locked by other user           */
    } else {
        unlink($file);
        Fail($db,102);  /* Authorization code check failed         */
    }
}

$tm = (int)$rtm;
$life=time() - $tm;

if($life > 1800) {
    unlink($file);
    echo("<h2>Time expired. Operation is canceled</h2>");
    Fail($db,103);      /* Time expired                             */
}

}
                /******************************************/
                /* Decode date from internal fmt (integer)*/
funct dcdata(char $dbdata)  /* returns a three elemnt array:          */
                /*     dd[0]=day                          */
                /*     dd[1]=month                        */
                /*     dd[2]=year                         */
{
$dd[0]=(int)strseg($dbdata,6,7);
$dd[1]=(int)strseg($dbdata,4,5);
$dd[2]=(int)strseg($dbdata,0,3);

return($dd);
}


                /******************************************/
                /* Encode date to internale fmt (integer) */
funct encdata(int $day,     /*                                        */
              int $month,
              int $year)    /* $data = $year*10000+$month*100+$day    */
{
$dt= $year * 10000;
$dt= $dt + ($month * 100);
$dt= $dt + $day;

return($dt);
}


                /******************************************/
funct opendb(char $dbname)  /* Opens the specified database for access*/
{
$sock=msqlConnect();
if($sock < 0) {
    echo("<h2>msql2d non risponde</h2>");
    exit(1);
}

if(msqlSelectDB($sock, $dbname) < 0) {
    echo("<h2>Errore da msqlSelectDB($dbname): $ERRMSG<h2>\n");
    msqlClose($sock);
    exit(1);
}
return($sock);
}



                /******************************************/
funct getrec(char $db,      /* Gets record with specified _rowid      */
             char $tb,      /* from a specified database and table    */
             int $Rowid,
             int $Debug,
             char $q    )   /* if $q=="" the full query is built by   */
                /*           this subprogram.             */
                /* if $q=="select row1,row2,...,rowN"     */
                /*           this part is used in the     */
                                /*           query to select specified    */
                /*           fields                       */
{
$sock=opendb($db);

if($q == "") {
    $q = "select " + fdlist(1);
}

$q = $q + " from " + $tb + " where _rowid=" + (char)$Rowid;

if($Debug==1) {
    printf("<p><pre><b>Query: </b>%s</pre><p><hr>\n",$q);
}

if (msqlQuery($sock, $q) < 0) {
        echo("<h2>Errore da msqlQuery</h2>");
    echo("<b>Query: </b> $q <br>");
    echo("<b>ErrMsg: </b> $ERRMSG<p>\n");
        msqlClose($sock);
        exit(1);
}

$res=msqlStoreResult();
$row = msqlFetchRow($res);
msqlClose($sock);

if ( # $row == 0) { 
    echo("<h2>Errore Interno</h2>");
    echo("Il record (_rowid: $Rowid) non esiste nel database!");
    exit(1);
}

$i=1;           /* This loop is to transform NULL fields into ""    */
while($i<# $row) {
    $row[$i]=(char)$row[$i];
    $i=$i + 1;
}
return($row);
}


                /******************************************/
funct searchq(char $db,     /* Sends a search query                   */
              char $cm,
              int  $Debug)
{
$sock=opendb($db);
if($Debug==1) {
    echo("<pre>DBG>Entered searchq\n");
    echo("DBG> <b>Database: </b> $db \n");
    echo("DBG> <b>   Query: </b> $cm \n</pre>\n");
}
$ret= msqlQuery($sock, $cm);
if ($ret < 0) {
    echo("<h2>Errore da msqlQuery</h2>");
    echo("<b>Query: </b> $cm <br>");
    echo("<b>ErrMsg: </b> $ERRMSG<p>\n");
    msqlClose($sock);
    exit(1);
}

$ret=msqlStoreResult();

msqlClose($sock);
return($ret);
}


                /******************************************/
funct plaincmd(char $db,    /* Sends the specified SQL command        */
               char $cm,    /* The db is openend end then closed      */
               int $Debug)
{
$sock=opendb($db);

if($Debug==1) {
    echo("<pre>DBG>Entered plaincmd\n");
    echo("DBG> <b>Database: </b> $db \n");
    echo("DBG> <b>   Query: </b> $cm \n</pre>\n");
}
$ret= msqlQuery($sock, $cm);
if ($ret < 0) {
    echo("<h2>Errore da msqlQuery</h2>");
    echo("<b>Query: </b> $cm <br>");
    echo("<b>ErrMsg: </b> $ERRMSG<p>\n");
}

msqlClose($sock);
return($ret);
}


                /******************************************/
funct docommand(char $db,   /* Sends the specified SQL query appending*/
                char $rowid,    /* the proper "where" clause              */
                char $cmd,
                int $Debug)
{
if($rowid == "") {
    printf("<h2>Internal error: No record selected.!</h2>\n");
    exit(0);
}

$q=$cmd + " where _rowid=" + $rowid;

$ret=plaincmd($db,$q,$Debug);
return($ret);
}

                /******************************************/
funct selecttable(char $db,     /* Prints out an HTML menu of type SELECT */
                  char $tbname, /* getting data from the specified table  */

                  int  $lng,    /* Length of the menu field               */
                  char $pname,  /* name of the HTML argument              */
                  char $slctd,  /* name of a field to be "selected"       */
                  int  $Debug)
{
$q="select item from " + $tbname + " order by item";
$res=searchq($db,$q,$Debug);

$n = # $selected - 1;

$loop=1;

echo("<select name=$pname size=$lng>\n");
while($loop>0) {
    $row = msqlFetchRow($res);
    if ( # $row == 0) {
        $loop=0;
    } else {
    $s="";
    if($n>=0) {
        if(strseg($row[0],0,$n) == $slctd) {
            $s="selected";
        }
    }
        echo("<option $s>$row[0]</option>\n");
    }
}
echo("</select>\n");
}


                /******************************************/
funct getnext(char $db,     /* Get the next free record number        */
              char $tb,
              char $fd,     /* name of the field containing rec.numb. */
              int  $Dbg) 
{
    
$q = "select " + $fd + " from " + $tb + " order by " + $fd + " desc limit 1";

$res=searchq($db,$q,$Dbg);
$row = msqlFetchRow($res);
$n = (int)$row[0] + 1;

return($n);
}



                /******************************************/
funct fields(char $db,      /* Analize structure of the given table   */
             char $tb)      /* Returns array with elements containing:*/
{               /*                                        */
                /* "name,type,length" (comma separated)   */
                /* (type=0: _rowid)                       */

$sock=opendb($db);
$res=msqlInitFieldList ($sock,$tb);
$field = msqlListField($res);

$fld[0]="_rowid,0,0";

$i=1;
while( # $field > 0) {
    if(($field[2]==1)||($field[2]==2)||($field[2]==6)) {
        $ty = $field[2];
        $fld[$i] = $field[0] + "," + (char)$ty + "," + (char)$field[3];
        $i=$i + 1;
    }
    $field = msqlListField($res);
}

msqlClose($sock);
return($fld);
}

About this document ...

This document was generated using the LaTeX2HTML translator Version 96.1 (Feb 5, 1996) Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.

The command line arguments were:
latex2html -split 0 -external_images -html_version 3.1 techdeteng.

The translation was initiated by Luca Fini on Thu Feb 26 16:40:52 MET 1998


Luca Fini
Thu Feb 26 16:40:52 MET 1998