home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
clipper
/
nannws22.arc
/
LCPACK.C
< prev
next >
Wrap
Text File
|
1987-12-08
|
11KB
|
412 lines
/***************************************************************/
/* lcpack.c memo file packing program */
/* for Lattice C 3.1 and Clipper */
/* Author: Don L. Powells */
/* Purpose: Function to pack .dbt files */
/* Usage: In Clipper program the function can be invoked as a */
/* User-defined Function. */
/* Example: errcode=mpack(dbf_name) */
/***************************************************************/
/* Include the necessary header files */
#include "stdio.h"
#include "string.h"
#include "fcntl.h"
#include "extend.h"
/* Define program constants */
#define DBT_EXT ".dbt"
#define DBF_EXT ".dbf"
#define SIZE 512
#define MODE 0
#define MAXFIELDS 1024
#define ONE_A '\032'
#define SPACE " "
/* Declare variables and functions*/
int fieldlen[MAXFIELDS];
int memofields[MAXFIELDS];
int offset[MAXFIELDS];
int packmem();
void reterr();
/************* Function mpack **********/
/* Purpose: Receives the parameter and checks to see if it */
/* has an extension */
void mpack()
{
char *parm;
int error;
int i;
/* CHECK to be sure that a file name was passed */
if (PCOUNT != 1 || !ISCHAR(1))
_retni(1);
/* Use Clipper Extend system to get filename off stack */
parm = _parc(1);
/* Truncate the extension off the filename if passed */
i=0;
while(parm[i] != 0L)
{
if(parm[i] == '.')
parm[i] = 0L;
++i;
}
/* Call the memo packing function and return the error code */
/* to Clipper */
error = packmem(parm);
_retni(error);
}
/************* Function packmem **********/
/* Purpose: To pack dbt files by writing only the current, */
/* usable memos to another file, updating the dbf */
/* pointers and deleting the old dbt file. */
packmem(filename)
char *filename;
{
char dbf_name[64];
char dbt_name[64];
int old_dbt;
int dbf;
int new_dbt;
unsigned char buffer[513];
int count;
long apos;
long rpos;
long reccnt;
unsigned int hdrsize;
unsigned int recsize;
int numofflds;
int numofmems;
int numflds2add;
unsigned int nextblk;
int i;
int j;
int k;
int m;
char blk_num[11];
int curr_blk;
int onea_found;
char lead_spc[10];
typedef struct
{
char sign;
char date[3];
long recc;
unsigned int data_off;
unsigned int rec_size;
char pad[20];
} DBF_HEADER;
DBF_HEADER head;
struct
{
char fieldname[11];
char field_type;
char fpad[4];
char field_len;
char field_dec;
char res_bytes[14];
}field_def;
/* Concatenate extensions to passed name */
strcpy(dbf_name,filename);
strcpy(dbt_name,filename);
strcat(dbf_name,DBF_EXT);
strcat(dbt_name,DBT_EXT);
printf("DP & Associates ");
for (i=1;i < 25;i++)
printf("\n");
printf(" Packing %s. Please wait a moment.",dbt_name);
for (i=1;i < 12;i++)
printf("\n");
/* OPEN the dbf file */
if ((dbf = open(dbf_name,O_RDWR | O_RAW)) == -1)
{
return(2);
}
/* READ first byte of the dbf file and if it is !=83H then */
/* give an error message saying this is not a dbf */
/* file with a memo field */
if ((count = read(dbf,buffer,1)) < 1)
{
/* CLOSE the dbf file */
close(dbf);
return(3);
}
else
if (buffer[0] != 0x83)
{
/* CLOSE the dbf file */
close(dbf);
return(4);
}
/* RENAME original dbt file as temp (cpackmem.bak) */
if (rename(dbt_name,"cpackmem.bak") == -1)
{
/* CLOSE the dbf file */
close(dbf);
return(5);
}
/* OPEN the temp dbt file */
if ((old_dbt = open("cpackmem.bak",O_RDONLY | O_RAW)) == -1)
{
/* CLOSE the dbf file */
close(dbf);
rename("cpackmem.bak",dbt_name);
return(6);
}
/* CREATe the new dbt file with original name */
if ((new_dbt = open(dbt_name,O_RDWR | O_TRUNC | O_RAW | O_CREAT,
S_IREAD | S_IWRITE)) == -1)
{
/* CLOSE the dbf file */
close(dbf);
rename("cpackmem.bak",dbt_name);
return(7);
}
/* READ the first 512 byte block from cpackmem.bak and WRITE */
/* to new dbt */
if ((count = read(old_dbt,buffer,SIZE)) < SIZE)
{
reterr(dbt_name);
return(8);
}
if ((count = write(new_dbt,buffer,SIZE)) < SIZE)
{
reterr(dbt_name);
return(9);
}
/***************************************************************/
/* READ the dbf header to find out how many memo fields there */
/* are and what their offsets are. */
if ((apos = lseek(dbf,0L,MODE)) == -1)
{
reterr(dbt_name);
return(10);
}
if ((count = read(dbf,(char *) &head,sizeof(head))) < 32)
{
reterr(dbt_name);
return(11);
}
/* LSEEK and READ bytes 4-7 to get number of records and store */
/* in a memory variable reccnt */
reccnt = head.recc;
/* LSEEK and READ bytes 8-9 to get the number of bytes in the */
/* header and store in a memory variable hdrsize */
hdrsize = head.data_off;
/* LSEEK and READ bytes 10-11 to get the number of bytes in */
/* the record and store in a memory variable recsize */
recsize = head.rec_size;
/* LSEEK byte 32 the first field descriptor */
rpos = 32;
if ((apos = lseek(dbf,rpos,MODE)) == -1)
{
reterr(dbt_name);
return(12);
}
numofflds = 0;
numofmems = 0;
/* READ the 32 byte field descriptor into the buffer */
if ((count = read(dbf,(char *) &field_def,sizeof(field_def)))<32)
{
reterr(dbt_name);
return(13);
}
/* WHILE buffer[1] != 0DH */
while(field_def.fieldname[0] != 0x0D)
{
/* numofflds = numofflds + 1 */
numofflds ++;
/* IF buffer[11] (fieldtype) is M */
/* INCrement numofmems */
/* add field num to */
/* memofield array {memofield[numofmems]=numofflds} */
/* ENDIF (fieldtype=M) */
if (field_def.field_type == 'M')
{
numofmems++;
memofields[numofmems] = numofflds;
}
/* LSEEK byte 16 to get field length and add to */
/* fieldlen array */
/* fieldlen[numofflds] = buffer[16] */
fieldlen[numofflds] = field_def.field_len;
/* READ the 32 byte field descriptor into the buffer */
if ((count = read(dbf,(char *) &field_def,sizeof(field_def)))
<32)
{
reterr(dbt_name);
return(14);
}
}
/********* Build offset array **********************************/
/* FOR i=1 to numofmems */
for (i=1;i<=numofmems;i++)
{
/* numflds2add = memofields[i] - 1 */
numflds2add = memofields[i] - 1;
offset[i] = 1;
/* FOR j=1 to numflds2add */
for (j=1;j<=numflds2add;j++)
{
/* offset[i] = offset[i] + fieldlen[j] */
offset[i] = offset[i] + fieldlen[j];
/* NEXT (fieldlen to add) */
}
/* NEXT (memo field) */
}
/* ******* Process memo data ***********************************/
nextblk = 1;
/* FOR i=1 to reccnt */
for (i=1;i<=reccnt;i++)
{
/* FOR j=1 to number of memo fields (numofmems) in dbf file */
for (j=1;j<=numofmems;j++)
{
/* find pointer (512 byte block#) to memo field */
/* LSEEK (hdrsize + (i-1) * recsize + offset[j]) and */
/* READ 10 bytes*/
rpos = hdrsize + (i-1) * recsize + offset[j];
apos = lseek(dbf,rpos,MODE);
blk_num[10] = '\0';
count = read(dbf,blk_num,10);
curr_blk = atoi(blk_num);
if (curr_blk != 0)
{
/* LSEEK -10 bytes and WRITE new pointer # in dbf file*/
rpos = -10;
apos = lseek(dbf,rpos,1);
sprintf(blk_num,"%d",nextblk);
if ((count = strlen(blk_num)) < 10)
{
strcpy(lead_spc,SPACE);
for (m = 1;m < (10 - count);m++)
{
strcat(lead_spc,SPACE);
}
strcat(lead_spc,blk_num);
}
strcpy(blk_num,lead_spc);
count = write(dbf,blk_num,10);
/* LSEEK proper dbt block ((pointer)* 512) */
rpos = (long) curr_blk * SIZE;
apos = lseek(old_dbt,rpos,MODE);
/* READ 512 bytes into the buffer */
count = read(old_dbt,buffer,SIZE);
/* do while not eomemo (1A1A not found) */
onea_found = 0;
do
{
/* WRITE buffer to temp file */
count = write(new_dbt,buffer,SIZE);
apos = lseek(new_dbt,0L,1);
/* increment temp file pointer # memory variable */
++nextblk;
k=0;
while(k<=512)
{
if (buffer[k] == ONE_A)
onea_found =1;
/* endo (1A1A found) */
++k;
}
/* READ 512 bytes into the buffer */
if (!onea_found)
count = read(old_dbt,buffer,SIZE);
}while(!onea_found);
}
/* NEXT J (memo field) */
}
/* NEXT I (record) */
}
/* WRITE next available block in temp dbt as */
/* pointer # memory variable + 1 */
apos = lseek(new_dbt,0L,MODE);
rpos = (long) nextblk;
count = write(new_dbt,(char *) &rpos,4);
/* */
/************* TERMINATE ***************************************/
/* CLOSE the temp dbt file */
close(new_dbt);
/* CLOSE the dbf file */
close(dbf);
/* CLOSE the original dbt file */
close(old_dbt);
/* UNLINK (delete) original dbt file */
unlink("cpackmem.bak");
/* RETURN to calling program with code 0=successful */
/* 2=file not found 4=too many files open 29=write error */
/* 30=read error */
return(0);
}
/************* Function ERRor **********/
/* Purpose:To delete new dbt and rename old dbt to */
/* itself when function can not successfully complete */
/* the packing. */
void reterr(dbt_file)
char dbt_file[64];
{
unlink(dbt_file);
rename("cpackmem.bak",dbt_file);
return;
}