Пример #1
0
static void putfile(const char *path, struct stat *sb,
					unsigned opt, const char *output)
{
	putmode_t how = putNormal;
	bool file_exists = false;
	char *dest, *dpath;
	int r;
	bool dir_created;
	char *dest_dir, *q_dest_dir;

	if((put_glob_mask && fnmatch(put_glob_mask, base_name_ptr(path),
								 FNM_EXTMATCH) == FNM_NOMATCH)
#ifdef HAVE_REGEX
	   || (put_rx_mask_set && regexec(&put_rx_mask, base_name_ptr(path),
									  0, 0, 0) == REG_NOMATCH)
#endif
		)
		return;

	if(!output)
		output = ".";

	if(test(opt, PUT_PARENTS)) {
		char *p = base_dir_xptr(path);
		asprintf(&dest, "%s/%s/%s", output, p, base_name_ptr(path));
		free(p);
	} else if(test(opt, PUT_OUTPUT_FILE))
		dest = xstrdup(output);
	else
		asprintf(&dest, "%s/%s", output, base_name_ptr(path));

	path_collapse(dest);

	/* make sure destination directory exists */
	dpath = base_dir_xptr(dest);
	dest_dir = ftp_path_absolute(dpath);
	q_dest_dir = bash_backslash_quote(dest_dir);
	r = ftp_mkpath(q_dest_dir);
	free(q_dest_dir);
	free(dest_dir);
	if(r == -1) {
		transfer_mail_msg(_("failed to create directory %s\n"), dest_dir);
		free(dpath);
		free(dest);
		return;
	}
	dir_created = (r == 1);

	if(!dir_created && !test(opt, PUT_UNIQUE) && !test(opt, PUT_FORCE)) {
		rfile *f;
		f = ftp_get_file(dest);
		file_exists = (f != 0);
		if(f && risdir(f)) {
			/* can't overwrite a directory */
			printf(_("%s: is a directory\n"), dest);
			free(dest);
			return;
		}
	}

	if(test(opt, PUT_APPEND)) {
		how = putAppend;
	} else if(file_exists) {
		if(test(opt, PUT_SKIP_EXISTING)) {
			printf(_("Remote file '%s' exists, skipping...\n"),
				   shortpath(dest, 42, ftp->homedir));
			free(dest);
			return;
		}
		else if(test(opt, PUT_NEWER)) {
			time_t ft = ftp_filetime(dest);
			if(ft != (time_t)-1 && ft >= sb->st_mtime) {
				printf(_("Remote file '%s' is newer than local, skipping...\n"),
					   shortpath(dest, 42, ftp->homedir));
				free(dest);
				return;
			}
		}
		else if(!test(opt, PUT_RESUME)) {
			if(!put_owbatch) {
				struct tm *fan = gmtime(&sb->st_mtime);
				time_t ft;
				int a;
				rfile *f;
				char *e;

				f = ftp_get_file(dest);
				ft = ftp_filetime(f->path);
				sb->st_mtime = gmt_mktime(fan);
				e = xstrdup(ctime(&sb->st_mtime));
				a = ask(ASKYES|ASKNO|ASKUNIQUE|ASKCANCEL|ASKALL|ASKRESUME,
						ASKRESUME,
						_("Remote file '%s' exists\nLocal: %lld bytes, %sRemote: %lld bytes, %sOverwrite?"),
						shortpath(dest, 42, ftp->homedir),
						(unsigned long long) sb->st_size, e ? e : "unknown size",
						ftp_filesize(f->path), ctime(&ft));
				free(e);
				if(a == ASKCANCEL) {
					put_quit = true;
					free(dest);
					return;
				}
				else if(a == ASKNO) {
					free(dest);
					return;
				}
				else if(a == ASKUNIQUE)
					opt |= PUT_UNIQUE; /* for this file only */
				else if(a == ASKALL)
					put_owbatch = true;
				else if(a == ASKRESUME)
					opt |= PUT_RESUME; /* for this file only */
				/* else a == ASKYES */
			}
		}
	}

	if(test(opt, PUT_RESUME))
		how = putResume;
	if(test(opt, PUT_UNIQUE))
		how = putUnique;

	r = do_the_put(path, dest, how, opt);
	free(dest);
	if(r != 0)
		return;

	if(test(opt, PUT_PRESERVE)) {
		if(ftp->has_site_chmod_command)
			ftp_chmod(ftp->ti.local_name, get_mode_string(sb->st_mode));
	}

	if(test(opt, PUT_DELETE_AFTER)) {
		bool dodel = false;

		if(!test(opt, PUT_FORCE) && !put_delbatch) {
			int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES,
						_("Delete local file '%s'?"),
						shortpath(path, 42, gvLocalHomeDir));
			if(a == ASKALL) {
				put_delbatch = true;
				dodel = true;
			}
			else if(a == ASKCANCEL)
				put_quit = true;
			else if(a != ASKNO)
				dodel = true;
		} else
			dodel = true;

		if(dodel) {
			if(unlink(path) == 0)
				printf(_("%s: deleted\n"),
					   shortpath(path, 42, gvLocalHomeDir));
			else
				printf(_("error deleting '%s': %s\n"),
					   shortpath(path, 42, gvLocalHomeDir),
					   strerror(errno));
		}
	}
}
Пример #2
0
static int fxpfile(const rfile *fi, unsigned int opt,
					const char *output, const char *destname)
{
	fxpmode_t how = fxpNormal;
	bool file_exists = false;
	char *dest, *dpath;
	bool dir_created;
	char *dest_dir, *q_dest_dir;
	Ftp *thisftp = ftp;

	if((fxp_glob_mask
		&& fnmatch(fxp_glob_mask, base_name_ptr(fi->path), 0) == FNM_NOMATCH)
#ifdef HAVE_REGEX
	   || (fxp_rx_mask_set
		   && regexec(&fxp_rx_mask,
					  base_name_ptr(fi->path), 0, 0, 0) == REG_NOMATCH)
#endif
		)
		return 0;

	if(!output)
		output = ".";

	if(test(opt, FXP_PARENTS)) {
		char *p = base_dir_xptr(fi->path);
		if (asprintf(&dest, "%s/%s/%s", output, p, base_name_ptr(fi->path)) == -1)
    {
      fprintf(stderr, _("Failed to allocate memory.\n"));
      free(p);
      return -1;
    }
		free(p);
	} else if(test(opt, FXP_OUTPUT_FILE))
		dest = xstrdup(output);
	else
		if (asprintf(&dest, "%s/%s", output, base_name_ptr(fi->path)) == -1)
    {
      fprintf(stderr, _("Failed to allocate memory.\n"));
      return -1;
    }

	path_collapse(dest);

	ftp_use(fxp_target);

	/* make sure destination directory exists */
	dpath = base_dir_xptr(dest);
	dest_dir = ftp_path_absolute(dpath);
	q_dest_dir = backslash_quote(dest_dir);
	int r = ftp_mkpath(q_dest_dir);
	free(q_dest_dir);
	free(dest_dir);
	if(r == -1) {
		transfer_mail_msg(_("Couldn't create directory: %s\n"), dest_dir);
		free(dpath);
		free(dest);
		ftp_use(thisftp);
		return -1;
	}
	dir_created = (r == 1);

	if(!dir_created && !test(opt, FXP_UNIQUE) && !test(opt, FXP_FORCE)) {
		rfile *f;
		f = ftp_get_file(dest);
		file_exists = (f != 0);
		if(f && risdir(f)) {
			/* can't overwrite a directory */
			printf(_("%s: is a directory\n"), dest);
			free(dest);
			return 0;
		}
	}

	if(test(opt, FXP_APPEND)) {
		how = fxpAppend;
	} else if(file_exists) {
		if(test(opt, FXP_SKIP_EXISTING)) {
			char* sp = shortpath(dest, 42, ftp->homedir);
			printf(_("Remote file '%s' exists, skipping...\n"), sp);
			free(sp);
			free(dest);
			ftp_use(thisftp);
			return 0;
		}
		else if(test(opt, FXP_NEWER)) {
			time_t src_ft;
			time_t dst_ft;

			ftp_use(thisftp);
			src_ft = ftp_filetime(fi->path, test(opt, FXP_FORCE_NEWER));
			ftp_use(fxp_target);

			dst_ft = ftp_filetime(dest, test(opt, FXP_FORCE_NEWER));

			if(src_ft != (time_t)-1 && dst_ft != (time_t)-1 && dst_ft >= src_ft) {
				char* sp = shortpath(dest, 42, ftp->homedir);
				printf(_("Remote file '%s' is newer than local, skipping...\n"), sp);
				free(sp);
				free(dest);
				ftp_use(thisftp);
				return 0;
			}
		}
		else if(!test(opt, FXP_RESUME)) {
			if(!fxp_owbatch) {
				char* sp = shortpath(dest, 42, ftp->homedir);
				int a = ask(ASKYES|ASKNO|ASKUNIQUE|ASKCANCEL|ASKALL|ASKRESUME,
							ASKRESUME,
							_("File '%s' exists, overwrite?"),
							sp);
				free(sp);
				if(a == ASKCANCEL) {
					fxp_quit = true;
					free(dest);
					ftp_use(thisftp);
					return 0;
				}
				else if(a == ASKNO) {
					free(dest);
					ftp_use(thisftp);
					return 0;
				}
				else if(a == ASKUNIQUE)
					opt |= FXP_UNIQUE; /* for this file only */
				else if(a == ASKALL)
					fxp_owbatch = true;
				else if(a == ASKRESUME)
					opt |= FXP_RESUME; /* for this file only */
				/* else a == ASKYES */
			}
		}
	}

	if(test(opt, FXP_RESUME))
		how = fxpResume;
	if(test(opt, FXP_UNIQUE))
		how = fxpUnique;

	r = do_the_fxp(thisftp, fi->path, fxp_target, dest, how, opt);
	free(dest);
	if(r != 0) {
		ftp_use(thisftp);
		return -1;
	}

	if(test(opt, FXP_PRESERVE))
		fxp_preserve_attribs(fi, dest);

	if(test(opt, FXP_DELETE_AFTER)) {
		bool dodel = false;

		ftp_use(thisftp);

		if(!test(opt, FXP_FORCE)
		   && !fxp_delbatch && !gvSighupReceived)
			{
				char* sp = shortpath(fi->path, 42, ftp->homedir);
				int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES,
							_("Delete remote file '%s'?"),
							sp);
				free(sp);
				if(a == ASKALL) {
					fxp_delbatch = true;
					dodel = true;
				}
				else if(a == ASKCANCEL)
					fxp_quit = true;
				else if(a != ASKNO)
					dodel = true;
			} else
				dodel = true;

		if(dodel) {
			ftp_unlink(fi->path);
			char* sp = shortpath(fi->path, 42, ftp->homedir);
			if(ftp->code == ctComplete)
				fprintf(stderr, _("%s: deleted\n"), sp);
			else
				fprintf(stderr, _("error deleting '%s': %s\n"), sp,
						ftp_getreply(false));
			free(sp);
		}
	}

	ftp_use(thisftp);
	return 0;
}