SQ snapper: clean up snaphot path<->id conversion
authorDavid Disseldorp <ddiss@samba.org>
Mon, 15 Oct 2012 15:02:41 +0000 (17:02 +0200)
committerDavid Disseldorp <ddiss@samba.org>
Mon, 15 Apr 2013 16:15:22 +0000 (18:15 +0200)
Split into helper functions.

source3/modules/vfs_snapper.c

index d9d406fcefc76f41ef2948c056c37747bea095e9..3e6d95a86c67f1fadca70403e418dc553428b39d 100644 (file)
@@ -859,6 +859,82 @@ static NTSTATUS snapper_del_snap_unpack(DBusConnection *conn,
        return NT_STATUS_OK;
 }
 
+/*
+ * Determine the snapper snapshot id given a path.
+ * Ideally this should be determined via a lookup.
+ */
+static NTSTATUS snapper_snap_path_to_id(TALLOC_CTX *mem_ctx,
+                                       const char *snap_path,
+                                       uint32_t *snap_id_out)
+{
+       char *path_dup;
+       char *str_idx;
+       char *str_end;
+       uint32_t snap_id;
+
+       path_dup = talloc_strdup(mem_ctx, snap_path);
+       if (path_dup == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       /* trim trailing '/' */
+       str_idx = path_dup + strlen(path_dup) - 1;
+       while (*str_idx == '/') {
+               *str_idx = '\0';
+               str_idx--;
+       }
+
+       str_idx = strrchr(path_dup, '/');
+       if ((str_idx == NULL)
+        || (strcmp(str_idx + 1, "snapshot") != 0)) {
+               talloc_free(path_dup);
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       while (*str_idx == '/') {
+               *str_idx = '\0';
+               str_idx--;
+       }
+
+       str_idx = strrchr(path_dup, '/');
+       if (str_idx == NULL) {
+               talloc_free(path_dup);
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       str_idx++;
+       snap_id = strtoul(str_idx, &str_end, 10);
+       if (str_idx == str_end) {
+               talloc_free(path_dup);
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       talloc_free(path_dup);
+       *snap_id_out = snap_id;
+       return NT_STATUS_OK;
+}
+
+/*
+ * Determine the snapper snapshot path given an id and base.
+ * Ideally this should be determined via a lookup.
+ */
+static NTSTATUS snapper_snap_id_to_path(TALLOC_CTX *mem_ctx,
+                                       const char *base_path,
+                                       uint32_t snap_id,
+                                       char **snap_path_out)
+{
+       char *snap_path;
+
+       snap_path = talloc_asprintf(mem_ctx, "%s/.snapshots/%u/snapshot",
+                                   base_path, snap_id);
+       if (snap_path == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       *snap_path_out = snap_path;
+       return NT_STATUS_OK;
+}
+
 static NTSTATUS snapper_get_conf_call(TALLOC_CTX *mem_ctx,
                                      DBusConnection *dconn,
                                      const char *path,
@@ -1003,20 +1079,16 @@ static NTSTATUS snapper_create_snap_call(TALLOC_CTX *mem_ctx,
                goto err_rsp_free;
        }
 
+       status = snapper_snap_id_to_path(mem_ctx, base_path, snap_id,
+                                        &snap_path);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto err_rsp_free;
+       }
+
        dbus_message_unref(rsp_msg);
        dbus_message_unref(req_msg);
 
-       DEBUG(6, ("created new snapshot %u\n", snap_id));
-
-       /*
-        * Assume snapshot exists in the .snapshots subdir of the base.
-        * TODO lookup via GetSnapshot
-        */
-       snap_path = talloc_asprintf(mem_ctx, "%s/.snapshots/%u", base_path, snap_id);
-       if (snap_path == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto err_rsp_free;
-       }
+       DEBUG(6, ("created new snapshot %u at %s\n", snap_id, snap_path));
        *snap_path_out = snap_path;
 
        return NT_STATUS_OK;
@@ -1170,8 +1242,6 @@ static struct tevent_req *snapper_snap_delete_send(struct vfs_handle_struct *han
        DBusConnection *dconn;
        struct snapper_snap_delete_state *delete_state;
        NTSTATUS status;
-       char *snap_id_str;
-       char *str_end;
 
        req = tevent_req_create(mem_ctx, &delete_state,
                                struct snapper_snap_delete_state);
@@ -1193,17 +1263,9 @@ static struct tevent_req *snapper_snap_delete_send(struct vfs_handle_struct *han
                return tevent_req_post(req, ev);
        }
 
-       /* TODO we should look this up by doing a list_snapshots */
-       snap_id_str = strrchr(snap_path, '/');
-       if (snap_id_str == NULL) {
-               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               dbus_connection_unref(dconn);
-               return tevent_req_post(req, ev);
-       }
-       snap_id_str++;
-       delete_state->snap_id = strtoul(snap_id_str, &str_end, 10);
-       if (snap_id_str == str_end) {
-               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+       status = snapper_snap_path_to_id(delete_state, snap_path,
+                                        &delete_state->snap_id);
+       if (tevent_req_nterror(req, status)) {
                dbus_connection_unref(dconn);
                return tevent_req_post(req, ev);
        }