Esempio n. 1
0
/* return the fd of a local copy, to operate on */
int
dfs_get_local_copy(pentry_t *pe,
                   const char * const remote,
                   int flags)
{
        int fd;
        dpl_dict_t *metadata = NULL;
        dpl_dict_t *headers = NULL;
        struct get_data get_data = { .fd = -1, .buf = NULL };
        dpl_status_t rc = DPL_FAILURE;
        char *local = NULL;
        unsigned encryption = 0;

        local = tmpstr_printf("%s%s", conf->cache_dir, remote);
        LOG(LOG_DEBUG, "bucket=%s, path=%s, local=%s",
            ctx->cur_bucket, remote, local);

        if (-1 == download_headers((char *)remote, &headers)) {
                LOG(LOG_NOTICE, "%s: can't download headers", remote);
                fd = -1;
                goto end;
        }

        metadata = dpl_dict_new(13);
        if (! metadata) {
                LOG(LOG_ERR, "dpl_dict_new: can't allocate memory");
                fd = -1;
                goto end;
        }

        if (DPL_FAILURE == dpl_get_metadata_from_headers(
#if defined(DPL_VERSION_MAJOR) && defined(DPL_VERSION_MINOR) && (DPL_VERSION_MAJOR == 0 && DPL_VERSION_MINOR >= 2) || (DPL_VERSION_MAJOR > 0)
                                                         ctx,
#endif
                                                         headers, metadata)) {
                LOG(LOG_ERR, "%s: metadata extraction failed", remote);
                fd = -1;
                goto end;
        }

        if (-1 == pentry_set_metadata(pe, metadata)) {
                LOG(LOG_ERR, "can't update metadata");
                fd = -1;
                goto end;
        }

        if (-1 == check_permissions(pe, metadata)) {
                LOG(LOG_NOTICE, "permission denied");
                fd = -1;
                goto end;
        }

        /* If the remote MD5 matches a cache file, we don't have to download
         * it again, just return the (open) file descriptor of the cache file
         */
        if (0 == compare_digests(pe, headers))  {
                fd = pentry_get_fd(pe);
                goto end;
        }

        /* a cache file already exists, its MD5 digest is different, so
         * just remove it */
        if (0 == access(local, F_OK)) {
                LOG(LOG_DEBUG, "removing cache file '%s'", local);
                if (-1 == unlink(local))
                        LOG(LOG_ERR, "unlink(%s): %s", local, strerror(errno));
        }

        get_data.fd = open(local, O_RDWR|O_CREAT|O_TRUNC, 0600);
        if (-1 == get_data.fd) {
                LOG(LOG_ERR, "open: %s: %s (%d)",
                    local, strerror(errno), errno);
                fd = -1;
                goto end;
        }

        encryption = check_encryption_flag(metadata);

        rc = dpl_openread(ctx,
                          (char *)remote,
                          encryption,
                          NULL,
                          cb_get_buffered,
                          &get_data,
                          &metadata);

        if (DPL_SUCCESS != rc) {
                LOG(LOG_ERR, "dpl_openread: %s", dpl_status_str(rc));
                close(get_data.fd);
                fd = -1;
                goto end;
        }

        /* If the file is compressed, uncompress it! */
        if(-1 == handle_compression(remote, local, &get_data, metadata)) {
                fd = -1;
                goto end;
        }

        if (-1 == close(get_data.fd)) {
                LOG(LOG_ERR, "close(path=%s, fd=%d): %s",
                    local, get_data.fd, strerror(errno));
                fd = -1;
                goto end;
        }

        fd = open(local, flags, 0600);
        if (-1 == fd) {
                LOG(LOG_ERR, "open(path=%s, fd=%d): %s",
                    local, fd, strerror(errno));
                fd = -1;
                goto end;
        }

  end:
        if (metadata)
                dpl_dict_free(metadata);

        if (headers)
                dpl_dict_free(headers);

        return fd;
}
Esempio n. 2
0
int
cmd_get(int argc,
        char **argv)
{
  int ret;
  char opt;
  char *path = NULL;
  dpl_dict_t *metadata = NULL;
  struct get_data get_data;
  int do_stdout = 0;
  int kflag = 0;
  char *local_file = NULL;
  int start = -1;
  int start_inited = 0;
  int end = -1;
  int end_inited = 0;
  int mflag = 0;

  memset(&get_data, 0, sizeof (get_data));
  get_data.fd = -1;

  var_set("status", "1", VAR_CMD_SET, NULL);

  optind = 0;

  while ((opt = getopt(argc, argv, usage_getoptstr(get_usage))) != -1)
    switch (opt)
      {
      case 'm':
        mflag = 1;
        break ;
      case 's':
        start = strtol(optarg, NULL, 0);
        start_inited = 1;
        break ;
      case 'e':
        end = strtol(optarg, NULL, 0);
        end_inited = 1;
        break ;
      case 'k':
        kflag = 1;
        break ;
      case '?':
      default:
        usage_help(&get_cmd);
        return SHELL_CONT;
      }
  argc -= optind;
  argv += optind;

  if (start_inited != end_inited)
    {
      fprintf(stderr, "please provide -s and -e\n");
      return SHELL_CONT;
    }

  if (2 == argc)
    {
      path = argv[0];
      local_file = argv[1];
    }
  else if (1 == argc)
    {
      path = argv[0];
      local_file = rindex(path, '/');
      if (NULL != local_file)
        local_file++;
      else
        local_file = path;
    }
  else
    {
      usage_help(&get_cmd);
      return SHELL_CONT;
    }

  if (!strcmp(local_file, "-"))
    {
      get_data.fd = 1;
      do_stdout = 1;
    }
  else if ('|' == local_file[0])
    {
      get_data.pipe = popen(local_file + 1, "w");
      if (NULL == get_data.pipe)
        {
          fprintf(stderr, "pipe failed\n");
          goto end;
        }
    }
  else
    {
      ret = access(local_file, F_OK);
      if (0 == ret)
        {
          if (1 == ask_for_confirmation("file already exists, overwrite?"))
            return SHELL_CONT;
        }

      get_data.fd = open(local_file, O_WRONLY|O_CREAT, 0600);
      if (-1 == get_data.fd)
        {
          perror("open");
          goto end;
        }
    }

  if (1 == start_inited && 1 == end_inited)
    {
      char *data_buf;
      u_int data_len;

      ret = dpl_openread_range(ctx, path, (1 == kflag ? DPL_VFILE_FLAG_ENCRYPT : 0u), NULL, start, end, &data_buf, &data_len, &metadata);
      if (DPL_SUCCESS != ret)
        {
          fprintf(stderr, "status: %s (%d)\n", dpl_status_str(ret), ret);
          goto end;
        }
      ret = write_all(get_data.fd, data_buf, data_len);
      free(data_buf);
      if (0 != ret)
        {
          fprintf(stderr, "short write\n");
          goto end;
        }
      if (1 == mflag)
        dpl_dict_iterate(metadata, cb_print_metadata, NULL);
    }
  else
    {
      ret = dpl_openread(ctx, path, (1 == kflag ? DPL_VFILE_FLAG_ENCRYPT : 0u), NULL, cb_get_buffered, &get_data, &metadata);
      if (DPL_SUCCESS != ret)
        {
          fprintf(stderr, "status: %s (%d)\n", dpl_status_str(ret), ret);
          goto end;
        }
      if (1 == mflag)
        dpl_dict_iterate(metadata, cb_print_metadata, NULL);
    }

  var_set("status", "0", VAR_CMD_SET, NULL);

 end:

  if (NULL != metadata)
    dpl_dict_free(metadata);

  if (0 == do_stdout)
    {
      if (-1 != get_data.fd)
        close(get_data.fd);

      if (NULL != get_data.pipe)
        pclose(get_data.pipe);
    }

  return SHELL_CONT;
}