tAdd SLIST for peers handling - synk - synchronize files between hosts
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 613d8bc78a5d4230b4c6157ae1921d548569405b
 (DIR) parent 23aed767285fc976c45fbb874cc11fef0ccb464d
 (HTM) Author: Willy <willyatmailoodotorg>
       Date:   Wed, 24 Aug 2016 15:13:36 +0200
       
       Add SLIST for peers handling
       
       Diffstat:
         M synk.c                              |      86 ++++++++++++++++++++++---------
       
       1 file changed, 61 insertions(+), 25 deletions(-)
       ---
 (DIR) diff --git a/synk.c b/synk.c
       t@@ -6,6 +6,7 @@
        #include <string.h>
        #include <unistd.h>
        #include <arpa/inet.h>
       +#include <sys/queue.h>
        #include <sys/socket.h>
        #include <sys/stat.h>
        #include <sys/types.h>
       t@@ -19,30 +20,40 @@
        #define TIMESTAMP_MAX  19 /* length of LONG_MAX */
        #define CONNECTION_MAX 1
        
       -
       +/* hold a socket connection, used to pass a connection to a thread */
        struct client_t {
                int fd;
                struct in_addr inet;
        };
        
       +/* metadata informations about a file, to decide about the synkro state */
        struct metadata_t {
                char path[PATH_MAX];
                unsigned char hash[64];
                long mtime;
        };
        
       +/* singly-linked list for all the nodes that should be in synk */
       +struct node_t {
       +        struct metadata_t meta;
       +        struct sockaddr_in peer;
       +        SLIST_ENTRY(node_t) entries;
       +};
       +
       +/* different operationnal mode for TCP connection */
        enum {
                SYNK_CLIENT,
                SYNK_SERVER
        };
        
        const char *rsync_cmd[] = { "rsync", "-azEq", "--delete", NULL };
       +SLIST_HEAD(head_node_t, node_t) head;
        
        void  usage(char *name);
        long  gettimestamp(const char *path);
        void *handleclient(void *arg);
        int   server(in_addr_t, in_port_t);
       -int   client(in_addr_t, in_port_t, FILE *, const char *path);
       +int   client(struct metadata_t, struct node_t *);
        
        void
        usage(char *name)
       t@@ -97,8 +108,6 @@ handleclient(void *arg)
        
                local.mtime = gettimestamp(local.path);
        
       -        printf("%s: %s\t%s\t%lu\n", inet_ntoa(c->inet), local.path,
       -                                    sha512_format(local.hash), local.mtime);
                /* .. and send it to the client */
                write(c->fd, &local, sizeof(local));
                close(c->fd);
       t@@ -169,49 +178,76 @@ server(in_addr_t host, in_port_t port)
         * socket. Connection is terminated after receiving the timestamp
         */
        int
       -client(in_addr_t host, in_port_t port, FILE *f, const char *fn)
       +client(struct metadata_t local, struct node_t *clt)
        {
                int cfd;
                ssize_t len = 0;
       -        struct sockaddr_in clt;
       -        struct metadata_t local, remote;
       -
       -        memset(&local, 0, sizeof(local));
       -        memset(&remote, 0, sizeof(remote));
        
                if ((cfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
                        perror("socket");
                        return 1;
                }
        
       -        memset(&clt, 0, sizeof(clt));
       -        clt.sin_family        = AF_INET;
       -        clt.sin_addr.s_addr   = htonl(host);
       -        clt.sin_port          = htons(port);
       -
       -        if (connect(cfd, (struct sockaddr *)&clt, sizeof(clt)) < 0) {
       -                perror(inet_ntoa(clt.sin_addr));
       +        if (connect(cfd, (struct sockaddr *) &(clt->peer), sizeof(clt->peer)) < 0) {
       +                perror(inet_ntoa(clt->peer.sin_addr));
                        return -1;
                }
        
       -        sha512(f, local.hash);
       -        snprintf(local.path, PATH_MAX, "%s", fn);
       -        local.mtime = gettimestamp(local.path);
       -
                if ((len = write(cfd, &local, sizeof(struct metadata_t))) < 0) {
                        perror("write");
                        return -1;
                }
        
                /* ... which should return the timestamp of this file */
       -        if ((len = read(cfd, &remote, sizeof(struct metadata_t))) < 0) {
       +        if ((len = read(cfd, &(clt->meta), sizeof(struct metadata_t))) < 0) {
                        perror("write");
                        return -1;
                }
        
       -        printf("%s\t%s\n", local.path, sha512_compare(local.hash, remote.hash)?"NOT SYNKED":"SYNKED");
       +        if (sha512_compare(local.hash, clt->meta.hash) == 0) {
       +                printf("%s\tSYNKED\n", local.path);
       +        } else {
       +                printf("%s\t%s\t%s\t%lu\n", inet_ntoa(clt->peer.sin_addr), clt->meta.path, sha512_format(clt->meta.hash), clt->meta.mtime);
       +        }
       +
       +        return close(cfd);
       +}
       +
       +int
       +synkronize(in_addr_t host, in_port_t port, FILE *f, const char *fn)
       +{
       +        int cfd;
       +        struct metadata_t local;
       +        struct node_t *tmp = NULL;
       +
       +        memset(&local, 0, sizeof(local));
       +
       +        sha512(f, local.hash);
       +        snprintf(local.path, PATH_MAX, "%s", fn);
       +        local.mtime = gettimestamp(local.path);
       +        printf("localhost\t%s\t%s\t%lu\n", local.path, sha512_format(local.hash), local.mtime);
       +
       +        tmp = malloc(sizeof(struct node_t));
       +
       +        memset(&tmp->meta, 0, sizeof(struct metadata_t));
       +        memset(&tmp->peer, 0, sizeof(struct sockaddr_in));
       +
       +        if ((cfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
       +                perror("socket");
       +                return 1;
       +        }
       +
       +        tmp->peer.sin_family        = AF_INET;
       +        tmp->peer.sin_addr.s_addr   = htonl(host);
       +        tmp->peer.sin_port          = htons(port);
        
       -        close(cfd);
       +        SLIST_INIT(&head);
       +        SLIST_INSERT_HEAD(&head, tmp, entries);
       +
       +        SLIST_FOREACH(tmp, &head, entries) {
       +                client(local, tmp);
       +                SLIST_REMOVE(&head, tmp, node_t, entries);
       +        }
        
                return 0;
        }
       t@@ -239,7 +275,7 @@ main(int argc, char *argv[])
                        while ((fn = *(argv++)) != NULL) {
                                f = fopen(fn, "r");
                                if (f) {
       -                                client(host, port, f, fn);
       +                                synkronize(host, port, f, fn);
                                        fclose(f);
                                }
                        }