コード例 #1
0
ファイル: ftpsend.c プロジェクト: sebastinas/yafc
static bool ftp_pasv(bool ipv6, unsigned char* result, unsigned short* ipv6_port)
{
  if (!ftp->has_pasv_command) {
    ftp_err(_("Host doesn't support passive mode\n"));
    return false;
  }
  ftp_set_tmp_verbosity(vbNone);

  /* request passive mode */
  if (!ipv6)
    ftp_cmd("PASV");
#ifdef HAVE_IPV6
  else if (ipv6)
    ftp_cmd("EPSV");
#endif
  else
    return false;

  if (!ftp_connected())
    return false;

  if (ftp->code != ctComplete) {
    ftp_err(_("Unable to enter passive mode\n"));
    if(ftp->code == ctError) /* no use try it again */
      ftp->has_pasv_command = false;
    return false;
  }

  const char* e = ftp_getreply(false);
  while (e && !isdigit((int)*e))
    e++;

  if (!e)
  {
    ftp_err(_("Error parsing EPSV/PASV reply: '%s'\n"), ftp_getreply(false));
    return false;
  }

  if (!ipv6)
  {
    if (sscanf(e, "%hhu,%hhu,%hhu,%hhu,%hhu,%hhu", &result[0], &result[1],
          &result[2], &result[3], &result[4], &result[5]) != 6)
    {
      ftp_err(_("Error parsing PASV reply: '%s'\n"), ftp_getreply(false));
      return false;
    }
  }
#ifdef HAVE_IPV6
  else
  {
    if (sscanf(e, "%hu", ipv6_port) != 1)
    {
      ftp_err(_("Error parsing EPSV reply: '%s'\n"), ftp_getreply(false));
      return false;
    }
  }
#endif

  return true;
}
コード例 #2
0
ファイル: commands.c プロジェクト: wmene/yafc-1.1.2
void cmd_chmod(int argc, char **argv)
{
	int i;
	list *gl;
	listitem *li;

	OPT_HELP("Change permissions on remote file.  Usage:\n"
			 "  chmod [options] <mode> <file>\n"
			 "Options:\n"
			 "  -h, --help    show this help\n"
			 "<mode> is the permission mode, in octal (ex 644)\n");

	minargs(optind + 1);
	need_connected();
	need_loggedin();

	gl = rglob_create();
	for(i=optind+1; i<argc; i++) {
		stripslash(argv[i]);
		rglob_glob(gl, argv[i], true, true, NODOTDIRS);
	}

	for(li=gl->first; li; li=li->next) {
		if(ftp_chmod(((rfile *)li->data)->path, argv[optind]) != 0)
			printf("%s: %s\n", ((rfile *)li->data)->path, ftp_getreply(false));
	}
	rglob_destroy(gl);
}
コード例 #3
0
ファイル: ftp.c プロジェクト: casualuser/yafc
static void ftp_print_reply(void)
{
    verbose_t v = ftp_get_verbosity();

    ftp_trace("<-- [%s] %s\n",
              ftp->url ? ftp->url->hostname : host_getname(ftp->host),
              ftp_getreply(true));

    if(v >= vbCommand || (ftp->code >= ctTransient && v == vbError)) {
        if(v == vbDebug)
            fprintf(stderr, "<-- [%s] %s\n",
                    ftp->url ? ftp->url->hostname : host_getname(ftp->host),
                    ftp_getreply(true));
        else
            fprintf(stderr, "%s\n", ftp_getreply(false));
    }
}
コード例 #4
0
ファイル: get.c プロジェクト: sebastinas/yafc
/* just gets the file SRC and store in local file DEST
 * doesn't parse any LIST output
 * returns 0 on success, else -1
 */
