home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / database / db_dump / db_dump.c next >
Encoding:
C/C++ Source or Header  |  1987-06-07  |  7.6 KB  |  277 lines

  1. /*
  2.  * These functions are used to read dbase files.
  3.  *
  4.  * These functions are provided by Valour Software as a gift.
  5.  *
  6.  * The program is for test purposes only.  No warranty is expressed nor
  7.  * implied. USE AT YOUR OWN RISK!
  8.  *
  9.  */
  10.  
  11. /* Some slight modifications by Andrew Schulman 6-7-87
  12.  * to enable, cc -DAS db_dump.c
  13.  */
  14.  
  15. #include "fcntl.h"
  16. #ifdef WIZARD
  17. #include "stdlib.h"
  18. #else
  19. #ifdef AS
  20. #include "types.h"
  21. #include "stat.h"
  22. #include "string.h"
  23. #else
  24. #include "c:\dev\msc\include\sys\types.h"
  25. #include "c:\dev\msc\include\sys\stat.h"
  26. #endif
  27. #include "io.h"
  28. #include "malloc.h"
  29. #endif
  30.  
  31. typedef  struct dbase_head {
  32.     unsigned char   version;     /*03 for dbIII and 83 for dbIII w/memo file*/
  33.     unsigned char   l_update[3];                    /*yymmdd for last update*/
  34.     unsigned long   count;                       /*number of records in file*/
  35.     unsigned int    header;                           /*length of the header
  36.                                                        *includes the \r at end
  37.                                                        */
  38.     unsigned int    lrecl;                            /*length of a record
  39.                                                        *includes the delete
  40.                                                        *byte
  41.                                                        */
  42.     unsigned char   reserv[20];
  43.     } DBASE_HEAD;
  44.  
  45. typedef struct dbase_fld {
  46.     char    name[11];                                           /*field name*/
  47.     char    type;                                               /*field type*/
  48. #define DB_FLD_CHAR  'C'
  49. #define DB_FLD_NUM   'N'
  50. #define DB_FLD_LOGIC 'L'
  51. #define DB_FLD_MEMO  'M'
  52. #define DB_FLD_DATE  'D'
  53.     /* A-T uses large data model but drop it for now */
  54. #ifdef WIZARD
  55.     char *far data_ptr;
  56. #else
  57.     char far        *data_ptr;                         /*pointer into buffer*/
  58. #endif
  59.     unsigned char   length;                                   /*field length*/
  60.     unsigned char   dec_point;                         /*field decimal point*/
  61.     unsigned char   fill[14];
  62.     } DBASE_FIELD;
  63.  
  64. typedef struct fld_list {
  65.     struct fld_list *next;
  66.     DBASE_FIELD     *fld;
  67.     char            *data;
  68.     } FLD_LIST;
  69.  
  70. DBASE_HEAD  dbhead={0};
  71. FLD_LIST    *db_fld_root=0;
  72. char        *Buffer;
  73. char        buf_work[255];
  74. int         dbfile;
  75. #ifdef AS
  76. int            first,last;
  77. #endif
  78.  
  79. /*------------------------------------------------------------code-------*/
  80. main(argc,argv)
  81. int     argc;
  82. char    *argv[];
  83. {
  84. #ifdef AS
  85.     char dbfname[50];
  86.  
  87.     if (argc < 2)
  88.         error("Usage: db_dump filename[.dbf] [count | range]");
  89.     strcpy(dbfname,argv[1]);
  90.     if (! strchr(dbfname, '.') )
  91.         strcat(dbfname, ".dbf");
  92.     dbfile=open(dbfname,O_RDONLY);
  93. #else
  94.     if(argc!=2)
  95.         error("Usage is db_dump filename.dbf");
  96.     dbfile=open(argv[1],O_RDONLY);
  97. #endif    
  98.     if(dbfile==-1)
  99.         error("Unable to open file");
  100.     db3_read_dic();
  101. #ifdef AS
  102. #define min(a,b)    ((a) < (b) ? (a) : (b))
  103. #define max(a,b)    ((a) < (b) ? (b) : (a))
  104.     /* optional second param is number of records to show OR range of
  105.      * records first-last.  Both are checked against actual number of
  106.      * records in dbhead.count.  If no second argument is supplied, the
  107.      * default is to show entire database (i.e., first = 1 and last =
  108.      * dbhead.count).
  109.      */
  110.     if ( *argv[2] && strchr(argv[2], '-') )
  111.         {
  112.         char *tmp = argv[2];
  113.         first = max(atoi(tmp), 1);
  114.         while (*tmp != '-') tmp++;            /* move to hyphen */
  115.         ++tmp;                                /* move past hyphen */
  116.         last = min(dbhead.count, atoi(tmp));
  117.         }
  118.     else
  119.         {
  120.         first = 1;
  121.         last = (*argv[2] ? min( dbhead.count, atoi(argv[2]) ) : dbhead.count);
  122.         }
  123.     db3_print_recs();
  124. #else
  125.     db3_print_recs(5);
  126.     printf("\n\n\t\t\tProcessing complete");
  127. #endif
  128.     close(dbfile);
  129.     exit(0);
  130. }
  131.  
  132.  
  133. /******************************************************
  134.                                          db3_read_dic()
  135. This function is called with a file name to
  136. read to create a record type to support the
  137. dbase file
  138. ******************************************************/
  139.  
  140. db3_read_dic()
  141. {
  142.     int             fields;
  143.     DBASE_FIELD     *fld;
  144.  
  145.     if(dbfile==-1) {
  146.         printf("open failed");
  147.         exit(200);
  148.         }
  149.     read(dbfile,&dbhead,sizeof(DBASE_HEAD));
  150.     if( !(dbhead.version==3 || dbhead.version==0x83) )
  151.         error("\n\aVersion %d not supported",dbhead.version);
  152.  
  153.     printf("update year    %3d\n",dbhead.l_update[0]);
  154.     printf("update mon     %3d\n",dbhead.l_update[1]);
  155.     printf("update day     %3d\n",dbhead.l_update[2]);
  156.     printf("number of recs %3d\n",dbhead.count);
  157.     printf("header length  %3d\n",dbhead.header);
  158.     printf("record length  %3d\n",dbhead.lrecl);
  159.     Buffer=malloc(dbhead.lrecl);
  160.  
  161.     fields=(dbhead.header-1)/32-1;
  162.     printf("\nField Name\tType\tLength\tDecimal Pos\n");
  163.     while(fields--) {
  164.         fld=(DBASE_FIELD *)malloc(sizeof(DBASE_FIELD));
  165.         if(!fld)
  166.             error("\n\aNot enough memory\n");
  167.         read(dbfile,fld,sizeof(DBASE_FIELD));
  168.         printf("%-10s\t  %c\t  %3d\t  %3d\n",fld->name,fld->type,
  169.                                      fld->length,fld->dec_point);
  170.         stack_field(fld);
  171.         }
  172.     read(dbfile,Buffer,1);              /*read the silly little \r character*/
  173.     return;
  174. }
  175.  
  176. /******************************************************
  177.                                         db3_print_recs()
  178. Read records and print the data
  179. ******************************************************/
  180.  
  181. #ifdef AS
  182. db3_print_recs()
  183. {
  184.     int bytes;
  185.     static int recno = 0;
  186.  
  187.     while (1) {
  188.         recno++;
  189.         bytes=read(dbfile,Buffer,dbhead.lrecl);
  190.         if(bytes!=dbhead.lrecl)
  191.             break;
  192.         if (recno > last)
  193.             break;
  194.         else if (Buffer[0] != '*' && recno >= first)
  195.             db3_print();
  196.         }
  197.     return;
  198. #else
  199. db3_print_recs(cnt)
  200. int     cnt;
  201. {
  202.     int     bytes;
  203.  
  204.     while(cnt) {
  205.         bytes=read(dbfile,Buffer,dbhead.lrecl);
  206.         if(bytes!=dbhead.lrecl)
  207.             break;
  208.         if(Buffer[0]!='*') {
  209.             db3_print();
  210.             cnt--;
  211.             }
  212.         }
  213.     return;
  214. #endif    
  215. }
  216.  
  217.  
  218. /******************************************************
  219.                                           db3_print()
  220. Print a single record
  221. ******************************************************/
  222.  
  223. db3_print()
  224. {
  225.     FLD_LIST    *list, *temp;
  226.  
  227.     temp=db_fld_root;
  228.     printf("\n");
  229.     while(temp) {
  230.         memcpy(buf_work,temp->data,temp->fld->length);
  231.         buf_work[temp->fld->length]='\0';
  232.         printf("%-10s=%s\n",temp->fld->name,buf_work);
  233.         temp=temp->next;
  234.         }
  235.     return;
  236. }
  237.  
  238. /******************************************************
  239.                                          stack_field()
  240. Add a field to the linked list of fields
  241. ******************************************************/
  242.  
  243. stack_field(fld)
  244. DBASE_FIELD *fld;
  245. {
  246.     FLD_LIST    *list, *temp;
  247.  
  248.     list=(FLD_LIST *)calloc(1,sizeof(FLD_LIST));
  249.     if(!list)
  250.         error("\n\aNot enough memory\n");
  251.     list->fld=fld;
  252.     if(!db_fld_root) {
  253.         list->data=Buffer+1;               /*skip delete byte*/
  254.         db_fld_root=list;
  255.         return;
  256.         }
  257.     temp=db_fld_root;
  258.     while(temp->next)
  259.         temp=temp->next;
  260.     temp->next=list;
  261.     list->data=temp->data + temp->fld->length;
  262.     return;
  263. }
  264.  
  265.  
  266. /******************************************************
  267.                                             error()
  268. Produce error msg and abort
  269. ******************************************************/
  270.  
  271. error(msg)
  272. char    *msg;
  273. {
  274.     printf(msg);
  275.     close(dbfile);
  276.     exit(255);
  277. }