#include #include #include #include #include #include #include #include #include #include #include char* pnd_fields[] = { "Titel:", "Name:", "Alternativnamen:", "Kurzbeschreibung:", "Geburtsdatum:", "Geburtsort:", "Sterbedatum:", "Sterbeort:", 0 }; int main(int argc, char** argv) { outbuf err = {2}; char* cmdname = *argv++; --argc; if (argc != 2) { outbuf_printf(&err, "Usage: %s dbfile port\n", cmdname); outbuf_flush(&err); exit(1); } char* dbname = *argv++; --argc; int portnum = atoi(*argv++); --argc; if (portnum <= 0) { outbuf_printf(&err, "%s: bad port number\n", cmdname); outbuf_flush(&err); exit(1); } DB* dbp; if (db_create(&dbp, 0, 0) != 0 || dbp->open(dbp, /* DB structure pointer */ 0, /* transaction pointer */ dbname, /* on-disk file that holds the database */ 0, /* optional logical database name */ DB_BTREE, /* database access method */ 0, /* open flags */ 0) != 0) { /* file mode */ outbuf_printf(&err, "%s: cannot open %s\n", cmdname, dbname); outbuf_flush(&err); exit(1); } struct sockaddr_in address = {0}; address.sin_family = AF_INET; address.sin_addr.s_addr = htonl(INADDR_ANY); address.sin_port = htons(portnum); int sfd = socket(PF_INET, SOCK_STREAM, 0); int optval = 1; if (sfd < 0 || setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval) < 0 || bind(sfd, (struct sockaddr *) &address, sizeof address) < 0 || listen(sfd, SOMAXCONN) < 0) { outbuf_printf(&err, "%s: %s\n", cmdname, strerror(errno)); exit(1); } stralloc data_buffer = {0}; u_int32_t pagesize; if (dbp->get_pagesize(dbp, &pagesize) != 0) { pagesize = 1024; } stralloc_ready(&data_buffer, pagesize); stralloc key_string = {0}; int fd; while ((fd = accept(sfd, 0, 0)) >= 0) { inbuf in = {fd}; outbuf out = {fd}; if (inbuf_scan(&in, "[ \t]*(.*?)[ \t]*\r?\n", &key_string) == 1) { DBT key = {.data = key_string.s, .size = key_string.len, .flags = DB_DBT_USERMEM}; DBT data = {.data = data_buffer.s, .ulen = data_buffer.a, .flags = DB_DBT_USERMEM}; int ret; for(;;) { ret = dbp->get(dbp, 0, &key, &data, 0); if (ret == 0) break; if (ret == DB_BUFFER_SMALL) { /* enlarge input buffer */ if (!stralloc_ready(&data_buffer, data.size + 1)) { outbuf_printf(&err, "%s: out of memory.\n", cmdname); outbuf_flush(&err); exit(1); } data.ulen = data_buffer.a; } else { outbuf_printf(&err, "%s: db retrieval failed for key '%.*s'.\n", cmdname, key_string.len, key_string.s); outbuf_flush(&err); break; } } if (ret == 0) { data_buffer.len = data.size; char* cp = data_buffer.s; for (char** fields = pnd_fields; *fields; ++fields) { char* next = cp; while (*next != '\t' && next < data_buffer.s + data_buffer.len) { ++next; } if (next > cp) { outbuf_printf(&out, "%-20s %.*s\r\n", *fields, next-cp, cp); } cp = next+1; } } else { outbuf_printf(&out, "No record found for this key.\r\n"); } outbuf_flush(&out); } close(fd); } }