]> arthur.barton.de Git - netatalk.git/blobdiff - bin/misc/fce.c
fce: FCE version 2 with new event types and new config options
[netatalk.git] / bin / misc / fce.c
index 23101bfbb34ed7a1622c488f82a1fa4e58278c88..cd767e9aa110647e2c5969589594e0acf86808a1 100644 (file)
@@ -27,52 +27,103 @@ static char *fce_ev_names[] = {
     "FCE_FILE_DELETE",
     "FCE_DIR_DELETE",
     "FCE_FILE_CREATE",
-    "FCE_DIR_CREATE"
+    "FCE_DIR_CREATE",
+    "FCE_FILE_MOVE",
+    "FCE_DIR_MOVE",
+    "FCE_LOGIN",
+    "FCE_LOGOUT"
 };
 
 static int unpack_fce_packet(unsigned char *buf, struct fce_packet *packet)
 {
     unsigned char *p = buf;
+    uint16_t uint16;
+    uint32_t uint32;
+    uint64_t uint64;
 
-    memcpy(&packet->magic[0], p, sizeof(packet->magic));
-    p += sizeof(packet->magic);
+    memcpy(&packet->fcep_magic[0], p, sizeof(packet->fcep_magic));
+    p += sizeof(packet->fcep_magic);
 
-    packet->version = *p;
-    p++;
+    packet->fcep_version = *p++;
 
-    packet->mode = *p;
-    p++;
+    if (packet->fcep_version > 1)
+        packet->fcep_options = *p++;
 
-    memcpy(&packet->event_id, p, sizeof(packet->event_id));
-    p += sizeof(packet->event_id);
-    packet->event_id = ntohl(packet->event_id);
+    packet->fcep_event = *p++;
 
-    memcpy(&packet->datalen, p, sizeof(packet->datalen));
-    p += sizeof(packet->datalen);
-    packet->datalen = ntohs(packet->datalen);
+    if (packet->fcep_version > 1)
+        /* padding */
+        p++;
 
-    memcpy(&packet->data[0], p, packet->datalen);
-    packet->data[packet->datalen] = 0; /* 0 terminate strings */
-    p += packet->datalen;
+    if (packet->fcep_version > 1)
+        /* reserved */
+        p += 8;
+
+    memcpy(&packet->fcep_event_id, p, sizeof(packet->fcep_event_id));
+    p += sizeof(packet->fcep_event_id);
+    packet->fcep_event_id = ntohl(packet->fcep_event_id);
+
+    if (packet->fcep_options & FCE_EV_INFO_PID) {
+        memcpy(&packet->fcep_pid, p, sizeof(packet->fcep_pid));
+        packet->fcep_pid = hton64(packet->fcep_pid);
+        p += sizeof(packet->fcep_pid);
+    }
+
+    if (packet->fcep_options & FCE_EV_INFO_USER) {
+        memcpy(&packet->fcep_userlen, p, sizeof(packet->fcep_userlen));
+        packet->fcep_userlen = ntohs(packet->fcep_userlen);
+        p += sizeof(packet->fcep_userlen);
+
+        memcpy(&packet->fcep_user[0], p, packet->fcep_userlen);
+        packet->fcep_user[packet->fcep_userlen] = 0; /* 0 terminate strings */
+        p += packet->fcep_userlen;
+    }
+
+    /* path */
+    memcpy(&packet->fcep_pathlen1, p, sizeof(packet->fcep_pathlen1));
+    p += sizeof(packet->fcep_pathlen1);
+    packet->fcep_pathlen1 = ntohs(packet->fcep_pathlen1);
+
+    memcpy(&packet->fcep_path1[0], p, packet->fcep_pathlen1);
+    packet->fcep_path1[packet->fcep_pathlen1] = 0; /* 0 terminate strings */
+    p += packet->fcep_pathlen1;
+
+    if (packet->fcep_options & FCE_EV_INFO_SRCPATH) {
+        memcpy(&packet->fcep_pathlen2, p, sizeof(packet->fcep_pathlen2));
+        p += sizeof(packet->fcep_pathlen2);
+        packet->fcep_pathlen2 = ntohs(packet->fcep_pathlen2);
+        memcpy(&packet->fcep_path2[0], p, packet->fcep_pathlen2);
+        packet->fcep_path2[packet->fcep_pathlen2] = 0; /* 0 terminate strings */
+        p += packet->fcep_pathlen2;
+    }
 
     return 0;
 }
 
-int main(void)
+int main(int argc, char **argv)
 {
-    int sockfd;
+    int sockfd, rv, c;
     struct addrinfo hints, *servinfo, *p;
-    int rv;
     int numbytes;
     struct sockaddr_storage their_addr;
     char buf[MAXBUFLEN];
     socklen_t addr_len;
+    char s[INET6_ADDRSTRLEN];
+    char *host = "localhost";
+
+    while ((c = getopt(argc, argv, "h:")) != -1) {
+        switch(c) {
+        case 'h':
+            host = strdup(optarg);
+            break;
+        }
+    }
 
     memset(&hints, 0, sizeof hints);
     hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
     hints.ai_socktype = SOCK_DGRAM;
 
-    if ((rv = getaddrinfo(NULL, FCE_DEFAULT_PORT_STRING, &hints, &servinfo)) != 0) {
+    if ((rv = getaddrinfo(host, FCE_DEFAULT_PORT_STRING, &hints, &servinfo)) != 0) {
         fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
         return 1;
     }
@@ -119,9 +170,9 @@ int main(void)
 
         unpack_fce_packet((unsigned char *)buf, &packet);
 
-        if (memcmp(packet.magic, FCE_PACKET_MAGIC, sizeof(packet.magic)) == 0) {
+        if (memcmp(packet.fcep_magic, FCE_PACKET_MAGIC, sizeof(packet.fcep_magic)) == 0) {
 
-            switch (packet.mode) {
+            switch (packet.fcep_event) {
             case FCE_CONN_START:
                 printf("FCE Start\n");
                 break;
@@ -131,8 +182,16 @@ int main(void)
                 break;
 
             default:
-                printf("ID: %" PRIu32 ", Event: %s, Path: %s\n",
-                       packet.event_id, fce_ev_names[packet.mode], packet.data);
+                printf("ID: %" PRIu32 ", Event: %s", packet.fcep_event_id, fce_ev_names[packet.fcep_event]);
+                if (packet.fcep_options & FCE_EV_INFO_PID)
+                    printf(", pid: %" PRId64, packet.fcep_pid);
+                if (packet.fcep_options & FCE_EV_INFO_USER)
+                    printf(", user: %s", packet.fcep_user);
+
+                if (packet.fcep_options & FCE_EV_INFO_SRCPATH)
+                    printf(", source: %s", packet.fcep_path2);
+
+                printf(", Path: %s\n", packet.fcep_path1);
                 break;
             }
         }