From da7cc55488f90b3294dbb7aa186184e6e8501d7e Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 24 Aug 2009 09:26:47 +0000 Subject: [PATCH] hxing --- TODO | 1 + src/fs/Makefile.am | 1 + src/fs/fs.h | 140 +++++++- src/fs/fs_file_information.c | 572 ++++++++++++++++++++++++++++++- src/include/Makefile.am | 1 + src/include/gnunet_bio_lib.h | 281 +++++++++++++++ src/include/gnunet_disk_lib.h | 10 +- src/include/gnunet_fs_service.h | 32 +- src/include/gnunet_util_lib.h | 1 + src/util/Makefile.am | 1 + src/util/bio.c | 545 +++++++++++++++++++++++++++++ src/util/container_bloomfilter.c | 10 +- src/util/disk.c | 8 +- src/util/pseudonym.c | 2 +- 14 files changed, 1579 insertions(+), 26 deletions(-) create mode 100644 src/include/gnunet_bio_lib.h create mode 100644 src/util/bio.c diff --git a/TODO b/TODO index 8b400d5de..94fc5d4e5 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,7 @@ Implementable right now (but not necessarily important), with caveats (unavailable components that will limit what can be implemented right away), in order in which they will likely be done: +* Buffered IO library (extend gnunet_disk_lib.h?) * TESTING * FS (DHT not available) * SETUP diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am index 9fca261cb..db9567fb1 100644 --- a/src/fs/Makefile.am +++ b/src/fs/Makefile.am @@ -24,6 +24,7 @@ libgnunetfs_la_SOURCES = \ libgnunetfs_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ + -lextractor \ $(GN_LIBINTL) $(XLIB) libgnunetfs_la_LDFLAGS = \ diff --git a/src/fs/fs.h b/src/fs/fs.h index 024e0ecc8..0c82d5831 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h @@ -116,14 +116,37 @@ struct GNUNET_FS_Uri * (only in URI-strings). */ char **keywords; + + /** + * Size of the keywords array. + */ unsigned int keywordCount; } ksk; + struct { + /** + * Hash of the public key for the namespace. + */ GNUNET_HashCode namespace; + + /** + * Human-readable identifier chosen for this + * entry in the namespace. + */ char *identifier; } sks; + + /** + * Information needed to retrieve a file (content-hash-key + * plus file size). + */ struct FileIdentifier chk; + + /** + * Information needed to retrieve a file including signed + * location (identity of a peer) of the content. + */ struct Location loc; } data; @@ -134,9 +157,124 @@ struct GNUNET_FS_Uri * Information for a file or directory that is * about to be published. */ -struct GNUNET_FS_FileInformation +struct GNUNET_FS_FileInformation { + /** + * Files in a directory are kept as a linked list. + */ + struct GNUNET_FS_FileInformation *next; + + /** + * If this is a file in a directory, "dir" refers to + * the directory; otherwise NULL. + */ + struct GNUNET_FS_FileInformation *dir; + + /** + * Pointer kept for the client. + */ + void *client_info; + + /** + * Metadata to use for the file. + */ + struct GNUNET_CONTAINER_MetaData *meta; + + /** + * Keywords to use for KBlocks. + */ + struct GNUNET_FS_Uri *keywords; + + /** + * At what time should the content expire? + */ + struct GNUNET_TIME_Absolute expirationTime; + + /** + * Under what filename is this struct serialized + * (for operational persistence). + */ + char *serialization; + + /** + * How many bytes of this file or directory have been + * published so far? + */ + uint64_t publish_offset; + + /** + * Data describing either the file or the directory. + */ + union + { + + /** + * Data for a file. + */ + struct { + + /** + * Function that can be used to read the data for the file. + */ + GNUNET_FS_DataReader reader; + + /** + * Closure for reader. + */ + void *reader_cls; + + /** + * Size of the file (in bytes). + */ + uint64_t file_size; + + /** + * Should the file be indexed or inserted? + */ + int do_index; + + } file; + + /** + * Data for a directory. + */ + struct { + + /** + * Name of the directory. + */ + char *dirname; + + /** + * Linked list of entries in the directory. + */ + struct GNUNET_FS_FileInformation *entries; + + /** + * Size of the directory itself (in bytes); 0 if the + * size has not yet been calculated. + */ + uint64_t dir_size; + + } dir; + + } data; + + /** + * Is this struct for a file or directory? + */ + int is_directory; + + /** + * Desired anonymity level. + */ + unsigned int anonymity; + + /** + * Desired priority (for keeping the content in the DB). + */ + unsigned int priority; }; diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c index d565f4397..9b806184b 100644 --- a/src/fs/fs_file_information.c +++ b/src/fs/fs_file_information.c @@ -22,16 +22,141 @@ * @file fs/fs_file_information.c * @brief Manage information for publishing directory hierarchies * @author Christian Grothoff + * + * TODO: + * - publishing progress update API (increment offset, serialize) + * - serialization/deserialization (& deserialization API) + * - metadata filename clean up code + * - metadata/ksk generation for directories from contained files */ #include "platform.h" +#include #include "gnunet_fs_service.h" #include "fs.h" +/** + * Create a temporary file disk to store the current + * state of "fi" in. + */ +static void +fi_sync (struct GNUNET_FS_FileInformation * fi) +{ + if (NULL == fi->serialization) + { + fi->serialization = NULL; // FIXME + } + // FIXME... +} + + +/** + * Load file information from the file to which + * it was sync'ed. + * + * @param filename name of the file to use + * @return NULL on error + */ +static struct GNUNET_FS_FileInformation * +fi_load (const char *filename) +{ + struct GNUNET_FS_FileInformation *ret; + // FIXME! + return NULL; +} + + +/** + * Closure for "data_reader_file". + */ +struct FileInfo +{ + /** + * Name of the file to read. + */ + char *filename; + + /** + * File descriptor, NULL if it has not yet been opened. + */ + struct GNUNET_DISK_FileHandle *fd; +}; + + +/** + * Function that provides data by reading from a file. + * + * @param cls closure (points to the file information) + * @param offset offset to read from; it is possible + * that the caller might need to go backwards + * a bit at times + * @param max maximum number of bytes that should be + * copied to buf; readers are not allowed + * to provide less data unless there is an error; + * a value of "0" will be used at the end to allow + * the reader to clean up its internal state + * @param buf where the reader should write the data + * @param emsg location for the reader to store an error message + * @return number of bytes written, usually "max", 0 on error + */ +static size_t +data_reader_file(void *cls, + uint64_t offset, + size_t max, + void *buf, + char **emsg) +{ + struct FileInfo *fi = cls; + ssize_t ret; + + if (max == 0) + { + if (fi->fd != NULL) + GNUNET_DISK_file_close (fi->fd); + GNUNET_free (fi->filename); + GNUNET_free (fi); + return 0; + } + if (fi->fd == NULL) + { + fi->fd = GNUNET_DISK_file_open (fi->filename, + GNUNET_DISK_OPEN_READ); + if (fi->fd == NULL) + { + GNUNET_asprintf (emsg, + _("Could not open file `%s': %s"), + fi->filename, + STRERROR (errno)); + return 0; + } + } + GNUNET_DISK_file_seek (fi->fd, offset, GNUNET_DISK_SEEK_SET); + ret = GNUNET_DISK_file_read (fi->fd, buf, max); + if (ret == -1) + { + GNUNET_asprintf (emsg, + _("Could not read file `%s': %s"), + fi->filename, + STRERROR (errno)); + return 0; + } + if (ret != max) + { + GNUNET_asprintf (emsg, + _("Short read reading from file `%s'!"), + fi->filename); + return 0; + } + return max; +} + + /** * Create an entry for a file in a publish-structure. * * @param filename name of the file or directory to publish + * @param keywords under which keywords should this file be available + * directly; can be NULL * @param meta metadata for the file * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, * GNUNET_SYSERR for simulation @@ -45,21 +170,80 @@ struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_from_file (void *client_info, const char *filename, + const struct GNUNET_FS_Uri *keywords, const struct GNUNET_CONTAINER_MetaData *meta, int do_index, unsigned int anonymity, unsigned int priority, struct GNUNET_TIME_Absolute expirationTime) { - return NULL; + struct FileInfo *fi; + struct stat sbuf; + + if (0 != STAT (filename, &sbuf)) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, + "stat", + filename); + return NULL; + } + fi = GNUNET_malloc (sizeof(struct FileInfo)); + fi->filename = GNUNET_strdup (filename); + return GNUNET_FS_file_information_create_from_reader (client_info, + sbuf.st_size, + &data_reader_file, + fi, + keywords, + meta, + do_index, + anonymity, + priority, + expirationTime); } + +/** + * Function that provides data by copying from a buffer. + * + * @param cls closure (points to the buffer) + * @param offset offset to read from; it is possible + * that the caller might need to go backwards + * a bit at times + * @param max maximum number of bytes that should be + * copied to buf; readers are not allowed + * to provide less data unless there is an error; + * a value of "0" will be used at the end to allow + * the reader to clean up its internal state + * @param buf where the reader should write the data + * @param emsg location for the reader to store an error message + * @return number of bytes written, usually "max", 0 on error + */ +static size_t +data_reader_copy(void *cls, + uint64_t offset, + size_t max, + void *buf, + char **emsg) +{ + char *data = cls; + if (max == 0) + { + GNUNET_free (data); + return 0; + } + memcpy (buf, &data[offset], max); + return max; +} + + /** * Create an entry for a file in a publish-structure. * * @param length length of the file * @param data data for the file (should not be used afterwards by * the caller; caller will "free") + * @param keywords under which keywords should this file be available + * directly; can be NULL * @param meta metadata for the file * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, * GNUNET_SYSERR for simulation @@ -74,13 +258,23 @@ struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_from_data (void *client_info, uint64_t length, void *data, + const struct GNUNET_FS_Uri *keywords, const struct GNUNET_CONTAINER_MetaData *meta, int do_index, unsigned int anonymity, unsigned int priority, struct GNUNET_TIME_Absolute expirationTime) { - return NULL; + return GNUNET_FS_file_information_create_from_reader (client_info, + length, + &data_reader_copy, + data, + keywords, + meta, + do_index, + anonymity, + priority, + expirationTime); } @@ -114,10 +308,151 @@ GNUNET_FS_file_information_create_from_reader (void *client_info, unsigned int priority, struct GNUNET_TIME_Absolute expirationTime) { - return NULL; + struct GNUNET_FS_FileInformation *ret; + + ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation)); + ret->client_info = client_info; + ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); + ret->keywords = (keywords == NULL) ? NULL : GNUNET_FS_uri_dup (keywords); + ret->expirationTime = expirationTime; + ret->data.file.reader = reader; + ret->data.file.reader_cls = reader_cls; + ret->data.file.do_index = do_index; + ret->anonymity = anonymity; + ret->priority = priority; + fi_sync (ret); + return ret; } +/** + * Closure for "dir_scan_cb". + */ +struct DirScanCls +{ + /** + * Metadata extractors to use. + */ + struct EXTRACTOR_Extractor *extractors; + + /** + * Function to call on each directory entry. + */ + GNUNET_FS_FileProcessor proc; + + /** + * Closure for proc. + */ + void *proc_cls; + + /** + * Scanner to use for subdirectories. + */ + GNUNET_FS_DirectoryScanner scanner; + + /** + * Closure for scanner. + */ + void *scanner_cls; + + /** + * Set to an error message (if any). + */ + char *emsg; + + /** + * Should files be indexed? + */ + int do_index; + + /** + * Desired anonymity level. + */ + unsigned int anonymity; + + /** + * Desired publishing priority. + */ + unsigned int priority; + + /** + * Expiration time for publication. + */ + struct GNUNET_TIME_Absolute expiration; +}; + + +/** + * Function called on each entry in a file to + * cause default-publishing. + * @param cls closure (struct DirScanCls) + * @param filename name of the file to be published + * @return GNUNET_OK on success, GNUNET_SYSERR to abort + */ +static int +dir_scan_cb (void *cls, + const char *filename) +{ + struct DirScanCls *dsc = cls; + struct stat sbuf; + struct GNUNET_FS_FileInformation *fi; + struct GNUNET_FS_Uri *ksk_uri; + struct GNUNET_FS_Uri *keywords; + struct GNUNET_CONTAINER_MetaData *meta; + + if (0 != STAT (filename, &sbuf)) + { + GNUNET_asprintf (&dsc->emsg, + _("`%s' failed on file `%s': %s"), + "stat", + filename, + STRERROR (errno)); + return GNUNET_SYSERR; + } + if (S_ISDIR (sbuf.st_mode)) + { + fi = GNUNET_FS_file_information_create_from_directory (NULL, + filename, + dsc->scanner, + dsc->scanner_cls, + dsc->do_index, + dsc->anonymity, + dsc->priority, + dsc->expiration, + &dsc->emsg); + if (NULL == fi) + { + GNUNET_assert (NULL != dsc->emsg); + return GNUNET_SYSERR; + } + } + else + { + meta = GNUNET_CONTAINER_meta_data_create (); + GNUNET_CONTAINER_meta_data_extract_from_file (meta, + filename, + dsc->extractors); + // FIXME: remove path from filename in metadata! + keywords = GNUNET_FS_uri_ksk_create_from_meta_data (meta); + ksk_uri = GNUNET_FS_uri_ksk_canonicalize (keywords); + fi = GNUNET_FS_file_information_create_from_file (NULL, + filename, + ksk_uri, + meta, + dsc->do_index, + dsc->anonymity, + dsc->priority, + dsc->expiration); + GNUNET_CONTAINER_meta_data_destroy (meta); + GNUNET_FS_uri_destroy (keywords); + GNUNET_FS_uri_destroy (ksk_uri); + } + dsc->proc (dsc->proc_cls, + filename, + fi); + return GNUNET_OK; +} + /** * Simple, useful default implementation of a directory scanner @@ -132,6 +467,10 @@ GNUNET_FS_file_information_create_from_reader (void *client_info, * * @param cls must be of type "struct EXTRACTOR_Extractor*" * @param dirname name of the directory to scan + * @param do_index should files be indexed or inserted + * @param anonymity desired anonymity level + * @param priority priority for publishing + * @param expirationTime expiration for publication * @param proc function called on each entry * @param proc_cls closure for proc * @param emsg where to store an error message (on errors) @@ -140,10 +479,70 @@ GNUNET_FS_file_information_create_from_reader (void *client_info, int GNUNET_FS_directory_scanner_default (void *cls, const char *dirname, + int do_index, + unsigned int anonymity, + unsigned int priority, + struct GNUNET_TIME_Absolute expirationTime, GNUNET_FS_FileProcessor proc, - void *proc_cls) + void *proc_cls, + char **emsg) { - return GNUNET_SYSERR; + struct EXTRACTOR_Extractor *ex = cls; + struct DirScanCls dsc; + + dsc.extractors = ex; + dsc.proc = proc; + dsc.proc_cls = proc_cls; + dsc.scanner = &GNUNET_FS_directory_scanner_default; + dsc.scanner_cls = cls; + dsc.do_index = do_index; + dsc.anonymity = anonymity; + dsc.priority = priority; + dsc.expiration = expirationTime; + if (-1 == GNUNET_DISK_directory_scan (dirname, + &dir_scan_cb, + &dsc)) + { + GNUNET_assert (NULL != dsc.emsg); + *emsg = dsc.emsg; + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Closure for dirproc function. + */ +struct EntryProcCls +{ + /** + * Linked list of directory entries that is being + * created. + */ + struct GNUNET_FS_FileInformation *entries; + +}; + + +/** + * Function that processes a directory entry that + * was obtained from the scanner. + * @param cls our closure + * @param filename name of the file (unused, why there???) + * @param fi information for publishing the file + */ +static void +dirproc (void *cls, + const char *filename, + struct GNUNET_FS_FileInformation *fi) +{ + struct EntryProcCls *dc = cls; + + GNUNET_assert (fi->next == NULL); + GNUNET_assert (fi->dir == NULL); + fi->next = dc->entries; + dc->entries = fi; } @@ -160,22 +559,61 @@ GNUNET_FS_directory_scanner_default (void *cls, * @param filename name of the top-level file or directory * @param scanner function used to get a list of files in a directory * @param scanner_cls closure for scanner + * @param do_index should files in the hierarchy be indexed? * @param anonymity what is the desired anonymity level for sharing? * @param priority what is the priority for OUR node to * keep this file available? Use 0 for maximum anonymity and * minimum reliability... * @param expirationTime when should this content expire? + * @param emsg where to store an error message * @return publish structure entry for the directory, NULL on error */ struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_from_directory (void *client_info, + const char *filename, GNUNET_FS_DirectoryScanner scanner, void *scanner_cls, + int do_index, unsigned int anonymity, unsigned int priority, - struct GNUNET_TIME_Absolute expirationTime) + struct GNUNET_TIME_Absolute expirationTime, + char **emsg) { - return NULL; + struct GNUNET_FS_FileInformation *ret; + struct EntryProcCls dc; + struct GNUNET_FS_Uri *ksk; + struct GNUNET_CONTAINER_MetaData *meta; + + dc.entries = NULL; + meta = GNUNET_CONTAINER_meta_data_create (); + GNUNET_FS_meta_data_make_directory (meta); + + scanner (scanner_cls, + filename, + do_index, + anonymity, + priority, + expirationTime, + &dirproc, + &dc, + emsg); + ksk = NULL; // FIXME... + // FIXME: create meta! + ret = GNUNET_FS_file_information_create_empty_directory (client_info, + meta, + ksk, + anonymity, + priority, + expirationTime); + ret->data.dir.entries = dc.entries; + while (dc.entries != NULL) + { + dc.entries->dir = ret; + fi_sync (dc.entries); + dc.entries = dc.entries->next; + } + fi_sync (ret); + return ret; } @@ -203,7 +641,18 @@ GNUNET_FS_file_information_create_empty_directory (void *client_info, unsigned int priority, struct GNUNET_TIME_Absolute expirationTime) { - return NULL; + struct GNUNET_FS_FileInformation *ret; + + ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation)); + ret->client_info = client_info; + ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); + ret->keywords = GNUNET_FS_uri_dup (keywords); + ret->expirationTime = expirationTime; + ret->is_directory = GNUNET_YES; + ret->anonymity = anonymity; + ret->priority = priority; + fi_sync (ret); + return ret; } @@ -213,16 +662,30 @@ GNUNET_FS_file_information_create_empty_directory (void *client_info, * "GNUNET_FS_publish_start" already. * * @param dir the directory - * @param end the entry to add; the entry must not have been + * @param ent the entry to add; the entry must not have been * added to any other directory at this point and * must not include "dir" in its structure * @return GNUNET_OK on success, GNUNET_SYSERR on error */ int GNUNET_FS_file_information_add (struct GNUNET_FS_FileInformation *dir, - struct GNUNET_FS_FileInformation *end) + struct GNUNET_FS_FileInformation *ent) { - return GNUNET_SYSERR; + if ( (ent->dir != NULL) || + (ent->next != NULL) || + (! dir->is_directory) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + ent->dir = dir; + ent->next = dir->data.dir.entries; + dir->data.dir.entries = ent; + dir->data.dir.dir_size = 0; + dir->publish_offset = 0; + fi_sync (ent); + fi_sync (dir); + return GNUNET_OK; } @@ -245,6 +708,46 @@ GNUNET_FS_file_information_inspect (struct GNUNET_FS_FileInformation *dir, GNUNET_FS_FileInformationProcessor proc, void *proc_cls) { + struct GNUNET_FS_FileInformation *pos; + + if (dir->is_directory) + { + proc (proc_cls, + dir, + dir->data.dir.dir_size, + dir->meta, + &dir->keywords, + &dir->anonymity, + &dir->priority, + &dir->expirationTime, + &dir->client_info); + pos = dir->data.dir.entries; + while (pos != NULL) + { + proc (proc_cls, + pos, + pos->data.dir.dir_size, + pos->meta, + &pos->keywords, + &pos->anonymity, + &pos->priority, + &pos->expirationTime, + &pos->client_info); + pos = pos->next; + } + } + else + { + proc (proc_cls, + dir, + dir->data.file.file_size, + dir->meta, + &dir->keywords, + &dir->anonymity, + &dir->priority, + &dir->expirationTime, + &dir->client_info); + } } @@ -263,6 +766,53 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi, GNUNET_FS_FileInformationProcessor cleaner, void *cleaner_cls) { + struct GNUNET_FS_FileInformation *pos; + + if (fi->is_directory) + { + /* clean up directory */ + while (NULL != (pos = fi->data.dir.entries)) + { + fi->data.dir.entries = pos->next; + GNUNET_FS_file_information_destroy (pos, cleaner, cleaner_cls); + } + /* clean up client-info */ + cleaner (cleaner_cls, + fi, + fi->data.dir.dir_size, + fi->meta, + &fi->keywords, + &fi->anonymity, + &fi->priority, + &fi->expirationTime, + &fi->client_info); + GNUNET_free (fi->data.dir.dirname); + } + else + { + /* call clean-up function of the reader */ + fi->data.file.reader (fi->data.file.reader_cls, 0, 0, NULL, NULL); + /* clean up client-info */ + cleaner (cleaner_cls, + fi, + fi->data.file.file_size, + fi->meta, + &fi->keywords, + &fi->anonymity, + &fi->priority, + &fi->expirationTime, + &fi->client_info); + } + + /* clean up serialization */ + if (0 != UNLINK (fi->serialization)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, + "unlink", + fi->serialization); + GNUNET_FS_uri_destroy (fi->keywords); + GNUNET_CONTAINER_meta_data_destroy (fi->meta); + GNUNET_free (fi->serialization); + GNUNET_free (fi); } diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 69954fd30..008d6a180 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -13,6 +13,7 @@ nodist_gnunetinclude_HEADERS = \ gnunetinclude_HEADERS = \ gnunet_arm_service.h \ + gnunet_bio_lib.h \ gnunet_client_lib.h \ gnunet_common.h \ gnunet_constants.h \ diff --git a/src/include/gnunet_bio_lib.h b/src/include/gnunet_bio_lib.h new file mode 100644 index 000000000..02b04570e --- /dev/null +++ b/src/include/gnunet_bio_lib.h @@ -0,0 +1,281 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + 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 + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + 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. +*/ + +/** + * @file include/gnunet_bio_lib.h + * @brief buffered IO API + * @author Christian Grothoff + */ + +#ifndef GNUNET_BIO_LIB_H +#define GNUNET_BIO_LIB_H + +#include "gnunet_container_lib.h" + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +/** + * Handle for buffered reading. + */ +struct GNUNET_BIO_ReadHandle; + + +/** + * Open a file for reading. + * + * @param fn file name to be opened + * @return IO handle on success, NULL on error + */ +struct GNUNET_BIO_ReadHandle *GNUNET_BIO_read_open (const char *fn); + + +/** + * Close an open file. Reports if any errors reading + * from the file were encountered. + * + * @param h file handle + * @param emsg set to the error message + * @return GNUNET_OK on success, GNUNET_SYSERR otherwise + */ +int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h, + char **emsg); + + +/** + * Read the contents of a binary file into a buffer. + * + * @param h handle to an open file + * @param what describes what is being read (for error message creation) + * @param result the buffer to write the result to + * @param len the number of bytes to read + * @return len on success, GNUNET_SYSERR on failure + */ +ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, + const char *what, + void *result, + size_t len); + +/** + * Read 0-terminated string from a file. + * + * @param h handle to an open file + * @param what describes what is being read (for error message creation) + * @param result the buffer to store a pointer to the (allocated) string to + * (note that *result could be set to NULL as well) + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, + const char *what, + char **result); + + +/** + * Read metadata container from a file. + * + * @param h handle to an open file + * @param what describes what is being read (for error message creation) + * @param result the buffer to store a pointer to the (allocated) metadata + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +int GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h, + const char *what, + struct GNUNET_CONTAINER_MetaData **result); + + +/** + * Read a float. + * + * @param h hande to open file + * @param f address of float to read + */ +#define GNUNET_BIO_read_float(h, f) (sizeof(float) == GNUNET_BIO_read (h, __FILE__ "##__LINE__##", f, sizeof(float))) + + + +/** + * Read a double. + * + * @param h hande to open file + * @param f address of double to read + */ +#define GNUNET_BIO_read_double(h, f) (sizeof(double) == GNUNET_BIO_read (h, __FILE__ "##__LINE__##", f, sizeof(double))) + + +/** + * Read an (u)int32_t. + * + * @param h hande to open file + * @param what describes what is being read (for error message creation) + * @param i address of 32-bit integer to read + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h, + const char *what, + int32_t *i); + + +/** + * Read an (u)int32_t. + * + * @param h hande to open file + * @param i address of 32-bit integer to read + */ +#define GNUNET_BIO_read_int32(h, i) GNUNET_BIO_read_int32__ (h, __FILE__ "##__LINE__##", (int32_t*) i) + + +/** + * Read an (u)int64_t. + * + * @param h hande to open file + * @param what describes what is being read (for error message creation) + * @param i address of 64-bit integer to read + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h, + const char *what, + int64_t *i); + + +/** + * Read an (u)int64_t. + * + * @param h hande to open file + * @param i address of 64-bit integer to read + */ +#define GNUNET_BIO_read_int64(h, i) (sizeof(int64_t) == GNUNET_BIO_read (h, __FILE__ "##__LINE__##", (int64_t*) i, sizeof(int64_t))) + + +/** + * Handle for buffered writing. + */ +struct GNUNET_BIO_WriteHandle; +/** + * Open a file for writing. + * + * @param fn file name to be opened + * @return IO handle on success, NULL on error + */ +struct GNUNET_BIO_WriteHandle *GNUNET_BIO_write_open (const char *fn); + + +/** + * Close an open file for writing. + * + * @param h file handle + * @return GNUNET_OK on success, GNUNET_SYSERR otherwise + */ +int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h); + + +/** + * Write a buffer to a file. + * + * @param h handle to open file + * @param buffer the data to write + * @param n number of bytes to write + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +ssize_t GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, + const void *buffer, + size_t n); + + +/** + * Write a string to a file. + * + * @param h handle to open file + * @param s string to write (can be NULL) + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h, + const char *s); + + + + +/** + * Write metadata container to a file. + * + * @param h handle to open file + * @param m metadata to write + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h, + const struct GNUNET_CONTAINER_MetaData *m); + + + +/** + * Write a float. + * + * @param h hande to open file + * @param f float to write (must be a variable) + */ +#define GNUNET_BIO_write_float(h, f) (sizeof(float) == GNUNET_BIO_write (h, &f, sizeof(float))) + + + +/** + * Write a double. + * + * @param h hande to open file + * @param f double to write (must be a variable) + */ +#define GNUNET_BIO_write_float(h, f) (sizeof(double) == GNUNET_BIO_write (h, &f, sizeof(double))) + + +/** + * Write an (u)int32_t. + * + * @param h hande to open file + * @param i address of 32-bit integer to write + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h, + int32_t i); + + +/** + * Write an (u)int64_t. + * + * @param h hande to open file + * @param i address of 64-bit integer to write + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_write_int64 (struct GNUNET_BIO_ReadHandle *h, + int64_t i); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_BIO_LIB_H */ +#endif +/* end of gnunet_bio_lib.h */ diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h index a5f279f05..f4fd6f36b 100644 --- a/src/include/gnunet_disk_lib.h +++ b/src/include/gnunet_disk_lib.h @@ -72,7 +72,12 @@ extern "C" #define GNUNET_DISK_PERM_OTHER_WRITE 128 #define GNUNET_DISK_PERM_OTHER_EXEC 256 -enum GNUNET_DISK_Seek {GNUNET_SEEK_SET, GNUNET_SEEK_CUR, GNUNET_SEEK_END}; +enum GNUNET_DISK_Seek + { + GNUNET_DISK_SEEK_SET, + GNUNET_DISK_SEEK_CUR, + GNUNET_DISK_SEEK_END + }; struct GNUNET_DISK_FileHandle; @@ -250,7 +255,8 @@ int GNUNET_DISK_file_copy (const char *src, const char *dst); * @return the number of files found, -1 on error */ int GNUNET_DISK_directory_scan (const char *dirName, - GNUNET_FileNameCallback callback, void *data); + GNUNET_FileNameCallback callback, + void *data); /** diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h index 236bdd083..45cd1e77e 100644 --- a/src/include/gnunet_fs_service.h +++ b/src/include/gnunet_fs_service.h @@ -1418,6 +1418,8 @@ typedef int (*GNUNET_FS_FileInformationProcessor)(void *cls, * Create an entry for a file in a publish-structure. * * @param filename name of the file or directory to publish + * @param keywords under which keywords should this file be available + * directly; can be NULL * @param meta metadata for the file * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, * GNUNET_SYSERR for simulation @@ -1431,6 +1433,7 @@ typedef int (*GNUNET_FS_FileInformationProcessor)(void *cls, struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_from_file (void *client_info, const char *filename, + const struct GNUNET_FS_Uri *keywords, const struct GNUNET_CONTAINER_MetaData *meta, int do_index, unsigned int anonymity, @@ -1444,6 +1447,8 @@ GNUNET_FS_file_information_create_from_file (void *client_info, * @param length length of the file * @param data data for the file (should not be used afterwards by * the caller; caller will "free") + * @param keywords under which keywords should this file be available + * directly; can be NULL * @param meta metadata for the file * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, * GNUNET_SYSERR for simulation @@ -1458,6 +1463,7 @@ struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_from_data (void *client_info, uint64_t length, void *data, + const struct GNUNET_FS_Uri *keywords, const struct GNUNET_CONTAINER_MetaData *meta, int do_index, unsigned int anonymity, @@ -1539,6 +1545,10 @@ typedef void (*GNUNET_FS_FileProcessor)(void *cls, * * @param cls closure * @param dirname name of the directory to scan + * @param do_index should files be indexed or inserted + * @param anonymity desired anonymity level + * @param priority priority for publishing + * @param expirationTime expiration for publication * @param proc function to call on each entry * @param proc_cls closure for proc * @param emsg where to store an error message (on errors) @@ -1546,6 +1556,10 @@ typedef void (*GNUNET_FS_FileProcessor)(void *cls, */ typedef int (*GNUNET_FS_DirectoryScanner)(void *cls, const char *dirname, + int do_index, + unsigned int anonymity, + unsigned int priority, + struct GNUNET_TIME_Absolute expirationTime, GNUNET_FS_FileProcessor proc, void *proc_cls, char **emsg); @@ -1565,6 +1579,10 @@ typedef int (*GNUNET_FS_DirectoryScanner)(void *cls, * * @param cls must be of type "struct EXTRACTOR_Extractor*" * @param dirname name of the directory to scan + * @param do_index should files be indexed or inserted + * @param anonymity desired anonymity level + * @param priority priority for publishing + * @param expirationTime expiration for publication * @param proc function called on each entry * @param proc_cls closure for proc * @param emsg where to store an error message (on errors) @@ -1573,8 +1591,13 @@ typedef int (*GNUNET_FS_DirectoryScanner)(void *cls, int GNUNET_FS_directory_scanner_default (void *cls, const char *dirname, + int do_index, + unsigned int anonymity, + unsigned int priority, + struct GNUNET_TIME_Absolute expirationTime, GNUNET_FS_FileProcessor proc, - void *proc_cls); + void *proc_cls, + char **emsg); /** @@ -1590,20 +1613,25 @@ GNUNET_FS_directory_scanner_default (void *cls, * @param filename name of the top-level file or directory * @param scanner function used to get a list of files in a directory * @param scanner_cls closure for scanner + * @param do_index should files in the hierarchy be indexed? * @param anonymity what is the desired anonymity level for sharing? * @param priority what is the priority for OUR node to * keep this file available? Use 0 for maximum anonymity and * minimum reliability... * @param expirationTime when should this content expire? + * @param emsg where to store an error message * @return publish structure entry for the directory, NULL on error */ struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_from_directory (void *client_info, + const char *filename, GNUNET_FS_DirectoryScanner scanner, void *scanner_cls, + int do_index, unsigned int anonymity, unsigned int priority, - struct GNUNET_TIME_Absolute expirationTime); + struct GNUNET_TIME_Absolute expirationTime, + char **emsg); /** diff --git a/src/include/gnunet_util_lib.h b/src/include/gnunet_util_lib.h index fe382be3f..6bb87bf4d 100644 --- a/src/include/gnunet_util_lib.h +++ b/src/include/gnunet_util_lib.h @@ -37,6 +37,7 @@ extern "C" #endif #include "gnunet_common.h" +#include "gnunet_bio_lib.h" #include "gnunet_client_lib.h" #include "gnunet_configuration_lib.h" #include "gnunet_connection_lib.h" diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 46d1c3a7a..f6c1783a6 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -15,6 +15,7 @@ endif lib_LTLIBRARIES = libgnunetutil.la libgnunetutil_la_SOURCES = \ + bio.c \ client.c \ common_allocation.c \ common_endian.c \ diff --git a/src/util/bio.c b/src/util/bio.c new file mode 100644 index 000000000..060b6f94b --- /dev/null +++ b/src/util/bio.c @@ -0,0 +1,545 @@ +/* + This file is part of GNUnet. + (C) 2006, 2009 Christian Grothoff (and other contributing authors) + + 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 + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + 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. +*/ + + +/** + * @file util/bio.c + * @brief functions for buffering IO + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_bio_lib.h" + + +/** + * Handle for buffered reading. + */ +struct GNUNET_BIO_ReadHandle +{ +}; + + +/** + * Open a file for reading. + * + * @param fn file name to be opened + * @return IO handle on success, NULL on error + */ +struct GNUNET_BIO_ReadHandle *GNUNET_BIO_read_open (const char *fn) +{ + return NULL; +} + + +/** + * Close an open file. Reports if any errors reading + * from the file were encountered. + * + * @param h file handle + * @param emsg set to the error message + * @return GNUNET_OK on success, GNUNET_SYSERR otherwise + */ +int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h, + char **emsg) +{ + return GNUNET_SYSERR; +} + + +/** + * Read the contents of a binary file into a buffer. + * + * @param h handle to an open file + * @param what describes what is being read (for error message creation) + * @param result the buffer to write the result to + * @param len the number of bytes to read + * @return len on success, GNUNET_SYSERR on failure + */ +ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, + const char *what, + void *result, + size_t len) +{ +} + + +/** + * Read 0-terminated string from a file. + * + * @param h handle to an open file + * @param what describes what is being read (for error message creation) + * @param result the buffer to store a pointer to the (allocated) string to + * (note that *result could be set to NULL as well) + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, + const char *what, + char **result) +{ +} + + +/** + * Read metadata container from a file. + * + * @param h handle to an open file + * @param what describes what is being read (for error message creation) + * @param result the buffer to store a pointer to the (allocated) metadata + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +int GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h, + const char *what, + struct GNUNET_CONTAINER_MetaData **result) +{ +} + + +/** + * Read an (u)int32_t. + * + * @param h hande to open file + * @param what describes what is being read (for error message creation) + * @param i address of 32-bit integer to read + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h, + const char *what, + int32_t *i); + + +/** + * Read an (u)int64_t. + * + * @param h hande to open file + * @param what describes what is being read (for error message creation) + * @param i address of 64-bit integer to read + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h, + const char *what, + int64_t *i); + +/** + * Handle for buffered writing. + */ +struct GNUNET_BIO_WriteHandle +{ +}; + + +/** + * Open a file for writing. + * + * @param fn file name to be opened + * @return IO handle on success, NULL on error + */ +struct GNUNET_BIO_WriteHandle *GNUNET_BIO_write_open (const char *fn) +{ + return NULL; +} + + +/** + * Close an open file for writing. + * + * @param h file handle + * @return GNUNET_OK on success, GNUNET_SYSERR otherwise + */ +int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h); + + +/** + * Write a buffer to a file. + * + * @param h handle to open file + * @param buffer the data to write + * @param n number of bytes to write + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +ssize_t GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, + const void *buffer, + size_t n); + + +/** + * Write a string to a file. + * + * @param h handle to open file + * @param s string to write (can be NULL) + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h, + const char *s); + + + + +/** + * Write metadata container to a file. + * + * @param h handle to open file + * @param m metadata to write + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h, + const struct GNUNET_CONTAINER_MetaData *m); + + + +/** + * Write a float. + * + * @param h hande to open file + * @param f float to write (must be a variable) + */ +#define GNUNET_BIO_write_float(h, f) (sizeof(float) == GNUNET_BIO_write (h, &f, sizeof(float))) + + + +/** + * Write a double. + * + * @param h hande to open file + * @param f double to write (must be a variable) + */ +#define GNUNET_BIO_write_float(h, f) (sizeof(double) == GNUNET_BIO_write (h, &f, sizeof(double))) + + +/** + * Write an (u)int32_t. + * + * @param h hande to open file + * @param i address of 32-bit integer to write + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h, + int32_t i); + + +/** + * Write an (u)int64_t. + * + * @param h hande to open file + * @param i address of 64-bit integer to write + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int GNUNET_BIO_write_int64 (struct GNUNET_BIO_ReadHandle *h, + int64_t i); + + + + + +typedef struct +{ + int fd; + unsigned int have; + unsigned int size; + char *buffer; +} WriteBuffer; + +static void +write_buffered (WriteBuffer * wb, const void *s, unsigned int size) +{ + const char *src = s; + unsigned int min; + unsigned int pos; + int ret; + + if (wb->fd == -1) + return; + pos = 0; + do + { + /* first, just use buffer */ + min = wb->size - wb->have; + if (min > size - pos) + min = size - pos; + memcpy (&wb->buffer[wb->have], &src[pos], min); + pos += min; + wb->have += min; + if (pos == size) + return; /* done */ + GNUNET_GE_ASSERT (NULL, wb->have == wb->size); + ret = WRITE (wb->fd, wb->buffer, wb->size); + if (ret != wb->size) + { + CLOSE (wb->fd); + wb->fd = -1; + return; /* error */ + } + wb->have = 0; + } + while (pos < size); /* should always be true */ +} + + +static void +WRITEINT (WriteBuffer * wb, int val) +{ + int big; + big = htonl (val); + write_buffered (wb, &big, sizeof (int)); +} + +static void +WRITELONG (WriteBuffer * wb, long long val) +{ + long long big; + big = GNUNET_htonll (val); + write_buffered (wb, &big, sizeof (long long)); +} + +static void +writeURI (WriteBuffer * wb, const struct GNUNET_ECRS_URI *uri) +{ + char *buf; + unsigned int size; + + buf = GNUNET_ECRS_uri_to_string (uri); + size = strlen (buf); + WRITEINT (wb, size); + write_buffered (wb, buf, size); + GNUNET_free (buf); +} + +static void +WRITESTRING (WriteBuffer * wb, const char *name) +{ + GNUNET_GE_BREAK (NULL, name != NULL); + WRITEINT (wb, strlen (name)); + write_buffered (wb, name, strlen (name)); +} + +static void +writeMetaData (struct GNUNET_GE_Context *ectx, + WriteBuffer * wb, const struct GNUNET_MetaData *meta) +{ + unsigned int size; + char *buf; + + size = GNUNET_meta_data_get_serialized_size (meta, + GNUNET_SERIALIZE_FULL + | + GNUNET_SERIALIZE_NO_COMPRESS); + if (size > 1024 * 1024) + size = 1024 * 1024; + buf = GNUNET_malloc (size); + GNUNET_meta_data_serialize (ectx, + meta, + buf, + size, + GNUNET_SERIALIZE_PART | + GNUNET_SERIALIZE_NO_COMPRESS); + WRITEINT (wb, size); + write_buffered (wb, buf, size); + GNUNET_free (buf); +} + + +static void +writeFileInfo (struct GNUNET_GE_Context *ectx, WriteBuffer * wb, + const GNUNET_ECRS_FileInfo * fi) +{ + writeMetaData (ectx, wb, fi->meta); + writeURI (wb, fi->uri); +} + + + + +typedef struct +{ + int fd; + unsigned int have; + unsigned int size; + unsigned int pos; + char *buffer; +} ReadBuffer; + +static int +read_buffered (ReadBuffer * rb, void *d, unsigned int size) +{ + char *dst = d; + unsigned int min; + unsigned int pos; + int ret; + + if (rb->fd == -1) + return -1; + pos = 0; + do + { + /* first, use buffer */ + min = rb->have - rb->pos; + if (min > 0) + { + if (min > size - pos) + min = size - pos; + memcpy (&dst[pos], &rb->buffer[rb->pos], min); + rb->pos += min; + pos += min; + } + if (pos == size) + return pos; /* done! */ + GNUNET_GE_ASSERT (NULL, rb->have == rb->pos); + /* fill buffer */ + ret = READ (rb->fd, rb->buffer, rb->size); + if (ret == -1) + { + CLOSE (rb->fd); + rb->fd = -1; + return -1; + } + if (ret == 0) + return 0; + rb->pos = 0; + rb->have = ret; + } + while (pos < size); /* should always be true */ + return pos; +} + + +static int +read_int (ReadBuffer * rb, int *val) +{ + int big; + + if (sizeof (int) != read_buffered (rb, &big, sizeof (int))) + return GNUNET_SYSERR; + *val = ntohl (big); + return GNUNET_OK; +} + +static unsigned int +read_uint (ReadBuffer * rb, unsigned int *val) +{ + unsigned int big; + + if (sizeof (unsigned int) != + read_buffered (rb, &big, sizeof (unsigned int))) + return GNUNET_SYSERR; + *val = ntohl (big); + return GNUNET_OK; +} + +#define READINT(a) if (GNUNET_OK != read_int(rb, (int*) &a)) return GNUNET_SYSERR; + +static int +read_long (ReadBuffer * rb, long long *val) +{ + long long big; + + if (sizeof (long long) != read_buffered (rb, &big, sizeof (long long))) + return GNUNET_SYSERR; + *val = GNUNET_ntohll (big); + return GNUNET_OK; +} + +#define READLONG(a) if (GNUNET_OK != read_long(rb, (long long*) &a)) return GNUNET_SYSERR; + +static struct GNUNET_ECRS_URI * +read_uri (struct GNUNET_GE_Context *ectx, ReadBuffer * rb) +{ + char *buf; + struct GNUNET_ECRS_URI *ret; + unsigned int size; + + if (GNUNET_OK != read_uint (rb, &size)) + return NULL; + buf = GNUNET_malloc (size + 1); + buf[size] = '\0'; + if (size != read_buffered (rb, buf, size)) + { + GNUNET_free (buf); + return NULL; + } + ret = GNUNET_ECRS_string_to_uri (ectx, buf); + GNUNET_GE_BREAK (ectx, ret != NULL); + GNUNET_free (buf); + return ret; +} + +#define READURI(u) if (NULL == (u = read_uri(ectx, rb))) return GNUNET_SYSERR; + +static char * +read_string (ReadBuffer * rb, unsigned int maxLen) +{ + char *buf; + unsigned int big; + + if (GNUNET_OK != read_uint (rb, &big)) + return NULL; + if (big > maxLen) + return NULL; + buf = GNUNET_malloc (big + 1); + buf[big] = '\0'; + if (big != read_buffered (rb, buf, big)) + { + GNUNET_free (buf); + return NULL; + } + return buf; +} + +#define READSTRING(c, max) if (NULL == (c = read_string(rb, max))) return GNUNET_SYSERR; + +/** + * Read file info from file. + * + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +static struct GNUNET_MetaData * +read_meta (struct GNUNET_GE_Context *ectx, ReadBuffer * rb) +{ + unsigned int size; + char *buf; + struct GNUNET_MetaData *meta; + + if (read_uint (rb, &size) != GNUNET_OK) + { + GNUNET_GE_BREAK (ectx, 0); + return NULL; + } + if (size > 1024 * 1024) + { + GNUNET_GE_BREAK (ectx, 0); + return NULL; + } + buf = GNUNET_malloc (size); + if (size != read_buffered (rb, buf, size)) + { + GNUNET_free (buf); + GNUNET_GE_BREAK (ectx, 0); + return NULL; + } + meta = GNUNET_meta_data_deserialize (ectx, buf, size); + if (meta == NULL) + { + GNUNET_free (buf); + GNUNET_GE_BREAK (ectx, 0); + return NULL; + } + GNUNET_free (buf); + return meta; +} + +/* end of bio.c */ diff --git a/src/util/container_bloomfilter.c b/src/util/container_bloomfilter.c index cf99ac7b4..9efc2647c 100644 --- a/src/util/container_bloomfilter.c +++ b/src/util/container_bloomfilter.c @@ -157,7 +157,7 @@ incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File fileSlot = bitIdx / 2; targetLoc = bitIdx % 2; - GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET)); + GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET)); if (1 != GNUNET_DISK_file_read (fh, &value, 1)) value = 0; low = value & 0xF; @@ -174,7 +174,7 @@ incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File high++; } value = ((high << 4) | low); - GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET)); + GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET)); GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1)); } @@ -200,7 +200,7 @@ decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File /* Each char slot in the counter file holds two 4 bit counters */ fileSlot = bitIdx / 2; targetLoc = bitIdx % 2; - GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET); + GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET); if (1 != GNUNET_DISK_file_read (fh, &value, 1)) value = 0; low = value & 0xF; @@ -226,7 +226,7 @@ decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File } } value = ((high << 4) | low); - GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET); + GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET); GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1)); } @@ -250,7 +250,7 @@ makeEmptyFile (const struct GNUNET_DISK_FileHandle *fh, unsigned int size) return GNUNET_SYSERR; buffer = GNUNET_malloc (BUFFSIZE); memset (buffer, 0, BUFFSIZE); - GNUNET_DISK_file_seek (fh, 0, GNUNET_SEEK_SET); + GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_SET); while (bytesleft > 0) { diff --git a/src/util/disk.c b/src/util/disk.c index b9fad5477..7bf8e9753 100644 --- a/src/util/disk.c +++ b/src/util/disk.c @@ -150,8 +150,8 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, off_t offset, #ifdef MINGW DWORD ret; - static DWORD t[] = { [GNUNET_SEEK_SET] = FILE_BEGIN, - [GNUNET_SEEK_CUR] = FILE_CURRENT, [GNUNET_SEEK_END] = FILE_END }; + static DWORD t[] = { [GNUNET_DISK_SEEK_SET] = FILE_BEGIN, + [GNUNET_DISK_SEEK_CUR] = FILE_CURRENT, [GNUNET_DISK_SEEK_END] = FILE_END }; ret = SetFilePointer (h->h, offset, NULL, t[whence]); if (ret == INVALID_SET_FILE_POINTER) @@ -161,8 +161,8 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, off_t offset, } return ret; #else - static int t[] = { [GNUNET_SEEK_SET] = SEEK_SET, - [GNUNET_SEEK_CUR] = SEEK_CUR, [GNUNET_SEEK_END] = SEEK_END }; + static int t[] = { [GNUNET_DISK_SEEK_SET] = SEEK_SET, + [GNUNET_DISK_SEEK_CUR] = SEEK_CUR, [GNUNET_DISK_SEEK_END] = SEEK_END }; return lseek (h->fd, offset, t[whence]); #endif diff --git a/src/util/pseudonym.c b/src/util/pseudonym.c index 441865acc..5bda78a89 100644 --- a/src/util/pseudonym.c +++ b/src/util/pseudonym.c @@ -391,7 +391,7 @@ GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); GNUNET_free (fn); - GNUNET_DISK_file_seek (fh, idx * sizeof (GNUNET_HashCode), GNUNET_SEEK_SET); + GNUNET_DISK_file_seek (fh, idx * sizeof (GNUNET_HashCode), GNUNET_DISK_SEEK_SET); if (sizeof (GNUNET_HashCode) != GNUNET_DISK_file_read (fh, nsid, sizeof (GNUNET_HashCode))) { GNUNET_DISK_file_close (fh); -- 2.25.1