]> arthur.barton.de Git - netatalk.git/commitdiff
Allow enabling/disabling notifications on a per event type basis
authorFrank Lahm <franklahm@googlemail.com>
Mon, 30 May 2011 13:26:38 +0000 (15:26 +0200)
committerFrank Lahm <franklahm@googlemail.com>
Mon, 30 May 2011 13:26:38 +0000 (15:26 +0200)
etc/afpd/afp_options.c
etc/afpd/fce_api.c
etc/afpd/fce_api_internal.h
etc/afpd/volume.c
include/atalk/fce_api.h

index 7a2d405f82045aa4947d986a4b55a595f037d21a..82db1c8e5bae81acf233e733b5fe96f8b96d719a 100644 (file)
@@ -487,6 +487,10 @@ int afp_options_parseline(char *buf, struct afp_options *options)
                LOG(log_note, logtype_afpd, "Fce coalesce: %s", c);
                fce_set_coalesce(c);
        }
+       if ((c = getoption(buf, "-fceevents"))) {
+               LOG(log_note, logtype_afpd, "Fce events: %s", c);
+               fce_set_events(c);
+       }
 
     return 1;
 }
index 8df502b6e7b77351f8d778fd5358c5b016f2203e..0240b547eb29221488a4392abb816abcd8a0ff49 100755 (executable)
@@ -65,8 +65,8 @@
 static struct udp_entry udp_socket_list[FCE_MAX_UDP_SOCKS];\r
 static int udp_sockets = 0;\r
 static int udp_initialized = FCE_FALSE;\r
