bprompt.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <db.h>
  4. #include <fcntl.h>
  5. #include <limits.h>
  6. #include <unistd.h>
  7. #include <err.h>
  8. #include <string.h>
  9. #include <sys/types.h>
  10. #include <malloc_np.h>
  11. #include <getopt.h>
  12. #include <sys/stat.h>
  13. #include "bcompare.h"
  14. #include <sys/capsicum.h>
  15. /* yacc */
  16. int yyparse(void);
  17. extern int yyin;
  18. int btreeparse(const char *line);
  19. int do_quit = 0;
  20. /* MALLOC_CONF=stats_print:true,junk:true */
  21. static DB * btreedb;
  22. #define KEYDATA_MAX 64
  23. static struct option longopts[] = {
  24. { "db", required_argument, NULL, 'd' },
  25. { NULL, 0, NULL, 0 }
  26. };
  27. __attribute__((noreturn)) static int usage(void)
  28. {
  29. fputs("bprompt [--db filename]\n", stderr);
  30. exit (EXIT_SUCCESS);
  31. }
  32. /*
  33. * insert key/val pair in database
  34. *
  35. * @key: key id
  36. * @data: cargo
  37. *
  38. * return 0 on success, -1 otherwise
  39. */
  40. int dbinsert(size_t key, char *data)
  41. {
  42. DBT k = {};
  43. DBT d = {};
  44. int rc = 0;
  45. size_t l =strnlen(data, KEYDATA_MAX);
  46. k.data = &key;
  47. k.size = sizeof key;
  48. d.size = l + 1;
  49. d.data = malloc(KEYDATA_MAX);
  50. *((char *) mempcpy (d.data, data, l)) = '\0';
  51. rc = btreedb->put(btreedb, &k, &d, R_NOOVERWRITE);
  52. if (rc == -1) {
  53. warn("Failed to insert record %zu:", key);
  54. goto dbinsert_out;
  55. }
  56. if (rc) {
  57. warnx("This record can't be ovewritten.");
  58. rc = -1;
  59. goto dbinsert_out;
  60. }
  61. printf("Record inserted with key %zu.\n", key);
  62. dbinsert_out:
  63. free(d.data);
  64. return rc;
  65. }
  66. /*
  67. * delete key/val pair from database
  68. *
  69. * @key: key id
  70. *
  71. * return 0 on success, -1 otherwise
  72. */
  73. int dbdelete(size_t key)
  74. {
  75. DBT k = {};
  76. k.data = &key;
  77. k.size = sizeof key;
  78. int rc;
  79. rc = btreedb->del(btreedb, &k, 0);
  80. if (rc == -1) {
  81. warn("Failed to delete record %zu:", key);
  82. return -1;
  83. }
  84. if (rc) {
  85. warnx("record key %zu was not found.", key);
  86. return -1;
  87. }
  88. printf("Record %zu deleted.\n", key);
  89. return 0;
  90. }
  91. /*
  92. * display key/val pair from database
  93. *
  94. * @key: key id
  95. *
  96. * return 0 on success, -1 otherwise
  97. */
  98. int dbget(size_t key)
  99. {
  100. DBT k = {};
  101. DBT d = {};
  102. k.data = &key;
  103. k.size = sizeof key;
  104. int rc;
  105. rc = btreedb->get(btreedb, &k, &d, 0);
  106. if (rc == -1) {
  107. warn("Failed to grab record %zu.", key);
  108. return -1;
  109. }
  110. if (rc) {
  111. warnx("record %zu was not found.", key);
  112. return -1;
  113. }
  114. printf("-> %s.\n", (char *)d.data);
  115. return 0;
  116. }
  117. int main(int argc, char *argv[])
  118. {
  119. cap_rights_t rights_wr;
  120. char *dbname = NULL;
  121. char buf[PATH_MAX];
  122. /* btree */
  123. BTREEINFO type = {};
  124. /* opt */
  125. int ch;
  126. while ((ch = getopt_long(argc, argv, "d:", longopts, NULL)) != -1) {
  127. switch (ch) {
  128. case 'd':
  129. dbname = optarg;
  130. break;
  131. case 0:
  132. /* long option */
  133. break;
  134. default:
  135. usage();
  136. }
  137. }
  138. if (optind != argc)
  139. usage();
  140. if (dbname == NULL) {
  141. const char *t = getenv("TMPDIR");
  142. if (t == NULL)
  143. t = "/tmp";
  144. (void)snprintf(buf, sizeof(buf), "%s/david", t);
  145. dbname = buf;
  146. }
  147. type.compare = compare;
  148. btreedb= dbopen(dbname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, DB_BTREE, &type);
  149. if (btreedb == NULL)
  150. err(EXIT_FAILURE, "Failed to create database.");
  151. if (cap_enter() < 0)
  152. err(EXIT_FAILURE, "cap_enter() failed");
  153. cap_rights_init(&rights_wr, CAP_READ, CAP_FSTAT, CAP_SEEK, CAP_WRITE);
  154. if (btreedb->fd(btreedb) < 0)
  155. errx(EXIT_FAILURE, "No database access");
  156. if (cap_rights_limit(btreedb->fd(btreedb), &rights_wr) < 0)
  157. err(EXIT_FAILURE, "cap_rights_limit() failed");
  158. while (!do_quit) {
  159. yyparse();
  160. }
  161. btreedb->close(btreedb);
  162. printf("Data stored into %s.\n", dbname);
  163. }