summaryrefslogtreecommitdiff
path: root/ext/dbase/dbf_head.c
diff options
context:
space:
mode:
authorStig Bakken <ssb@php.net>1999-04-19 13:56:50 +0000
committerStig Bakken <ssb@php.net>1999-04-19 13:56:50 +0000
commit6094128afeacfa87d35d1246610a3010654b052f (patch)
tree369d029066cf2a735b6a638b94d4bdc529b6c373 /ext/dbase/dbf_head.c
parentb515f34dd1d5956aeb758cc3f636c183c8adcc73 (diff)
downloadphp-git-6094128afeacfa87d35d1246610a3010654b052f.tar.gz
moved dbase into ext/ along with the bundled library
dbase programs are no longer included
Diffstat (limited to 'ext/dbase/dbf_head.c')
-rw-r--r--ext/dbase/dbf_head.c261
1 files changed, 261 insertions, 0 deletions
diff --git a/ext/dbase/dbf_head.c b/ext/dbase/dbf_head.c
new file mode 100644
index 0000000000..1f104e3d81
--- /dev/null
+++ b/ext/dbase/dbf_head.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Brad Eacker,
+ * (Music, Intuition, Software, and Computers)
+ * All Rights Reserved
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+
+#include "dbf.h"
+
+void free_dbf_head(dbhead_t *dbh);
+int get_dbf_field(dbhead_t *dbh, dbfield_t *dbf);
+
+/*
+ * get the header info from the file
+ * basic header info & field descriptions
+ */
+dbhead_t *get_dbf_head(int fd)
+{
+ dbhead_t *dbh;
+ struct dbf_dhead dbhead;
+ dbfield_t *dbf, *cur_f;
+ int ret, nfields, offset;
+
+ if ((dbh = (dbhead_t *)malloc(sizeof(dbhead_t))) == NULL)
+ return NULL;
+ if (lseek(fd, 0, 0) < 0)
+ return NULL;
+ if ((ret = read(fd, &dbhead, sizeof(dbhead))) < 0)
+ return NULL;
+
+ /* build in core info */
+ dbh->db_fd = fd;
+ dbh->db_dbt = dbhead.dbh_dbt;
+ dbh->db_records = get_long(dbhead.dbh_records);
+ dbh->db_hlen = get_short(dbhead.dbh_hlen);
+ dbh->db_rlen = get_short(dbhead.dbh_rlen);
+
+ db_set_date(dbh->db_date, dbhead.dbh_date[DBH_DATE_YEAR] + 1900,
+ dbhead.dbh_date[DBH_DATE_MONTH],
+ dbhead.dbh_date[DBH_DATE_DAY]);
+
+ dbh->db_nfields = nfields = (dbh->db_hlen - sizeof(struct dbf_dhead)) /
+ sizeof(struct dbf_dfield);
+
+ /* get all the field info */
+ dbf = (dbfield_t *)malloc(sizeof(dbfield_t) * nfields);
+
+ offset = 1;
+ for (cur_f = dbf; cur_f < &dbf[nfields] ; cur_f++) {
+ if (get_dbf_field(dbh, cur_f) < 0) {
+ free_dbf_head(dbh);
+ return NULL;
+ }
+ cur_f->db_foffset = offset;
+ offset += cur_f->db_flen;
+ }
+ dbh->db_fields = dbf;
+
+ return dbh;
+}
+
+/*
+ * free up the header info built above
+ */
+void free_dbf_head(dbhead_t *dbh)
+{
+ dbfield_t *dbf, *cur_f;
+ int nfields;
+
+ dbf = dbh->db_fields;
+ nfields = dbh->db_nfields;
+ for (cur_f = dbf; cur_f < &dbf[nfields]; cur_f++) {
+ if (cur_f->db_format) {
+ free(cur_f->db_format);
+ }
+ }
+
+ free(dbf);
+ free(dbh);
+}
+
+/*
+ * put out the header info
+ */
+int put_dbf_head(dbhead_t *dbh)
+{
+ int fd = dbh->db_fd;
+ struct dbf_dhead dbhead;
+ int ret;
+
+ memset (&dbhead, 0, sizeof(dbhead));
+
+ /* build on disk info */
+ dbhead.dbh_dbt = dbh->db_dbt;
+ put_long(dbhead.dbh_records, dbh->db_records);
+ put_short(dbhead.dbh_hlen, dbh->db_hlen);
+ put_short(dbhead.dbh_rlen, dbh->db_rlen);
+
+ /* put the date spec'd into the on disk header */
+ dbhead.dbh_date[DBH_DATE_YEAR] =(char)(db_date_year(dbh->db_date) -
+ 1900);
+ dbhead.dbh_date[DBH_DATE_MONTH]=(char)(db_date_month(dbh->db_date));
+ dbhead.dbh_date[DBH_DATE_DAY] =(char)(db_date_day(dbh->db_date));
+
+ if (lseek(fd, 0, 0) < 0)
+ return -1;
+ if ((ret = write(fd, &dbhead, sizeof(dbhead))) < 0)
+ return -1;
+ return ret;
+}
+
+/*
+ * get a field off the disk from the current file offset
+ */
+int get_dbf_field(dbhead_t *dbh, dbfield_t *dbf)
+{
+ struct dbf_dfield dbfield;
+ int ret;
+
+ if ((ret = read(dbh->db_fd, &dbfield, sizeof(dbfield))) < 0) {
+ return ret;
+ }
+
+ /* build the field name */
+ copy_crimp(dbf->db_fname, dbfield.dbf_name, DBF_NAMELEN);
+
+ dbf->db_type = dbfield.dbf_type;
+ switch (dbf->db_type) {
+ case 'N':
+ dbf->db_flen = dbfield.dbf_flen[0];
+ dbf->db_fdc = dbfield.dbf_flen[1];
+ break;
+ default:
+ dbf->db_flen = get_short(dbfield.dbf_flen);
+ }
+
+ if ((dbf->db_format = get_dbf_f_fmt(dbf)) == NULL) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * put a field out on the disk at the current file offset
+ */
+int put_dbf_field(dbhead_t *dbh, dbfield_t *dbf)
+{
+ struct dbf_dfield dbfield;
+ char *scp, *dcp;
+ int ret;
+
+ memset (&dbfield, 0, sizeof(dbfield));
+
+ /* build the on disk field info */
+ scp = dbf->db_fname; dcp = dbfield.dbf_name;
+
+ strncpy(dbfield.dbf_name, dbf->db_fname, DBF_NAMELEN);
+
+ dbfield.dbf_type = dbf->db_type;
+ switch (dbf->db_type) {
+ case 'N':
+ dbfield.dbf_flen[0] = dbf->db_flen;
+ dbfield.dbf_flen[1] = dbf->db_fdc;
+ break;
+ default:
+ put_short(dbfield.dbf_flen, dbf->db_flen);
+ }
+
+ /* now write it out to disk */
+ if ((ret = write(dbh->db_fd, &dbfield, sizeof(dbfield))) < 0) {
+ return ret;
+ }
+ return 1;
+}
+
+/*
+ * put out all the info at the top of the file...
+ */
+static char end_stuff[2] = {0x0d, 0};
+
+void put_dbf_info(dbhead_t *dbh)
+{
+ dbfield_t *dbf;
+ char *cp;
+ int fcnt;
+
+ if ((cp = db_cur_date(NULL))) {
+ strncpy(dbh->db_date, cp, 8);
+ free(cp);
+ }
+ put_dbf_head(dbh);
+ dbf = dbh->db_fields;
+ for (fcnt = dbh->db_nfields; fcnt > 0; fcnt--, dbf++)
+ put_dbf_field(dbh, dbf);
+ write(dbh->db_fd, end_stuff, 1);
+}
+
+char *get_dbf_f_fmt(dbfield_t *dbf)
+{
+ char format[100];
+
+ /* build the field format for printf */
+ switch (dbf->db_type) {
+ case 'C':
+ sprintf(format, "%%-%ds", dbf->db_flen);
+ break;
+ case 'N':
+ case 'L':
+ case 'D':
+ sprintf(format, "%%%ds", dbf->db_flen);
+ break;
+ case 'M':
+ strcpy(format, "%s");
+ break;
+ }
+ return (char *)strdup(format);
+}
+
+dbhead_t *dbf_open(char *dp, int o_flags)
+{
+ int fd;
+ char *cp;
+ dbhead_t *dbh;
+
+ cp = dp;
+ if ((fd = open(cp, o_flags|O_BINARY)) < 0) {
+ cp = (char *)malloc(256);
+ strcpy(cp, dp); strcat(cp, ".dbf");
+ if ((fd = open(cp, o_flags)) < 0) {
+ perror("open");
+ return NULL;
+ }
+ }
+
+ if ((dbh = get_dbf_head(fd)) == 0) {
+ fprintf(stderr, "Unable to get header\n");
+ return NULL;
+ }
+ dbh->db_name = cp;
+ dbh->db_cur_rec = 0;
+
+ return dbh;
+}
+
+void dbf_head_info(dbhead_t *dbh)
+{
+ int nfields;
+ dbfield_t *dbf, *cur_f;
+
+ nfields = dbh->db_nfields;
+ printf("# fields: %d, record len: %d, total records %ld\n",
+ nfields, dbh->db_rlen, dbh->db_records);
+ dbf = dbh->db_fields;
+ for (cur_f = dbf; cur_f < &dbf[nfields] ; cur_f++) {
+ printf("# %s, %c, %d, %d\n", cur_f->db_fname,
+ cur_f->db_type, cur_f->db_flen, cur_f->db_fdc);
+ }
+}