⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gnunet-auto-share.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
     This file is part of GNUnet.
     (C) 2008 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/tools/gnunet-auto-share.c
 * @brief Tool to share directories
 * @author Christian Grothoff
 */

#include "platform.h"
#include "gnunet_directories.h"
#include "gnunet_fs_lib.h"
#include "gnunet_fsui_lib.h"
#include "gnunet_util.h"
#include <extractor.h>

#define PIDFILE_DATA "GNUNET-AUTO-SHARE", "PIDFILE", GNUNET_DEFAULT_HOME_DIRECTORY DIR_SEPARATOR_STR "gnunet-auto-share.pid"

struct FileRecord
{
  struct FileRecord *next;
  char *filename;
  time_t mtime;
  time_t last_seen;
  off_t size;
  GNUNET_HashCode hc;
};

struct DirectoryRecord
{
  struct DirectoryRecord *next;

  struct FileRecord *records;

  char *dirname;

  int records_changed;

  int run;

};

static struct GNUNET_FSUI_UploadList *ul;

static struct GNUNET_ClientServerConnection *sock;

static struct GNUNET_GC_Configuration *meta_cfg;

static int upload_done;

static struct GNUNET_GC_Configuration *cfg;

static struct GNUNET_GE_Context *ectx;

static struct GNUNET_FSUI_Context *ctx;

static char *cfgFilename =
#ifndef MINGW
  GNUNET_DEFAULT_CLIENT_CONFIG_FILE
#else
  GNUNET_DEFAULT_CLIENT_SITE_CONFIG_FILE
#endif
  ;

static struct GNUNET_ECRS_URI *gloKeywords;

static unsigned int anonymity = 1;

static unsigned int priority = 365;

static int do_no_direct_references;

static int debug_flag;

static FILE *myout;

#ifdef MINGW
/**
 * Windows service information
 */
static SERVICE_STATUS theServiceStatus;
static SERVICE_STATUS_HANDLE hService;
#endif

/**
 * Print progess message.
 */
static void *
printstatus (void *ctx, const GNUNET_FSUI_Event * event)
{
  unsigned long long *verboselevel = ctx;
  char *fstring;

  switch (event->type)
    {
    case GNUNET_FSUI_upload_progress:
      if ((*verboselevel > 2) && (event->data.UploadProgress.uc.pos != ul))
        {
          fprintf (myout,
                   _("Upload of `%s' at %llu out of %llu bytes.\n"),
                   event->data.UploadProgress.filename,
                   event->data.UploadProgress.completed,
                   event->data.UploadProgress.total);
          fflush (myout);
        }
      break;
    case GNUNET_FSUI_upload_completed:
      if (*verboselevel)
        {
          fstring =
            GNUNET_ECRS_uri_to_string (event->data.UploadCompleted.uri);
          fprintf (myout,
                   _("Upload of `%s' complete, URI is `%s'.\n"),
                   event->data.UploadCompleted.filename, fstring);
          fflush (myout);
          GNUNET_free (fstring);
        }
      if (ul == event->data.UploadCompleted.uc.pos)
        upload_done = GNUNET_YES;
      break;
    case GNUNET_FSUI_upload_aborted:
      fprintf (myout, _("Upload aborted.\n"));
      fflush (myout);
      upload_done = GNUNET_YES;
      break;
    case GNUNET_FSUI_upload_error:
      fprintf (myout,
               _("Error uploading file: %s\n"),
               event->data.UploadError.message);
      fflush (myout);
      upload_done = GNUNET_YES;
      break;
    case GNUNET_FSUI_upload_started:
      if ((*verboselevel > 1) && (ul == NULL))
        {
          fprintf (myout,
                   _("Starting upload of `%s'.\n"),
                   event->data.UploadStarted.filename);
          fflush (myout);
        }
      break;
    case GNUNET_FSUI_upload_stopped:
      break;
    case GNUNET_FSUI_upload_suspended:
      if ((ul != NULL) && (event->data.UploadSuspended.uc.pos == ul))
        {
          fprintf (myout, _("Uploading suspended.\n"));
          fflush (myout);
          ul = NULL;
        }
      break;
    case GNUNET_FSUI_upload_resumed:
      if (ul == NULL)
        {
          ul = event->data.UploadResumed.uc.pos;
          if (GNUNET_FSUI_ACTIVE != event->data.UploadResumed.state)
            {
              upload_done = GNUNET_YES;
            }
          else
            {
              fprintf (myout, _("Uploading `%s' resumed.\n"),
                       event->data.UploadResumed.filename);
              fflush (myout);
            }
        }
      break;
    default:
      fprintf (myout, _("Unexpected event: %d\n"), event->type);
      fflush (myout);
      GNUNET_GE_BREAK (ectx, 0);
      break;
    }
  return NULL;
}

/**
 * All gnunet-auto-share command line options
 */
