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 */
-}