summaryrefslogtreecommitdiffstats
path: root/util/cacheserver.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/cacheserver.c')
-rw-r--r--util/cacheserver.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/util/cacheserver.c b/util/cacheserver.c
new file mode 100644
index 00000000..14fe5909
--- /dev/null
+++ b/util/cacheserver.c
@@ -0,0 +1,120 @@
+#include "bbs.h"
+#include <err.h>
+#include <avltree.h>
+
+int acceptone(int port);
+void usage(void);
+ssize_t Read(int fd, void *buf, size_t nbytes);
+
+int main(int argc, char **argv)
+{
+ int sfd, len;
+ int port = -1;
+ char ch;
+ OCbuf_t OCbuf;
+
+ AVL_IX_DESC ix;
+ AVL_IX_REC pe;
+ OCstore_t *store;
+ avl_create_index(&ix, AVL_COUNT_DUPS, OC_KEYLEN);
+
+ while( (ch = getopt(argc, argv, "p:")) != -1 )
+ switch( ch ){
+ case 'p':
+ port = atoi(optarg);
+ break;
+ }
+ if( port == -1 )
+ usage();
+
+ sfd = acceptone(port);
+ while( Read(sfd, &len, sizeof(len)) > 0 ){
+ printf("reading %d bytes\n", len);
+ Read(sfd, &OCbuf, len);
+ printf("read! pid: %d\n", OCbuf.key.pid);
+
+ memset(&pe, 0, sizeof(pe));
+ if( OCbuf.key.pid <= 1 ){
+ /* garbage collection */
+ }
+ else if( OCbuf.key.pid < OC_pidadd ){
+ /* store */
+ puts("swapin");
+
+ len = OC_HEADERLEN + OCbuf.length;
+ store = (OCstore_t *)malloc(sizeof(time_t) + len);
+ store->mtime = time(NULL);
+ memcpy(&(store->data), &OCbuf, len);
+
+ pe.recptr = (void *)store;
+ memcpy(pe.key, &OCbuf.key, OC_KEYLEN);
+ if( avl_add_key(&pe, &ix) != AVL_IX_OK )
+ puts("add key error");
+ }
+ else {
+ OCbuf.key.pid -= OC_pidadd;
+ memcpy(pe.key, &OCbuf.key, OC_KEYLEN);
+ if( avl_find_key(&pe, &ix) == AVL_IX_OK ){
+ store = (OCstore_t *)pe.recptr;
+
+ len = store->data.length + OC_HEADERLEN;
+ write(sfd, &len, sizeof(len));
+ write(sfd, &(store->data), len);
+ free(store);
+ if( avl_delete_key(&pe, &ix) != AVL_IX_OK )
+ puts("delete key error");
+ }
+ else
+ puts("error");
+ }
+ }
+ return 0;
+}
+
+int acceptone(int port)
+{
+ int sockfd, val, cfd, len;
+ struct sockaddr_in servaddr, clientaddr;
+
+ if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
+ err(1, NULL);
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
+
+ bzero(&servaddr, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ servaddr.sin_port = htons(port);
+ if( bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 )
+ err(1, NULL);
+ if( listen(sockfd, 5) < 0 )
+ err(1, NULL);
+
+ len = sizeof(struct sockaddr_in);
+
+ if( (cfd = accept(sockfd, (struct sockaddr *)&clientaddr, &len)) < 0 )
+ err(1, NULL);
+
+ close(sockfd);
+ return cfd;
+}
+
+void usage(void)
+{
+ fprintf(stderr,
+ "usage:\tcacheserver [options]\n"
+ "-p port\tlistenport\n");
+ exit(0);
+}
+
+ssize_t Read(int fd, void *BUF, size_t nbytes)
+{
+ char *buf = (char *)BUF;
+ size_t thisgot, totalgot = nbytes;
+ while( nbytes > 0 ){
+ if( (thisgot = read(fd, buf, nbytes)) <= 0 )
+ err(1, "read from socket: ");
+ nbytes -= thisgot;
+ buf += thisgot;
+ }
+ return totalgot;
+}