You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
4.0 KiB

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