linssh2 sftp读取远端目录,获取远端文件或者目录信息

环境信息

  • rhel65
  • libssh2版本:libssh2-1.8.2

libssh2目前遇到几个注意事项:

  • 读取远端目录时,实体的名称没有存储在LIBSSH2_SFTP_ATTRIBUTES中(具体看读取远端目录的实例)
  • 在libssh2-1.5之后的版本判断远端是否是目录还是文件,不能使用系统的函数,得使用libssh2封装的函数(具体查看实例)参考
    https://www.libssh2.org//libssh2_sftp_fstat_ex.html
  • libssh2对于sftp操作的错误信息没有相关msg,只有对应的number,而且ibssh2_sftp_mkdir_ex(),如果远端文件存在,则返回的错误码为“LIBSSH2_FX_FAILURE”,所以自行封装了一个错误输出函数

实例一:读取远端目录

int sftpReadDir(LIBSSH2_SESSION *session, LIBSSH2_SFTP *sftp, const char * path)
{
    LIBSSH2_SFTP_HANDLE *sftp_handle;;
	LIBSSH2_SFTP_ATTRIBUTES attrs;
	int rc;
	sftp_handle = libssh2_sftp_opendir(sftp, path);
	if (!sftp_handle)
	{
		processErr(session, sftp, path);
		return -1;
	}
	
	for(;;) {
        char mem[1024];
        char longentry[1024];
 
        /* loop until we fail */ 
        rc = libssh2_sftp_readdir_ex(sftp_handle, mem, sizeof(mem),

                                     longentry, sizeof(longentry), &attrs);
        if(rc > 0) {
            /* rc is the length of the file name in the mem
               buffer */ 
 
            if(longentry[0] != '\0') {
				if (!strcmp(mem, ".") || !strcmp(mem, "..")){
					continue;
				}
				if(S_ISREG(attrs.permissions)){
					cout<<"file name is "<<mem;
				}
				else if(S_ISDIR(attrs.permissions)){
					cout<<"dir name is "<<mem;
				}
            }
           
        }
        else
            break;
 
	}


	rc =  libssh2_sftp_closedir(sftp_handle);
	if (rc != 0)
	{
		fprintf(stderr, "Can't close directory\n");
		return rc;
	}

	return 0;
}

实例二:读取文件或目录属性,并判断是文件还是目录

int sftpStat(LIBSSH2_SESSION *session, LIBSSH2_SFTP *sftp, const char * path,int & perm)
{
  LIBSSH2_SFTP_ATTRIBUTES attrs;
  LIBSSH2_SFTP_HANDLE *sftp_handle;
  int rc;
  while ((rc=libssh2_sftp_lstat(sftp,path, &attrs)==LIBSSH2_ERROR_EAGAIN));
  if (rc!=0)
  {
    processErr(session, sftp, path);
	return -1;
  }
  else
  {    
    perm = attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS ? attrs.permissions : 0644;
  }
  return 0;
}

int per;
rc = sftpStat(session,sftp_session,sstrRemoteFile.c_str(),per);
if(LIBSSH2_SFTP_S_ISREG(per)){
    cout<<"file";
}else if(LIBSSH2_SFTP_S_ISDIR(per)){
    cout<<"dir";
}

实例三:sftp 错误解析

int printErr(LIBSSH2_SESSION *session, LIBSSH2_SFTP *sftp,const char * path){
	if( libssh2_session_last_error(session,NULL,NULL,0)==LIBSSH2_ERROR_SFTP_PROTOCOL){
		switch (libssh2_sftp_last_error(sftp))
		{
			case 	LIBSSH2_FX_FILE_ALREADY_EXISTS:
				cerr<<"Error: Directory or file already exists: "<<path<<endl;
				break;
			case 	LIBSSH2_FX_PERMISSION_DENIED:
				cerr<<"Error: Permission denied: "<<path<<endl;
				break;
			case 	LIBSSH2_FX_NO_SUCH_FILE:
				cerr<<"Error: No such File : "<<path<<endl;
				break;
			case 	LIBSSH2_FX_EOF:
				cout<<"LIBSSH2_FX_EOF"<<endl;
				break;
			case 	LIBSSH2_FX_FAILURE:
				cout<<"LIBSSH2_FX_FAILURE"<<endl;
				break;
			case 	LIBSSH2_FX_NO_SUCH_PATH:
				cerr<<"Error: No such path : "<<path<<endl;
				break;
			case 	LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
				cerr<<"Error: No space left on device"<<endl;
				break;
			case 	LIBSSH2_FX_NO_CONNECTION:
				cerr<<"Error: Unconnected"<<endl;
				break;
			case 	LIBSSH2_FX_CONNECTION_LOST:
				cerr<<"Error: Connection lost"<<endl;
				break;
			case 	LIBSSH2_FX_WRITE_PROTECT:
				cerr<<"Error: Write protect : "<<path<<endl;
				break;
			case 	LIBSSH2_FX_DIR_NOT_EMPTY:
				cerr<<"Error: Dir is not empty : "<<path<<endl;
				break;
			case 	LIBSSH2_FX_NOT_A_DIRECTORY:
				cout<<"LIBSSH2_FX_NOT_A_DIRECTORY"<<endl;
				cerr<<"Error: Path is not Dir : "<<path<<endl;
				break;
			default:
				cerr<<"Error: "<<libssh2_sftp_last_error(sftp)<<endl;
				break;
		}
	}
	return 0;

}


版权声明:本文为leiweip原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。