#include #include #include #include #include #include #include #include #include #include #include #include #include "bcompare.h" #include /* yacc */ int yyparse(void); extern int yyin; int btreeparse(const char *line); int do_quit = 0; /* MALLOC_CONF=stats_print:true,junk:true */ static DB * btreedb; #define KEYDATA_MAX 64 static struct option longopts[] = { { "db", required_argument, NULL, 'd' }, { NULL, 0, NULL, 0 } }; __attribute__((noreturn)) static int usage(void) { fputs("bprompt [--db filename]\n", stderr); exit (EXIT_SUCCESS); } /* * insert key/val pair in database * * @key: key id * @data: cargo * * return 0 on success, -1 otherwise */ int dbinsert(size_t key, char *data) { DBT k = {}; DBT d = {}; int rc = 0; size_t l =strnlen(data, KEYDATA_MAX); k.data = &key; k.size = sizeof key; d.size = l + 1; d.data = malloc(KEYDATA_MAX); *((char *) mempcpy (d.data, data, l)) = '\0'; rc = btreedb->put(btreedb, &k, &d, R_NOOVERWRITE); if (rc == -1) { warn("Failed to insert record %zu:", key); goto dbinsert_out; } if (rc) { warnx("This record can't be ovewritten."); rc = -1; goto dbinsert_out; } printf("Record inserted with key %zu.\n", key); dbinsert_out: free(d.data); return rc; } /* * delete key/val pair from database * * @key: key id * * return 0 on success, -1 otherwise */ int dbdelete(size_t key) { DBT k = {}; k.data = &key; k.size = sizeof key; int rc; rc = btreedb->del(btreedb, &k, 0); if (rc == -1) { warn("Failed to delete record %zu:", key); return -1; } if (rc) { warnx("record key %zu was not found.", key); return -1; } printf("Record %zu deleted.\n", key); return 0; } /* * display key/val pair from database * * @key: key id * * return 0 on success, -1 otherwise */ int dbget(size_t key) { DBT k = {}; DBT d = {}; k.data = &key; k.size = sizeof key; int rc; rc = btreedb->get(btreedb, &k, &d, 0); if (rc == -1) { warn("Failed to grab record %zu.", key); return -1; } if (rc) { warnx("record %zu was not found.", key); return -1; } printf("-> %s.\n", (char *)d.data); return 0; } int main(int argc, char *argv[]) { cap_rights_t rights_wr; char *dbname = NULL; char buf[PATH_MAX]; /* btree */ BTREEINFO type = {}; /* opt */ int ch; while ((ch = getopt_long(argc, argv, "d:", longopts, NULL)) != -1) { switch (ch) { case 'd': dbname = optarg; break; case 0: /* long option */ break; default: usage(); } } if (optind != argc) usage(); if (dbname == NULL) { const char *t = getenv("TMPDIR"); if (t == NULL) t = "/tmp"; (void)snprintf(buf, sizeof(buf), "%s/david", t); dbname = buf; } type.compare = compare; btreedb= dbopen(dbname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, DB_BTREE, &type); if (btreedb == NULL) err(EXIT_FAILURE, "Failed to create database."); if (cap_enter() < 0) err(EXIT_FAILURE, "cap_enter() failed"); cap_rights_init(&rights_wr, CAP_READ, CAP_FSTAT, CAP_SEEK, CAP_WRITE); if (btreedb->fd(btreedb) < 0) errx(EXIT_FAILURE, "No database access"); if (cap_rights_limit(btreedb->fd(btreedb), &rights_wr) < 0) err(EXIT_FAILURE, "cap_rights_limit() failed"); while (!do_quit) { yyparse(); } btreedb->close(btreedb); printf("Data stored into %s.\n", dbname); }