summaryrefslogtreecommitdiffstats
path: root/util/localserver.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/localserver.c')
-rw-r--r--util/localserver.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/util/localserver.c b/util/localserver.c
new file mode 100644
index 00000000..eb90bd6f
--- /dev/null
+++ b/util/localserver.c
@@ -0,0 +1,116 @@
+#include "bbs.h"
+#include <err.h>
+
+void usage(void);
+int connectserver(char *, int);
+void listennetwork(int, int);
+void listenmsgqueue(int, int);
+
+int main(int argc, char **argv)
+{
+ char *host = NULL;
+ int port = 0, ch, sfd, msto, mtos;
+ pid_t pid;
+ while( (ch = getopt(argc, argv, "s:p:")) != -1 )
+ switch( ch ){
+ case 's':
+ host = strdup(optarg);
+ break;
+ case 'p':
+ port = atoi(optarg);
+ break;
+ default:
+ usage();
+ }
+
+ if( host == NULL || port == 0 )
+ usage();
+
+ printf("connecting to server %s:%d\n", host, port);
+ sfd = connectserver(host, port);
+ puts("connected");
+
+ puts("attaching message queue");
+ if( (msto = msgget(OC_msto, 0600 | IPC_CREAT)) < 0 )
+ err(1, "msgget OC_msto");
+ if( (mtos = msgget(OC_mtos, 0600 | IPC_CREAT)) < 0 )
+ err(1, "msgget OC_mtos");
+ puts("attached");
+
+ if( (pid = fork()) < 0 )
+ err(1, "fork()");
+ else if( pid == 0 )
+ listennetwork(sfd, msto);
+ listenmsgqueue(sfd, mtos);
+
+ return 0;
+}
+
+void usage(void)
+{
+ fprintf(stderr, "usage:\tlocalserver -s host -p port\n");
+ exit(0);
+}
+
+int connectserver(char *host, int port)
+{
+ struct sockaddr_in servaddr;
+ int fd;
+
+ if( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
+ err(1, "socket");
+ bzero(&servaddr, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ inet_pton(AF_INET, host, &servaddr.sin_addr);
+ servaddr.sin_port = htons(port);
+ if( connect(fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 )
+ err(1, "connect");
+ return fd;
+}
+
+void listennetwork(int netfd, int msgfd)
+{
+ int len;
+ char buf[CACHE_BUFSIZE];
+ printf("(%d)listening network %d => message queue %d\n",
+ getpid(), netfd, msgfd);
+ while( Read(netfd, &len, 4) > 0 ){
+ if( Read(netfd, buf, len) < 0 )
+ err(1, "(network)read()");
+ if( msgsnd(msgfd, buf, len, 0) < 0 )
+ err(1, "(network)msgsnd()");
+ }
+ exit(0);
+}
+
+void listenmsgqueue(int netfd, int msgfd)
+{
+ char buf[CACHE_BUFSIZE];
+ OCbuf_t *ptr;
+ int len;
+ printf("(%d)listening message queue %d => network %d\n",
+ getpid(), msgfd, netfd);
+ while( msgrcv(msgfd, buf, CACHE_BUFSIZE, 0, 0) > 0 ){
+ ptr = (OCbuf_t *)buf;
+ len = ptr->length + OC_HEADERLEN;
+ if( write(netfd, &len, sizeof(len)) < 0 ||
+ write(netfd, ptr, ptr->length + OC_HEADERLEN) < 0 )
+ err(1, "(msgqueue)write()");
+ }
+ err(1, "(msgqueue)msgrcv()");
+ 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;
+}
+