static int do_the_get(const char *src, const char *dest,
                      putmode_t how, unsigned opt)
{
    char *fulldest;
    char *tmp;
    transfer_mode_t type;

    type = ascii_transfer(src) ? tmAscii : gvDefaultType;
    if(test(opt, GET_ASCII))
        type = tmAscii;
    else if(test(opt, GET_BINARY))
        type = tmBinary;

    tmp = getcwd(NULL, 0);
    if (tmp == (char *)NULL)
        return -1;

    fulldest = path_absolute(dest, tmp, 0);

#if 0 && (defined(HAVE_SETPROCTITLE) || defined(linux))
    if(gvUseEnvString && ftp_connected())
        setproctitle("%s, get %s", ftp->url->hostname, src);
#endif

    int r = ftp_getfile(src, dest, how, type,
                        test(opt, GET_VERBOSE)
                        && !gvSighupReceived
                        && !test(opt, GET_NOHUP) ? transfer : 0);

    if(r == 0 && (test(opt, GET_NOHUP) || gvSighupReceived)) {
        fprintf(stderr, "%s [%sb of ",
                src, human_size(ftp->ti.size));
        fprintf(stderr, "%sb]\n", human_size(ftp->ti.total_size));
    }
    if(test(opt, GET_NOHUP)) {
        if(r == 0)
            transfer_mail_msg(_("received %s\n"), src);
        else
            transfer_mail_msg(_("failed to receive %s: %s\n"),
                              src, ftp_getreply(false));
    }
    free(fulldest);
#if 0 && (defined(HAVE_SETPROCTITLE) || defined(linux))
    if(gvUseEnvString && ftp_connected())
        setproctitle("%s", ftp->url->hostname);
#endif

    free(tmp);

    return r;
}
コード例 #5
0
ファイル: commands.c プロジェクト: Celelibi/yafc
void cmd_filetime(int argc, char **argv)
{
	int i;

	OPT_HELP_NEW(_("Show modification time of remote file."), "filetime [options] <file>...", NULL);
	minargs(optind);
	need_connected();
	need_loggedin();

	for(i=optind;i<argc;i++) {
		time_t t = ftp_filetime(argv[i], true);
		if(t != (time_t) -1)
			printf("%s: %s", argv[i], ctime(&t));
		else
			printf("%s\n", ftp_getreply(false));
	}
}
コード例 #6
0
ファイル: commands.c プロジェクト: wmene/yafc-1.1.2
void cmd_filetime(int argc, char **argv)
{
	int i;

	OPT_HELP("Show modification time of remote file.  Usage:\n"
			 "  filetime [options] <file>...\n"
			 "Options:\n"
			 "  -h, --help    show this help\n");

	minargs(optind);
	need_connected();
	need_loggedin();

	for(i=optind;i<argc;i++) {
		time_t t = ftp_filetime(argv[i]);
		if(t != (time_t) -1)
			printf("%s: %s", argv[i], ctime(&t));
		else
			printf("%s\n", ftp_getreply(false));
	}
}
コード例 #7
0
ファイル: ftpsend.c プロジェクト: wmene/yafc-1.1.2
static int ftp_pasv(unsigned char result[6])
{
    int pa[6];
    char *e;
    int i;

    if(!ftp->has_pasv_command) {
        ftp_err(_("Host doesn't support passive mode\n"));
        return -1;
    }
    ftp_set_tmp_verbosity(vbNone);

    /* request passive mode */
    ftp_cmd("PASV");

    if(!ftp_connected())
        return -1;

    if(ftp->code != ctComplete) {
        ftp_err(_("Unable to enter passive mode\n"));
        if(ftp->code == ctError) /* no use try it again */
            ftp->has_pasv_command = false;
        return -1;
    }

    e = ftp->reply + 4;
    while(!isdigit((int)*e))
        e++;

    if(sscanf(e, "%d,%d,%d,%d,%d,%d",
              &pa[0], &pa[1], &pa[2], &pa[3], &pa[4], &pa[5]) != 6) {
        ftp_err(_("Error parsing PASV reply: '%s'\n"),
                ftp_getreply(false));
        return -1;
    }
    for(i=0; i<6; i++)
        result[i] = (unsigned char)(pa[i] & 0xFF);

    return 0;
}
コード例 #8
0
ファイル: fxp.c プロジェクト: Celelibi/yafc
static int do_the_fxp(Ftp *srcftp, const char *src,
					  Ftp *destftp, const char *dest,
					  fxpmode_t how, unsigned opt)
{
	transfer_mode_t type;

	if(test(opt, FXP_NOHUP))
		fprintf(stderr, "%s\n", src);

	type = ascii_transfer(src) ? tmAscii : gvDefaultType;
	if(test(opt, FXP_ASCII))
		type = tmAscii;
	else if(test(opt, FXP_BINARY))
		type = tmBinary;

#if 0 && (defined(HAVE_SETPROCTITLE) || defined(linux))
	if(gvUseEnvString && ftp_connected())
		setproctitle("%s, fxp %s", srcftp->url->hostname, src);
#endif
	if(test(opt, FXP_VERBOSE)) {
		printf("%s\n", src);
	}
	const int r = ftp_fxpfile(srcftp, src, destftp, dest, how, type);
#if 0 && (defined(HAVE_SETPROCTITLE) || defined(linux))
	if(gvUseEnvString && ftp_connected())
		setproctitle("%s", srcftp->url->hostname);
#endif

	if(test(opt, FXP_NOHUP)) {
		if(r == 0)
			transfer_mail_msg(_("sent %s\n"), src);
		else
			transfer_mail_msg(_("failed to send %s: %s\n"),
							  src, ftp_getreply(false));
	}

	return r;
}
コード例 #9
0
ファイル: get.c プロジェクト: sebastinas/yafc
/* returns:
 * 0   ok, remove file from list
 * -1  failure
 */