static struct GNUNET_CommandLineOption gnunetauto_shareOptions[] = {
  {'a', "anonymity", "LEVEL",
   gettext_noop ("set the desired LEVEL of sender-anonymity"),
   1, &GNUNET_getopt_configure_set_uint, &anonymity},
  GNUNET_COMMAND_LINE_OPTION_CFG_FILE (&cfgFilename),   /* -c */
  {'@', "win-service", NULL, "", 0,
   &GNUNET_getopt_configure_set_option, "GNUNET-AUTO-SHARE:WINSERVICE"},
  {'d', "debug", NULL,
   gettext_noop ("run in debug mode; gnunet-auto-share will "
                 "not daemonize and error messages will "
                 "be written to stderr instead of a logfile"),
   0, &GNUNET_getopt_configure_set_one, &debug_flag},
  {'D', "disable-direct", NULL,
   gettext_noop
   ("do not use libextractor to add additional references to directory entries and/or the published file"),
   0, &GNUNET_getopt_configure_set_one, &do_no_direct_references},
  GNUNET_COMMAND_LINE_OPTION_HELP (gettext_noop ("Automatically share a directory.")),  /* -h */
  GNUNET_COMMAND_LINE_OPTION_HOSTNAME,  /* -H */
  {'K', "global-key", "KEYWORD",
   gettext_noop ("add an additional keyword for all files and directories"
                 " (this option can be specified multiple times)"),
   1, &GNUNET_ECRS_getopt_configure_set_keywords, &gloKeywords},
  GNUNET_COMMAND_LINE_OPTION_LOGGING,   /* -L */
  {'p', "priority", "PRIORITY",
   gettext_noop ("specify the priority of the content"),
   1, &GNUNET_getopt_configure_set_uint, &priority},
  GNUNET_COMMAND_LINE_OPTION_VERSION (PACKAGE_VERSION), /* -v */
  GNUNET_COMMAND_LINE_OPTION_VERBOSE,
  GNUNET_COMMAND_LINE_OPTION_END,
};

static char *
get_record_file_name (const char *dirname)
{
  GNUNET_EncName enc;
  GNUNET_HashCode hc;

  GNUNET_hash (dirname, strlen (dirname), &hc);
  GNUNET_hash_to_enc (&hc, &enc);
  return GNUNET_get_home_filename (ectx, cfg,
#ifndef MINGW
                                   GNUNET_NO,
#else
                                   GNUNET_YES,
#endif
                                   "auto-share-info",
                                   (const char *) &enc, NULL);
}

/**
 * Write the given record to the buffer.
 * @param buf if NULL, only calculate size
 * @return number of bytes written (or number
 *         of bytes that would be written)
 */
static unsigned int
write_file_record (char *buf, unsigned int max, const struct FileRecord *rec)
{
  unsigned int wi;
  unsigned long long wl;

  if ((buf != NULL) &&
      (max <
       sizeof (unsigned long long) * 3 + sizeof (GNUNET_HashCode) +
       strlen (rec->filename) + sizeof (unsigned int)))
    {
      GNUNET_GE_BREAK (NULL, 0);
      return 0;
    }
  if (buf != NULL)
    {
      wi = htonl (strlen (rec->filename));
      memcpy (buf, &wi, sizeof (unsigned int));
      buf += sizeof (unsigned int);
      memcpy (buf, &rec->hc, sizeof (GNUNET_HashCode));
      buf += sizeof (GNUNET_HashCode);
      wl = GNUNET_htonll (rec->mtime);
      memcpy (buf, &wl, sizeof (unsigned long long));
      buf += sizeof (unsigned long long);
      wl = GNUNET_htonll (rec->last_seen);
      memcpy (buf, &wl, sizeof (unsigned long long));
      buf += sizeof (unsigned long long);
      wl = GNUNET_htonll (rec->size);
      memcpy (buf, &wl, sizeof (unsigned long long));
      buf += sizeof (unsigned long long);
      memcpy (buf, rec->filename, strlen (rec->filename));
    }
  return sizeof (unsigned long long) * 3 + sizeof (GNUNET_HashCode) +
    strlen (rec->filename) + sizeof (unsigned int);
}

/**
 * Read a file record.
 * @param head old head of the list, afterwards points to
 *        the new head
 * @param size number of bytes available in buf
 * @return 0 on error, otherwise number of bytes read
 */
static unsigned int
read_file_record (const char *buf,
                  unsigned int size, struct FileRecord **head)
{
  unsigned int wi;
  unsigned long long wl;
  struct FileRecord *r;

  if (size < sizeof (unsigned int))
    {
      GNUNET_GE_BREAK (NULL, 0);
      return 0;
    }
  memcpy (&wi, buf, sizeof (unsigned int));
  if (size <
      ntohl (wi) + sizeof (unsigned long long) * 3 +
      sizeof (GNUNET_HashCode) + sizeof (unsigned int))
    {
      GNUNET_GE_BREAK (NULL, 0);
      return 0;
    }
  buf += sizeof (unsigned int);
  r = GNUNET_malloc (sizeof (struct FileRecord));
  r->next = *head;
  memcpy (&r->hc, buf, sizeof (GNUNET_HashCode));
  buf += sizeof (GNUNET_HashCode);
  memcpy (&wl, buf, sizeof (unsigned long long));
  r->mtime = (time_t) GNUNET_ntohll (wl);
  buf += sizeof (unsigned long long);
  memcpy (&wl, buf, sizeof (unsigned long long));
  r->last_seen = (time_t) GNUNET_ntohll (wl);
  buf += sizeof (unsigned long long);
  memcpy (&wl, buf, sizeof (unsigned long long));
  r->size = (off_t) GNUNET_ntohll (wl);
  buf += sizeof (unsigned long long);
  r->filename = GNUNET_malloc (ntohl (wi) + 1);
  r->filename[ntohl (wi)] = '\0';
  memcpy (r->filename, buf, ntohl (wi));
  *head = r;
  return ntohl (wi) + sizeof (unsigned long long) * 3 +
    sizeof (GNUNET_HashCode) + sizeof (unsigned int);
}

static struct FileRecord *
read_all_records (const char *dir_name)
{
  long off;
  unsigned int d;
  unsigned long long size;
  char *record_fn;
  int fd;
  char *buf;
  struct FileRecord *ret;

  record_fn = get_record_file_name (dir_name);
  if ((GNUNET_OK !=
       GNUNET_disk_file_size (ectx,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -