diff options
Diffstat (limited to 'contrib/dbase/dbf.c')
-rw-r--r-- | contrib/dbase/dbf.c | 520 |
1 files changed, 0 insertions, 520 deletions
diff --git a/contrib/dbase/dbf.c b/contrib/dbase/dbf.c deleted file mode 100644 index f202213b11a..00000000000 --- a/contrib/dbase/dbf.c +++ /dev/null @@ -1,520 +0,0 @@ -/* $PostgreSQL: pgsql/contrib/dbase/dbf.c,v 1.11 2006/06/08 03:28:01 momjian Exp $ */ - -/* Routines to read and write xBase-files (.dbf) - - By Maarten Boekhold, 29th of oktober 1995 - - Modified by Frank Koormann (fkoorman@usf.uni-osnabrueck.de), Jun 10 1996 - prepare dataarea with memset - get systemtime and set filedate - set formatstring for real numbers -*/ - -#include "postgres_fe.h" - -#include <fcntl.h> -#include <ctype.h> -#include <time.h> -#include <unistd.h> - -#include "dbf.h" - -/* open a dbf-file, get it's field-info and store this information */ - -dbhead * -dbf_open(char *file, int flags) -{ - int file_no; - dbhead *dbh; - f_descr *fields; - dbf_header *head; - dbf_field *fieldc; - int t; - - if ((dbh = (dbhead *) malloc(sizeof(dbhead))) == NULL) - return (dbhead *) DBF_ERROR; - - if ((head = (dbf_header *) malloc(sizeof(dbf_header))) == NULL) - { - free(dbh); - return (dbhead *) DBF_ERROR; - } - - if ((fieldc = (dbf_field *) malloc(sizeof(dbf_field))) == NULL) - { - free(head); - free(dbh); - return (dbhead *) DBF_ERROR; - } - - if ((file_no = open(file, flags, 0)) == -1) - { - free(fieldc); - free(head); - free(dbh); - return (dbhead *) DBF_ERROR; - } - -/* read in the disk-header */ - - if (read(file_no, head, sizeof(dbf_header)) == -1) - { - close(file_no); - free(fieldc); - free(head); - free(dbh); - return (dbhead *) DBF_ERROR; - } - - if (!(head->dbh_dbt & DBH_NORMAL)) - { - close(file_no); - free(fieldc); - free(head); - free(dbh); - return (dbhead *) DBF_ERROR; - } - - dbh->db_fd = file_no; - if (head->dbh_dbt & DBH_MEMO) - dbh->db_memo = 1; - else - dbh->db_memo = 0; - dbh->db_year = head->dbh_year; - dbh->db_month = head->dbh_month; - dbh->db_day = head->dbh_day; - dbh->db_hlen = get_short((u_char *) &head->dbh_hlen); - dbh->db_records = get_long((u_char *) &head->dbh_records); - dbh->db_currec = 0; - dbh->db_rlen = get_short((u_char *) &head->dbh_rlen); - dbh->db_nfields = (dbh->db_hlen - sizeof(dbf_header)) / sizeof(dbf_field); - - /* - * dbh->db_hlen - sizeof(dbf_header) isn't the correct size, cos dbh->hlen - * is in fact a little more cos of the 0x0D (and possibly another byte, - * 0x4E, I have seen this somewhere). Because of rounding everything turns - * out right :) - */ - - if ((fields = (f_descr *) calloc(dbh->db_nfields, sizeof(f_descr))) - == NULL) - { - close(file_no); - free(fieldc); - free(head); - free(dbh); - return (dbhead *) DBF_ERROR; - } - - for (t = 0; t < dbh->db_nfields; t++) - { -/* Maybe I have calculated the number of fields incorrectly. This can happen - when programs reserve lots of space at the end of the header for future - expansion. This will catch this situation */ - if (fields[t].db_name[0] == 0x0D) - { - dbh->db_nfields = t; - break; - } - read(file_no, fieldc, sizeof(dbf_field)); - strncpy(fields[t].db_name, fieldc->dbf_name, DBF_NAMELEN); - fields[t].db_type = fieldc->dbf_type; - fields[t].db_flen = fieldc->dbf_flen; - fields[t].db_dec = fieldc->dbf_dec; - } - - dbh->db_offset = dbh->db_hlen; - dbh->db_fields = fields; - - if ((dbh->db_buff = (u_char *) malloc(dbh->db_rlen)) == NULL) - return (dbhead *) DBF_ERROR; - - free(fieldc); - free(head); - - return dbh; -} - -int -dbf_write_head(dbhead * dbh) -{ - dbf_header head; - time_t now; - struct tm *dbf_time; - - if (lseek(dbh->db_fd, 0, SEEK_SET) == -1) - return DBF_ERROR; - -/* fill up the diskheader */ - -/* Set dataarea of head to '\0' */ - memset(&head, '\0', sizeof(dbf_header)); - - head.dbh_dbt = DBH_NORMAL; - if (dbh->db_memo) - head.dbh_dbt = DBH_MEMO; - - now = time((time_t *) NULL); - dbf_time = localtime(&now); - head.dbh_year = dbf_time->tm_year; - head.dbh_month = dbf_time->tm_mon + 1; /* Months since January + 1 */ - head.dbh_day = dbf_time->tm_mday; - - put_long(head.dbh_records, dbh->db_records); - put_short(head.dbh_hlen, dbh->db_hlen); - put_short(head.dbh_rlen, dbh->db_rlen); - - if (write(dbh->db_fd, &head, sizeof(dbf_header)) != sizeof(dbf_header)) - return DBF_ERROR; - - return 0; -} - -int -dbf_put_fields(dbhead * dbh) -{ - dbf_field field; - u_long t; - u_char end = 0x0D; - - if (lseek(dbh->db_fd, sizeof(dbf_header), SEEK_SET) == -1) - return DBF_ERROR; - -/* Set dataarea of field to '\0' */ - memset(&field, '\0', sizeof(dbf_field)); - - for (t = 0; t < dbh->db_nfields; t++) - { - strncpy(field.dbf_name, dbh->db_fields[t].db_name, DBF_NAMELEN - 1); - field.dbf_type = dbh->db_fields[t].db_type; - field.dbf_flen = dbh->db_fields[t].db_flen; - field.dbf_dec = dbh->db_fields[t].db_dec; - - if (write(dbh->db_fd, &field, sizeof(dbf_field)) != sizeof(dbf_field)) - return DBF_ERROR; - } - - if (write(dbh->db_fd, &end, 1) != 1) - return DBF_ERROR; - - return 0; -} - -int -dbf_add_field(dbhead * dbh, char *name, u_char type, - u_char length, u_char dec) -{ - f_descr *ptr; - u_char *foo; - u_long size, - field_no; - - size = (dbh->db_nfields + 1) * sizeof(f_descr); - if (!(ptr = (f_descr *) realloc(dbh->db_fields, size))) - return DBF_ERROR; - dbh->db_fields = ptr; - - field_no = dbh->db_nfields; - strncpy(dbh->db_fields[field_no].db_name, name, DBF_NAMELEN); - dbh->db_fields[field_no].db_type = type; - dbh->db_fields[field_no].db_flen = length; - dbh->db_fields[field_no].db_dec = dec; - - dbh->db_nfields++; - dbh->db_hlen += sizeof(dbf_field); - dbh->db_rlen += length; - - if (!(foo = (u_char *) realloc(dbh->db_buff, dbh->db_rlen))) - return DBF_ERROR; - - dbh->db_buff = foo; - - return 0; -} - -dbhead * -dbf_open_new(char *name, int flags) -{ - dbhead *dbh; - - if (!(dbh = (dbhead *) malloc(sizeof(dbhead)))) - return (dbhead *) DBF_ERROR; - - if (flags & O_CREAT) - { - if ((dbh->db_fd = open(name, flags, DBF_FILE_MODE)) == -1) - { - free(dbh); - return (dbhead *) DBF_ERROR; - } - } - else - { - if ((dbh->db_fd = open(name, flags, 0)) == -1) - { - free(dbh); - return (dbhead *) DBF_ERROR; - } - } - - - dbh->db_offset = 0; - dbh->db_memo = 0; - dbh->db_year = 0; - dbh->db_month = 0; - dbh->db_day = 0; - dbh->db_hlen = sizeof(dbf_header) + 1; - dbh->db_records = 0; - dbh->db_currec = 0; - dbh->db_rlen = 1; - dbh->db_nfields = 0; - dbh->db_buff = NULL; - dbh->db_fields = (f_descr *) NULL; - - return dbh; -} - -void -dbf_close(dbhead * dbh) -{ - int t; - - close(dbh->db_fd); - - for (t = 0; t < dbh->db_nfields; t++) - free(&dbh->db_fields[t]); - - if (dbh->db_buff != NULL) - free(dbh->db_buff); - - free(dbh); -} - -int -dbf_get_record(dbhead * dbh, field * fields, u_long rec) -{ - u_char *data; - int t, - i, - offset; - u_char *dbffield, - *end; - -/* calculate at which offset we have to read. *DON'T* forget the - 0x0D which seperates field-descriptions from records! - - Note (april 5 1996): This turns out to be included in db_hlen -*/ - offset = dbh->db_hlen + (rec * dbh->db_rlen); - - if (lseek(dbh->db_fd, offset, SEEK_SET) == -1) - { - lseek(dbh->db_fd, 0, SEEK_SET); - dbh->db_offset = 0; - return DBF_ERROR; - } - - dbh->db_offset = offset; - dbh->db_currec = rec; - data = dbh->db_buff; - - read(dbh->db_fd, data, dbh->db_rlen); - - if (data[0] == DBF_DELETED) - return DBF_DELETED; - - dbffield = &data[1]; - for (t = 0; t < dbh->db_nfields; t++) - { - strncpy(fields[t].db_name, dbh->db_fields[t].db_name, DBF_NAMELEN); - fields[t].db_type = dbh->db_fields[t].db_type; - fields[t].db_flen = dbh->db_fields[t].db_flen; - fields[t].db_dec = dbh->db_fields[t].db_dec; - - if (fields[t].db_type == 'C') - { - end = &dbffield[fields[t].db_flen - 1]; - i = fields[t].db_flen; - while (i > 0 && !isprint(*end)) - { - end--; - i--; - } - strncpy((char *) fields[t].db_contents, (char *) dbffield, i); - fields[t].db_contents[i] = '\0'; - } - else - { - end = dbffield; - i = fields[t].db_flen; - while (i > 0 && !isprint(*end)) - { - end++; - i--; - } - strncpy((char *) fields[t].db_contents, (char *) end, i); - fields[t].db_contents[i] = '\0'; - } - - dbffield += fields[t].db_flen; - } - - dbh->db_offset += dbh->db_rlen; - - return DBF_VALID; -} - -field * -dbf_build_record(dbhead * dbh) -{ - int t; - field *fields; - - if (!(fields = (field *) calloc(dbh->db_nfields, sizeof(field)))) - return (field *) DBF_ERROR; - - for (t = 0; t < dbh->db_nfields; t++) - { - if (!(fields[t].db_contents = - (u_char *) malloc(dbh->db_fields[t].db_flen + 1))) - { - for (t = 0; t < dbh->db_nfields; t++) - { - if (fields[t].db_contents != 0) - { - free(fields[t].db_contents); - free(fields); - } - return (field *) DBF_ERROR; - } - } - strncpy(fields[t].db_name, dbh->db_fields[t].db_name, DBF_NAMELEN); - fields[t].db_type = dbh->db_fields[t].db_type; - fields[t].db_flen = dbh->db_fields[t].db_flen; - fields[t].db_dec = dbh->db_fields[t].db_dec; - } - - return fields; -} - -void -dbf_free_record(dbhead * dbh, field * rec) -{ - int t; - - for (t = 0; t < dbh->db_nfields; t++) - free(rec[t].db_contents); - - free(rec); -} - -int -dbf_put_record(dbhead * dbh, field * rec, u_long where) -{ - u_long offset, - new, - idx, - t, - h, - length; - u_char *data, - end = 0x1a; - double fl; - char foo[128], - format[32]; - -/* offset: offset in file for this record - new: real offset after lseek - idx: index to which place we are inside the 'hardcore'-data for this - record - t: field-counter - data: the hardcore-data that is put on disk - h: index into the field-part in the hardcore-data - length: length of the data to copy - fl: a float used to get the right precision with real numbers - foo: copy of db_contents when field is not 'C' - format: sprintf format-string to get the right precision with real numbers - - NOTE: this declaration of 'foo' can cause overflow when the contents-field - is longer the 127 chars (which is highly unlikely, because it is not used - in text-fields). -*/ -/* REMEMBER THAT THERE'S A 0x1A AT THE END OF THE FILE, SO DON'T - DO A SEEK_END WITH 0!!!!!! USE -1 !!!!!!!!!! -*/ - - if (where > dbh->db_records) - { - if ((new = lseek(dbh->db_fd, -1, SEEK_END)) == -1) - return DBF_ERROR; - dbh->db_records++; - } - else - { - offset = dbh->db_hlen + (where * dbh->db_rlen); - if ((new = lseek(dbh->db_fd, offset, SEEK_SET)) == -1) - return DBF_ERROR; - } - - dbh->db_offset = new; - - data = dbh->db_buff; - -/* Set dataarea of data to ' ' (space) */ - memset(data, ' ', dbh->db_rlen); - -/* data[0] = DBF_VALID; */ - - idx = 1; - for (t = 0; t < dbh->db_nfields; t++) - { -/* if field is empty, don't do a thing */ - if (rec[t].db_contents[0] != '\0') - { -/* Handle text */ - if (rec[t].db_type == 'C') - { - if (strlen((char *) rec[t].db_contents) > rec[t].db_flen) - length = rec[t].db_flen; - else - length = strlen((char *) rec[t].db_contents); - strncpy((char *) data + idx, (char *) rec[t].db_contents, - length); - } - else - { -/* Handle the rest */ -/* Numeric is special, because of real numbers */ - if ((rec[t].db_type == 'N') && (rec[t].db_dec != 0)) - { - fl = atof((char *) rec[t].db_contents); - snprintf(format, 32, "%%.%df", rec[t].db_dec); - snprintf(foo, 128, format, fl); - } - else - strncpy(foo, (char *) rec[t].db_contents, 128); - if (strlen(foo) > rec[t].db_flen) - length = rec[t].db_flen; - else - length = strlen(foo); - h = rec[t].db_flen - length; - strncpy((char *) (data + idx + h), foo, length); - } - } - idx += rec[t].db_flen; - } - - if (write(dbh->db_fd, data, dbh->db_rlen) != dbh->db_rlen) - return DBF_ERROR; - - /* There's a 0x1A at the end of a dbf-file */ - if (where == dbh->db_records) - { - if (write(dbh->db_fd, &end, 1) != 1) - return DBF_ERROR; - } - - dbh->db_offset += dbh->db_rlen; - - return 0; -} |