]> arthur.barton.de Git - netatalk.git/blobdiff - bin/misc/fce.c
Fix compiler diagnostics
[netatalk.git] / bin / misc / fce.c
index 863665b408c4187e0820cd799e45b6a5064fc718..23101bfbb34ed7a1622c488f82a1fa4e58278c88 100644 (file)
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/param.h>
 
 #include <atalk/fce_api.h>
+#include <atalk/util.h>
+
+#define MAXBUFLEN 1024
 
-#define MAXBUFLEN 100
+static char *fce_ev_names[] = {
+    "",
+    "FCE_FILE_MODIFY",
+    "FCE_FILE_DELETE",
+    "FCE_DIR_DELETE",
+    "FCE_FILE_CREATE",
+    "FCE_DIR_CREATE"
+};
 
-// get sockaddr, IPv4 or IPv6:
-void *get_in_addr(struct sockaddr *sa)
+static int unpack_fce_packet(unsigned char *buf, struct fce_packet *packet)
 {
-    if (sa->sa_family == AF_INET) {
-        return &(((struct sockaddr_in*)sa)->sin_addr);
-    }
+    unsigned char *p = buf;
+
+    memcpy(&packet->magic[0], p, sizeof(packet->magic));
+    p += sizeof(packet->magic);
+
+    packet->version = *p;
+    p++;
 
-    return &(((struct sockaddr_in6*)sa)->sin6_addr);
+    packet->mode = *p;
+    p++;
+
+    memcpy(&packet->event_id, p, sizeof(packet->event_id));
+    p += sizeof(packet->event_id);
+    packet->event_id = ntohl(packet->event_id);
+
+    memcpy(&packet->datalen, p, sizeof(packet->datalen));
+    p += sizeof(packet->datalen);
+    packet->datalen = ntohs(packet->datalen);
+
+    memcpy(&packet->data[0], p, packet->datalen);
+    packet->data[packet->datalen] = 0; /* 0 terminate strings */
+    p += packet->datalen;
+
+    return 0;
 }
 
 int main(void)
@@ -32,12 +67,10 @@ int main(void)
     struct sockaddr_storage their_addr;
     char buf[MAXBUFLEN];
     socklen_t addr_len;
-    char s[INET6_ADDRSTRLEN];
 
     memset(&hints, 0, sizeof hints);
     hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
     hints.ai_socktype = SOCK_DGRAM;
-//    hints.ai_flags = AI_PASSIVE; // use my IP
 
     if ((rv = getaddrinfo(NULL, FCE_DEFAULT_PORT_STRING, &hints, &servinfo)) != 0) {
         fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
@@ -71,21 +104,40 @@ int main(void)
     printf("listener: waiting to recvfrom...\n");
 
     addr_len = sizeof their_addr;
-    if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
-                             (struct sockaddr *)&their_addr, &addr_len)) == -1) {
-        perror("recvfrom");
-        exit(1);
-    }
 
-    printf("listener: got packet from %s\n",
-           inet_ntop(their_addr.ss_family,
-                     get_in_addr((struct sockaddr *)&their_addr),
-                     s, sizeof s));
-    printf("listener: packet is %d bytes long\n", numbytes);
-    buf[numbytes] = '\0';
-    printf("listener: packet contains \"%s\"\n", buf);
+    struct fce_packet packet;
+    while (1) {
+        if ((numbytes = recvfrom(sockfd,
+                                 buf,
+                                 MAXBUFLEN - 1,
+                                 0,
+                                 (struct sockaddr *)&their_addr,
+                                 &addr_len)) == -1) {
+            perror("recvfrom");
+            exit(1);
+        }
 
-    close(sockfd);
+        unpack_fce_packet((unsigned char *)buf, &packet);
+
+        if (memcmp(packet.magic, FCE_PACKET_MAGIC, sizeof(packet.magic)) == 0) {
+
+            switch (packet.mode) {
+            case FCE_CONN_START:
+                printf("FCE Start\n");
+                break;
 
+            case FCE_CONN_BROKEN:
+                printf("Broken FCE connection\n");
+                break;
+
+            default:
+                printf("ID: %" PRIu32 ", Event: %s, Path: %s\n",
+                       packet.event_id, fce_ev_names[packet.mode], packet.data);
+                break;
+            }
+        }
+    }
+
+    close(sockfd);
     return 0;
 }