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 + -
显示快捷键?