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

📄 gnunet-auto-share.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 3 页
字号:
                              record_fn,
                              &size,
                              GNUNET_YES)) ||
      (-1 == (fd = GNUNET_disk_file_open (ectx, record_fn, O_RDONLY))))
    {
      GNUNET_free (record_fn);
      return NULL;
    }
  buf = MMAP (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
  if (buf == MAP_FAILED)
    {
      GNUNET_GE_LOG_STRERROR_FILE (ectx,
                                   GNUNET_GE_ADMIN | GNUNET_GE_USER |
                                   GNUNET_GE_ERROR | GNUNET_GE_BULK,
                                   "mmap", record_fn);
      GNUNET_free (record_fn);
      CLOSE (fd);
      return NULL;
    }
  ret = NULL;
  off = 0;
  while (off < size)
    {
      d = read_file_record (&buf[off], size - off, &ret);
      if (d == 0)
        {
          GNUNET_GE_BREAK (NULL, 0);
          break;
        }
      off += d;
    }
  MUNMAP (buf, size);
  CLOSE (fd);
  return ret;
}

static void
write_all_records (struct DirectoryRecord *dr)
{
  const char dummy;
  long off;
  unsigned int d;
  unsigned long long size;
  char *record_fn;
  int fd;
  char *buf;
  struct FileRecord *pos;

  size = 0;
  pos = dr->records;
  while (pos != NULL)
    {
      size += write_file_record (NULL, 0, pos);
      pos = pos->next;
    }
  record_fn = get_record_file_name (dr->dirname);
  if ((-1 == (fd = GNUNET_disk_file_open (ectx,
                                          record_fn,
                                          O_RDWR | O_CREAT | O_TRUNC,
                                          S_IRUSR | S_IWUSR))))
    {
      GNUNET_free (record_fn);
      return;
    }
  LSEEK (fd, size - 1, SEEK_SET);
  WRITE (fd, &dummy, 1);
  buf = MMAP (NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
  if (buf == MAP_FAILED)
    {
      GNUNET_GE_LOG_STRERROR_FILE (ectx,
                                   GNUNET_GE_ADMIN | GNUNET_GE_USER |
                                   GNUNET_GE_ERROR | GNUNET_GE_BULK,
                                   "mmap", record_fn);
      CLOSE (fd);
      UNLINK (record_fn);
      GNUNET_free (record_fn);
      return;
    }
  off = 0;
  pos = dr->records;
  while (pos != NULL)
    {
      d = write_file_record (&buf[off], size - off, pos);
      if (d == 0)
        {
          GNUNET_GE_BREAK (NULL, 0);
          break;
        }
      pos = pos->next;
      off += d;
    }
  MUNMAP (buf, size);
  CLOSE (fd);
}

static struct FileRecord *
find_entry (struct DirectoryRecord *dr, const char *filename)
{
  struct FileRecord *pos = dr->records;
  while ((pos != NULL) && (0 != strcmp (filename, pos->filename)))
    pos = pos->next;
  return pos;
}

static int
test_run (const char *filename, const char *dirName, void *cls)
{
  struct DirectoryRecord *dr = cls;
  GNUNET_HashCode hc;
  struct FileRecord *rec;
  struct stat buf;
  char *fn;

  if (filename[0] == '.')
    return GNUNET_OK;
  if (ul != NULL)
    return GNUNET_SYSERR;
  fn = GNUNET_malloc (strlen (filename) + strlen (dirName) + 2);
  strcpy (fn, dirName);
  strcat (fn, DIR_SEPARATOR_STR);
  strcat (fn, filename);
  if (0 != stat (fn, &buf))
    {
      fprintf (myout, _("Could not access `%s': %s\n"), fn, strerror (errno));
      fflush (myout);
      GNUNET_free (fn);
      return GNUNET_OK;
    }
  rec = find_entry (dr, fn);
  if (rec == NULL)
    {
      rec = GNUNET_malloc (sizeof (struct FileRecord));
      rec->next = dr->records;
      rec->filename = GNUNET_strdup (fn);
      rec->mtime = buf.st_mtime;
      rec->size = buf.st_size;
      rec->last_seen = time (NULL);
      GNUNET_hash_file (NULL, fn, &rec->hc);
      rec->next = dr->records;
      dr->records = rec;
      dr->records_changed = GNUNET_YES;
      if (GNUNET_NO == GNUNET_FS_test_indexed (sock, &rec->hc))
        {
          dr->run = 1;
          GNUNET_free (fn);
          /* keep iterating to mark all other files in this tree! */
          return GNUNET_OK;
        }
    }
  else
    {
      rec->last_seen = time (NULL);
    }
  if ((rec->mtime != buf.st_mtime) || (rec->size != buf.st_size))
    {
      GNUNET_hash_file (NULL, fn, &hc);
      if (0 != memcmp (&hc, &rec->hc, sizeof (GNUNET_HashCode)))
        dr->run = 1;
      rec->mtime = buf.st_mtime;
      rec->size = buf.st_size;
      rec->hc = hc;
    }
  if (S_ISDIR (buf.st_mode))
    GNUNET_disk_directory_scan (ectx, fn, &test_run, dr);
  GNUNET_free (fn);
  return GNUNET_OK;
}

struct AddMetadataClosure
{
  const char *filename;
  struct GNUNET_MetaData *meta;
};


static int
add_meta_data (void *cls,
               struct GNUNET_GC_Configuration *cfg,
               struct GNUNET_GE_Context *ectx,
               const char *section, const char *option)
{
  struct AddMetadataClosure *amc = cls;
  EXTRACTOR_KeywordType type;
  EXTRACTOR_KeywordType max;
  char *value;

  if ((0 != strcmp (amc->filename, section)) &&
      ((0 != strncmp (amc->filename,
                      section,
                      strlen (amc->filename))) ||
       (strlen (section) != strlen (amc->filename) + 1) ||
       ((section[strlen (section) - 1] != '/') &&
        (section[strlen (section) - 1] != '\\'))))
    return 0;
  max = EXTRACTOR_getHighestKeywordTypeNumber ();
  for (type = 0; type < max; type++)
    {
      if (0 == strcasecmp (option, EXTRACTOR_getKeywordTypeAsString (type)))
        break;
    }
  if (type == max)
    {
      GNUNET_GE_LOG (ectx,
                     GNUNET_GE_USER | GNUNET_GE_WARNING | GNUNET_GE_BULK,
                     _
                     ("Unknown keyword type `%s' in metadata configuration\n"),
                     option);
      return 0;
    }
  value = NULL;
  GNUNET_GC_get_configuration_value_string (cfg,
                                            section, option, NULL, &value);
  if (value != NULL)
    {
      GNUNET_meta_data_insert (amc->meta, type, value);
      GNUNET_free (value);
    }
  return 0;
}

static int
probe_directory (const char *filename, const char *dirName, void *cls)
{
  struct DirectoryRecord *dr = cls;
  struct stat buf;
  struct AddMetadataClosure amc;
  struct GNUNET_ECRS_URI *kuri;
  char *fn;
  char *keys;

  if (GNUNET_shutdown_test ())
    return GNUNET_SYSERR;       /* aborted */
  if (filename[0] == '.')
    return GNUNET_OK;
  if (ul != NULL)
    return GNUNET_SYSERR;
  fn = GNUNET_malloc (strlen (filename) + strlen (dirName) + 2);
  strcpy (fn, dirName);
  strcat (fn, DIR_SEPARATOR_STR);
  strcat (fn, filename);
  if (0 != stat (fn, &buf))
    {
      fprintf (myout, "Could not stat `%s': %s\n", fn, STRERROR (errno));
      fflush (myout);
      GNUNET_free (fn);
      return GNUNET_OK;
    }
  dr->run = 0;
  test_run (filename, dirName, dr);
  if (0 == dr->run)
    {
      GNUNET_free (fn);
      return GNUNET_OK;
    }
  amc.meta = GNUNET_meta_data_create ();
  amc.filename = filename;
  /* attaching a listener will prompt iteration
     over all config values! */
  GNUNET_GC_attach_change_listener (meta_cfg, &add_meta_data, &amc);
  GNUNET_GC_detach_change_listener (meta_cfg, &add_meta_data, &amc);
  keys = GNUNET_meta_data_get_by_type (amc.meta, EXTRACTOR_KEYWORDS);
  if (keys != NULL)
    kuri = GNUNET_ECRS_keyword_string_to_uri (NULL, keys);
  else
    kuri = NULL;
  GNUNET_meta_data_delete (amc.meta, EXTRACTOR_KEYWORDS, keys);
  GNUNET_free_non_null (keys);
  ul = GNUNET_FSUI_upload_start (ctx,
                                 fn,
                                 (GNUNET_FSUI_DirectoryScanCallback) &
                                 GNUNET_disk_directory_scan, ectx, anonymity,
                                 priority, GNUNET_YES, GNUNET_YES,
                                 !do_no_direct_references,
                                 GNUNET_get_time () + 2 * GNUNET_CRON_YEARS,
                                 amc.meta, gloKeywords, kuri);
  if (kuri != NULL)
    GNUNET_ECRS_uri_destroy (kuri);
  GNUNET_meta_data_destroy (amc.meta);
  GNUNET_free (fn);
  return GNUNET_SYSERR;
}


/**
 * Actual main function.
 *
 * @return return 0 for ok, -1 on error
 */
int
auto_share_main ()
{
  int errorCode;
  int work_done;
  unsigned long long verbose;
  GNUNET_CronTime delay;
  char *metafn;
  char *dirs;
  char *dirs_idx1;
  char *dirs_idx2;
  struct FileRecord *rpos;
  int filedes[2];               /* pipe between client and parent */
  struct DirectoryRecord *head;
  struct DirectoryRecord *pos;

  if (GNUNET_SYSERR == GNUNET_pid_file_kill_owner (ectx, cfg, PIDFILE_DATA))
    {
      fprintf (myout, _("Failed to stop running gnunet-auto-share.\n"));
      fflush (myout);
      errorCode = -1;
      if (GNUNET_NO == debug_flag)
        GNUNET_terminal_detach_complete (ectx, filedes, GNUNET_NO);
      return GNUNET_SYSERR;
    }
  errorCode = 0;
  if ((GNUNET_NO == debug_flag)
      && (GNUNET_OK != GNUNET_terminal_detach (ectx, cfg, filedes,
                                               PIDFILE_DATA)))
    return GNUNET_SYSERR;
  if (GNUNET_NO != debug_flag)
    GNUNET_pid_file_write (ectx, cfg, getpid (), PIDFILE_DATA);
  head = NULL;
  sock = GNUNET_client_connection_create (ectx, cfg);
  if (sock == NULL)
    {
      fprintf (myout, _("Failed to connect to gnunetd.\n"));
      fflush (myout);
      errorCode = -1;
      if (GNUNET_NO == debug_flag)
        GNUNET_terminal_detach_complete (ectx, filedes, GNUNET_NO);
      goto quit;
    }

  GNUNET_GC_get_configuration_value_number (cfg,
                                            "GNUNET",
                                            "VERBOSE", 0, 9999, 0, &verbose);
  metafn = NULL;
  GNUNET_GC_get_configuration_value_filename (cfg,
                                              "GNUNET-AUTO-SHARE",
                                              "METADATA",
                                              GNUNET_DEFAULT_HOME_DIRECTORY
                                              "/metadata.conf", &metafn);
  GNUNET_GC_get_configuration_value_string (cfg,
                                            "GNUNET-AUTO-SHARE",
                                            "DIRS", "", &dirs);
  meta_cfg = GNUNET_GC_create ();
  if (GNUNET_YES == GNUNET_disk_file_test (NULL, metafn))
    GNUNET_GC_parse_configuration (meta_cfg, metafn);
  if (GNUNET_NO == debug_flag)
    GNUNET_terminal_detach_complete (ectx, filedes, GNUNET_YES);
  GNUNET_free (metafn);
  /* fundamental init */

⌨️ 快捷键说明

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