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)); }
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; }
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; }
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 */ }