/* abort routine originally from Cftp by Dieter Baron */ int ftp_abort(Socket* fp) { char buf[4096]; #ifdef HAVE_LIBSSH if(ftp->session) /* FIXME: what? */ return 0; #endif if(!ftp_connected()) return -1; ftp_set_close_handler(); if (sock_check_pending(fp, false) == 1) { ftp_trace("There is data on the control channel, won't send ABOR\n"); /* read remaining bytes from connection */ while(fp && sock_read(fp, buf, sizeof(buf)) > 0) /* LOOP */ ; return 0; } ftp->ti.interrupted = true; ftp_err(_("Waiting for remote to finish abort...\n")); ftp_trace("--> telnet interrupt\n"); if(sock_telnet_interrupt(ftp->ctrl) != 0) ftp_err("telnet interrupt: %s\n", strerror(errno)); /* ftp_cmd("ABOR") won't work here, * we must flush data between the ABOR command and ftp_read_reply() */ sock_krb_printf(ftp->ctrl, "ABOR"); sock_printf(ftp->ctrl, "\r\n"); sock_flush(ftp->ctrl); if(ftp_get_verbosity() == vbDebug) ftp_err("--> [%s] ABOR\n", ftp->url->hostname); else ftp_trace("--> [%s] ABOR\n", ftp->url->hostname); /* read remaining bytes from connection */ while(fp && sock_read(fp, buf, sizeof(buf)) > 0) /* LOOP */ ; /* we expect a 426 or 226 reply here... */ ftp_read_reply(); if(ftp->fullcode != 426 && ftp->fullcode != 226) ftp_trace("Huh!? Expected a 426 or 226 reply\n"); /* ... and a 226 or 225 reply here, respectively */ /* FIXME: should skip this reply if prev. reply wasn't 426 or 226 ? */ ftp_read_reply(); if(ftp->fullcode != 226 && ftp->fullcode != 225) ftp_trace("Huh!? Expected a 226 or 225 reply\n"); return -1; }
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)); } }
static void ftp_print_cmd(const char *cmd, va_list ap) { if(ftp_get_verbosity() == vbDebug) { ftp_err("--> [%s] ", ftp->url->hostname); if(strncmp(cmd, "PASS", 4) == 0) ftp_err("PASS ********"); else { vfprintf(stderr, cmd, ap); ftp_vtrace(cmd, ap); } ftp_err("\n"); } else { ftp_trace("--> [%s] ", ftp->url->hostname); if(strncmp(cmd, "PASS", 4) == 0) ftp_trace("PASS ********"); else ftp_vtrace(cmd, ap); ftp_trace("\n"); } }
void cmd_system(int argc, char **argv) { if(argv) { OPT_HELP_NEW(_("Show type of remote system."), "system [options]\n", NULL); maxargs(optind - 1); } need_connected(); need_loggedin(); #ifdef HAVE_LIBSSH if(ftp->session) { fprintf(stderr, "remote system: SSH (version %d)\n", ftp->ssh_version); return; } #endif if(ftp_get_verbosity() != vbDebug) fprintf(stderr, _("remote system: ")); ftp_set_tmp_verbosity(vbCommand); ftp_cmd("SYST"); }
void cmd_system(int argc, char **argv) { if(argv) { OPT_HELP("Show type of remote system. Usage:\n" " system [options]\n" "Options:\n" " -h, --help show this help\n"); maxargs(optind - 1); } need_connected(); need_loggedin(); if(ftp->ssh_pid) { fprintf(stderr, "remote system: SSH (version %d)\n", ftp->ssh_version); return; } if(ftp_get_verbosity() != vbDebug) fprintf(stderr, _("remote system: ")); ftp_set_tmp_verbosity(vbCommand); ftp_cmd("SYST"); }
static char *remote_completion_function(const char *text, int state) { static int len; /* length of unquoted */ static char *dir = NULL; /* any initial directory in text */ static char *unquoted = NULL; /* the unquoted filename (or beginning of it) */ static listitem *lip = NULL; static rdirectory *rdir = NULL; /* the cached remote directory */ static char merge_fmt[] = "%s/%s"; if (!ftp_loggedin()) return 0; /* this is not really true, this is for local filename completion, * but it works here too (sort of), and it looks nicer, since * the whole path is not printed by readline, ie * only foo is printed and not /bar/fu/foo (if cwd == /bar/fu) * readline appends a class character (ie /,@,*) in _local_ filenames */ rl_filename_completion_desired = 1; #ifndef HAVE_LIBEDIT rl_filename_quoting_desired = 1; #endif if (!state) { dir = base_dir_xptr(text); if (dir) { stripslash(dir); char* e = strchr(dir, 0); if (e[-1]=='\"') e[-1] = '\0'; unquote(dir); if (strcmp(dir, "/") == 0) strlcpy(merge_fmt, "%s%s", sizeof(merge_fmt)); else strlcpy(merge_fmt, "%s/%s", sizeof(merge_fmt)); } #ifndef HAVE_LIBEDIT if(gvWaitingDots) { rl_insert_text("..."); /* show dots while waiting, like ncftp */ rl_redisplay(); } #endif char* ap = ftp_path_absolute(dir); rdir = ftp_cache_get_directory(ap); const bool dir_is_cached = (rdir != 0); if (!rdir) rdir = ftp_read_directory(ap); free(ap); #ifndef HAVE_LIBEDIT if (gvWaitingDots) rl_do_undo(); /* remove the dots */ #endif if (!dir_is_cached && ftp_get_verbosity() >= vbCommand) rl_forced_update_display(); if (!rdir) { free(dir); return 0; } unquoted = dequote_filename(base_name_ptr(text), 0); if (!unquoted) unquoted = (char *)xmalloc(1); len = strlen(unquoted); lip = rdir->files->first; } while (lip) { rfile* fp = (rfile *)lip->data; lip = lip->next; /* 0 = not dir, 1 = dir, 2 = link (maybe dir) */ const int isdir = ftp_maybe_isdir(fp); if (remote_dir_only && isdir == 0) continue; const char* name = base_name_ptr(fp->path); /* skip dotdirs in completion */ if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue; if (strncmp(name, unquoted, len) == 0) { char *ret; if (dir) { if (asprintf(&ret, merge_fmt, dir, name) == -1) { fprintf(stderr, _("Failed to allocate memory.\n")); free(unquoted); free(dir); return NULL; } } else ret = xstrdup(name); if (isdir == 1) { rl_completion_append_character = '/'; } else { rl_completion_append_character = ' '; } return ret; } } free(unquoted); free(dir); return NULL; }
int ssh_open_url(url_t* urlp) { ftp->session = ssh_new(); if (!ftp->session) return -1; /* set log level */ if (ftp_get_verbosity() == vbDebug) { int verbosity = SSH_LOG_PROTOCOL; ssh_options_set(ftp->session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); } /* If we have ssh options from yafcrc, load them */ if (gvSSHOptions) { args_t *args = args_create(); args_init(args, 0, NULL); args_push_back(args, gvSSHOptions); int argc = 0; if (ssh_options_getopt(ftp->session, &argc, args->argv) != SSH_OK) { ftp_err(_("Failed to load SSH options from yafcrc config (ssh_options = '%s')\n"), gvSSHOptions); ssh_free(ftp->session); ftp->session = NULL; return -1; } args->argc = argc; args_destroy(args); } /* set host name */ ssh_options_set(ftp->session, SSH_OPTIONS_HOST, urlp->hostname); /* if we have port use that one */ if (urlp->port > 0) ssh_options_set(ftp->session, SSH_OPTIONS_PORT, &urlp->port); /* parse .ssh/config */ int r = ssh_options_parse_config(ftp->session, NULL); if (r != SSH_OK) { ftp_err(_("Failed to parse ssh config: %s\n"), ssh_get_error(ftp->session)); ssh_free(ftp->session); ftp->session = NULL; return r; } /* if we have username use that one */ if (urlp->username) ssh_options_set(ftp->session, SSH_OPTIONS_USER, urlp->username); /* connect to server */ r = ssh_connect(ftp->session); if (r != SSH_OK) { ftp_err(_("Couldn't initialise connection to server: %s\n"), ssh_get_error(ftp->session)); ssh_free(ftp->session); ftp->session = NULL; return r; } /* verify server */ if (verify_knownhost(ftp->session)) { ssh_disconnect(ftp->session); ssh_free(ftp->session); ftp->session = NULL; return -1; } /* authenticate user */ r = test_several_auth_methods(ftp->session, urlp); if (r != SSH_OK) { ftp_err(_("Authentication failed: %s\n"), ssh_get_error(ftp->session)); ssh_disconnect(ftp->session); ssh_free(ftp->session); ftp->session = NULL; return -1; } ftp->ssh_version = ssh_get_version(ftp->session); if (!ftp->ssh_version) { ftp_err(_("Couldn't initialise connection to server\n")); return -1; } ftp->sftp_session = sftp_new(ftp->session); if (!ftp->sftp_session) { ftp_err(_("Couldn't initialise ftp subsystem: %s\n"), ssh_get_error(ftp->session)); ssh_disconnect(ftp->session); ssh_free(ftp->session); ftp->session = NULL; return -1; } r = sftp_init(ftp->sftp_session); if (r != SSH_OK) { ftp_err(_("Couldn't initialise ftp subsystem: %s\n"), ssh_get_error(ftp->sftp_session)); sftp_free(ftp->sftp_session); ftp->sftp_session = NULL; ssh_disconnect(ftp->session); ssh_free(ftp->session); ftp->session = NULL; return r; } ftp->connected = true; ftp->loggedin = true; free(ftp->homedir); ftp->homedir = ftp_getcurdir(); url_destroy(ftp->url); ftp->url = url_clone(urlp); free(ftp->curdir); ftp->curdir = xstrdup(ftp->homedir); free(ftp->prevdir); ftp->prevdir = xstrdup(ftp->homedir); if (ftp->url->directory) ftp_chdir(ftp->url->directory); ftp_get_feat(); return 0; }
int ssh_open_url(url_t *urlp) { char *sftp = gvSFTPServerProgram; char *s; int r; args_clear(ftp->ssh_args); if(urlp->sftp_server) sftp = urlp->sftp_server; args_push_back(ftp->ssh_args, gvSSHProgram); if(gvSSHOptions && strlen(gvSSHOptions)) args_push_back(ftp->ssh_args, gvSSHOptions); args_push_back(ftp->ssh_args, urlp->hostname); r = get_username(urlp, gvUsername, false); if(r != 0) return r; if(urlp->username) { args_push_back(ftp->ssh_args, "-l"); args_push_back(ftp->ssh_args, urlp->username); } else { /* we need a username, otherwise other functions will fail */ urlp->username = xstrdup(gvUsername); } if(urlp->port) { char *p; asprintf(&p, "%d", urlp->port); args_push_back(ftp->ssh_args, "-p"); args_push_back(ftp->ssh_args, p); free(p); } if(ftp_get_verbosity() == vbDebug) args_push_back(ftp->ssh_args, "-v"); /* no subsystem if the server-spec contains a '/' */ if(sftp == 0 || strchr(sftp, '/') == 0) args_push_back(ftp->ssh_args, "-s"); /* Otherwise finish up and return the arg array */ if(sftp != 0) args_push_back(ftp->ssh_args, sftp); else args_push_back(ftp->ssh_args, "sftp"); s = args_cat2(ftp->ssh_args, 0); ftp_trace("SSH args: %s\n", s); if(ftp_get_verbosity() == vbDebug) fprintf(stderr, "SSH args: %s\n", s); free(s); args_add_null(ftp->ssh_args); if(ssh_connect(ftp->ssh_args->argv, &ftp->ssh_in, &ftp->ssh_out, &ftp->ssh_pid) == -1) { return -1; } ftp->ssh_version = ssh_init(); if(ftp->ssh_version == -1) { ftp_err("Couldn't initialise connection to server\n"); return -1; } ftp->connected = true; ftp->loggedin = true; ftp->homedir = ftp_getcurdir(); url_destroy(ftp->url); ftp->url = url_clone(urlp); ftp->curdir = xstrdup(ftp->homedir); ftp->prevdir = xstrdup(ftp->homedir); if(ftp->url->directory) ftp_chdir(ftp->url->directory); ftp_get_feat(); return 0; }
/* abort routine originally from Cftp by Dieter Baron */ int ftp_abort(FILE *fp) { char buf[4096]; fd_set ready; struct timeval poll; if(ftp->ssh_pid) /* FIXME: what? */ return 0; if(!ftp_connected()) return -1; ftp_set_close_handler(); poll.tv_sec = poll.tv_usec = 0; FD_ZERO(&ready); FD_SET(ftp->ctrl->handle, &ready); if(select(ftp->ctrl->handle+1, &ready, 0, 0, &poll) == 1) { ftp_trace("There is data on the control channel, won't send ABOR\n"); /* read remaining bytes from connection */ while(fp && fread(buf, 1, 4096, fp) > 0) /* LOOP */ ; return 0; } ftp->ti.interrupted = true; ftp_err(_("Waiting for remote to finish abort...\n")); ftp_trace("--> telnet interrupt\n"); if(sock_telnet_interrupt(ftp->ctrl) != 0) ftp_err("telnet interrupt: %s\n", strerror(errno)); /* ftp_cmd("ABOR") won't work here, * we must flush data between the ABOR command and ftp_read_reply() */ sock_krb_printf(ftp->ctrl, "ABOR"); sock_printf(ftp->ctrl, "\r\n"); sock_flush(ftp->ctrl); if(ftp_get_verbosity() == vbDebug) ftp_err("--> [%s] ABOR\n", ftp->url->hostname); else ftp_trace("--> [%s] ABOR\n", ftp->url->hostname); /* read remaining bytes from connection */ while(fp && fread(buf, 1, 4096, fp) > 0) /* LOOP */ ; /* we expect a 426 or 226 reply here... */ ftp_read_reply(); if(ftp->fullcode != 426 && ftp->fullcode != 226) ftp_trace("Huh!? Expected a 426 or 226 reply\n"); /* ... and a 226 or 225 reply here, respectively */ /* FIXME: should skip this reply if prev. reply wasn't 426 or 226 ? */ ftp_read_reply(); if(ftp->fullcode != 226 && ftp->fullcode != 225) ftp_trace("Huh!? Expected a 226 or 225 reply\n"); return -1; }