tMove client/server part into a single program - synk - synchronize files between hosts
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 01aea7ee2faa01002207932529972d3c491dfca1
 (DIR) parent 78511ee61482c9fbf336fa601f841113a5544d1e
 (HTM) Author: Willy <willyatmailoodotorg>
       Date:   Tue, 16 Aug 2016 14:02:00 +0200
       
       Move client/server part into a single program
       
       Diffstat:
         M mkfile                              |       4 ++--
         M synk.c                              |     124 ++++++++++++++++++++++++++++---
         D synkd.c                             |     127 -------------------------------
       
       3 files changed, 116 insertions(+), 139 deletions(-)
       ---
 (DIR) diff --git a/mkfile b/mkfile
       t@@ -1,6 +1,6 @@
        <config.mk
        
       -all:V: synk synkd
       +all:V: synk
        
        %: %.o
                $LD -o $target $prereq $LDFLAGS $LIBS
       t@@ -9,7 +9,7 @@ all:V: synk synkd
                $CC $CFLAGS -c $stem.c -o $stem.o
        
        clean:V:
       -        rm -f *.o synk synkd
       +        rm -f *.o synk
        
        install:V: all
                mkdir -p ${DESTDIR}${PREFIX}/bin
 (DIR) diff --git a/synk.c b/synk.c
       t@@ -11,23 +11,116 @@
        
        #include "arg.h"
        
       -#define SERVER_HOST "127.0.0.1"
       -#define SERVER_PORT 9723
       +#define SERVER_HOST    "127.0.0.1"
       +#define SERVER_PORT    9723
       +#define TIMESTAMP_MAX  32
       +#define CONNECTION_MAX 1
       +
       +struct client_t {
       +        int fd;
       +        struct in_addr in;
       +};
       +
       +enum {
       +        SYNK_CLIENT,
       +        SYNK_SERVER
       +};
        
        void
        usage(char *name)
        {
       -        fprintf(stderr, "usage: %s [-h HOST] [-p PORT] FILE\n", name),
       +        fprintf(stderr, "usage: %s [-s] [-h HOST] [-p PORT] [FILE..]\n", name),
                exit(1);
        }
        
       +void *
       +handleclient(void *arg)
       +{
       +        int i = 0;
       +        char path[PATH_MAX] = "", ts[32] = "";
       +        size_t len = 0;
       +        struct stat sb;
       +        struct client_t *c = *(struct client_t **)arg;
       +
       +        printf("%s: connected\n", inet_ntoa(c->in));
       +        while ((len = read(c->fd, &path, PATH_MAX)) > 0) {
       +                if (i > PATH_MAX) {
       +                        printf("%s: filename too long (>%d)\n", inet_ntoa(c->in), PATH_MAX);
       +                        break;
       +                }
       +
       +                path[len] = '\0';
       +                printf("%s: %s\n", inet_ntoa(c->in), path);
       +                stat(path, &sb);
       +                snprintf(ts, 32, "%lu", sb.st_mtim.tv_sec);
       +                len = strnlen(ts, 32);
       +                write(c->fd, ts, len);
       +                memset(path, 0, PATH_MAX);
       +                i = 0;
       +        }
       +
       +        close(c->fd);
       +        len = 0;
       +        printf("%s: disconnected\n", inet_ntoa(c->in));
       +        free(c);
       +        pthread_exit((int *)&len);
       +}
       +
       +int
       +server(in_addr_t host, in_port_t port)
       +{
       +        int sfd;
       +        int cfd;
       +        socklen_t len;
       +        struct sockaddr_in clt;
       +        struct sockaddr_in srv;
       +        struct client_t *c = NULL;
       +        pthread_t th;
       +
       +        if ((sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
       +                perror("socket");
       +                return 1;
       +        }
       +
       +        memset(&srv, 0, sizeof(srv));
       +        srv.sin_family        = AF_INET;
       +        srv.sin_addr.s_addr   = htonl(host);
       +        srv.sin_port          = htons(port);
       +
       +        if (bind(sfd, (struct sockaddr *)&srv, sizeof(srv)) < 0) {
       +                perror("bind");
       +                return 1;
       +        }
       +
       +        if (listen(sfd, CONNECTION_MAX) < 0) {
       +                perror("listen");
       +                return 1;
       +        }
       +
       +        for (;;) {
       +                len = sizeof(clt);
       +                if ((cfd = accept(sfd, (struct sockaddr *)&clt, &len)) < 0) {
       +                        perror("accept");
       +                        return 1;
       +                }
       +
       +                c = malloc(sizeof(struct client_t));
       +                c->fd = cfd;
       +                c->in = clt.sin_addr;
       +
       +                pthread_create(&th, NULL, handleclient, &c);
       +        }
       +
       +        return 0;
       +}
       +
        int
        client(in_addr_t host, in_port_t port, const char *fn)
        {
                int cfd;
       -        size_t len = 0;
       +        ssize_t len = 0;
                struct sockaddr_in clt;
       -        char path[PATH_MAX] = "", ts[PATH_MAX] = "";
       +        char path[PATH_MAX] = "", ts[TIMESTAMP_MAX] = "";
                
                if ((cfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
                        perror("socket");
       t@@ -40,10 +133,11 @@ client(in_addr_t host, in_port_t port, const char *fn)
                clt.sin_port          = htons(port);
        
                if (connect(cfd, (struct sockaddr *)&clt, sizeof(clt)) < 0) {
       -                perror("connect");
       -                return 1;
       +                perror(inet_ntoa(clt.sin_addr));
       +                return -1;
                }
        
       +        /* we first send a filename to the server ... */
                snprintf(path, PATH_MAX, "%s", fn);
                len = strnlen(path, PATH_MAX);
                printf("%s: %s\n", inet_ntoa(clt.sin_addr), path);
       t@@ -52,7 +146,8 @@ client(in_addr_t host, in_port_t port, const char *fn)
                        return -1;
                }
        
       -        read(cfd, ts, PATH_MAX);
       +        /* ... which should return the timestamp of this file */
       +        read(cfd, ts, TIMESTAMP_MAX);
                printf("%s: %s\n", path, ts);
        
                close(cfd);
       t@@ -64,17 +159,26 @@ int
        main(int argc, char *argv[])
        {
                char *argv0;
       +        uint8_t mode = SYNK_CLIENT;
                in_port_t port = SERVER_PORT;
                in_addr_t host = INADDR_LOOPBACK;
        
                ARGBEGIN{
                case 'h': host = inet_network(EARGF(usage(argv0))); break;
                case 'p': port = atoi(EARGF(usage(argv0))); break;
       +        case 's': mode = SYNK_SERVER; break;
                }ARGEND;
        
       -        if (argc < 1)
       +        if (mode == SYNK_CLIENT && argc < 1)
                        usage(argv0);
        
       -        client(host, port, argv[0]);
       +        switch(mode) {
       +        case SYNK_CLIENT:
       +                client(host, port, argv[0]);
       +                break;
       +        case SYNK_SERVER:
       +                server(host, port);
       +                break; /* NOTREACHED */
       +        }
                return 0;
        }
 (DIR) diff --git a/synkd.c b/synkd.c
       t@@ -1,127 +0,0 @@
       -#include <limits.h>
       -#include <pthread.h>
       -#include <stdio.h>
       -#include <stdlib.h>
       -#include <string.h>
       -#include <unistd.h>
       -#include <arpa/inet.h>
       -#include <sys/socket.h>
       -#include <sys/stat.h>
       -#include <sys/types.h>
       -
       -#include "arg.h"
       -
       -#define LISTEN_PORT 9723
       -#define MAXCONN 10
       -
       -struct client_t {
       -        int fd;
       -        struct in_addr in;        
       -};
       -
       -void
       -usage(char *name) {
       -        fprintf(stderr, "usage: %s [-h HOST] [-p PORT]\n", name);
       -        exit(1);
       -}
       -
       -void *
       -handleclient(void *arg)
       -{
       -        int i = 0;
       -        char path[PATH_MAX] = "", ts[32] = "";
       -        size_t len = 0;
       -        struct stat sb;
       -        struct client_t *c = *(struct client_t **)arg;
       -
       -        printf("%s: connected\n", inet_ntoa(c->in));
       -        while ((len = read(c->fd, &path, PATH_MAX)) > 0) {
       -                if (i > PATH_MAX) {
       -                        printf("%s: filename too long (>%d)\n", inet_ntoa(c->in), PATH_MAX);
       -                        break;
       -                }
       -
       -                path[len] = '\0';
       -                printf("%s: %s\n", inet_ntoa(c->in), path);
       -                stat(path, &sb);
       -                snprintf(ts, 32, "%lu", sb.st_mtim.tv_sec);
       -                len = strnlen(ts, 32);
       -                write(c->fd, ts, len);
       -                memset(path, 0, PATH_MAX);
       -                i = 0;
       -        }
       -
       -        close(c->fd);
       -        len = 0;
       -        printf("%s: disconnected\n", inet_ntoa(c->in));
       -        free(c);
       -        pthread_exit((int *)&len);
       -}
       -
       -int
       -server(in_addr_t host, in_port_t port)
       -{
       -        int sfd;
       -        int cfd;
       -        socklen_t len;
       -        struct sockaddr_in clt;
       -        struct sockaddr_in srv;
       -        struct client_t *c = NULL;
       -        pthread_t th;
       -
       -        if ((sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
       -                perror("socket");
       -                return 1;
       -        }
       -
       -        memset(&srv, 0, sizeof(srv));
       -        srv.sin_family        = AF_INET;
       -        srv.sin_addr.s_addr   = htonl(host);
       -        srv.sin_port          = htons(port);
       -
       -        if (bind(sfd, (struct sockaddr *)&srv, sizeof(srv)) < 0) {
       -                perror("bind");
       -                return 1;
       -        }
       -
       -        if (listen(sfd, MAXCONN) < 0) {
       -                perror("listen");
       -                return 1;
       -        }
       -
       -        for (;;) {
       -                len = sizeof(clt);
       -                if ((cfd = accept(sfd, (struct sockaddr *)&clt, &len)) < 0) {
       -                        perror("accept");
       -                        return 1;
       -                }
       -
       -                c = malloc(sizeof(struct client_t));
       -                c->fd = cfd;
       -                c->in = clt.sin_addr;
       -
       -                pthread_create(&th, NULL, handleclient, &c);
       -        }
       -        return 0;
       -}
       -
       -int
       -main(int argc, char *argv[])
       -{
       -        char *argv0;
       -        in_port_t port = LISTEN_PORT;
       -        in_addr_t host = INADDR_LOOPBACK;
       -
       -        ARGBEGIN{
       -        case 'h':
       -                host = inet_network(EARGF(usage(argv0)));
       -                break;
       -        case 'p':
       -                port = atoi(EARGF(usage(argv0)));
       -                break;
       -        }ARGEND;
       -        
       -        server(host, port);
       -
       -        return 0; /* NOTREACHED */
       -}