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);
}
}