static int ftp_init_receive(const char *path, transfer_mode_t mode, ftp_transfer_func hookf) { long rp = ftp->restart_offset; char *e; ftp->restart_offset = 0L; foo_hookf = hookf; reset_transfer_info(); if(ftp_init_transfer() != 0) return -1; ftp_type(mode); if(rp > 0) { /* fp is assumed to be fseek'd already */ ftp_cmd("REST %ld", rp); if(ftp->code != ctContinue) return -1; ftp->ti.size = rp; ftp->ti.restart_size = rp; } ftp_cmd("RETR %s", path); if(ftp->code != ctPrelim) return -1; if(!sock_accept(ftp->data, "r", ftp_is_passive())) { ftp_err(_("data connection not accepted\n")); return -1; } /* try to get the total file size */ { /* see if we have cached this directory/file */ rfile *f = ftp_cache_get_file(path); if(f) ftp->ti.total_size = f->size; else { /* try to figure out file size from RETR reply * Opening BINARY mode data connection for foo.mp3 (14429793 bytes) * ^^^^^^^^ aha! * * note: this might not be the _total_ filesize if we are RESTarting */ e = strstr(ftp->reply, " bytes"); if(e != 0) { while((e > ftp->reply) && isdigit((int)e[-1])) e--; ftp->ti.total_size = strtoul(e,NULL,10); } /* else we don't bother */ } } return 0; }
int ssh_chdir(const char *path) { char* tmp = ftp_path_absolute(path); char *p = sftp_canonicalize_path(ftp->sftp_session, tmp); free(tmp); if (!p) { ftp_err("%s: %s\n", path, ssh_get_error(ftp->session)); return -1; } bool isdir = false; /* First check if this file is cached and is a directory, else we * need to stat the file to see if it really is a directory */ stripslash(p); isdir = (ftp_cache_get_directory(p) != 0); if(!isdir) { rfile *rf = ftp_cache_get_file(p); isdir = (rf && risdir(rf)); } if (!isdir) { sftp_attributes attrib = sftp_stat(ftp->sftp_session, p); if (!attrib) { ftp_err(_("Couldn't stat directory: %s\n"), ssh_get_error(ftp->session)); free(p); return -1; } if (!S_ISDIR(attrib->permissions)) { ftp_err(_("%s: not a directory\n"), p); sftp_attributes_free(attrib); free(p); return -1; } sftp_attributes_free(attrib); } ftp_update_curdir_x(p); free(p); return 0; }
int ssh_do_receive(const char *infile, FILE *fp, getmode_t mode, ftp_transfer_func hookf) { uint64_t offset = ftp->restart_offset; ftp->ti.size = ftp->ti.restart_size = offset; ftp->restart_offset = 0L; rfile* f = ftp_cache_get_file(infile); if (f) ftp->ti.total_size = f->size; else ftp->ti.total_size = ssh_filesize(infile); int r = do_read(infile, fp, mode, hookf, offset); transfer_finished(); return (r == 0 && !ftp->ti.ioerror && !ftp->ti.interrupted) ? 0 : -1; }
/* returns the rfile at PATH * if it's not in the cache, reads the directory * returns 0 if not found */ rfile *ftp_get_file(const char *path) { rfile *f; char *ap; if(!path) return 0; ap = ftp_path_absolute(path); stripslash(ap); f = ftp_cache_get_file(ap); if(!f) { char *p = base_dir_xptr(ap); rdirectory *rdir = ftp_get_directory(p); free(p); if(rdir) f = rdir_get_file(rdir, base_name_ptr(ap)); } free(ap); return f; }
int ftp_maybe_isdir(rfile *fp) { if(risdir(fp)) return 1; if(rislink(fp)) { /* found a link; if the link is in the cache, * check if it's a directory, else we don't * read the directory just to check if it's a * directory */ char *adir = base_dir_xptr(fp->path); char *ap = path_absolute(fp->link, adir, ftp->homedir); rfile *lnfp = ftp_cache_get_file(ap); free(adir); free(ap); if(lnfp) return risdir(lnfp) ? 1 : 0; else /* return maybe ;-) */ return 2; } return 0; }
int ssh_chdir(const char *path) { Attrib *aa; char *p = ftp_path_absolute(path); bool isdir = false; /* First check if this file is cached and is a directory, else we * need to stat the file to see if it really is a directory */ stripslash(p); isdir = (ftp_cache_get_directory(p) != 0); if(!isdir) { rfile *rf = ftp_cache_get_file(p); isdir = (rf && risdir(rf)); } if(!isdir) { if ((aa = ssh_stat(p)) == 0) { free(p); return -1; } if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) { ftp_err("Can't change directory: Can't check target"); free(p); return -1; } if (!S_ISDIR(aa->perm)) { ftp_err("%s: not a directory\n", p); free(p); return -1; } } ftp_update_curdir_x(p); return 0; }