"Database Developer"
by Ken North
Web Techniques, November 1998

Web Techniques grants permission to use these listings (and code) for 
private or commercial use provided that credit to Web Techniques and 
the author is maintained within the comments of the source. For 
questions, contact editors@web-techniques.com. 



[LISTING ONE]


/***********************************************************************
* FILE NAME:  listruct.c     TITLE:  data base functions: list structure
*
* SYNOPSIS:  List the structure of DBF files 
************************************************************************
*                                                                        
*
* $Revision:$0.1
*
* Revision $Date: Saturday, 20 May 1989.  Time: 01:04:17.
*
* Revision History:
*   Vers. 1.0           adapted from an article by Kent Porter
*
* $Log:$
*
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include "dbase.h"                /* dBASE definitions */


void main (int argc, char *argv[])

{
FILE *fp;
unsigned version, sql, memo, nfields, n, total = 1;
HEADREC    header;
FLDDES     field;
char    *dbname;
char    *getname(int, char*);


        /* get filename */

    dbname = getname (argc, argv[1]);        /* get file name */


        /* open as binary file and read header */

    if ((fp = fopen (dbname, "rb")) == NULL)
        {
        printf ("\nERROR: Unable to open %s", dbname);
        exit (1);
        }
    else
        fread (&header, 32, 1, fp);            /* read header */
        
            /* break down ID byte */

    version = header.id & 0x07;                     /* bits 0-2 */
    sql  =       (header.id >> 3) & 0x07;           /* bits 3-5 */
    memo =       (header.id >> 6) & 0x07;           /* bits 6-7 */
    nfields = (header.headerlen -33) / 32;           /* Number fo fields */


                                /* reject non-dBASE III/IV file */
    if ((version < 3) || (version > 4))
        {
        printf ("\nERROR: %s is not a dBASE III or IV format file", dbname);
        exit (1);
        }


            /* list contents of header record */
    
    printf ("\nDatabase Structure of %s:", dbname);
    printf ("\nVersion Number                       %u", version);
    printf ("\nSQL flag                             %x", sql);
    printf ("\nMemo flag                            %x", memo);

    printf ("\nDate of last update                  %u/%u/%u",
            header.mm, header.dd, header.yy);

    printf ("\nNumber of records                    %lu",
            header.nrecs);

    printf ("\nLength of header record              %u",
            header.headerlen);

    printf ("\nData record length                   %u",
            header.reclen);

    printf ("\nIncomplete transaction?              %s",
            header.incompletexn ? "Yes" : "No");


    printf ("\nEncrypted file?                      %s",
            header.encrypted ? "Yes" : "No");

    printf ("\n\n%d DATA FIELDS:", nfields);

    printf ("\n  ID     Name      Type          Width   Dec");
            
    for (n=0; n < nfields; n++)
        {
        fread (&field, 32, 1, fp);
        total+= field.length;
        printf ("\n%5d %-11s ", n+1, field.name);
        switch (field.type)
        {
        case 'C': printf ("%-9s", "Character");     break;
        case 'D': printf ("%-9s", "Date");          break;
        case 'N': 
        case 'F': printf ("%-9s", "Numeric");       break;
        case 'L': printf ("%-9s", "Logical");       break;
        case 'M': printf ("%-9s", "Memo");          break;
        }

        printf ("    %5d", field.length); 
        if (field.decimals != 0)
            printf ("    %3d", field.decimals);

        }

    printf ("\n             Deletion marker            %5d", 1);
    printf ("\n** Total **                             %5d\n", total);
    fclose (fp);

    }


/***********************************************************************
* FUNCTION NAME: getname
*
* VERSION: Date: Saturday, 20 May 1989.  Time: 01:18:24.
*
* SYNOPSIS: get filename from command line or user
***********************************************************************/

char *getname (int argc, char *argv)
        /* get filename */
{
static char name [80];

    if (argc > 1)
        strcpy (name, argv);
    else
        {
        printf ("dBASE data base filename ? ");
        gets (name);
        puts ("\n\n");
        }
    strupr (name);            /* shift name to upper case */
    if (strstr (name, ".DBF") == NULL)
        strcat (name, ".DBF");        /* add .DBF if not present */
    return name ;
}