예제 #1
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;
}
예제 #2
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;
  }
}
예제 #3
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;
}
예제 #4
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");
}
예제 #5
0
파일: ssh_cmd.c 프로젝트: casualuser/yafc
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;
}
예제 #6
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);
}
예제 #7
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");
}
예제 #8
0
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;
}