/*
This file is part of GNUnet
- (C) 2005-2012 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2005-2012 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
+ by the Free Software Foundation; either version 3, or (at your
option) any later version.
GNUnet is distributed in the hope that it will be useful, but
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
* Second argument to helper process.
*/
char *ex_arg;
-
+
/**
* The function that will be called every time there's a progress
* message.
*/
GNUNET_FS_DirScannerProgressCallback progress_callback;
-
+
/**
* A closure for progress_callback.
*/
/**
* After the scan is finished, it will contain a pointer to the
* top-level directory entry in the directory tree built by the
- * scanner.
+ * scanner.
*/
struct GNUNET_FS_ShareTreeItem *toplevel;
/**
* Task scheduled when we are done.
*/
- GNUNET_SCHEDULER_TaskIdentifier stop_task;
+ struct GNUNET_SCHEDULER_Task * stop_task;
/**
* Arguments for helper.
};
-
/**
* Abort the scan. Must not be called from within the progress_callback
* function.
{
/* terminate helper */
if (NULL != ds->helper)
- GNUNET_HELPER_stop (ds->helper);
-
+ GNUNET_HELPER_stop (ds->helper, GNUNET_NO);
+
/* free resources */
if (NULL != ds->toplevel)
GNUNET_FS_share_tree_free (ds->toplevel);
- if (GNUNET_SCHEDULER_NO_TASK != ds->stop_task)
+ if (NULL != ds->stop_task)
GNUNET_SCHEDULER_cancel (ds->stop_task);
GNUNET_free_non_null (ds->ex_arg);
GNUNET_free (ds->filename_expanded);
GNUNET_assert (NULL == ds->helper);
/* preserve result */
result = ds->toplevel;
- ds->toplevel = NULL;
+ ds->toplevel = NULL;
GNUNET_FS_directory_scan_abort (ds);
return result;
}
advance (struct GNUNET_FS_ShareTreeItem *pos)
{
int moved;
-
+
GNUNET_assert (NULL != pos);
moved = 0; /* must not terminate, even on file, otherwise "normal" */
while ( (pos->is_directory == GNUNET_YES) ||
struct GNUNET_FS_ShareTreeItem *chld;
size_t slen;
- chld = GNUNET_malloc (sizeof (struct GNUNET_FS_ShareTreeItem));
+ chld = GNUNET_new (struct GNUNET_FS_ShareTreeItem);
chld->parent = parent;
chld->filename = GNUNET_strdup (filename);
GNUNET_asprintf (&chld->short_filename,
if (NULL != parent)
GNUNET_CONTAINER_DLL_insert (parent->children_head,
parent->children_tail,
- chld);
+ chld);
return chld;
}
* 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)
+finish_scan (void *cls)
{
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,
+ ds->stop_task = NULL;
+ if (NULL != ds->helper)
+ {
+ GNUNET_HELPER_stop (ds->helper, GNUNET_NO);
+ ds->helper = NULL;
+ }
+ ds->progress_callback (ds->progress_callback_cls,
NULL, GNUNET_SYSERR,
- GNUNET_FS_DIRSCANNER_FINISHED);
+ GNUNET_FS_DIRSCANNER_FINISHED);
}
* @param msg message from the helper process
*/
static int
-process_helper_msgs (void *cls,
+process_helper_msgs (void *cls,
void *client,
const struct GNUNET_MessageHeader *msg)
{
GNUNET_break (0);
break;
}
- ds->progress_callback (ds->progress_callback_cls,
+ ds->progress_callback (ds->progress_callback_cls,
filename, GNUNET_NO,
GNUNET_FS_DIRSCANNER_FILE_START);
if (NULL == ds->toplevel)
ds->pos = ds->pos->parent;
return GNUNET_OK;
}
- ds->progress_callback (ds->progress_callback_cls,
+ ds->progress_callback (ds->progress_callback_cls,
filename, GNUNET_YES,
GNUNET_FS_DIRSCANNER_FILE_START);
ds->pos = expand_tree (ds->pos,
case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_SKIP_FILE:
if ('\0' != filename[left-1])
break;
- ds->progress_callback (ds->progress_callback_cls,
+ ds->progress_callback (ds->progress_callback_cls,
filename, GNUNET_SYSERR,
GNUNET_FS_DIRSCANNER_FILE_IGNORED);
return GNUNET_OK;
GNUNET_break (0);
break;
}
- ds->progress_callback (ds->progress_callback_cls,
+ ds->progress_callback (ds->progress_callback_cls,
NULL, GNUNET_SYSERR,
GNUNET_FS_DIRSCANNER_ALL_COUNTED);
ds->pos = ds->toplevel;
{
size_t nlen;
const char *end;
-
+
if (NULL == ds->pos)
{
GNUNET_break (0);
GNUNET_break (0);
break;
}
- ds->progress_callback (ds->progress_callback_cls,
+ ds->progress_callback (ds->progress_callback_cls,
filename, GNUNET_YES,
GNUNET_FS_DIRSCANNER_EXTRACT_FINISHED);
if (0 < left)
break;
}
/* having full filenames is too dangerous; always make sure we clean them up */
- GNUNET_CONTAINER_meta_data_delete (ds->pos->meta,
+ 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_GNUNET_ORIGINAL_FILENAME,
EXTRACTOR_METAFORMAT_UTF8, "text/plain",
- ds->pos->short_filename,
+ 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);
+ ds->pos = advance (ds->pos);
return GNUNET_OK;
}
case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_FINISHED:
{
GNUNET_break (0);
break;
- }
+ }
if (NULL == ds->toplevel)
{
GNUNET_break (0);
GNUNET_break (0);
break;
}
- ds->progress_callback (ds->progress_callback_cls,
+ ds->progress_callback (ds->progress_callback_cls,
NULL, GNUNET_SYSERR,
GNUNET_FS_DIRSCANNER_INTERNAL_ERROR);
return GNUNET_OK;
}
+/**
+ * Function called if our helper process died.
+ *
+ * @param cls the 'struct GNUNET_FS_DirScanner' callback.
+ */
+static void
+helper_died_cb (void *cls)
+{
+ struct GNUNET_FS_DirScanner *ds = cls;
+
+ ds->helper = NULL;
+ if (NULL != ds->stop_task)
+ return; /* normal death, was finished */
+ ds->progress_callback (ds->progress_callback_cls,
+ NULL, GNUNET_SYSERR,
+ GNUNET_FS_DIRSCANNER_INTERNAL_ERROR);
+}
+
+
/**
* Start a directory scanner thread.
*
* @param filename name of the directory to scan
- * @param disable_extractor GNUNET_YES to not to run libextractor on files (only build a tree)
+ * @param disable_extractor #GNUNET_YES to not run libextractor on files (only
+ * build a tree)
* @param ex if not NULL, must be a list of extra plugins for extractor
* @param cb the callback to call when there are scanning progress messages
* @param cb_cls closure for 'cb'
struct GNUNET_FS_DirScanner *
GNUNET_FS_directory_scan_start (const char *filename,
int disable_extractor, const char *ex,
- GNUNET_FS_DirScannerProgressCallback cb,
+ GNUNET_FS_DirScannerProgressCallback cb,
void *cb_cls)
{
struct stat sbuf;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Starting to scan directory `%s'\n",
filename_expanded);
- ds = GNUNET_malloc (sizeof (struct GNUNET_FS_DirScanner));
+ ds = GNUNET_new (struct GNUNET_FS_DirScanner);
ds->progress_callback = cb;
ds->progress_callback_cls = cb_cls;
ds->filename_expanded = filename_expanded;
- if (disable_extractor)
+ if (disable_extractor)
ds->ex_arg = GNUNET_strdup ("-");
- else
+ else
ds->ex_arg = (NULL != ex) ? GNUNET_strdup (ex) : NULL;
ds->args[0] = "gnunet-helper-fs-publish";
ds->args[1] = ds->filename_expanded;
ds->args[2] = ds->ex_arg;
ds->args[3] = NULL;
- ds->helper = GNUNET_HELPER_start ("gnunet-helper-fs-publish",
+ ds->helper = GNUNET_HELPER_start (GNUNET_NO,
+ "gnunet-helper-fs-publish",
ds->args,
&process_helper_msgs,
- ds);
+ &helper_died_cb, ds);
if (NULL == ds->helper)
- {
+ {
GNUNET_free (filename_expanded);
GNUNET_free (ds);
return NULL;