示例#1
0
static void
clone (GsfInput *input, GsfOutput *output)
{
	if (gsf_input_size (input) > 0) {
		guint8 const *data;
		size_t len;

		while ((len = gsf_input_remaining (input)) > 0) {
			/* copy in odd sized chunks to exercise system */
			if (len > 314)
				len = 314;
			if (NULL == (data = gsf_input_read (input, len, NULL))) {
				g_warning ("error reading ?");
				return;
			}
			if (!gsf_output_write (output, len, data)) {
				g_warning ("error writing ?");
				return;
			}
		}
	} else if (GSF_IS_INFILE(input))
		clone_dir (GSF_INFILE(input), GSF_OUTFILE(output));

	gsf_output_close (output);
	g_object_unref (G_OBJECT (output));
	g_object_unref (G_OBJECT (input));
}
示例#2
0
static int transfer_pull_dir(const char *path)
{
    int res;
    char *pr, *pc;

    if (!strcmp(path, "/"))
        return -1;

    pr = remote_path(path);
    pc = cache_path(path);

    if (!pr || !pc)
    {
        free(pr);
        free(pc);
        return -1;
    }

    res = clone_dir(pr, pc);

    if (res && errno == ENOENT)
    {
        int res2;
        char *parent = dirname_r(path);

        if (parent)
        {
            res2 = transfer_pull_dir(parent);
            free(parent);

            if (!res2)
                res = clone_dir(pr, pc);
        }
    }

    free(pr);
    free(pc);

    return res;
}
示例#3
0
int transfer_begin(struct job *j)
{
    int res;
    char *pread = NULL, *pwrite = NULL;
    size_t p_len;

    pthread_mutex_lock(&m_transfer);

    if (t_state.active)
    {
        DEBUG("called transfer_begin while a transfer is active!");
        pthread_mutex_unlock(&m_transfer);
        return TRANSFER_FAIL;
    }
    pthread_mutex_unlock(&m_transfer);

    p_len = strlen(j->path);

    if (j->op == JOB_PUSH)
    {
        pread = cache_path2(j->path, p_len);
        pwrite = remote_path2(j->path, p_len);
    }
    else if (j->op == JOB_PULL)
    {
        pread = remote_path2(j->path, p_len);
        pwrite = cache_path2(j->path, p_len);
    }

    if (!pread || !pwrite)
    {
        free(pread);
        free(pwrite);
        errno = ENOMEM;
        return -1;
    }

    if (is_reg(pread))
    {
        if (!is_reg(pwrite) && !is_nonexist(pwrite))
        {
            DEBUG("write target is non-regular file: %s", pwrite);
            free(pread);
            free(pwrite);
            return TRANSFER_FAIL;
        }

        pthread_mutex_lock(&m_transfer);
        t_state.active = true;
        t_state.job = j;
        t_state.offset = 0;
        pthread_mutex_unlock(&m_transfer);

        res = transfer(pread, pwrite);
        free(pread);
        free(pwrite);
        return res;
    }
    /* if symlink, copy instantly */
    else if (is_lnk(pread))
    {
        DEBUG("push/pull on symlink");
        copy_symlink(pread, pwrite);
        copy_attrs(pread, pwrite);
        free(pread);
        free(pwrite);
        return TRANSFER_FINISH;
    }
    else if (is_dir(pread))
    {
        DEBUG("push/pull on DIR");
        clone_dir(pread, pwrite);
        copy_attrs(pread, pwrite);
        free(pread);
        free(pwrite);
        return TRANSFER_FINISH;
    }
    else
    {
        ERROR("cannot read file %s", pread);
        free(pread);
        free(pwrite);
        return TRANSFER_FAIL;
    }

    DEBUG("wtf");
    return TRANSFER_FAIL;
}
示例#4
0
static void
clone (char* s_path, char* d_path, int sroot_flag, int level)
{
  struct stat src_stat_buf;
  struct stat dst_stat_buf;
  int dir_already_exists = 0;
  const char* intype = "file";

  if (lstat (s_path, &src_stat_buf) == -1)
    {
      if (!quiet_flag)
	{
          fprintf (stderr, "%s: error: can't get status of %s: %s\n",
	    pname, s_path, sys_errlist[errno]);
          fprintf (stderr, "%s: input entity %s will be ignored\n",
	    pname, s_path);
	}
      return;
    }
  if (sccs_flag && sroot_flag && S_ISLNK (src_stat_buf.st_mode))
    {

      /* If root of the source path is a symbolic link and
	 SCCS cloning is enabled, clone the target of the link */

      if (stat(s_path, &src_stat_buf) == -1)
	{
          if (!quiet_flag)
	    {
              fprintf (stderr, "%s: error: can't get status of %s: %s\n",
	        pname, s_path, sys_errlist[errno]);
              fprintf (stderr, "%s: input entity %s will be ignored\n",
	        pname, s_path);
            }	
          return;
	}
    }
  if (IS_DIR (src_stat_buf))
    intype = "directory";
  if (access (d_path, 0))
    {
      if (errno != ENOENT)
	{
	  if (!quiet_flag)
	    {
	      fprintf (stderr, "%s: error: can't check accessability of %s: %s\n",
	        pname, d_path, sys_errlist[errno]);
	      fprintf (stderr, "%s: input %s %s will be ignored\n",
	        pname, intype, s_path);
	    }
	  return;
	}
    }
  else
    {
      const char* outtype = "file";

      if (lstat (d_path, &dst_stat_buf) == -1)
	{
	  if (!quiet_flag)
	    {
	      fprintf (stderr, "%s: error: unable to get status of %s: %s\n"
,
	        pname, d_path, sys_errlist[errno]);
              fprintf (stderr, "%s: input %s %s will be ignored\n",
	        pname, intype, s_path);
	    }
	  return;
	}
      if (IS_DIR (dst_stat_buf))
	outtype = "directory";
      if (IS_DIR (src_stat_buf) && IS_DIR (dst_stat_buf))
	{
	  dir_already_exists = -1;

	  /* Have to make sure that we have full access to the output
	     directory (at least temporarily).  */

	  chmod (d_path, (dst_stat_buf.st_mode & 07777) | 0700);
	  if (access (d_path, R_OK | W_OK | X_OK) != 0)
	    {
	      if (!quiet_flag)
		{
	          fprintf (stderr, 
                    "%s: error: too few permissions for existing directory %s\n",
	            pname, d_path);
		  fprintf (stderr, "%s: input directory %s will be ignored\n",
	            pname, s_path);
		}
              return;
	    }
	}
      else
	{
          if (force_flag)
	    {
              if (remove_item (s_path, d_path))
	        return;
	    }
          else
	    {
	      if (!quiet_flag)
		{
	          fprintf (stderr, "%s: error: output %s already exists: %s\n",
	            pname, outtype, d_path);
	          fprintf (stderr, "%s: input %s %s will be ignored\n",
	            pname, intype, s_path);
		}
              return;
	    }
	}
    }

  switch (src_stat_buf.st_mode & S_IFMT)
    {
      case  S_IFDIR:				/* Clone a directory */

        if (!dir_already_exists)
          {
            /* Don't let others sneak in. 
               Only we can write the new directory (for now).  */
      
            if (mkdir (d_path, 0700))
              {
                if (!quiet_flag)
      	          {
                    fprintf (stderr, "%s: error: can't create output directory %s: %s\n",
	              pname, d_path, sys_errlist[errno]);
                    fprintf (stderr, "%s: input directory %s will be ignored\n",
	              pname, s_path);
	          }
                return;
	      }
            if (verbose_flag)
              fprintf (stderr, "%s: created new output directory: %s\n",
                pname, d_path);
          }

	clone_dir(s_path, d_path, level);

	/* By default, output directories which existed before this
	   program was executed are reset back to their original
	   permissions (when we are done adding things to them).  For
	   output directories which are actually created by this program
	   however, these have their permissions set so that they are
	   essentially the same as the permissions for their corresponding
	   input directories, except that the owner is given full
	   permissions.  */

	if (dir_already_exists)
	  fix_mode (dst_stat_buf.st_mode & 07777, d_path);
	else
	  fix_mode ((src_stat_buf.st_mode & 07777) | 0700, d_path);
	break;

#ifndef USG
      case S_IFLNK:				/* Clone a symbolic link */

	if (!sccs_flag)
          clone_symbolic_link (s_path, d_path);
	break;
#endif

      default:					/* Clone a normal file */

	if (sccs_flag)
	  break;

#ifndef USG
	if (symlink_flag)
	  mk_symbolic_link(s_path, d_path, level);
	else
#endif
	if (copy_flag)
	  copy_file(s_path, d_path);
	else
	  mk_hard_link(s_path, d_path);

	break;
    } /* switch */
}