summaryrefslogtreecommitdiffstats
path: root/util/cacheserver.c
blob: 14fe5909c12f8ddb462c7f35fc24cb5964099641 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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;
}