/***********************************************************************
* 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 ;
}