home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************/
- /* 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;
- }