upload.c
来自「GNUnet是一个安全的点对点网络框架」· C语言 代码 · 共 461 行 · 第 1/2 页
C
461 行
/* This file is part of GNUnet. (C) 2001, 2002, 2003, 2004, 2005, 2006 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 applications/fs/ecrs/upload.c * @brief Break file that is inserted into blocks and encrypts * them according to the ECRS scheme. * @see http://gnunet.org/encoding.php3 * @author Krista Bennett * @author Christian Grothoff */#include "platform.h"#include "gnunet_util.h"#include "gnunet_ecrs_lib.h"#include "gnunet_fs_lib.h"#include "gnunet_getoption_lib.h"#include "gnunet_protocols.h"#include "ecrs.h"#include "ecrs_core.h"#include "fs.h"#include "tree.h"#define DEBUG_UPLOAD GNUNET_NO/** * Append the given key and query to the iblock[level]. If * iblock[level] is already full, compute its chk and push it to * level+1 and clear the level. iblocks is guaranteed to be big * enough. */static intpushBlock (struct GNUNET_ClientServerConnection *sock, const GNUNET_EC_ContentHashKey * chk, unsigned int level, GNUNET_DatastoreValue ** iblocks, unsigned int prio, GNUNET_CronTime expirationTime){ unsigned int size; unsigned int present; GNUNET_DatastoreValue *value; GNUNET_EC_DBlock *db; GNUNET_EC_ContentHashKey ichk; size = ntohl (iblocks[level]->size); GNUNET_GE_ASSERT (NULL, size > sizeof (GNUNET_DatastoreValue)); size -= sizeof (GNUNET_DatastoreValue); GNUNET_GE_ASSERT (NULL, size - sizeof (GNUNET_EC_DBlock) <= GNUNET_ECRS_IBLOCK_SIZE); present = (size - sizeof (GNUNET_EC_DBlock)) / sizeof (GNUNET_EC_ContentHashKey); db = (GNUNET_EC_DBlock *) & iblocks[level][1]; if (present == GNUNET_ECRS_CHK_PER_INODE) { GNUNET_EC_file_block_get_key (db, size, &ichk.key); GNUNET_EC_file_block_get_query (db, size, &ichk.query); if (GNUNET_OK != pushBlock (sock, &ichk, level + 1, iblocks, prio, expirationTime)) return GNUNET_SYSERR; GNUNET_EC_file_block_encode (db, size, &ichk.query, &value); if (value == NULL) { GNUNET_GE_BREAK (NULL, 0); return GNUNET_SYSERR; } value->priority = htonl (prio); value->expiration_time = GNUNET_htonll (expirationTime); if (GNUNET_OK != GNUNET_FS_insert (sock, value)) { GNUNET_free (value); return GNUNET_SYSERR; } GNUNET_free (value); size = sizeof (GNUNET_EC_DBlock); /* type */ } /* append GNUNET_EC_ContentHashKey */ memcpy (&((char *) db)[size], chk, sizeof (GNUNET_EC_ContentHashKey)); size += sizeof (GNUNET_EC_ContentHashKey) + sizeof (GNUNET_DatastoreValue); GNUNET_GE_ASSERT (NULL, size < GNUNET_MAX_BUFFER_SIZE); iblocks[level]->size = htonl (size); return GNUNET_OK;}/** * Index or insert a file. * * @param priority what is the priority for OUR node to * keep this file available? Use 0 for maximum anonymity and * minimum reliability... * @param doIndex GNUNET_YES for index, GNUNET_NO for insertion, * GNUNET_SYSERR for simulation * @param uri set to the URI of the uploaded file * @return GNUNET_SYSERR if the upload failed (i.e. not enough space * or gnunetd not running) */intGNUNET_ECRS_file_upload (struct GNUNET_GE_Context *ectx, struct GNUNET_GC_Configuration *cfg, const char *filename, int doIndex, unsigned int anonymityLevel, unsigned int priority, GNUNET_CronTime expirationTime, GNUNET_ECRS_UploadProgressCallback upcb, void *upcbClosure, GNUNET_ECRS_TestTerminate tt, void *ttClosure, struct GNUNET_ECRS_URI **uri){ unsigned long long filesize; unsigned long long pos; unsigned int treedepth; int fd; int i; int ret; unsigned int size; GNUNET_DatastoreValue **iblocks; GNUNET_DatastoreValue *dblock; GNUNET_EC_DBlock *db; GNUNET_DatastoreValue *value; struct GNUNET_ClientServerConnection *sock; GNUNET_HashCode fileId; GNUNET_EC_ContentHashKey mchk; GNUNET_CronTime eta; GNUNET_CronTime start; GNUNET_CronTime now; GNUNET_EC_FileIdentifier fid;#if DEBUG_UPLOAD GNUNET_EncName enc;#endif GNUNET_GE_ASSERT (ectx, cfg != NULL); start = GNUNET_get_time (); memset (&mchk, 0, sizeof (GNUNET_EC_ContentHashKey)); if (GNUNET_YES != GNUNET_disk_file_test (ectx, filename)) { GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER, _("`%s' is not a file.\n"), filename); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_disk_file_size (ectx, filename, &filesize, GNUNET_YES)) { GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER, _("Cannot get size of file `%s'"), filename); return GNUNET_SYSERR; } sock = GNUNET_client_connection_create (ectx, cfg); if (sock == NULL) { GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER, _("Failed to connect to gnunetd.")); return GNUNET_SYSERR; } eta = 0; if (upcb != NULL) upcb (filesize, 0, eta, upcbClosure); if (doIndex == GNUNET_YES) { if (GNUNET_SYSERR == GNUNET_hash_file (ectx, filename, &fileId)) { GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER, _("Cannot hash `%s'.\n"), filename); GNUNET_client_connection_destroy (sock); return GNUNET_SYSERR; } if (GNUNET_YES == GNUNET_FS_test_indexed (sock, &fileId)) { /* file already indexed; simulate only to get the URI! */ doIndex = GNUNET_SYSERR; } } if (doIndex == GNUNET_YES) { now = GNUNET_get_time (); eta = now + 2 * (now - start); /* very rough estimate: GNUNET_hash reads once through the file, we'll do that once more and write it. But of course the second read may be cached, and we have the encryption, so a factor of two is really, really just a rough estimate */ start = now; /* reset the counter since the formula later does not take the time for GNUNET_hash_file into account */ switch (GNUNET_FS_prepare_to_index (sock, &fileId, filename)) { case GNUNET_SYSERR: GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER, _("Initialization for indexing file `%s' failed.\n"), filename); GNUNET_client_connection_destroy (sock); return GNUNET_SYSERR; case GNUNET_NO: GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER, _ ("Indexing file `%s' failed. Suggestion: try to insert the file.\n"), filename); GNUNET_client_connection_destroy (sock); return GNUNET_SYSERR; default: break; } } treedepth = GNUNET_ECRS_compute_depth (filesize);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?