1 : /*
2 : * Copyright (c) 1993 Brad Eacker,
3 : * (Music, Intuition, Software, and Computers)
4 : * All Rights Reserved
5 : */
6 :
7 : #ifdef HAVE_CONFIG_H
8 : #include "config.h"
9 : #endif
10 :
11 : #include "php.h"
12 :
13 : #include "ext/standard/flock_compat.h"
14 :
15 : #include <stdio.h>
16 : #include <fcntl.h>
17 :
18 : #include "dbf.h"
19 :
20 : int get_piece(dbhead_t *dbh, long offset, char *cp, int len);
21 : int put_piece(dbhead_t *dbh, long offset, char *cp, int len);
22 :
23 : /*
24 : * get a record off the database
25 : */
26 : char *get_dbf_record(dbhead_t *dbh, long rec_num)
27 11 : {
28 : long offset;
29 : char *cp;
30 :
31 11 : if (rec_num > dbh->db_records) {
32 1 : return NULL;
33 : }
34 10 : if ((cp = (char *)malloc(dbh->db_rlen)) == NULL) {
35 0 : return NULL;
36 : }
37 :
38 : /* go to the correct spot on the file */
39 10 : offset = dbh->db_hlen + (rec_num - 1) * dbh->db_rlen;
40 10 : if (get_piece(dbh, offset, cp, dbh->db_rlen) != dbh->db_rlen) {
41 0 : free(cp);
42 0 : cp = NULL;
43 : }
44 10 : if (cp)
45 10 : dbh->db_cur_rec = rec_num;
46 10 : return cp;
47 : }
48 :
49 : int
50 : get_piece(dbhead_t *dbh, long offset, char *cp, int len)
51 11 : {
52 : /* go to the correct spot on the file */
53 11 : if ( lseek(dbh->db_fd, offset, 0) < 0 ) {
54 0 : return -1;
55 : }
56 :
57 : /* read the record into the allocated space */
58 11 : return read(dbh->db_fd, cp, len);
59 : }
60 :
61 : /*
62 : * put a record to the database
63 : */
64 : long put_dbf_record(dbhead_t *dbh, long rec_num, char *cp)
65 10 : {
66 : long offset;
67 :
68 10 : if (rec_num == 0) {
69 0 : rec_num = dbh->db_records;
70 : }
71 10 : if (rec_num > dbh->db_records) {
72 0 : return 0L;
73 : }
74 : /* go to the correct spot on the file */
75 10 : offset = dbh->db_hlen + (rec_num - 1) * dbh->db_rlen;
76 10 : if (put_piece(dbh, offset, cp, dbh->db_rlen) != dbh->db_rlen) {
77 0 : rec_num = -1;
78 : }
79 10 : return rec_num;
80 : }
81 :
82 : int put_piece(dbhead_t *dbh, long offset, char *cp, int len)
83 10 : {
84 : /* go to the correct spot on the file */
85 10 : if ( lseek(dbh->db_fd, offset, 0) < 0 ) {
86 0 : return -1;
87 : }
88 :
89 : /* write the record into the file */
90 10 : return write(dbh->db_fd, cp, len);
91 : }
92 :
93 : int del_dbf_record(dbhead_t *dbh, long rec_num)
94 2 : {
95 2 : int ret = 0;
96 : char *cp;
97 :
98 2 : if (rec_num > dbh->db_records)
99 0 : return -1;
100 2 : if ((cp = get_dbf_record(dbh, rec_num))) {
101 2 : *cp = DELETED_RECORD;
102 2 : ret = put_dbf_record(dbh, rec_num, cp);
103 2 : free(cp);
104 : }
105 2 : return ret;
106 : }
107 :
108 : void pack_dbf(dbhead_t *dbh)
109 1 : {
110 : long out_off, in_off;
111 : int rec_cnt, new_cnt;
112 : char *cp;
113 :
114 1 : if ((cp = (char *)malloc(dbh->db_rlen)) == NULL) {
115 0 : return;
116 : }
117 1 : in_off = out_off = dbh->db_hlen;
118 :
119 1 : new_cnt = 0;
120 1 : rec_cnt = dbh->db_records;
121 3 : while (rec_cnt > 0) {
122 1 : if (get_piece(dbh, in_off, cp, dbh->db_rlen) < 0)
123 0 : break;
124 :
125 1 : if (*cp != DELETED_RECORD) {
126 : /* write the record into the file */
127 0 : if (put_piece(dbh, out_off, cp, dbh->db_rlen) < 0)
128 0 : break;
129 0 : out_off += dbh->db_rlen;
130 0 : new_cnt++;
131 : }
132 1 : in_off += dbh->db_rlen;
133 1 : rec_cnt--;
134 : }
135 1 : free(cp);
136 :
137 : /* Try to truncate the file to the right size. */
138 1 : if (ftruncate(dbh->db_fd, out_off) != 0) {
139 : TSRMLS_FETCH();
140 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "dbase_pack() couldn't truncate the file to the right size. Some deleted records may still be left in there.");
141 : }
142 :
143 1 : if (rec_cnt == 0)
144 1 : dbh->db_records = new_cnt;
145 : }
146 :
147 : /* routine to get a field from a record */
148 : char *get_field_val(char *rp, dbfield_t *fldp, char *cp)
149 32 : {
150 32 : int flen = fldp->db_flen;
151 :
152 32 : if ( !cp )
153 0 : cp = (char *)malloc(flen + 1);
154 32 : if ( cp ) {
155 32 : strlcpy(cp, &rp[fldp->db_foffset], flen + 1);
156 : }
157 32 : return cp;
158 : }
159 :
160 : void put_field_val(char *rp, dbfield_t *fldp, char *cp)
161 0 : {
162 0 : strncpy(&rp[fldp->db_foffset], cp, fldp->db_flen);
163 0 : }
164 :
165 : /*
166 : * output a record
167 : */
168 : void out_rec(dbhead_t *dbh, dbfield_t *dbf, char *cp)
169 0 : {
170 : dbfield_t *cur_f;
171 0 : int nfields = dbh->db_nfields;
172 0 : char *fnp = (char *)malloc(dbh->db_rlen);
173 :
174 0 : printf("%c", *cp);
175 0 : for (cur_f = dbf; cur_f < &dbf[nfields] ; cur_f++) {
176 0 : printf(" ");
177 0 : printf(cur_f->db_format, get_field_val(cp, cur_f, fnp));
178 : }
179 0 : printf("\n");
180 0 : free(fnp);
181 0 : }
182 :
183 : /* check for record validity */
184 : int is_valid_rec(char *cp)
185 0 : {
186 0 : if (cp && (*cp == VALID_RECORD))
187 0 : return 1;
188 : else
189 0 : return 0;
190 : }
191 :
192 : /* get the next record */
193 : char *dbf_get_next(dbhead_t *dbh)
194 0 : {
195 0 : return get_dbf_record(dbh, dbh->db_cur_rec + 1);
196 : }
197 :
198 : /*
199 : * Local variables:
200 : * tab-width: 4
201 : * c-basic-offset: 4
202 : * End:
203 : * vim600: sw=4 ts=4 fdm=marker
204 : * vim<600: sw=4 ts=4
205 : */
|