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;
}
Example #2
0
int CSFTPSession::Stat(const char *path, struct __stat64* buffer)
{
  if(m_connected)
  {
    P8PLATFORM::CLockObject lock(m_lock);
    m_LastActive = P8PLATFORM::GetTimeMs();
    sftp_attributes attributes = sftp_stat(m_sftp_session, CorrectPath(path).c_str());

    if (attributes)
    {
      memset(buffer, 0, sizeof(struct __stat64));
      buffer->st_size = attributes->size;
      buffer->st_mtime = attributes->mtime;
      buffer->st_atime = attributes->atime;

      if S_ISDIR(attributes->permissions)
        buffer->st_mode = S_IFDIR;
      else if S_ISREG(attributes->permissions)
        buffer->st_mode = S_IFREG;

      sftp_attributes_free(attributes);
      return 0;
    }
    else
    {
Example #3
0
void clSFTP::Write(const wxMemoryBuffer& fileContent, const wxString& remotePath) throw(clException)
{
    if(!m_sftp) {
        throw clException("SFTP is not initialized");
    }

    int access_type = O_WRONLY | O_CREAT | O_TRUNC;
    sftp_file file;
    wxString tmpRemoteFile = remotePath;
    tmpRemoteFile << ".codelitesftp";

    file = sftp_open(m_sftp, tmpRemoteFile.mb_str(wxConvUTF8).data(), access_type, 0644);
    if(file == NULL) {
        throw clException(wxString() << _("Can't open file: ") << tmpRemoteFile << ". "
                                     << ssh_get_error(m_ssh->GetSession()),
                          sftp_get_error(m_sftp));
    }

    char* p = (char*)fileContent.GetData();
    const int maxChunkSize = 65536;
    wxInt64 bytesLeft = fileContent.GetDataLen();

    while(bytesLeft > 0) {
        wxInt64 chunkSize = bytesLeft > maxChunkSize ? maxChunkSize : bytesLeft;
        wxInt64 bytesWritten = sftp_write(file, p, chunkSize);
        if(bytesWritten < 0) {
            sftp_close(file);
            throw clException(wxString() << _("Can't write data to file: ") << tmpRemoteFile << ". "
                                         << ssh_get_error(m_ssh->GetSession()),
                              sftp_get_error(m_sftp));
        }
        bytesLeft -= bytesWritten;
        p += bytesWritten;
    }
    sftp_close(file);

    // Unlink the original file if it exists
    bool needUnlink = false;
    {
        // Check if the file exists
        sftp_attributes attr = sftp_stat(m_sftp, remotePath.mb_str(wxConvISO8859_1).data());
        if(attr) {
            needUnlink = true;
            sftp_attributes_free(attr);
        }
    }

    if(needUnlink && sftp_unlink(m_sftp, remotePath.mb_str(wxConvUTF8).data()) < 0) {
        throw clException(wxString() << _("Failed to unlink file: ") << remotePath << ". "
                                     << ssh_get_error(m_ssh->GetSession()),
                          sftp_get_error(m_sftp));
    }

    // Rename the file
    if(sftp_rename(m_sftp, tmpRemoteFile.mb_str(wxConvUTF8).data(), remotePath.mb_str(wxConvUTF8).data()) < 0) {
        throw clException(wxString() << _("Failed to rename file: ") << tmpRemoteFile << " -> " << remotePath << ". "
                                     << ssh_get_error(m_ssh->GetSession()),
                          sftp_get_error(m_sftp));
    }
}
Example #4
0
void clSFTP::Mkpath(const wxString& remoteDirFullpath) throw(clException)
{
    if(!m_sftp) {
        throw clException("SFTP is not initialized");
    }

    wxString tmpPath = remoteDirFullpath;
    tmpPath.Replace("\\", "/");
    if(!tmpPath.StartsWith("/")) {
        throw clException("Mkpath: path must be absolute");
    }

    wxFileName fn(remoteDirFullpath, "");
    const wxArrayString& dirs = fn.GetDirs();
    wxString curdir;

    curdir << "/";
    for(size_t i = 0; i < dirs.GetCount(); ++i) {
        curdir << dirs.Item(i);
        sftp_attributes attr = sftp_stat(m_sftp, curdir.mb_str(wxConvISO8859_1).data());
        if(!attr) {
            // directory does not exists
            CreateDir(curdir);

        } else {
            // directory already exists
            sftp_attributes_free(attr);
        }
        curdir << "/";
    }
}
Example #5
0
static int ggnfs_getattr(const char *path, struct stat *stbuf)
{
 
    int res = 0;
    char filePath[PATH_MAX];
    strcpy(filePath, remotePath);
    strcat(filePath,"/");
    strcat(filePath,path);

    sftp_dir dir;
    sftp_attributes attributes;
    attributes = sftp_lstat(ggnfs_data.sftp, filePath); 
    
    if (attributes != NULL) 
    {
        res = 1;
        // setting struct stat
	memset(stbuf, 0, sizeof(struct stat));

        stbuf->st_uid   = attributes->uid; 
        stbuf->st_gid   = attributes->gid;
        stbuf->st_atime = attributes->atime;
        stbuf->st_ctime = attributes->createtime;
        stbuf->st_mtime = attributes->mtime;
        stbuf->st_size  = attributes->size;
        stbuf->st_mode  = attributes->permissions;

        sftp_attributes_free(attributes);
	res = SSH_OK;
     }
    return EXIT_SUCCESS;    

}
Example #6
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;
}
Example #7
0
uint64_t ssh_filesize(const char *path)
{
  sftp_attributes attrib = sftp_stat(ftp->sftp_session, path);
  if (!attrib)
    return 0;

  uint64_t res = attrib->size;
  sftp_attributes_free(attrib);
  return res;
}
Example #8
0
time_t ssh_filetime(const char *filename)
{
  sftp_attributes attrib = sftp_stat(ftp->sftp_session, filename);
  if (!attrib)
    return -1;

  time_t res = attrib->mtime; /* mtime 64? */
  sftp_attributes_free(attrib);
  return res;
}
void SFTPAttribute::DoClear()
{
    if ( m_attributes ) {
        sftp_attributes_free( m_attributes );
    }
    m_attributes = NULL;
    m_name.Clear();
    m_flags = 0;
    m_size = 0;
    m_permissions = 0;
}
int FSSftp::OpenCreate  ( FSPath& path, bool overwrite, int mode, int* err, FSCInfo* info )
{
	MutexLock lock( &mutex );
	int ret = CheckSession( err, info );

	if ( ret ) { return ret; }

	if ( !overwrite )
	{
		/*
		   заебался выяснять почему sftp_open  с  O_EXCL выдает "generc error" при наличии файла, а не EEXIST какой нибудь
		   поэтому встанил эту дурацкую проверку на наличие
		*/
		sftp_attributes a = sftp_lstat( sftpSession, ( char* ) path.GetString( _operParam.charset, '/' ) );

		if ( a )
		{
			sftp_attributes_free( a ); //!!!

			if ( err ) { *err = SSH_FX_FILE_ALREADY_EXISTS; }

			return -1;
		}
	}


	int n = 0;

	for ( ; n < MAX_FILES; n++ )
		if ( !fileTable[n] ) { break; }

	if ( n >= MAX_FILES )
	{
		if ( err ) { *err = SSH_INTERROR_OUTOF; }

		return -1;
	}

	sftp_file f = sftp_open( sftpSession, ( char* ) path.GetString( _operParam.charset, '/' ),
	                         O_CREAT | O_WRONLY | ( overwrite ? O_TRUNC : O_EXCL ),
	                         mode );

	if ( !f )
	{
//printf("ssh-err:'%s'\n",ssh_get_error(sshSession));
		if ( err ) { *err = sftp_get_error( sftpSession ); }

		return -1;
	}

	fileTable[n] = f;

	return n;
}
Example #11
0
void sftp_client_message_free(SFTP_CLIENT_MESSAGE *msg) {
    if(msg->filename)
        free(msg->filename);
    if(msg->data)
        free(msg->data);
    if(msg->attr)
        sftp_attributes_free(msg->attr);
    if(msg->handle)
        free(msg->handle);
    memset(msg,'X',sizeof(*msg));
    free(msg);
}
Example #12
0
static csync_vio_file_stat_t *_sftp_readdir(csync_vio_method_handle_t *dhandle) {
  sftp_attributes dirent = NULL;
  csync_vio_file_stat_t *fs = NULL;

  /* TODO: consider adding the _sftp_connect function */
  dirent = sftp_readdir(_sftp_session, dhandle);
  if (dirent == NULL) {
    errno = _sftp_portable_to_errno(sftp_get_error(_sftp_session));
    return NULL;
  }

  fs = c_malloc(sizeof(csync_vio_file_stat_t));
  if (fs == NULL) {
    sftp_attributes_free(dirent);
    return NULL;
  }

  fs->name = c_strdup(dirent->name);
  fs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;

  switch (dirent->type) {
    case SSH_FILEXFER_TYPE_REGULAR:
      fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
      fs->type = CSYNC_VIO_FILE_TYPE_REGULAR;
      break;
    case SSH_FILEXFER_TYPE_DIRECTORY:
      fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
      fs->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
      break;
    case SSH_FILEXFER_TYPE_SYMLINK:
    case SSH_FILEXFER_TYPE_SPECIAL:
    case SSH_FILEXFER_TYPE_UNKNOWN:
      break;
  }

  sftp_attributes_free(dirent);
  return fs;
}
Example #13
0
void sftp_client_message_free(sftp_client_message msg) {
  if (msg == NULL) {
    return;
  }

  SAFE_FREE(msg->filename);
  ssh_string_free(msg->data);
  ssh_string_free(msg->handle);
  sftp_attributes_free(msg->attr);
  ssh_buffer_free(msg->complete_message);
  SAFE_FREE(msg->str_data);
  ZERO_STRUCTP(msg);
  SAFE_FREE(msg);
}
Example #14
0
static int ggnfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
			 off_t offset, struct fuse_file_info *fi)
{
    int res = 0;
    (void) offset;
    (void) fi;	 

    sftp_dir *dir;
    dir = (sftp_dir *)(uintptr_t) fi->fh;
    sftp_attributes attributes;
    int rc1;
    
    while ((attributes = sftp_readdir(ggnfs_data.sftp, dir)) != NULL)
    {
	struct stat stbuf;

        stbuf.st_uid   = attributes->uid; 
        stbuf.st_gid   = attributes->gid;
        stbuf.st_atime = attributes->atime;
        stbuf.st_ctime = attributes->createtime;
        stbuf.st_mtime = attributes->mtime;
        stbuf.st_size  = attributes->size;
        stbuf.st_mode  = attributes->permissions;

        if(filler(buf, attributes->name, &stbuf, 0))
        {
            fprintf(stderr, "Error ggnfs_readdir filler: buffer full");
            return -ENOMEM;
        }
     sftp_attributes_free(attributes);
    }

    if (!sftp_dir_eof(dir))
    {
        fprintf(stderr, "Can't list directory: %s\n",
            ssh_get_error(ggnfs_data.session));
        sftp_closedir(dir);
        return SSH_ERROR;
    }

    rc1 = sftp_closedir(dir);
    if (rc1 != SSH_OK)
    {
         fprintf(stderr, " inside Readdir: Canftp_list_dirt close directory\n");
    }
    return EXIT_SUCCESS;
}
Example #15
0
uint8_t* sn_sftp_load_file(ssh_session ssh, sftp_session sftp, std::string path) {
	uint8_t *data;

	int access_type, fd, nbytes, index, rc;
	char buffer[SFTP_MAX_XFER_BUFFER];

	index = 0;

	sftp_file file;

	access_type = O_RDONLY;

	file = sftp_open(sftp, path.c_str(), access_type, 0);

	if (file == NULL) {
		std::cerr << "Can't open file for reading: " << strerror(errno) << std::endl;
		return NULL;
	}

	sftp_attributes attr = sftp_fstat(file);

	data = new uint8_t[attr->size + 1];

	for(;;) {
		nbytes = sftp_read(file, buffer, sizeof(buffer));
		if (nbytes == 0) {
			break;
		} else if (nbytes < 0) {
			std::cerr << "Error while reading file: " << ssh_get_error(ssh) << std::endl;
			sftp_close(file);
			delete[] data;
			return NULL;
		}

		memcpy(data + index, buffer, nbytes); 
		index += nbytes;
	}

	rc = sftp_close(file);
	assert(rc == SSH_OK);

	data[attr->size] = '\0';
	sftp_attributes_free(attr);
	return data;
}
Example #16
0
int sftp_list_dir(ssh_session session, sftp_session sftp)
{
  sftp_dir dir;
  sftp_attributes attributes;
  int rc;
  dir = sftp_opendir(sftp, remotePath);
  if (!dir)
  {
    fprintf(stderr, "Directory not opened: %s\n",
            ssh_get_error(session));
    return SSH_ERROR;
  }
  printf("Name                       Size Perms    Owner\tGroup\n");
  while ((attributes = sftp_readdir(sftp, dir)) != NULL)
  {
    printf("%-20s %10llu %.8o %s(%d)\t%s(%d)\n",
     attributes->name,
     (long long unsigned int) attributes->size,
     attributes->permissions,
     attributes->owner,
     attributes->uid,
     attributes->group,
     attributes->gid);
     sftp_attributes_free(attributes);
  }
  if (!sftp_dir_eof(dir))
  {
    fprintf(stderr, "Can't list directory: %s\n",
            ssh_get_error(session));
    sftp_closedir(dir);
    return SSH_ERROR;
  }
  rc = sftp_closedir(dir);
  if (rc != SSH_OK)
  {
    fprintf(stderr, "Can't close directory: %s\n",
            ssh_get_error(session));
    return rc;
  }
}
Example #17
0
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");
}
Example #18
0
static int sftp_list_file(ssh_session session,char *remote_dir,char *remote_file)
{
	sftp_attributes file;
	char datex[22];
	char mtemp[1024];
	time_t mtime=0;
#ifdef WIN32
	struct tm *mytime=NULL;
	int x=0;
#endif
	sftp_session sftp=sftp_new(session);

	if(!sftp)
	{
		prterr("sftp error initialising channel: %s\n",ssh_get_error(session));
		return(1);
	}
	if(sftp_init(sftp))
	{
        	prterr("error initializing sftp: %s\n",ssh_get_error(session));
		return(1);
	}
	
	memset(datex,0,22);
	memset(mtemp,0,1024);
	if(isEMPTY(remote_dir) || !RDAstrcmp(remote_dir,"\"\""))
	{
		sprintf(mtemp,"%s",remote_file);
	} else {
		sprintf(mtemp,"%s/%s",remote_dir,remote_file);
	}
	file=sftp_stat(sftp,mtemp);
	if(file==NULL)
	{
		/* when file=NULL, an error has occured OR the directory listing is end of file */
		prterr("Error getting file info for [%s]",mtemp);
		sftp_free(sftp);
		return(1);
	}else{
	

#ifndef WIN32
#ifdef _POSIX_SOURCE
		mtime=file->mtime;
		//strftime(datex,22,"%b %d %Y %l:%M %p",localtime(&file->mtime));
		strftime(datex,22,"%b %d %Y %l:%M %p",localtime(&mtime));
#else
		TRACE;
		ascftime(datex,"%b %d %Y %l:%M %p",localtime(&file->mtime));
#endif /* _POSIX_SOURCE */
#else /* WIN32 */
		TRACE;
		mytime=localctime(&file->mtime);
		x=mytime->tm_year;
		while(x>=200) x-=100;
		sprintf(datex,"%02d/%02d/%04d  ",mytime->tm_mon+1,mytime->tm_mday,1900+my_time->tm_year);
#endif
		fprintf(stdout,"%s\t\t%llu\t\t%s\r\n",remote_file,(long long unsigned int) file->size,datex);

		if(diagapps)
		{
		prterr("\"%30s\"(%.8o) : %s(%.5d) %s(%.5d) : %.10llu bytes  %.10llu\n",
			file->name,
			file->permissions,
			file->owner,
			file->uid,
			file->group,
			file->gid,
			(long long unsigned int) file->size,
			(long long unsigned int) file->mtime);
		}
		sftp_attributes_free(file);
	}
	sftp_free(sftp);
	return(0);
}
Example #19
0
static void do_sftp(ssh_session session)
{
	sftp_session sftp=sftp_new(session);
	sftp_dir dir;
	sftp_attributes file;
	char datex[11];
	time_t atime=0;
#ifdef WIN32
	struct tm *mytime=NULL;
	int x=0;
#endif

	if(!sftp)
	{
		prterr("sftp error initialising channel: %s\n",ssh_get_error(session));
		return;
	}
	if(sftp_init(sftp))
	{
        	prterr("error initializing sftp: %s\n",ssh_get_error(session));
		return;
	}
	dir=sftp_opendir(sftp,docfolder);
	if(!dir) 
	{
		prterr("Directory not opened(%s)\n", ssh_get_error(session));
		return;
	}
/* reading the whole directory, file by file */
	while((file=sftp_readdir(sftp,dir)))
	{
		if(strncmp(file->name,".",1))
		{
			if(details==FALSE)
			{
				fprintf(stdout,"%s\r\n",file->name);
			} else {
#ifndef WIN32
#ifdef _POSIX_SOURCE
				atime=file->atime;
				strftime(datex,11,"%m/%d/%Y",localtime(&atime));
#else
				ascftime(datex,"%m/%d/%Y",localtime(&file->atime));
#endif /* _POSIX_SOURCE */
#else /* WIN32 */
				mytime=localctime(&file->atime);
				x=mytime->tm_year;
				while(x>=200) x-=100;
				sprintf(datex,"%02d/%02d/%04d",mytime->tm_mon+1,mytime->tm_mday,1900+my_time->tm_year);
#endif
				fprintf(stdout,"%s\t%llu\t%s\r\n",file->name,(long long unsigned int) file->size,datex);
			}
		}
		if(diagapps)
		{
		prterr("%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))
	{
		prterr("Error: %s\n", ssh_get_error(session));
		return;
	}
	if(sftp_closedir(dir))
	{
		prterr("Error: %s\n", ssh_get_error(session));
		return;
	}
	sftp_free(sftp);
}
Example #20
0
int ftp_getfile(const char *infile, const char *outfile, getmode_t how,
				transfer_mode_t mode, ftp_transfer_func hookf)
{
	FILE *fp;
	int r;
	struct stat statbuf;
	long rp = 0;
	int (*close_func)(FILE *fp);

	if(stat(outfile, &statbuf) == 0) {
		if(S_ISDIR(statbuf.st_mode)) {
			ftp_err(_("%s: is a directory\n"), outfile);
			return -1;
		}
		if(!(statbuf.st_mode & S_IWRITE)) {
			ftp_err(_("%s: permission denied\n"), outfile);
			return -1;
		}
		if(how == getResume)
			ftp->restart_offset = statbuf.st_size;
	} else
		ftp->restart_offset = 0L;

	ftp->ti.total_size = -1;

	/* we need to save this, because ftp_init_receive() sets it to zero */
	rp = ftp->restart_offset;

	reset_transfer_info();
#ifdef HAVE_LIBSSH
	if (ftp->session)
	{
		/* we need to stat the remote file, so we are sure we can read it
		 * this needs to be done before we call ssh_do_receive, because by
		 * then, the file is created, and would leave a zero-size file opon
		 * failure
		 */
		sftp_attributes a = sftp_stat(ftp->sftp_session, infile);
		if(!a) {
			ftp_err(_("Unable to stat file '%s': %s\n"), infile, ssh_get_error(ftp->session));
			return -1;
		}
		sftp_attributes_free(a);
		/* FIXME: how can we check if it will be possible to transfer
		 * the specified file?
		 */
	}
	else
#endif
	if (ftp_init_receive(infile, mode, hookf) != 0)
		return -1;

	if(how == getPipe) {
		fp = popen(outfile, "w");
		close_func = pclose;
	} else {
		fp = fopen(outfile,
				   (rp > 0L || (how == getAppend)) ? "a" : "w");
		close_func = fclose;
	}
	if(!fp) {
		ftp_err("%s: %s\n", outfile, strerror(errno));
		ftp->restart_offset = 0L;
		return -1;
	}

	if(rp > 0L) {
		if(fseek(fp, rp, SEEK_SET) != 0) {
			ftp_err(_("%s: %s, transfer cancelled\n"),
					outfile, strerror(errno));
			close_func(fp);
			ftp->restart_offset = 0L;
			return -1;
		}
	}

	free(ftp->ti.remote_name);
	free(ftp->ti.local_name);
	ftp->ti.remote_name = xstrdup(infile);
	ftp->ti.local_name = xstrdup(outfile);

	foo_hookf = hookf;

#ifdef HAVE_LIBSSH
	if(ftp->session)
		r = ssh_do_receive(infile, fp, mode, hookf);
	else
#endif
		r = ftp_do_receive(fp, mode, hookf);
	close_func(fp);
	return r;
}
Example #21
0
bool CSFTPSession::GetDirectory(const std::string& base, const std::string& folder,
                                std::vector<kodi::vfs::CDirEntry>& items)
{
  int sftp_error = SSH_FX_OK;
  if (m_connected)
  {
    sftp_dir dir = NULL;

    P8PLATFORM::CLockObject lock(m_lock);
    m_LastActive = P8PLATFORM::GetTimeMs();
    dir = sftp_opendir(m_sftp_session, CorrectPath(folder).c_str());

    //Doing as little work as possible within the critical section
    if (!dir)
      sftp_error = sftp_get_error(m_sftp_session);

    lock.Unlock();

    if (!dir)
    {
      kodi::Log(ADDON_LOG_ERROR, "%s: %s for '%s'", __FUNCTION__, SFTPErrorText(sftp_error), folder.c_str());
    }
    else
    {
      bool read = true;
      while (read)
      {
        sftp_attributes attributes = NULL;

        lock.Lock();
        read = sftp_dir_eof(dir) == 0;
        attributes = sftp_readdir(m_sftp_session, dir);
        lock.Unlock();

        if (attributes && (attributes->name == NULL || strcmp(attributes->name, "..") == 0 || strcmp(attributes->name, ".") == 0))
        {
          lock.Lock();
          sftp_attributes_free(attributes);
          lock.Unlock();
          continue;
        }

        if (attributes)
        {
          std::string itemName = attributes->name;
          std::string localPath = folder;
          localPath.append(itemName);

          if (attributes->type == SSH_FILEXFER_TYPE_SYMLINK)
          {
            lock.Lock();
            sftp_attributes_free(attributes);
            attributes = sftp_stat(m_sftp_session, CorrectPath(localPath).c_str());
            lock.Unlock();
            if (attributes == NULL)
              continue;
          }

          kodi::vfs::CDirEntry entry;
          entry.SetLabel(itemName);

          if (itemName[0] == '.')
            entry.AddProperty("file:hidden", "true");

          entry.SetDateTime(attributes->mtime64);

          if (attributes->type & SSH_FILEXFER_TYPE_DIRECTORY)
          {
            localPath.append("/");
            entry.SetFolder(true);
          }
          else
            entry.SetSize(attributes->size);

          entry.SetPath(base+localPath);
          items.push_back(entry);

          lock.Lock();
          sftp_attributes_free(attributes);
          lock.Unlock();
        }
        else
          read = false;
      }

      lock.Lock();
      sftp_closedir(dir);
      lock.Unlock();

      return true;
    }
  }
  else
    kodi::Log(ADDON_LOG_ERROR, "SFTPSession: Not connected, can't list directory '%s'", folder.c_str());

  return false;
}
Example #22
0
static int _sftp_stat(const char *uri, csync_vio_file_stat_t *buf) {
  sftp_attributes attrs;
  char *path = NULL;
  int rc = -1;

  if (_sftp_connect(uri) < 0) {
    return -1;
  }

  if (c_parse_uri(uri, NULL, NULL, NULL, NULL, NULL, &path) < 0) {
    return -1;
  }

  attrs = sftp_lstat(_sftp_session, path);
  if (attrs == NULL) {
    rc = -1;
    goto out;
  }

  buf->name = c_basename(path);
  if (buf->name == NULL) {
    csync_vio_file_stat_destroy(buf);
    goto out;
  }
  buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;

  switch (attrs->type) {
    case SSH_FILEXFER_TYPE_REGULAR:
      buf->type = CSYNC_VIO_FILE_TYPE_REGULAR;
      break;
    case SSH_FILEXFER_TYPE_DIRECTORY:
      buf->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
      break;
    case SSH_FILEXFER_TYPE_SYMLINK:
      buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
      break;
    case SSH_FILEXFER_TYPE_SPECIAL:
    case SSH_FILEXFER_TYPE_UNKNOWN:
      buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
      break;
  }
  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;

  buf->mode = attrs->permissions;
  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_PERMISSIONS;

  if (buf->type == CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK) {
    /* FIXME: handle symlink */
    buf->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK;
  } else {
    buf->flags = CSYNC_VIO_FILE_FLAGS_NONE;
  }
  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;

  buf->uid = attrs->uid;
  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_UID;

  buf->uid = attrs->gid;
  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_GID;

  buf->size = attrs->size;
  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;

  buf->atime = attrs->atime;
  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;

  buf->mtime = attrs->mtime;
  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;

  buf->ctime = attrs->createtime;
  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;

  rc = 0;
out:
  if (rc < 0) {
    errno = _sftp_portable_to_errno(sftp_get_error(_sftp_session));
  }
  SAFE_FREE(path);
  sftp_attributes_free(attrs);

  return rc;
}
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;
}
Example #24
0
/* it's just a proof of concept code for sftp, till i write a real documentation about it */
void do_sftp(SSH_SESSION *session){
    SFTP_SESSION *sftp=sftp_new(session);
    SFTP_DIR *dir;
    SFTP_ATTRIBUTES *file;
    SFTP_FILE *fichier;
    SFTP_FILE *to;
    int len=1;
    int i;
    char data[8000];
    if(!sftp){
        ssh_say(0,"sftp error initialising channel : %s\n",ssh_get_error(session));
        return;
    }
    if(sftp_init(sftp)){
        ssh_say(0,"error initialising sftp : %s\n",ssh_get_error(session));
        return;
    }
    /* the connection is made */
    /* opening a directory */
    dir=sftp_opendir(sftp,"./");
    if(!dir) {
        ssh_say(0,"Directory not opened(%s)\n",ssh_get_error(session));
        return ;
    }
    /* reading the whole directory, file by file */
    while((file=sftp_readdir(sftp,dir))){
        ssh_say(0,"%30s(%.8lo) : %.5d.%.5d : %.10lld bytes\n",file->name,file->permissions,file->uid,file->gid,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)){
        ssh_say(0,"error : %s\n",ssh_get_error(session));
        return;
    }
    if(sftp_dir_close(dir)){
        ssh_say(0,"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,NULL);
    if(!fichier){
        ssh_say(0,"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,NULL);
    if(!to){
        ssh_say(0,"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){
            ssh_say(0,"error writing %d bytes : %s\n",len,ssh_get_error(session));
            return;
        }
    }
    printf("finished\n");
    if(len<0)
        ssh_say(0,"Error reading file : %s\n",ssh_get_error(session));     
    sftp_file_close(fichier);
    sftp_file_close(to);
    printf("fichiers ferm�\n");
    to=sftp_open(sftp,"/tmp/grosfichier",O_WRONLY|O_CREAT,NULL);
    for(i=0;i<1000;++i){
        len=sftp_write(to,data,8000);
        printf("wrote %d bytes\n",len);
        if(len != 8000){
            printf("chunk %d : %d (%s)\n",i,len,ssh_get_error(session));
        }
    }
    sftp_file_close(to);
    /* close the sftp session */
    sftp_free(sftp);
    printf("session sftp termin�\n");
}
Example #25
0
static int do_read(const char* infile, FILE* fp, getmode_t mode,
                   ftp_transfer_func hookf, uint64_t offset)
{
  if (gvSSHTrySCP && !offset)
  {
    char* escaped = bash_backslash_quote(infile);
    /* try to set up a scp connection */
    ssh_scp scp = ssh_scp_new(ftp->session, SSH_SCP_READ, escaped);
    free(escaped);
    if (scp != NULL)
    {
      int rc = ssh_scp_init(scp);
      if (rc == SSH_OK)
        return do_scp_read(scp, infile, fp, mode, hookf);
      ssh_scp_free(scp);
    }
  }

  time_t then = time(NULL) - 1;
  ftp_set_close_handler();

  if (hookf)
    hookf(&ftp->ti);
  ftp->ti.begin = false;

  /* check if remote file is not a directory */
  sftp_attributes attrib = sftp_stat(ftp->sftp_session, infile);
  if (!attrib)
    return -1;

  if (S_ISDIR(attrib->permissions))
  {
    ftp_err(_("Cannot download a directory: %s\n"), infile);
    sftp_attributes_free(attrib);
    return -1;
  }
  sftp_attributes_free(attrib);

  /* open remote file */
  sftp_file file = sftp_open(ftp->sftp_session, infile, O_RDONLY, 0);
  if (!file)
  {
    ftp_err(_("Cannot open file for reading: %s\n"), ssh_get_error(ftp->session));
    return -1;
  }

  /* seek to offset */
  int r = sftp_seek64(file, offset);
  if (r != SSH_OK)
  {
    ftp_err(_("Failed to seek: %s\n"), ssh_get_error(ftp->session));
    sftp_close(file);
    return -1;
  }

  /* read file */
  char buffer[SSH_BUFSIZ];
  ssize_t nbytes = 0;
  while ((nbytes = sftp_read(file, buffer, sizeof(buffer))) > 0)
  {
    if (ftp_sigints() > 0)
    {
      ftp_trace("break due to sigint\n");
      break;
    }

    errno = 0;
    if (fwrite(buffer, nbytes, 1, fp) != 1)
    {
      ftp_err(_("Error while writing to file: %s\n"), strerror(errno));
      ftp->ti.ioerror = true;
      sftp_close(file);
      return -1;
    }

    ftp->ti.size += nbytes;
    if (hookf)
    {
      time_t now = time(NULL);
      if (now > then)
      {
        hookf(&ftp->ti);
        then = now;
      }
    }
  }

  if (nbytes < 0)
  {
    ftp_err(_("Error while reading from file: %s\n"), ssh_get_error(ftp->session));
    r = -1;
  }

  sftp_close(file);
  return r;
}
Example #26
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;
}