static int getfile(const rfile *fi, unsigned int opt,
             const char *output, const char *destname)
{
    struct stat sb;
    char* dest = NULL;
    getmode_t how = getNormal;
    bool mkunique = false;
    int r, ret = -1;

    if((get_glob_mask && fnmatch(get_glob_mask, base_name_ptr(fi->path),
                                 FNM_EXTMATCH) == FNM_NOMATCH)
#ifdef HAVE_REGEX
       || (get_rx_mask_set && regexec(&get_rx_mask, base_name_ptr(fi->path),
                                      0, 0, 0) == REG_NOMATCH)
#endif
        )
    {
        return 0;
    }

    if(!output)
        output = ".";

    if(test(opt, GET_PARENTS)) {
        char *apath = base_dir_xptr(fi->path);
        if (asprintf(&dest, "%s%s/%s", output, apath, destname) == -1)
        {
          free(apath);
          fprintf(stderr, _("Failed to allocate memory.\n"));
          return -1;
        }
        free(apath);
    } else {
        /* check if -o option is given, if GET_OUTPUT_FILE is set, we only
         * transfer one file and output is set to the filename. However, if
         * the destination already exists and is a directory, we assume
         * that the user meant a directory */

        int dest_is_file = test(opt, GET_OUTPUT_FILE);

        if(stat(output, &sb) == 0) {
            if(S_ISDIR(sb.st_mode)) {
                dest_is_file = false;
            }
        }

        if(dest_is_file)
            dest = xstrdup(output);
        else
            if (asprintf(&dest, "%s/%s", output, destname) == -1)
            {
              fprintf(stderr, _("Failed to allocate memory.\n"));
              return -1;
            }
    }

    /* make sure destination directory exists */
    {
        char *destdir = base_dir_xptr(dest);
        if(destdir) {
            bool r = make_path(destdir);
            if(!r) {
                if (errno == EEXIST)
                  ftp_err("`%s' exists but is not a directory\n", destdir);
                else
                  ftp_err("%s: %s\n", destdir, strerror(errno));
                transfer_mail_msg(_("Couldn't create directory: %s\n"),
                                  destdir);
                free(destdir);
                return -1;
            }
            /* change permission and group, if requested */
            if(test(opt, GET_CHMOD)) {
                if(stat(destdir, &sb) == 0) {
                    mode_t m = sb.st_mode;
                    m = mode_adjust(m, cmod);
                    if(chmod(destdir, m) != 0)
                        perror(destdir);
                }           }
            if(test(opt, GET_CHGRP)) {
                if(chown(destdir, -1, group_change) != 0)
                    perror(dest);
            }
            free(destdir);
        }
    }

    /* check if destination file exists */
    if(stat(dest, &sb) == 0) {
        if(test(opt, GET_SKIP_EXISTING)) {
            if(test(opt, GET_VERBOSE)) {
							char* sp = shortpath(dest, 42, gvLocalHomeDir);
              fprintf(stderr, _("Local file '%s' exists, skipping...\n"),
                      sp);
							stats_file(STATS_SKIP, 0);
							free(sp);
						}
            return 0;
        }
        if(test(opt, GET_UNIQUE))
            mkunique = true;
        else if(test(opt, GET_APPEND))
            how = getAppend;
        else if(test(opt, GET_NEWER)) {
            struct tm *fan = gmtime(&sb.st_mtime);
            time_t ft = ftp_filetime(fi->path, test(opt, GET_FORCE_NEWER));
            sb.st_mtime = gmt_mktime(fan);

            ftp_trace("get -n: remote file: %s", ctime(&ft));
            ftp_trace("get -n: local file: %s\n", ctime(&sb.st_mtime));

            if(sb.st_mtime >= ft && ft != (time_t)-1) {
                if(test(opt, GET_VERBOSE)) {
									char* sp = shortpath(dest, 30, gvLocalHomeDir);
                    ftp_err(_(
                        "Local file '%s' is newer than remote, skipping...\n"),
                            sp);
									stats_file(STATS_SKIP, 0);
									free(sp);
								}
                return 0;
            }
        } else if(!test(opt, GET_RESUME)) {
            if(!get_owbatch && !gvSighupReceived) {
                struct tm *fan = gmtime(&sb.st_mtime);
                time_t ft = ftp_filetime(fi->path, test(opt, GET_FORCE_NEWER));
                int a;
                char *e;

                sb.st_mtime = gmt_mktime(fan);
                e = xstrdup(ctime(&sb.st_mtime));
								char* sp = shortpath(dest, 42, gvLocalHomeDir);
                a = ask(ASKYES|ASKNO|ASKUNIQUE|ASKCANCEL|ASKALL|ASKRESUME,
                        ASKRESUME,
                        _("Local file '%s' exists\nLocal: %lld bytes, %sRemote: %lld bytes, %sOverwrite?"),
                        sp,
                        (unsigned long long) sb.st_size, e ? e : "unknown date\n",
                        ftp_filesize(fi->path), ctime(&ft));
								free(sp);
                free(e);
                if(a == ASKCANCEL) {
                    get_quit = true;
                    return 0;
                }
                else if(a == ASKNO)
                    return 0;
                else if(a == ASKUNIQUE)
                    mkunique = true;
                else if(a == ASKALL) {
                    get_owbatch = true;
                }
                else if(a == ASKRESUME)
                    opt |= GET_RESUME; /* for this file only */
                /* else a == ASKYES */
            }
        }
        if(test(opt, GET_RESUME))
            how = getResume;
    }

    if(mkunique) {
        char* newdest = make_unique_filename(dest);
        free(dest);
        dest = newdest;
    }

    /* the file doesn't exist or we choosed to overwrite it, or changed dest */

    if(rislink(fi) && test(opt, GET_NO_DEREFERENCE)) {
        /* remove any existing destination */
        unlink(dest);
        ftp_err(_("symlinking '%s' to '%s'\n"), dest, fi->link);
        if(symlink(fi->link, dest) != 0)
            perror(dest);
        ret = 0;
    }
    else {
        r = do_the_get(fi->path, dest, how, opt);

        if(r == 0) {
			stats_file(STATS_SUCCESS, ftp->ti.total_size);
            ret = 0;
            if(test(opt, GET_PRESERVE))
                get_preserve_attribs(fi, dest);
            if(test(opt, GET_CHMOD)) {
                mode_t m = rfile_getmode(fi);
                m = mode_adjust(m, cmod);
                if(chmod(dest, m) != 0)
                    perror(dest);
            }
            if(test(opt, GET_CHGRP)) {
                if(chown(dest, -1, group_change) != 0)
                    perror(dest);
            }
            if(test(opt, GET_DELETE_AFTER)) {
                bool dodel = false;
								char* sp = shortpath(fi->path, 42, ftp->homedir);
                if(!test(opt, GET_FORCE)
                   && !get_delbatch && !gvSighupReceived)
                {
                    int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES,
                                _("Delete remote file '%s'?"), sp);
                    if(a == ASKALL) {
                        get_delbatch = true;
                        dodel = true;
                    }
                    else if(a == ASKCANCEL)
                        get_quit = true;
                    else if(a != ASKNO)
                        dodel = true;
                } else
                    dodel = true;

                if(dodel) {
                    ftp_unlink(fi->path);
                    if(ftp->code == ctComplete)
                        fprintf(stderr, _("%s: deleted\n"), sp);
                    else
                        fprintf(stderr, _("error deleting '%s': %s\n"),
															  sp, ftp_getreply(false));
                }
								free(sp);
            }
        } else {
			stats_file(STATS_FAIL, 0);
			ret = -1;
		}
    }

    free(dest);
    return ret;
}
コード例 #10
0
ファイル: fxp.c プロジェクト: Celelibi/yafc
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;
}