int FSSftp::Stat ( FSPath& path, FSStat* st, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } char* fullPath = ( char* ) path.GetString( _operParam.charset ); sftp_attributes la = sftp_lstat( sftpSession, fullPath ); if ( !la ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } if ( la->type == SSH_FILEXFER_TYPE_SYMLINK ) { char* s = sftp_readlink( sftpSession, fullPath ); if ( s ) { st->link.Set( _operParam.charset, s ); } sftp_attributes_free( la ); //!!! } else { st->mode = la->permissions; st->size = la->size; st->uid = la->uid; st->gid = la->gid; st->mtime = la->mtime; sftp_attributes_free( la ); //!!! return 0; } sftp_attributes a = sftp_stat( sftpSession, fullPath ); if ( !a ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } st->mode = la->permissions; st->size = la->size; st->uid = la->uid; st->gid = la->gid; st->mtime = la->mtime; sftp_attributes_free( a ); //!!! return 0; }
rdirectory *ssh_read_directory(const char *path) { char *p = ftp_path_absolute(path); stripslash(p); sftp_dir dir = sftp_opendir(ftp->sftp_session, p); if (!dir) { free(p); return 0; } ftp_trace("*** start parsing directory listing ***\n"); rdirectory* rdir = rdir_create(); sftp_attributes attrib = NULL; while ((attrib = sftp_readdir(ftp->sftp_session, dir)) != NULL) { ftp_trace("%s\n", attrib->longname); rfile* rf = rfile_create(); rf->perm = perm2string(attrib->permissions); rf->nhl = 0; // atoi(e); if (attrib->owner) rf->owner = xstrdup(attrib->owner); if (attrib->group) rf->group = xstrdup(attrib->group); if (asprintf(&rf->path, "%s/%s", p, attrib->name) == -1) { ftp_err(_("Failed to allocate memory.\n")); sftp_closedir(dir); free(p); rdir_destroy(rdir); rfile_destroy(rf); } rf->mtime = attrib->mtime; rf->date = time_to_string(rf->mtime); rf->size = attrib->size; rfile_parse_colors(rf); rf->link = NULL; if (rislink(rf) && ftp->ssh_version > 2) rf->link = sftp_readlink(ftp->sftp_session, rf->path); list_additem(rdir->files, (void *)rf); sftp_attributes_free(attrib); } ftp_trace("*** end parsing directory listing ***\n"); if (!sftp_dir_eof(dir)) { ftp_err(_("Couldn't list directory: %s\n"), ssh_get_error(ftp->session)); sftp_closedir(dir); free(p); rdir_destroy(rdir); return NULL; } sftp_closedir(dir); rdir->path = p; ftp_trace("added directory '%s' to cache\n", p); list_additem(ftp->cache, rdir); return rdir; }
static void do_sftp(ssh_session session){ sftp_session sftp=sftp_new(session); sftp_dir dir; sftp_attributes file; sftp_statvfs_t sftpstatvfs; struct statvfs sysstatvfs; sftp_file fichier; sftp_file to; int len=1; unsigned int i; char data[DATALEN]={0}; char *lnk; unsigned int count; if(!sftp){ fprintf(stderr, "sftp error initialising channel: %s\n", ssh_get_error(session)); return; } if(sftp_init(sftp)){ fprintf(stderr, "error initialising sftp: %s\n", ssh_get_error(session)); return; } printf("Additional SFTP extensions provided by the server:\n"); count = sftp_extensions_get_count(sftp); for (i = 0; i < count; i++) { printf("\t%s, version: %s\n", sftp_extensions_get_name(sftp, i), sftp_extensions_get_data(sftp, i)); } /* test symlink and readlink */ if (sftp_symlink(sftp, "/tmp/this_is_the_link", "/tmp/sftp_symlink_test") < 0) { fprintf(stderr, "Could not create link (%s)\n", ssh_get_error(session)); return; } lnk = sftp_readlink(sftp, "/tmp/sftp_symlink_test"); if (lnk == NULL) { fprintf(stderr, "Could not read link (%s)\n", ssh_get_error(session)); return; } printf("readlink /tmp/sftp_symlink_test: %s\n", lnk); sftp_unlink(sftp, "/tmp/sftp_symlink_test"); if (sftp_extension_supported(sftp, "*****@*****.**", "2")) { sftpstatvfs = sftp_statvfs(sftp, "/tmp"); if (sftpstatvfs == NULL) { fprintf(stderr, "statvfs failed (%s)\n", ssh_get_error(session)); return; } printf("sftp statvfs:\n" "\tfile system block size: %llu\n" "\tfundamental fs block size: %llu\n" "\tnumber of blocks (unit f_frsize): %llu\n" "\tfree blocks in file system: %llu\n" "\tfree blocks for non-root: %llu\n" "\ttotal file inodes: %llu\n" "\tfree file inodes: %llu\n" "\tfree file inodes for to non-root: %llu\n" "\tfile system id: %llu\n" "\tbit mask of f_flag values: %llu\n" "\tmaximum filename length: %llu\n", (unsigned long long) sftpstatvfs->f_bsize, (unsigned long long) sftpstatvfs->f_frsize, (unsigned long long) sftpstatvfs->f_blocks, (unsigned long long) sftpstatvfs->f_bfree, (unsigned long long) sftpstatvfs->f_bavail, (unsigned long long) sftpstatvfs->f_files, (unsigned long long) sftpstatvfs->f_ffree, (unsigned long long) sftpstatvfs->f_favail, (unsigned long long) sftpstatvfs->f_fsid, (unsigned long long) sftpstatvfs->f_flag, (unsigned long long) sftpstatvfs->f_namemax); sftp_statvfs_free(sftpstatvfs); if (statvfs("/tmp", &sysstatvfs) < 0) { fprintf(stderr, "statvfs failed (%s)\n", strerror(errno)); return; } printf("sys statvfs:\n" "\tfile system block size: %llu\n" "\tfundamental fs block size: %llu\n" "\tnumber of blocks (unit f_frsize): %llu\n" "\tfree blocks in file system: %llu\n" "\tfree blocks for non-root: %llu\n" "\ttotal file inodes: %llu\n" "\tfree file inodes: %llu\n" "\tfree file inodes for to non-root: %llu\n" "\tfile system id: %llu\n" "\tbit mask of f_flag values: %llu\n" "\tmaximum filename length: %llu\n", (unsigned long long) sysstatvfs.f_bsize, (unsigned long long) sysstatvfs.f_frsize, (unsigned long long) sysstatvfs.f_blocks, (unsigned long long) sysstatvfs.f_bfree, (unsigned long long) sysstatvfs.f_bavail, (unsigned long long) sysstatvfs.f_files, (unsigned long long) sysstatvfs.f_ffree, (unsigned long long) sysstatvfs.f_favail, (unsigned long long) sysstatvfs.f_fsid, (unsigned long long) sysstatvfs.f_flag, (unsigned long long) sysstatvfs.f_namemax); } /* the connection is made */ /* opening a directory */ dir=sftp_opendir(sftp,"./"); if(!dir) { fprintf(stderr, "Directory not opened(%s)\n", ssh_get_error(session)); return ; } /* reading the whole directory, file by file */ while((file=sftp_readdir(sftp,dir))){ fprintf(stderr, "%30s(%.8o) : %s(%.5d) %s(%.5d) : %.10llu bytes\n", file->name, file->permissions, file->owner, file->uid, file->group, file->gid, (long long unsigned int) file->size); sftp_attributes_free(file); } /* when file=NULL, an error has occured OR the directory listing is end of file */ if(!sftp_dir_eof(dir)){ fprintf(stderr, "Error: %s\n", ssh_get_error(session)); return; } if(sftp_closedir(dir)){ fprintf(stderr, "Error: %s\n", ssh_get_error(session)); return; } /* this will open a file and copy it into your /home directory */ /* the small buffer size was intended to stress the library. of course, you can use a buffer till 20kbytes without problem */ fichier=sftp_open(sftp,"/usr/bin/ssh",O_RDONLY, 0); if(!fichier){ fprintf(stderr, "Error opening /usr/bin/ssh: %s\n", ssh_get_error(session)); return; } /* open a file for writing... */ to=sftp_open(sftp,"ssh-copy",O_WRONLY | O_CREAT, 0700); if(!to){ fprintf(stderr, "Error opening ssh-copy for writing: %s\n", ssh_get_error(session)); return; } while((len=sftp_read(fichier,data,4096)) > 0){ if(sftp_write(to,data,len)!=len){ fprintf(stderr, "Error writing %d bytes: %s\n", len, ssh_get_error(session)); return; } } printf("finished\n"); if(len<0) fprintf(stderr, "Error reading file: %s\n", ssh_get_error(session)); sftp_close(fichier); sftp_close(to); printf("fichiers ferm\n"); to=sftp_open(sftp,"/tmp/grosfichier",O_WRONLY|O_CREAT, 0644); for(i=0;i<1000;++i){ len=sftp_write(to,data,DATALEN); printf("wrote %d bytes\n",len); if(len != DATALEN){ printf("chunk %d : %d (%s)\n",i,len,ssh_get_error(session)); } } sftp_close(to); /* close the sftp session */ sftp_free(sftp); printf("sftp session terminated\n"); }
int FSSftp::ReadDir ( FSList* list, FSPath& path, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } if ( !list ) { return 0; } list->Clear(); sftp_dir dir = sftp_opendir( sftpSession, ( char* )path.GetString( _operParam.charset ) ); if ( !dir ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } try { while ( true ) { if ( info && info->Stopped() ) { sftp_closedir( dir ); return -2; } sftp_attributes attr = sftp_readdir( sftpSession, dir ); if ( !attr ) { if ( sftp_dir_eof( dir ) ) { break; } if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } try { //skip . and .. if ( !attr->name || attr->name[0] == '.' && ( !attr->name[1] || ( attr->name[1] == '.' && !attr->name[2] ) ) ) { continue; } clPtr<FSNode> pNode = new FSNode(); pNode->name.Set( _operParam.charset, attr->name ); pNode->st.size = attr->size; pNode->st.uid = attr->uid; pNode->st.gid = attr->gid; pNode->st.mtime = attr->mtime; if ( attr->type == SSH_FILEXFER_TYPE_SYMLINK ) { FSPath pt = path; pt.Push( _operParam.charset, attr->name ); char* fullPath = ( char* )pt.GetString( _operParam.charset ); char* s = sftp_readlink( sftpSession, fullPath ); if ( s ) { pNode->st.link.Set( _operParam.charset, s ); } sftp_attributes a = sftp_stat( sftpSession, fullPath ); if ( a ) { pNode->st.mode = a->permissions; pNode->st.mtime = a->mtime; sftp_attributes_free( a ); } else { pNode->st.mode = 0; } } else { pNode->st.mode = attr->permissions; } list->Append( pNode ); sftp_attributes_free( attr ); } catch ( ... ) { sftp_attributes_free( attr ); throw; } }; sftp_closedir( dir ); } catch ( ... ) { sftp_closedir( dir ); throw; } return 0; }