-\r
-\r
+static unsigned long fce_ev_enabled = 0;\r
+static size_t tm_used;          /* used for passing to event handler */\r
 static const char *skip_files[] = \r
 {\r
        ".DS_Store",\r
@@ -278,7 +278,7 @@ static int add_udp_socket(const char *target_ip, const char *target_port )
  * Dispatcher for all incoming file change events\r
  *\r
  * */\r
-static int register_fce( char *u_name, int is_dir, int mode )\r
+static int register_fce(const char *u_name, int is_dir, int mode)\r
 {\r
     if (udp_sockets == 0)\r
         /* No listeners configured */\r
@@ -293,6 +293,12 @@ static int register_fce( char *u_name, int is_dir, int mode )
        if (first_event)\r
        {\r
                fce_initialize_history();\r
+        fce_ev_enabled =\r
+            (1 << FCE_FILE_MODIFY) |\r
+            (1 << FCE_FILE_DELETE) |\r
+            (1 << FCE_DIR_DELETE) |\r
+            (1 << FCE_FILE_CREATE) |\r
+            (1 << FCE_DIR_CREATE);\r
        }\r
 \r
 \r
@@ -307,19 +313,16 @@ static int register_fce( char *u_name, int is_dir, int mode )
        char full_path_buffer[FCE_MAX_PATH_LEN + 1] = {""};\r
        const char *cwd = getcwdpath();\r
 \r
-       if (!is_dir || mode == FCE_DIR_DELETE)\r
-       {\r
-               if (strlen( cwd ) + strlen( u_name) + 1 >= FCE_MAX_PATH_LEN)\r
-               {\r
+    if (mode & FCE_TM_SIZE) {\r
+        strncpy(full_path_buffer, u_name, FCE_MAX_PATH_LEN);\r
+    } else if (!is_dir || mode == FCE_DIR_DELETE) {\r
+               if (strlen( cwd ) + strlen( u_name) + 1 >= FCE_MAX_PATH_LEN) {\r
                        LOG(log_error, logtype_afpd, "FCE file name too long: %s/%s", cwd, u_name );\r
                        return AFPERR_PARAM;\r
                }\r
                sprintf( full_path_buffer, "%s/%s", cwd, u_name );\r
-       }\r
-       else\r
-       {\r
-               if (strlen( cwd ) >= FCE_MAX_PATH_LEN)\r
-               {\r
+       } else {\r
+               if (strlen( cwd ) >= FCE_MAX_PATH_LEN) {\r
                        LOG(log_error, logtype_afpd, "FCE directory name too long: %s", cwd);\r
                        return AFPERR_PARAM;\r
                }\r
@@ -327,7 +330,7 @@ static int register_fce( char *u_name, int is_dir, int mode )
        }\r
 \r
        /* Can we ignore this event based on type or history? */\r
-       if (fce_handle_coalescation( full_path_buffer, is_dir, mode ))\r
+       if (!(mode & FCE_TM_SIZE) && fce_handle_coalescation( full_path_buffer, is_dir, mode ))\r
        {\r
                LOG(log_debug9, logtype_afpd, "Coalesced fc event <%d> for <%s>", mode, full_path_buffer );\r
                return AFP_OK;\r
@@ -363,7 +366,6 @@ static int register_fce( char *u_name, int is_dir, int mode )
  * */\r
 #ifndef FCE_TEST_MAIN\r
 \r
-\r
 int fce_register_delete_file( struct path *path )\r
 {\r
     int ret = AFP_OK;\r
@@ -371,6 +373,8 @@ int fce_register_delete_file( struct path *path )
     if (path == NULL)\r
         return AFPERR_PARAM;\r
 \r
+    if (!(fce_ev_enabled & (1 << FCE_FILE_DELETE)))\r
+        return ret;\r
        \r
     ret = register_fce( path->u_name, FALSE, FCE_FILE_DELETE );\r
 \r
@@ -383,6 +387,8 @@ int fce_register_delete_dir( char *name )
     if (name == NULL)\r
         return AFPERR_PARAM;\r
 \r
+    if (!(fce_ev_enabled & (1 << FCE_DIR_DELETE)))\r
+        return ret;\r
        \r
     ret = register_fce( name, TRUE, FCE_DIR_DELETE);\r
 \r
@@ -396,6 +402,9 @@ int fce_register_new_dir( struct path *path )
     if (path == NULL)\r
         return AFPERR_PARAM;\r
 \r
+    if (!(fce_ev_enabled & (1 << FCE_DIR_CREATE)))\r
+        return ret;\r
+\r
     ret = register_fce( path->u_name, TRUE, FCE_DIR_CREATE );\r
 \r
     return ret;\r
@@ -409,12 +418,14 @@ int fce_register_new_file( struct path *path )
     if (path == NULL)\r
         return AFPERR_PARAM;\r
 \r
+    if (!(fce_ev_enabled & (1 << FCE_FILE_CREATE)))\r
+        return ret;\r
+\r
     ret = register_fce( path->u_name, FALSE, FCE_FILE_CREATE );\r
 \r
     return ret;\r
 }\r
 \r
-\r
 int fce_register_file_modification( struct ofork *ofork )\r
 {\r
     char *u_name = NULL;\r
@@ -424,6 +435,9 @@ int fce_register_file_modification( struct ofork *ofork )
     if (ofork == NULL || ofork->of_vol == NULL)\r
         return AFPERR_PARAM;\r
 \r
+    if (!(fce_ev_enabled & (1 << FCE_FILE_MODIFY)))\r
+        return ret;\r
+\r
     vol = ofork->of_vol;\r
 \r
     if (NULL == (u_name = mtoupath(vol, of_name(ofork), ofork->of_did, utf8_encoding()))) \r
@@ -435,6 +449,22 @@ int fce_register_file_modification( struct ofork *ofork )
     \r
     return ret;    \r
 }\r
+\r
+int fce_register_tm_size(const char *vol, size_t used)\r
+{\r
+    int ret = AFP_OK;\r
+\r
+    if (vol == NULL)\r
+        return AFPERR_PARAM;\r
+\r
+    if (!(fce_ev_enabled & (1 << FCE_TM_SIZE)))\r
+        return ret;\r
+\r
+    tm_used = used;             /* oh what a hack */\r
+    ret = register_fce(vol, FALSE, FCE_TM_SIZE);\r
+\r
+    return ret;\r
+}\r
 #endif\r
 \r
 /*\r
@@ -457,7 +487,35 @@ int fce_add_udp_socket(const char *target)
        return add_udp_socket(target_ip, port);\r
 }\r
 \r
+int fce_set_events(const char *events)\r
+{\r
+    char *e;\r
+    char *p;\r
+    \r
+    if (events == NULL)\r
+        return AFPERR_PARAM;\r
+\r
+    e = strdup(events);\r
+    fce_ev_enabled = 0;\r
+\r
+    for (p = strtok(e, ","); p; p = strtok(NULL, ",")) {\r
+        if (strcmp(e, "fmod") == 0) {\r
+            fce_ev_enabled |= FCE_FILE_MODIFY;\r
+        } else if (strcmp(e, "fdel") == 0) {\r
+            fce_ev_enabled |= FCE_FILE_DELETE;\r
+        } else if (strcmp(e, "ddel") == 0) {\r
+            fce_ev_enabled |= FCE_DIR_DELETE;\r
+        } else if (strcmp(e, "fcre") == 0) {\r
+            fce_ev_enabled |= FCE_FILE_CREATE;\r
+        } else if (strcmp(e, "dcre") == 0) {\r
+            fce_ev_enabled |= FCE_DIR_CREATE;\r
+        } else if (strcmp(e, "tmsz") == 0) {\r
+            fce_ev_enabled |= FCE_TM_SIZE;\r
+        }\r
+    }\r
 \r
+    free(e);\r
+}\r
 \r
 #ifdef FCE_TEST_MAIN\r
 \r
index 9f2049fd1e0eeff5fe68a25e4050ce2974eab1a2..37988e89b53c4c4ad546ad9d93ad7ff6d5760b51 100755 (executable)
@@ -8,18 +8,6 @@
 #ifndef _FCE_API_INTERNAL_H\r
 #define        _FCE_API_INTERNAL_H\r
 \r
-/* fce_packet.mode */\r
-#define FCE_FILE_MODIFY     1\r
-#define FCE_FILE_DELETE     2\r
-#define FCE_DIR_DELETE      3\r
-#define FCE_FILE_CREATE     4\r
-#define FCE_DIR_CREATE      5\r
-#define FCE_CONN_START     42\r
-#define FCE_CONN_BROKEN    99\r
-\r
-/* fce_packet.fce_magic */\r
-#define FCE_PACKET_MAGIC  "at_fcapi"\r
-\r
 #define FCE_MAX_PATH_LEN 1024\r
 #define FCE_MAX_UDP_SOCKS 5     /* Allow a maximum of udp listeners for file change events */\r
 #define FCE_SOCKET_RETRY_DELAY_S 600 /* Pause this time in s after socket was broken */\r
@@ -36,28 +24,14 @@ struct udp_entry
     time_t next_try_on_error;      /* In case of error set next timestamp to retry */\r
 };\r
 \r
-/* This packet goes over the network, so we want to\r
- *  be shure about datastructs and type sizes between platforms\r
- */\r
-struct fce_packet\r
-{\r
-    char magic[8];\r
-    unsigned char version;\r
-    unsigned char mode;\r
-    uint16_t len;  /* network byte order */\r
-    uint32_t event_id; /* network byte order */\r
-    char data[FCE_MAX_PATH_LEN];\r
-};\r
-\r
 struct fce_history\r
 {\r
     unsigned char mode;\r
        int is_dir;\r
-       char path[FCE_MAX_PATH_LEN + 1];\r
+       char path[MAXPATHLEN + 1];\r
        struct timeval tv;\r
 };\r
 \r
-\r
 #define PACKET_HDR_LEN (sizeof(struct fce_packet) - FCE_MAX_PATH_LEN)\r
 \r
 int fce_handle_coalescation( char *path, int is_dir, int mode );\r
index b73d13c239ece87e8494c127dde753bc8ea7c235..cc98e09a908e3db9a4cacfbea1426b1231b80e10 100644 (file)
@@ -47,6 +47,7 @@ char *strchr (), *strrchr ();
 #include <atalk/uuid.h>
 #include <atalk/bstrlib.h>
 #include <atalk/bstradd.h>
+#include <atalk/fce_api.h>
 
 
 #ifdef CNID_DB
@@ -1495,6 +1496,7 @@ getvolspace_done:
         /* now buf contains only digits */
         long long used = atoll(buf) * multi;
         LOG(log_debug, logtype_afpd, "volparams: used on volume: %llu bytes", used);
+        fce_register_tm_size(vol->v_path, used);
 
         *xbtotal = min(*xbtotal, (vol->v_limitsize * 1024 * 1024));
         *xbfree = min(*xbfree, *xbtotal < used ? 0 : *xbtotal - used);
index 0e2f572dd299e5afdaf9a9c32c3c57adac5b700d..969b9d5f4deaff2abe1f2bf46e7c37f4df2e8a57 100755 (executable)
 #ifndef _FCE_API_H
 #define        _FCE_API_H
 
+/* fce_packet.mode */
+#define FCE_FILE_MODIFY     1
+#define FCE_FILE_DELETE     2
+#define FCE_DIR_DELETE      3
+#define FCE_FILE_CREATE     4
+#define FCE_DIR_CREATE      5
+#define FCE_TM_SIZE         6
+#define FCE_CONN_START     42
+#define FCE_CONN_BROKEN    99
+
+
+/* fce_packet.fce_magic */
+#define FCE_PACKET_MAGIC  "at_fcapi"
+
+/* This packet goes over the network, so we want to
+ *  be shure about datastructs and type sizes between platforms
+ */
+struct fce_packet
+{
+    char magic[8];
+    unsigned char version;
+    unsigned char mode;
+    uint16_t len;  /* network byte order */
+    uint32_t event_id; /* network byte order */
+    char data[MAXPATHLEN];
+};
+
 struct path;
 struct ofork;
+
 int fce_register_delete_file( struct path *path );
 int fce_register_delete_dir( char *name );
 int fce_register_new_dir( struct path *path );
 int fce_register_new_file( struct path *path );
 int fce_register_file_modification( struct ofork *ofork );
+int fce_register_tm_size(const char *vol, size_t used);
 
 int fce_add_udp_socket(const char *target );  // IP or IP:Port
 int fce_set_coalesce( char *coalesce_opt ); // all|delete|create
+int fce_set_events(const char *events);     /* fmod,fdel,ddel,fcre,dcre,tmsz (default is all) */
 
 #define FCE_DEFAULT_PORT 12250
 #define FCE_DEFAULT_PORT_STRING "12250"