2 This file is part of GNUnet
3 (C) 2005-2012 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file fs/fs_dirmetascan.c
23 * @brief code to asynchronously build a 'struct GNUNET_FS_ShareTreeItem'
24 * from an on-disk directory for publishing; use the 'gnunet-helper-fs-publish'.
26 * @author Christian Grothoff
29 #include "gnunet_fs_service.h"
30 #include "gnunet_scheduler_lib.h"
35 * An opaque structure a pointer to which is returned to the
36 * caller to be used to control the scanner.
38 struct GNUNET_FS_DirScanner
44 struct GNUNET_HELPER_Handle *helper;
47 * Expanded filename (as given by the scan initiator).
48 * The scanner thread stores a copy here, and frees it when it finishes.
50 char *filename_expanded;
53 * Second argument to helper process.
58 * The function that will be called every time there's a progress
61 GNUNET_FS_DirScannerProgressCallback progress_callback;
64 * A closure for progress_callback.
66 void *progress_callback_cls;
69 * After the scan is finished, it will contain a pointer to the
70 * top-level directory entry in the directory tree built by the
71 * scanner. Must only be manipulated by the thread for the
72 * duration of the thread's runtime.
74 struct GNUNET_FS_ShareTreeItem *toplevel;
83 * @param ds directory scanner structure
86 GNUNET_FS_directory_scan_abort (struct GNUNET_FS_DirScanner *ds)
88 /* terminate helper */
89 GNUNET_HELPER_stop (ds->helper);
92 if (NULL != ds->toplevel)
93 GNUNET_FS_share_tree_free (ds->toplevel);
94 GNUNET_free (ds->ex_arg);
95 GNUNET_free (ds->filename_expanded);
101 * Obtain the result of the scan after the scan has signalled
102 * completion. Must not be called prior to completion. The 'ds' is
103 * freed as part of this call.
105 * @param ds directory scanner structure
106 * @return the results of the scan (a directory tree)
108 struct GNUNET_FS_ShareTreeItem *
109 GNUNET_FS_directory_scan_get_result (struct GNUNET_FS_DirScanner *ds)
111 struct GNUNET_FS_ShareTreeItem *result;
113 /* check that we're actually done */
114 GNUNET_assert (NULL == ds->helper);
115 /* preserve result */
116 result = ds->toplevel;
118 GNUNET_FS_directory_scan_abort (ds);
124 * Called every time there is data to read from the scanner.
125 * Calls the scanner progress handler.
127 * @param cls the closure (directory scanner object)
128 * @param client always NULL
129 * @param msg message from the helper process
132 process_helper_msgs (void *cls,
134 const struct GNUNET_MessageHeader *msg)
136 struct GNUNET_FS_DirScanner *ds = cls;
139 enum GNUNET_FS_DirScannerProgressUpdateReason reason;
144 /* Process message. If message is malformed or can't be read, end the scanner */
145 /* read successfully, notify client about progress */
146 ds->progress_callback (ds->progress_callback_cls,
151 GNUNET_free (filename);
154 /* having full filenames is too dangerous; always make sure we clean them up */
155 item->short_filename = GNUNET_strdup (GNUNET_STRINGS_get_short_name (filename));
157 GNUNET_CONTAINER_meta_data_delete (item->meta,
158 EXTRACTOR_METATYPE_FILENAME,
160 GNUNET_CONTAINER_meta_data_insert (item->meta, "<libgnunetfs>",
161 EXTRACTOR_METATYPE_FILENAME,
162 EXTRACTOR_METAFORMAT_UTF8, "text/plain",
163 item->short_filename,
164 strlen (item->short_filename) + 1);
170 * Start a directory scanner thread.
172 * @param filename name of the directory to scan
173 * @param GNUNET_YES to not to run libextractor on files (only build a tree)
174 * @param ex if not NULL, must be a list of extra plugins for extractor
175 * @param cb the callback to call when there are scanning progress messages
176 * @param cb_cls closure for 'cb'
177 * @return directory scanner object to be used for controlling the scanner
179 struct GNUNET_FS_DirScanner *
180 GNUNET_FS_directory_scan_start (const char *filename,
181 int disable_extractor, const char *ex,
182 GNUNET_FS_DirScannerProgressCallback cb,
186 char *filename_expanded;
187 struct GNUNET_FS_DirScanner *ds;
190 if (0 != STAT (filename, &sbuf))
192 filename_expanded = GNUNET_STRINGS_filename_expand (filename);
193 if (NULL == filename_expanded)
195 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
196 "Starting to scan directory `%s'\n",
198 ds = GNUNET_malloc (sizeof (struct GNUNET_FS_DirScanner));
199 ds->progress_callback = cb;
200 ds->progress_callback_cls = cb_cls;
201 ds->filename_expanded = filename_expanded;
202 ds->ex_arg = GNUNET_strdup ((disable_extractor) ? "-" : ex);
203 args[0] = "gnunet-helper-fs-publish";
204 args[1] = ds->filename_expanded;
205 args[2] = ds->ex_arg;
207 ds->helper = GNUNET_HELPER_start ("gnunet-helper-fs-publish",
209 &process_helper_msgs,
211 if (NULL == ds->helper)
213 GNUNET_free (filename_expanded);
221 /* end of fs_dirmetascan.c */