-fix #2142
[oweals/gnunet.git] / src / fs / fs_dirmetascan.c
index 69c7770db753601295f8141331b818d576612324..5b7d2d0c1a811fb90cada8a17d4003748a9dc94d 100644 (file)
@@ -77,6 +77,11 @@ struct GNUNET_FS_DirScanner
    */
   struct GNUNET_FS_ShareTreeItem *pos;
 
+  /**
+   * Task scheduled when we are done.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier stop_task;
+
   /**
    * Arguments for helper.
    */
@@ -95,12 +100,15 @@ void
 GNUNET_FS_directory_scan_abort (struct GNUNET_FS_DirScanner *ds)
 {
   /* terminate helper */
-  GNUNET_HELPER_stop (ds->helper);
-
+  if (NULL != ds->helper)
+    GNUNET_HELPER_stop (ds->helper);
+  
   /* free resources */
   if (NULL != ds->toplevel)
     GNUNET_FS_share_tree_free (ds->toplevel);
-  GNUNET_free (ds->ex_arg);
+  if (GNUNET_SCHEDULER_NO_TASK != ds->stop_task)
+    GNUNET_SCHEDULER_cancel (ds->stop_task);
+  GNUNET_free_non_null (ds->ex_arg);
   GNUNET_free (ds->filename_expanded);
   GNUNET_free (ds);
 }
@@ -186,10 +194,21 @@ expand_tree (struct GNUNET_FS_ShareTreeItem *parent,
             int is_directory)
 {
   struct GNUNET_FS_ShareTreeItem *chld;
+  size_t slen;
 
   chld = GNUNET_malloc (sizeof (struct GNUNET_FS_ShareTreeItem));
   chld->parent = parent;
   chld->filename = GNUNET_strdup (filename);
+  GNUNET_asprintf (&chld->short_filename,
+                  "%s%s",
+                  GNUNET_STRINGS_get_short_name (filename),
+                  is_directory ? "/" : "");
+  /* make sure we do not end with '//' */
+  slen = strlen (chld->short_filename);
+  if ( (slen >= 2) &&
+       (chld->short_filename[slen-1] == '/') &&
+       (chld->short_filename[slen-2] == '/') )
+    chld->short_filename[slen-1] = '\0';
   chld->is_directory = is_directory;
   if (NULL != parent)
       GNUNET_CONTAINER_DLL_insert (parent->children_head,
@@ -199,6 +218,27 @@ expand_tree (struct GNUNET_FS_ShareTreeItem *parent,
 }
 
 
+/**
+ * Task run last to shut everything down.
+ *
+ * @param cls the 'struct GNUNET_FS_DirScanner'
+ * @param tc unused
+ */
+static void
+finish_scan (void *cls,
+            const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_FS_DirScanner *ds = cls;
+
+  ds->stop_task = GNUNET_SCHEDULER_NO_TASK;
+  GNUNET_HELPER_stop (ds->helper);
+  ds->helper = NULL;
+  ds->progress_callback (ds->progress_callback_cls, 
+                        NULL, GNUNET_SYSERR,
+                        GNUNET_FS_DIRSCANNER_FINISHED);    
+}
+
+
 /**
  * Called every time there is data to read from the scanner.
  * Calls the scanner progress handler.
@@ -229,8 +269,12 @@ process_helper_msgs (void *cls,
     ds->progress_callback (ds->progress_callback_cls, 
                           filename, GNUNET_NO,
                           GNUNET_FS_DIRSCANNER_FILE_START);
-    expand_tree (ds->pos,
-                filename, GNUNET_NO);
+    if (NULL == ds->toplevel)
+      ds->toplevel = expand_tree (ds->pos,
+                                 filename, GNUNET_NO);
+    else
+      (void) expand_tree (ds->pos,
+                         filename, GNUNET_NO);
     return;
   case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY:
     if (filename[left-1] != '\0')
@@ -271,6 +315,11 @@ process_helper_msgs (void *cls,
       GNUNET_break (0);
       break;
     }
+    if (NULL == ds->toplevel)
+    {
+      GNUNET_break (0);
+      break;
+    }
     ds->progress_callback (ds->progress_callback_cls, 
                           NULL, GNUNET_SYSERR,
                           GNUNET_FS_DIRSCANNER_ALL_COUNTED);
@@ -315,16 +364,17 @@ process_helper_msgs (void *cls,
          break;
        }
        /* having full filenames is too dangerous; always make sure we clean them up */
-       ds->pos->short_filename = GNUNET_strdup (GNUNET_STRINGS_get_short_name (filename));
        GNUNET_CONTAINER_meta_data_delete (ds->pos->meta, 
                                           EXTRACTOR_METATYPE_FILENAME,
                                           NULL, 0);
+       /* instead, put in our 'safer' original filename */
        GNUNET_CONTAINER_meta_data_insert (ds->pos->meta, "<libgnunetfs>",
-                                          EXTRACTOR_METATYPE_FILENAME,
+                                          EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
                                           EXTRACTOR_METAFORMAT_UTF8, "text/plain",
                                           ds->pos->short_filename, 
                                           strlen (ds->pos->short_filename) + 1);
       }
+      ds->pos->ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (ds->pos->meta);
       ds->pos = advance (ds->pos);      
       return;
     }
@@ -335,14 +385,17 @@ process_helper_msgs (void *cls,
       break;
     }
     if (0 != left)
+    {
+      GNUNET_break (0);
+      break;
+    }   
+    if (NULL == ds->toplevel)
     {
       GNUNET_break (0);
       break;
     }
-    ds->progress_callback (ds->progress_callback_cls, 
-                          NULL, GNUNET_SYSERR,
-                          GNUNET_FS_DIRSCANNER_INTERNAL_ERROR);
-    
+    ds->stop_task = GNUNET_SCHEDULER_add_now (&finish_scan,
+                                             ds);
     return;
   default:
     GNUNET_break (0);
@@ -351,7 +404,6 @@ process_helper_msgs (void *cls,
   ds->progress_callback (ds->progress_callback_cls, 
                         NULL, GNUNET_SYSERR,
                         GNUNET_FS_DIRSCANNER_INTERNAL_ERROR);
-
 }