home *** CD-ROM | disk | FTP | other *** search
- /* Somerset Data Systems, Inc. (908) 766-5845 */
- /* Version 1.2 April 6, 1991 */
- /* Programmer: Jay Parsons */
-
- /* Note: */
-
- /****************************************************************************/
-
- #include <ctype.h>
- #include <stdio.h>
- #include <string.h>
-
- /****************************************************************************/
- /* definitions */
- /****************************************************************************/
-
- /**** **** values **** ****/
-
- #define HEADLEN 32 /* sizeof ( mainhead or thisfield ) */
- #define MEMOLEN 10 /* length of memo field in .dbf */
- #define DBFTYPE 3 /* value of bits 0 and 1 if .dbf */
- #define EOH 0x0D /* end-of-header marker in .dbf file */
-
- /**** **** data types **** ****/
-
- typedef unsigned long ulong; /* just an abbreviation */
-
- extern char file_name[], message[], tempbuff[];
-
- /* first 32 bytes of a .dbf file */
-
- typedef struct
- {
- unsigned dbf:2; /* both 1 for dBASE III or IV .dbf */
- unsigned :1;
- unsigned db4dbt:1; /* 1 if a dBASE IV-type .dbt exists */
- unsigned :3;
- unsigned anydbt:1; /* 1 if any .dbt exists */
- char filedate[3]; /* date, YYMMDD, binary. YY=year-1900 */
- ulong records; /* records in the file */
- unsigned headerlen; /* bytes in the header */
- unsigned recordlen; /* bytes in a record */
- int rsrvd1;
- char incompleteflag; /* 01 if incomplete, else 00 */
- char encryptflag; /* 01 if encrypted, else 00 */
- char rsrvd2[12]; /* for LAN use */
- char mdxflag; /* 01 if production .mdx, else 00 */
- char rsrvd3[3];
- } dbfheader;
-
- /* field descriptor of a .dbf file */
-
- typedef struct
- {
- char fname[11]; /* field name, in capitals, null filled*/
- char ftype; /* field type, C, D, F, L, M or N */
- char rsrvd4[4]; /* used in memvars, not in files. */
- unsigned char flength; /* field length */
- unsigned char decimals; /* number of decimal places */
- int rsrvd5;
- char workarea;
- char rsrvd6[10];
- char mdxfield; /* 01 if tag field in production .mdx */
- } descriptor;
-
- /**** **** function prototypes **** ****/
-
- int dbfdoc ( char *filespec );
-
- FILE * dbfopen ( char *filespec, dbfheader *buffptr );
-
- int dbfield_off ( FILE *file, char *ourfield, descriptor *buf );
-
- /****************************************************************************/
- /* dbfdoc */
- /* Principal routine of this module. Reads and returns the structure */
- /* of the file of the name passed. */
- /* Returns: */
- /* 0 if successful, 1 if any error occurs. */
- /* */
- /* This routine creates two buffers for .dbf header information. */
- /* It then calls dbfopen() to open the file, test for it being a .dbf */
- /* type and place the main header in its buffer. */
- /****************************************************************************/
-
- int dbfdoc ( char *file_name )
- {
- FILE *dbffile;
- dbfheader mainhead;
- descriptor thisfield;
- int field, fields, err;
-
- /* open file and check for .dbf type */
-
- /* must close it if opened, else not */
-
- if ( ( dbffile = dbfopen( file_name, &mainhead ) ) == NULL )
- {
- sprintf( message, "Can't open file %s.", file_name );
- return 1;
- }
- sprintf( message, "Structure of %s", strupr( file_name ) );
- printit( 0 );
- sprintf( message, "%d records, last changed ", ( int ) mainhead.records );
- sprintf ( tempbuff, "%02d/", mainhead.filedate[1] );
- strcat( message, tempbuff );
- sprintf ( tempbuff, "%02d/", mainhead.filedate[2] );
- strcat( message, tempbuff );
- sprintf ( tempbuff, "%d", mainhead.filedate[0] + 1900 );
- strcat( message, tempbuff );
- printit( 0 );
- strcpy( message, "Field Type Len Dec" );
- printit( 0 );
-
- /* do it field by field. We are at byte 32 of file */
-
- fields = ( mainhead.headerlen - 33 ) / 32;
- for ( field = 1; field <= fields; field++ )
- {
- err = fread( &thisfield, HEADLEN, 1, dbffile ) - 1;
- if ( err )
- break;
- sprintf( message, "%-11s", thisfield.fname );
- strcat( message, " " );
- *tempbuff = thisfield.ftype;
- *( tempbuff + 1 ) = '\0';
- strcat( message, tempbuff );
- sprintf( tempbuff, " %3d %2d", thisfield.flength, thisfield.decimals );
- strcat( message, tempbuff );
- printit( 0 );
- }
-
- fclose( dbffile );
- return err;
- }
-
- /****************************************************************************/
- /* dbfopen */
- /* Routine to open .dbf file. */
- /* Parameters: */
- /* char *filespec -- pointer to spec of file to open */
- /* dbfheader *buf -- pointer to dbfheader structure */
- /* Returns: */
- /* Pointer to C file control structure (to NULL if error) */
- /* Side effects: */
- /* Opens file and moves pointer to byte 32; fills buffer at buf with */
- /* first 32 bytes of file. Closes file on error. */
- /****************************************************************************/
-
- FILE *dbfopen( char *filespec, dbfheader *buf )
- {
- FILE *file;
- char *endmark;
-
- if ( ( file = fopen( filespec, "rb" ) ) == NULL )
- return NULL; /* can't open .dbf */
-
- /* read the first 32 bytes into buffer */
-
- if ( fread( buf, HEADLEN, 1, file ) != 1 )
- {
- fclose( file );
- return NULL; /* can't read 32 bytes */
- }
-
- /* check first byte to be sure .dbf type */
-
- if ( buf->dbf != DBFTYPE )
- {
- fclose( file );
- return NULL; /* not a .dbf file */
- }
-
- /* check last byte of header */
-
- if ( fseek( file, buf->headerlen - 1, SEEK_SET ) != 0 )
- {
- fclose( file );
- return NULL; /* header corrupted */
- }
- if ( fread( endmark, 1, 1, file ) != 1 )
- {
- fclose( file );
- return NULL; /* can't read end of header */
- }
- if ( *endmark != EOH )
- {
- fclose( file );
- return NULL; /* no 0Dh at end of header */
- }
- fseek( file, HEADLEN, SEEK_SET );
- return file;
- }
-
- /* EOF */
-