精华内容
下载资源
问答
  • smbclient

    2021-01-15 14:43:33
    Linux 下访问另外一台Linux电脑的samba共享文件夹 ##命令 ...cd [目录] 切换到服务器端的指定目录,如未指定,则 smbclient 返回当前本地目录 lcd [目录] 切换到客户端指定的目录; dir 或ls 列出当前

    Linux 下访问另外一台Linux电脑的samba共享文件夹

    ##命令
    smbclicent //IP/文件夹名称 -U 用户%密码
    成功后就会出现如下图;
    在这里插入图片描述
    支持很多命令
    ?或help [command] 提供关于帮助或某个命令的帮助
    ![shell command] 执行所用的SHELL命令,或让用户进入 SHELL提示符
    cd [目录] 切换到服务器端的指定目录,如未指定,则 smbclient 返回当前本地目录
    lcd [目录] 切换到客户端指定的目录;
    dir 或ls 列出当前目录下的文件;
    exit 或quit 退出smbclient
    get file1 file2 从服务器上下载file1,并以文件名file2存在本地机上;如果不想改名,可以把file2省略
    mget file1 file2 file3 filen 从服务器上下载多个文件;
    md或mkdir 目录 在服务器上创建目录
    rd或rmdir 目录 删除服务器上的目录
    put file1 [file2] 向服务器上传一个文件file1,传到服务器上改名为file2;
    mput file1 file2 filen 向服务器上传多个文件

    展开全文
  • Smbclient

    千次阅读 2014-02-12 10:20:41
    1 Smbclient介绍 Smbclient(samba client)是基于SMB协议的,用于存取共享目标的客户端程序。 SMB协议介绍: 服务器信息块(SMB)协议是一种 IBM 协议,用于在计算机间共享文件、打印机、串口等。SMB 协议可以用在...
    1 Smbclient介绍
    Smbclient(samba client)是基于SMB协议的,用于存取共享目标的客户端程序。
    SMB协议介绍:
    服务器信息块(SMB)协议是一种 IBM 协议,用于在计算机间共享文件、打印机、串口等。SMB 协议可以用在因特网的TCP/IP协议之上,也可以用在其它网络协议如 IPX 和NetBEUI 之上。SMB 一种客户机/服务器、请求/响应协议。通过 SMB 协议,客户端应用程序可以在各种网络环境下读、写服务器上的文件,以及对服务器程序提出服务请求。此外通过 SMB 协议,应用程序可以访问远程服务器端的文件、以及打印机、邮件槽(mailslot)、命名管道(named pipe)等资源。 在 TCP/IP 环境下,客户机通过 NetBIOS over TCP/IP(或 NetBEUI/TCP 或 SPX/IPX)连接服务器。一旦连接成功,客户机可发送 SMB 命令到服务器上,从而客户机能够访问共享目录、打开文件、读写文件,以及一切在文件系统上能做的所有事情。从 Windows 95 开始,Microsoft Windows 操作系统(operating system)都包括了客户机和服务器 SMB 协议支持。Microsoft 为 Internet 提供了 SMB 的开源版本,即通用 Internet 文件系统 (CIFS)。与现有 Internet应用程序如文件传输协议(FTP)相比, CIFS 灵活性更大。对于 UNIX 系统,可使用一种称为 Samba 的共享软件。
    SMB 定义了两级安全保护:
    共享级保护(Share Level Protection)应用于服务器共享目录级。每个共享目录都需要提供一个访问口令。只有口令通过,客户机才能访问所有共享文件。
    用户级保护(Usr Level Protection)应用于共享目录中的单独文件,基于用户访问权限。每个用户(客户机)必须登录服务器并且获得服务器的认证许可。一旦认证通过,
    户 机会获得一个 UID 。在后来客户机访问服务器的过程中都需要使用该 UID 。
    2 Smbclient命令使用技巧
    2.1 smbclient功 能说明:
    可存取SMB/CIFS服务器的用户端程序。
     
    2.1.1 语法:
    smbclient [网络资源][密码][-EhLN][-B][-d<排错层级>][-i<范围>][-I][-l<记录文件>] [-M][-n][-O<连接槽选项>][-p][-R<名称解析顺序>][-s<目录>][-t<服务器字 码>][-T][-U<用户名称>][-W<工作群组>]补充说明:SMB与CIFS为服务器通信协议,常用于 Windows95/98/NT等系统。smbclient可让Linux系统存取Windows系统所分享的资源。
     
    2.1.2 参数:
    网络资源 网络资源的格式为//服务器名称/资源分享名称。
    密码 输入存取网络资源所需的密码。
    -B传送广播数据包时所用的IP地址。
    -d<排错层级> 指定记录文件所记载事件的详细程度。
    -E将信息送到标准错误输出设备。
    -h显示帮助。
    -i<范围> 设置NetBIOS名称范围。
    -I指定服务器的IP地址。
    -l<记录文件> 指定记录文件的名称。
    -L显示服务器端所分享出来的所有资源。
    -M可利用WinPopup协议,将信息送给选项中所指定的主机。
    -n指定用户端所要使用的NetBIOS名称。
    -N不用询问密码。
    -O<连接槽选项> 设置用户端TCP连接槽的选项。
    -p指定服务器端TCP连接端口编号。
    -R<名称解析顺序> 设置NetBIOS名称解析的顺序。
    -s<目录> 指定smb.conf所在的目录。
    -t<服务器字码> 设置用何种字符码来解析服务器端的文件名称。
    -T备份服务器端分享的全部文件,并打包成tar格式的文件。
    -U<用户名称> 指定用户名称。
    -W<工作群组> 指定工作群组名称。
    2.2 smbclient使 用举例:
    2.2.1 列出某个IP地 址所提供的共享文件夹
    smbclient -L 198.168.0.1 -U username%password
    2.2.2 像FTP客 户端一样使用smbclient
    smbclient //192.168.0.1/tmp -U username%password
    执行smbclient命令成功后,进入smbclient环境,出现提示符: smb:/>
    这里有许多命令和ftp命令相似,如cd 、lcd、get、megt、put、mput等。通过这些命令,我们可以访问远程主机的共享资源。
    2.2.3 直接一次性使用smbclient命 令
    smbclient -c "ls" //192.168.0.1/tmp -U username%password
    smbclient -c "get test.txt" //192.168.0.1/tmp -U username%password
    3 Smbclient开发技巧
    3.1 常用函数介绍
    Smbclient提供了两种外部接口,一种是SMBCCTX信息结构体中的函数指针,输入及输出中含有smbclient自定义的变量;另一种是smbc族的接口,输入及输出均为系统基本变量,其实质是通过对SMBCCTX中的函数指针的封装来实现的。
    3.1.1 Smbc族 函数:
    int smbc_init(smbc_get_auth_data_fn fn , int debug);
    初始化samba client库,此函数必须在所有其他smbc族API被调用前使用。
    参数:
    fn*:*用于传递SMB协议所需的基本信息;
    提供一个简单的fn实现(其中server为samba服务器地址,share为共享目录标识,workgroup为所在域的域 名,username为用户名,password为登录密码):
    static void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
    char *username, int unmaxlen, char *password, int pwmaxlen)
    {

    strncpy(workgroup, g_workgroup, wgmaxlen - 1);
    strncpy(username, g_username, unmaxlen - 1);
    strncpy(password, g_password, pwmaxlen - 1);
    strcpy(g_server, server);
    strcpy(g_share, share);
    // fprintf(stderr,"server[%s],share[%s]/n",server,share);
    }
    debug*:*调试信息等级(本人建议值0-10);
    返回值:
    0为成功,<0为失败,错误信息可通过errno获取。
    int smbc_open(const char *furl, int flags, mode_t mode);
    打开共享服务器上的一个文件,使用方法请参考open函数。
    int smbc_creat(const char *furl, mode_t mode);
    在共享服务器上创建一个文件,使用方法请参考open函数。
    ssize_t smbc_read(int fd, void *buf, size_t bufsize);
    使用一个打开的文件句柄来读取共享服务器上的文件,使用方法请参考read函数。
    ssize_t smbc_write(int fd, void *buf, size_t bufsize);
    使用一个打开的文件句柄向共享服务器上的文件写数据,使用方法请参考write函数。
    off_t smbc_lseek(int fd, off_t offset, int whence);
    移动文件的读写位置,使用方法请参考lseek函数。
    int smbc_close(int fd);
    关闭一个打开的文件句柄,使用方法请参考close函数。
    int smbc_unlink(const char *furl);
    删除一个共享服务器上的文件或者文件夹,使用方法请参考unlink函数。
    int smbc_rename(const char *ourl, cones char *nurl);
    重命名(或移动)共享目录上的文件或者文件夹,使用方法请参考rename函数。
    int smbc_opendir(const char *durl);
    打开共享服务器上的文件夹,使用方法请参考opendir函数。
    int smbc_closedir(int dh);
    关闭一个打开的文件夹句柄,使用方法请参考closedir函数。
    struct smbc_dirent* smbc_readdir(unsigned int dh);
    读取共享服务器上的文件夹信息,使用方法请参考readdir函数。
    off_t smbc_telldir(int dh);
    获取文件夹流当前的读取位置,使用方法请参考telldir函数。
    int smbc_mkdir(const char *durl, mode_t mode);
    在共享服务器上创建一个文件夹。
    参数:
    durl*:*路径
    mode*:*访问权限
    返回值:
    0为成功,<0为失败,失败信息可通过errno来获取。
    int smbc_rmdir(const char *durl);
    删除共享服务器上的一个文件夹。
    参数:
    durl*:*路径
    返回值:
    0为成功,<0为失败,失败信息可通过errno来获取。
    int smbc_stat(const char *url, struct stat *st);
    获取共享服务器上一个文件或者文件夹的所有信息,使用方法请参考stat函数。
    int smbc_fstat(int fd, struct stat *st);
    通过文件句柄来获取共享服务器上一个文件的所有信息,使用方法请参考fstat函数。
    int smbc_chown(const char *url, uid_t owner, gid_t group);
    修改共享服务器上文件或者文件夹的所有者信息,使用方法请参考chown函数。
    int smbc_chmod(const char *url, mode_t mode);
    修改共享服务器上的文件的权限,使用方法请参考chmod函数。
    int smbc_utimes(const char *url, struct timeval *tbuf);
    修改共享服务器上的文件的最后修改时间,使用方法请参考utimes函数。
    范例:
    #include <stdio.h>
    #include <stdlib.h>
    #include < errno.h>
    #include <dirent.h>
    #include < string.h>
    #include <unistd.h>
    #include < libsmbclient.h>

    #define MAX_BUFF_SIZE 255
    char g_workgroup[MAX_BUFF_SIZE];
    char g_username[MAX_BUFF_SIZE];
    char g_password[MAX_BUFF_SIZE];
    char g_server[MAX_BUFF_SIZE];
    char g_share[MAX_BUFF_SIZE];
    SMBCCTX * context;
    SMBCSRV * srv;
    static void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
    char *username, int unmaxlen, char *password, int pwmaxlen)
    {

    strncpy(workgroup, g_workgroup, wgmaxlen - 1);
    strncpy(username, g_username, unmaxlen - 1);
    strncpy(password, g_password, pwmaxlen - 1);
    strcpy(g_server, server);
    strcpy(g_share, share);
    // fprintf(stderr,"server[%s],share[%s]/n",server,share);
    }
    int main(int argc,char* argv[]){
    int err = -1;
    int dh = 0;
    int fd = -1;
    int buflen = 0;
    char buffer[1024] = {0};
    char url[MAX_BUFF_SIZE] = {0};
    char file[MAX_BUFF_SIZE] = {0};
    struct smbc_dirent* dirptr;

    bzero(g_workgroup,MAX_BUFF_SIZE);
    bzero(url,MAX_BUFF_SIZE);
    printf("%s/n",smbc_version());

    strncpy(g_workgroup,argv[1],strlen(argv[1]));
    strncpy(g_username,argv[2],strlen(argv[2]));
    strncpy(g_password,argv[3],strlen(argv[3]));
    strncpy(url,argv[4],strlen(argv[4]));
    if(url[strlen(url)-1] != '/'){
    strcat(url,"/");
    }
    err = smbc_init(auth_fn, 10);
    if(err < 0){
    perror("smbc_init error");
    }else{
    dh = smbc_opendir(url);
    while((dirptr = smbc_readdir(dh)) != NULL){
    bzero(file,MAX_BUFF_SIZE);
    printf("dirptr->name[%s],dirptr->smbc_type[%d]/n",dirptr->name,dirptr->smbc_type);
    if(dirptr->smbc_type == SMBC_FILE){
    bzero(buffer,1024);
    strncpy(file,url,strlen(url));
    strncat(file,dirptr->name,dirptr->namelen);
    printf("%s/n",file);
    if((fd = smbc_open(file,O_RDONLY,0666)) > 0){
    while((buflen = smbc_read(fd,buffer,1024)) > 0){
    // printf("buffer[%s]/n",buffer);
    }
    smbc_close(fd);
    }
    }
    }
    smbc_closedir(dh);
    // printf("smbc_rmdir(url)[%d]/n",smbc_rmdir(url));
    }
    return err;
    }
    3.1.2 函数指针:
    SMBCCTX *smbc_new_context(void);
    创建一个新的SMBCCTX结构体。
    返回值:
    SMBCCTX结构体指针,返回NULL为失败。错误信息可通过errno获取。
    int smbc_free_context(SMBCCTX *context, int shutdown_ctx);
    删除一个SMBCCTX结构体。
    参数:
    context*:*已创建的SMBCCTX结构体指针。
    shutdown_ctx*:*强制删除标识。
    为1时,为强制删除;
    为0时,若此context与共享服务器的连接仍在使用或者有文件仍被打开,则删除context失败;
    返回值:
    0为成功,1为失败。错误信息可通过errno获取。
    SMBCCTX *smbc_init_context(SMBCCTX * context);
    初始化SMBCCTX结构体。
    参数:
    context*:*已创建的SMBCCTX结构体执政。
    返回值:
    成功初始化的SMBCCTX结构体指针,若返回值NULL则为初始化失败。错误信息可通过errno获取。
    SMBCCTX * smbc_set_context(SMBCCTX * new_context);
    设置(或重置)SMBCCTX结构体数据。
    参数:
    new_context*:*已创建的SMBCCTX结构体指针。
    返回值:
    被设置前的原始SMBCCTX结构体指针。
    SMBCFILE *(*open) (SMBCCTX *c, const char *fname, int flags, mode_t mode);
    打开共享服务器上的一个文件。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    fname*:*文件路径;
    flags*:*打开方式;
    mode*:*文件权限
    返回值:
    成功打开的文件句柄,若<=0为失败,错误信息可通过errno获取。
    SMBCFILE *(*creat)(SMBCCTX *c, const char *path, mode_t mode);
    在共享服务器上的创建一个文件。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    path*:*文件路径;
    mode*:*文件权限
    返回值:
    成功创建的文件句柄,若<=0为失败,错误信息可通过errno获取。
    ssize_t (*read)(SMBCCTX *c, SMBCFILE *file, void *buf, size_t count);
    使用一个打开的文件句柄来读取共享服务器上的文件。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    file*:*文件句柄;
    buf*:*存放读取到的数据的内存指针;
    count*:*读取长度
    返回值:
    实际读取到的字节数,如果返回0,表示已到达文件尾或者无可读取的数据,此外文件读写位置会随读取到的字节移动,若返回-1表示有错误发生,错误信 息可通过errno获取。
    ssize_t (*write)(SMBCCTX *c, SMBCFILE *file, void *buf, size_t count);
    使用一个打开的文件句柄向共享服务器上的文件写数据。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    file*:*文件句柄;
    buf*:*需要写入的数据的指针;
    count*:*写入数据的长度
    返回值:
    实际写入的字节数,若返回-1表示有错误发生,错误信息可通过errno获取。
    int (*unlink)(SMBCCTX *c, const char *fname);
    删除一个共享服务器上的文件或者文件夹。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    fname*:*指定路径
    返回值:
    0为成功,-1为失败,错误信息可通过errno获取。
    int (*rename)(SMBCCTX *ocontext, const char *oname, SMBCCTX *ncontext, const char *nname);
    重命名(或移动)共享目录上的文件或者文件夹。
    参数:
    ocontext*:*已初始化(或设置)的SMBCCTX结构体指针;
    oname*:*源路径;
    ncontext*:*已初始化(或设置)的SMBCCTX结构体指针;
    nname*:*目标路径
    返回值:
    0为成功,-1为失败,错误信息可通过errno获取。
    off_t (*lseek)(SMBCCTX *c, SMBCFILE * file, off_t offset, int whence);
    移动文件的读写位置。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    file*:*文件句柄;
    offset*:*位移量;
    whence*:*位移起始位置(SEEK_SET,SEEK_CUR,SEEK_END)
    返回值:
    当前文件的读写位置,若返回-1表示有错误发生,错误信息可通过errno获取。
    int (*stat)(SMBCCTX *c, const char *fname, struct stat *st);
    获取共享服务器上一个文件或者文件夹的所有信息。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    fname*:*路径;
    st*:*文件属性结构体
    返回值:
    0为成功,-1为失败,错误信息可通过errno获取。
    int (*fstat)(SMBCCTX *c, SMBCFILE *file, struct stat *st);
    通过文件句柄来获取共享服务器上一个文件的所有信息。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    file*:*文件句柄;
    st*:*文件属性结构体
    返回值:
    0为成功,-1为失败,错误信息可通过errno获取。
    int (*close_fn)(SMBCCTX *c, SMBCFILE *file);
    关闭一个打开的文件句柄。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    file*:*文件句柄;
    返回值:
    0为成功,-1为失败,错误信息可通过errno获取。
    SMBCFILE *(*opendir)(SMBCCTX *c, const char *fname);
    打开共享服务器上的文件夹。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    fname*:*文件夹路径;
    返回值:
    成功打开的文件夹句柄,若NULL为失败,错误信息可通过errno获取。
    int (*closedir)(SMBCCTX *c, SMBCFILE *dir);
    关闭一个打开的文件夹句柄。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    fname*:*文件夹句柄;
    返回值:
    0为成功,-1为失败,错误信息可通过errno获取。
    struct smbc_dirent *(*readdir)(SMBCCTX *c, SMBCFILE *dir);
    读取共享服务器上的文件夹信息。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    dir*:*文件夹句柄;
    返回值:
    下个文件夹进入点,若NULL为失败或读取到目录文件尾,错误信息可通过errno获取。
    int (*mkdir)(SMBCCTX *c, const char *fname, mode_t mode);
    在共享服务器上创建一个文件夹。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    fname*:*文件夹路径;
    mode*:*权限;
    返回值:
    0为成功,-1为失败,错误信息可通过errno获取。
    int (*rmdir)(SMBCCTX *c, const char *fname);
    删除共享服务器上的一个文件夹。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    fname*:*文件夹路径;
    返回值:
    0为成功,-1为失败,错误信息可通过errno获取。
    off_t (*telldir) (SMBCCTX *c, SMBCFILE *dir);
    获取文件夹流当前的读取位置。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    dir*:*文件夹句柄;
    返回值:
    下一个读取位置,-1表示有错误发生,错误信息可通过errno获取。
    int (*chmod)(SMBCCTX *c, const char *fname, mode_t mode);
    修改共享服务器上的文件的权限。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    fname*:*文件夹路径;
    mode*:*权限;
    返回值:
    0为成功,-1为失败,错误信息可通过errno获取。
    int (*utimes)(SMBCCTX *c, const char *fname, struct timeval *tbuf);
    修改共享服务器上的文件的最后修改时间。
    参数:
    c*:*已初始化(或设置)的SMBCCTX结构体指针;
    fname*:*文件夹路径;
    tbuf*:*时间结构体;
    返回值:
    0为成功,-1为失败,错误信息可通过errno获取。 
    范例:
    #include < stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <dirent.h>
    #include <string.h>
    #include < unistd.h>
    #include <libsmbclient.h>

    #define MAX_BUFF_SIZE 255
    char g_workgroup[MAX_BUFF_SIZE];
    char g_username[MAX_BUFF_SIZE];
    char g_password[MAX_BUFF_SIZE];
    char g_server[MAX_BUFF_SIZE];
    char g_share[MAX_BUFF_SIZE];
    SMBCCTX * context;
    SMBCSRV * srv;
    //smbc_get_cached_srv_fn get_srv;

    static void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
    char *username, int unmaxlen, char *password, int pwmaxlen)
    {

    strncpy(workgroup, g_workgroup, wgmaxlen - 1);
    strncpy(username, g_username, unmaxlen - 1);
    strncpy(password, g_password, pwmaxlen - 1);
    strcpy(g_server, server);
    strcpy(g_share, share);
    // fprintf(stderr,"server[%s],share[%s]/n",server,share);
    }

    int main(int argc, char* argv[]){
    SMBCFILE* sfd;
    SMBCFILE* fd;
    int localfd = -1,readlen = -1;

    struct smbc_server_cache * getServerCacheData;
    char buff[1024*1024*4] = {0};
    char url[MAX_BUFF_SIZE] = {0};
    char file[MAX_BUFF_SIZE] = {0};
    struct smbc_dirent* dirptr;
    bzero(g_workgroup,MAX_BUFF_SIZE);
    bzero(url,MAX_BUFF_SIZE);
    printf("%s/n",smbc_version());

    strncpy(g_workgroup,argv[1],strlen(argv[1]));
    strncpy(g_username,argv[2],strlen(argv[2]));
    strncpy(g_password,argv[3],strlen(argv[3]));
    strncpy(url,argv[4],strlen(argv[4]));
    if(url[strlen(url)-1] != '/'){
    strcat(url,"/");
    }
    context = smbc_new_context();
    if(context != NULL){
    context->debug = 10;
    context->callbacks.auth_fn = auth_fn;
    context->options.one_share_per_server = 1;

    if(!smbc_init_context(context)){
    perror("smbc_init_context failed");
    smbc_free_context(context,1);
    return -1;
    }

    sfd = context->opendir(context,url);
    struct smbc_dirent dirptr1;
    while((dirptr = context->readdir(context,sfd)) != NULL){
    if(dirptr->smbc_type == SMBC_FILE){
    printf("name[%s]/n",dirptr->name);
    strncpy(file,url,strlen(url));
    strncat(file,dirptr->name,dirptr->namelen);
    if((fd = context->open(context,file,O_RDONLY,0666)) > 0){
    context->close_fn(context,fd);
    }
    }
    }
    context->closedir(context,sfd);
    }
    return 0;
    }
    4 Smbclient使 用的个人小结
    4.1 Smbclient编 程需要注意的地方:
    4.1.1 使用smbclient编程需要用到的库,/usr/lib/libsmbclient.so 或者/usr/lib/libsmbclient.a。
    4.1.2 smbclient中,同一个共享目录下的所有数据交互,控制消息使用的有且只有一个connection连接(通过设置 one_share_per_server属性,可将同一个共享服务器下所有操作及数据交互都使用同一个connection连接)。
    4.1.3 smbclient向samba服务器的连接方式:smbclient的连接请求是在调用除初始化设置外的所有API接口时才发起的。这些API中,首先 会查询当前srv下是否有可用的连接,若有则使用当前可用连接,若没有可用连接则建立新的连接。
    4.1.4 smbclient的句柄是一个包含与服务器连接fd,请求文件名,共享服务器句柄等连接信息的集合。
    4.1.5 smbclient的重连机制:smbclient的内部是不提供重连机制的,也就是说,若一个请求超时后,API将直接返回错误信息。由本节点第二点可 知,在应用层下一次调用API时,smbclient层会向samba服务器再次发出连接请求。
    4.1.6 smbclient的smbc族函数使用时需要注意的的地方:
    i. 由A可知,smbc_init函数实质 上是对smbc_new_context()和smbc_init_context(SMBCCTX *context)进行了封装,而smbc_init函数并没有提供参数来指定smbc_new_context和smbc_init_context使 用的context指针。因此,smbc_init函数初始化的是smbclient库中的一个全局变量SMBCCTX *statcont。我们知道当一个进程中多次调用同一个库文件时,库文件的全局变量的地址是唯一的,也就是说,若我们使用smbc族API来对 smbclient进行多线程编程是不可行的。
    ii. 由libsmbclient.h中的声明 可知,smbc族的API没用提供对SMBCCTX结构体的参数设置接口。也就是说这种API不适合有特殊需求的程序(例如需要获取的数据为 urlcontext类型,或者需要指定同一个共享服务器下的所有共享文件夹都只使用一个连接等)
    4.1.7 由SMB协议可知,基于SMB协议的数据交互必须遵循 连接->发送命令->接收数据 ->发送命令->......->断开连接 的阻塞通信模式,又因为当smbclient是以一个连接至少对应一个共享文件的方式来进行通信的,所以若简单的对smbclient使用多线程操作,会 出现数据混乱的情况,导致不可预期的错误。
    4.1.8 管理SMBCCTX的一些小技巧:
    i. 首先,我们需要使用SMBCCTX结构 体函数指针API。
    ii. SMBCCTX结构体中提供了一个callbacks结构体,我们可以通过使用其中的部分函数来获取SMBCCTX的一些状态,并进行管理。
    iii. get_cached_srv_fn:通 过服务器地址、共享目录名、用户名、所在域名来获取SMBCCTX中符合条件的srv,返回值将用于下面的这些函数调用。
    iv. check_server_fn:使用这个函 数可以查看指定的server的健康状态(这里特别提一下,在samba3.0.X的版本中,此函数是通过向服务器端发送自定义PING包来确定当前 server的连接是否正常,以此来判断server的健康状态的;而samba3.2.4中,则是通过当前连接所用的fd所对应的 socket_addr结构体是否存在来判断server的健康状态的。或许设计者的出发点不同,但samba3.0.X更加适合我们现在的项目)。
    v. remove_unsed_server_fn: 删除当前没有使用的srv
    vi. remove_cached_srv_fn: 删除缓存池指定的srv。
    vii. purge_cached_fn:删除缓存池 所有的srv
    4.2 多线程编程的解决方案:
    根 据samba官方消息,3.0.X版本的libsmbclient设计并未考虑成线程安全,因此最佳的多线程调用方式应该为加锁方式,至于新版本中是否为 线程安全,以及其使用方式,持续关注中。。。

     
    来自:http://blog.csdn.net/dxh040431104/article/details/5865790

     
    展开全文
  • Smbclient介绍

    千次阅读 2016-11-26 10:55:50
    Smbclient介绍 Smbclient(samba client)是基于SMB协议的,用于存取共享目标的客户端程序。 SMB 协议介绍 : 服务器信息块(SMB)协议是一种 IBM 协议,用于在计算机间共享文件、打印机、串口等。SMB 协议可以用...

    

    1      Smbclient介绍

    Smbclient(samba client)是基于SMB协议的,用于存取共享目标的客户端程序。

    SMB 协议介绍

    服务器信息块(SMB)协议是一种 IBM 协议,用于在计算机间共享文件、打印机、串口等。SMB 协议可以用在因特网的TCP/IP协议之上,也可以用在其它网络协议如 IPX 和 NetBEUI 之上。

    SMB 一种客户机/服务器、请求/响应协议。通过 SMB 协议,客户端应用程序可以在各种网络环境下读、写服务器上的文件,以及对服务器程序提出服务请求。此外通过 SMB 协议,应用程序可以访问远程服务器端的文件、以及打印机、邮件槽(mailslot)、命名管道(named pipe)等资源。

    在 TCP/IP 环境下,客户机通过 NetBIOS over TCP/IP(或 NetBEUI/TCP 或 SPX/IPX)连接服务器。一旦连接成功,客户机可发送 SMB 命令到服务器上,从而客户机能够访问共享目录、打开文件、读写文件,以及一切在文件系统上能做的所有事情。

    从 Windows 95 开始,Microsoft Windows 操作系统(operating system)都包括了客户机和服务器 SMB 协议支持。Microsoft 为 Internet 提供了 SMB 的开源版本,即通用 Internet 文件系统 (CIFS)。与现有 Internet应用程序如文件传输协议(FTP)相比, CIFS 灵活性更大。对于 UNIX 系统,可使用一种称为 Samba 的共享软件。

    SMB 定义了两级安全保护:

    共享级保护(Share Level Protection)应用于服务器共享目录级。每个共享目录都需要提供一个访问口令。只有口令通过,客户机才能访问所有共享文件。

    用户级保护(Usr Level Protection)应用于共享目录中的单独文件,基于用户访问权限。每个用户(客户机)必须登录服务器并且获得服务器的认证许可。一旦认证通过,客户 机会获得一个 UID 。在后来客户机访问服务器的过程中都需要使用该 UID 。

    2      Smbclient命令使用技巧

    2.1       smbclient 功 能说明:

    可存取SMB/CIFS服务器的用户端程序。

    2.1.1         语法 :

    smbclient [网络资源][密码][-EhLN][-B][-d<排错层级>][-i<范围>][-I][-l<记录文件>] [-M][-n][-O<连接槽选项>][-p][-R<名称解析顺序>][-s<目录>][-t<服务器字 码>][-T][-U<用户名称>][-W<工作群组>]补充说明:SMB与CIFS为服务器通信协议,常用于 Windows95/98/NT等系统。smbclient可让Linux系统存取Windows系统所分享的资源。

    2.1.2         参数:

    网络资源 网络资源的格式为//服务器名称/资源分享名称。

    密码 输入存取网络资源所需的密码。

    -B 传送广播数据包时所用的IP地址。

    -d< 排错层级> 指定记录文件所记载事件的详细程度。

    -E 将信息送到标准错误输出设备。

    -h 显示帮助。

    -i< 范围> 设置NetBIOS名称范围。

    -I 指定服务器的IP地址。

    -l< 记录文件> 指定记录文件的名称。

    -L 显示服务器端所分享出来的所有资源。

    -M 可利用WinPopup协议,将信息送给选项中所指定的主机。

    -n 指定用户端所要使用的NetBIOS名称。

    -N 不用询问密码。

    -O< 连接槽选项> 设置用户端TCP连接槽的选项。

    -p 指定服务器端TCP连接端口编号。

    -R< 名称解析顺序> 设置NetBIOS名称解析的顺序。

    -s< 目录> 指定smb.conf所在的目录。

    -t< 服务器字码> 设置用何种字符码来解析服务器端的文件名称。

    -T 备份服务器端分享的全部文件,并打包成tar格式的文件。

    -U< 用户名称> 指定用户名称。

    -W< 工作群组> 指定工作群组名称。

    2.2       smbclient 使 用举例:

    2.2.1      列出某个 IP 地 址所提供的共享文件夹

    smbclient -L 198.168.0.1 -U username%password

    2.2.2      像 FTP 客 户端一样使用 smbclient

    smbclient //192.168.0.1/tmp  -U username%password

    执行smbclient命令成功后,进入smbclient环境,出现提示符: smb:/>

    这里有许多命令和ftp命令相似,如cd 、lcd、get、megt、put、mput等。通过这些命令,我们可以访问远程主机的共享资源。

    2.2.3      直接一次性使用 smbclient 命 令

    smbclient -c "ls"  //192.168.0.1/tmp  -U username%password

    smbclient -c "get test.txt" //192.168.0.1/tmp -U username%password

    3      Smbclient开发技巧

    3.1       常用函数介绍

    Smbclient提供了两种外部接口,一种是SMBCCTX信息结构体中的函数指针,输入及输出中含有smbclient自定义的变量;另一种是 smbc族的接口,输入及输出均为系统基本变量,其实质是通过对SMBCCTX中的函数指针的封装来实现的。

    3.1.1       Smbc 族 函数:

    int smbc_init(smbc_get_auth_data_fn fn , int debug) ;

    初始化samba client库,此函数必须在所有其他smbc族API被调用前使用。

    参数:

    fn *:*用于传递SMB协议所需的基本信息;

    提供一个简单的fn实现(其中server为samba服务器地址,share为共享目录标识,workgroup为所在域的域 名,username为用户名,password为登录密码):

    static void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
                    char *username, int unmaxlen, char *password, int pwmaxlen)
    {
        
        strncpy(workgroup, g_workgroup, wgmaxlen - 1);
        strncpy(username, g_username, unmaxlen - 1);
        strncpy(password, g_password, pwmaxlen - 1);
        strcpy(g_server, server);
        strcpy(g_share, share);
    //    fprintf(stderr,"server[%s],share[%s]/n",server,share);
    }

    debug *:*调试信息等级(本人建议值0-10);

    返回值:

    0为成功,<0为失败,错误信息可通过errno获取。

    int smbc_open(const char *furl, int flags, mode_t mode);

    打开共享服务器上的一个文件,使用方法请参考open函数。

    int smbc_creat(const char *furl, mode_t mode);

    在共享服务器上创建一个文件,使用方法请参考open函数。

    ssize_t smbc_read(int fd, void *buf, size_t bufsize);

    使用一个打开的文件句柄来读取共享服务器上的文件,使用方法请参考read函数。

    ssize_t smbc_write(int fd, void *buf, size_t bufsize);

    使用一个打开的文件句柄向共享服务器上的文件写数据,使用方法请参考write函数。

    off_t smbc_lseek(int fd, off_t offset, int whence);

    移动文件的读写位置,使用方法请参考lseek函数。

    int smbc_close(int fd);

    关闭一个打开的文件句柄,使用方法请参考close函数。

    int smbc_unlink(const char *furl);

    删除一个共享服务器上的文件或者文件夹,使用方法请参考unlink函数。

    int smbc_rename(const char *ourl, cones char *nurl);

    重命名(或移动)共享目录上的文件或者文件夹,使用方法请参考rename函数。

    int smbc_opendir(const char *durl);

    打开共享服务器上的文件夹,使用方法请参考opendir函数。

    int smbc_closedir(int dh);

    关闭一个打开的文件夹句柄,使用方法请参考closedir函数。

    struct smbc_dirent* smbc_readdir(unsigned int dh);

    读取共享服务器上的文件夹信息,使用方法请参考readdir函数。

    off_t smbc_telldir(int dh);

    获取文件夹流当前的读取位置,使用方法请参考telldir函数。

    int smbc_mkdir(const char *durl, mode_t mode);

    在共享服务器上创建一个文件夹。

    参数:

    durl *:*路径

    mode *:*访问权限

    返回值:

    0为成功,<0为失败,失败信息可通过errno来获取。

    int smbc_rmdir(const char *durl);

    删除共享服务器上的一个文件夹。

    参数:

    durl *:*路径

    返回值:

    0为成功,<0为失败,失败信息可通过errno来获取。

    int smbc_stat(const char *url, struct stat *st);

    获取共享服务器上一个文件或者文件夹的所有信息,使用方法请参考stat函数。

    int smbc_fstat(int fd, struct stat *st);

    通过文件句柄来获取共享服务器上一个文件的所有信息,使用方法请参考fstat函数。

    int smbc_chown(const char *url, uid_t owner, gid_t group);

    修改共享服务器上文件或者文件夹的所有者信息,使用方法请参考chown函数。

    int smbc_chmod(const char *url, mode_t mode);

    修改共享服务器上的文件的权限,使用方法请参考chmod函数。

    int smbc_utimes(const char *url, struct timeval *tbuf);

    修改共享服务器上的文件的最后修改时间,使用方法请参考utimes函数。

    范例:

    #include <stdio.h>
    #include <stdlib.h>
    #include < errno.h>
    #include <dirent.h>
    #include < string.h>
    #include <unistd.h>
    #include < libsmbclient.h>

    #define MAX_BUFF_SIZE   255
    char g_workgroup[MAX_BUFF_SIZE];
    char g_username[MAX_BUFF_SIZE];
    char g_password[MAX_BUFF_SIZE];
    char g_server[MAX_BUFF_SIZE];
    char g_share[MAX_BUFF_SIZE];
    SMBCCTX * context;
    SMBCSRV * srv;

    static void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
                    char *username, int unmaxlen, char *password, int pwmaxlen)
    {
       
        strncpy(workgroup, g_workgroup, wgmaxlen - 1);
        strncpy(username, g_username, unmaxlen - 1);
        strncpy(password, g_password, pwmaxlen - 1);
        strcpy(g_server, server);
        strcpy(g_share, share);
    //    fprintf(stderr,"server[%s],share[%s]/n",server,share);
    }

    int main(int argc,char* argv[]){
        int err = -1;
        int dh = 0;
        int fd = -1;
        int buflen = 0;
        char buffer[1024] = {0};
        char url[MAX_BUFF_SIZE] = {0};
        char file[MAX_BUFF_SIZE] = {0};
        struct smbc_dirent* dirptr;
       
        bzero(g_workgroup,MAX_BUFF_SIZE);
        bzero(url,MAX_BUFF_SIZE);
        printf("%s/n",smbc_version());
       
        strncpy(g_workgroup,argv[1],strlen(argv[1]));
        strncpy(g_username,argv[2],strlen(argv[2]));
        strncpy(g_password,argv[3],strlen(argv[3]));
        strncpy(url,argv[4],strlen(argv[4]));
        if(url[strlen(url)-1] != '/'){
            strcat(url,"/");
        }
        err = smbc_init(auth_fn, 10);
        if(err < 0){
            perror("smbc_init error");
        }else{
            dh = smbc_opendir(url);
            while((dirptr = smbc_readdir(dh)) != NULL){
                bzero(file,MAX_BUFF_SIZE);
                printf("dirptr->name[%s],dirptr->smbc_type[%d]/n",dirptr->name,dirptr->smbc_type);
                if(dirptr->smbc_type == SMBC_FILE){
                    bzero(buffer,1024);
                    strncpy(file,url,strlen(url));
                    strncat(file,dirptr->name,dirptr->namelen);
                    printf("%s/n",file);
                    if((fd = smbc_open(file,O_RDONLY,0666)) > 0){
                        while((buflen = smbc_read(fd,buffer,1024)) > 0){
    //                        printf("buffer[%s]/n",buffer);
                        }
                        smbc_close(fd);
                    }
                }
            }
            smbc_closedir(dh);
    //        printf("smbc_rmdir(url)[%d]/n",smbc_rmdir(url));
        }
        return err;
    }

     

    3.1.2       函数指针:

    SMBCCTX *smbc_new_context(void);

    创建一个新的SMBCCTX结构体。

    返回值:

    SMBCCTX结构体指针,返回NULL为失败。错误信息可通过errno获取。

    int smbc_free_context(SMBCCTX *context, int shutdown_ctx);

    删除一个SMBCCTX结构体。

    参数:

    context *:*已创建的SMBCCTX结构体指针。

    shutdown_ctx *:*强制删除标识。

                          为1时,为强制删除;

    为0时,若此context与共享服务器的连接仍在使用或者有文件仍被打开,则删除context失败;

    返回值:

    0为成功,1为失败。错误信息可通过errno获取。

    SMBCCTX *smbc_init_context(SMBCCTX * context);

    初始化SMBCCTX结构体。

    参数:

    context *:*已创建的SMBCCTX结构体执政。

    返回值:

    成功初始化的SMBCCTX结构体指针,若返回值NULL则为初始化失败。错误信息可通过errno获取。

    SMBCCTX * smbc_set_context(SMBCCTX * new_context);

    设置(或重置)SMBCCTX结构体数据。

    参数:

    new_context *:*已创建的SMBCCTX结构体指针。

    返回值:

    被设置前的原始SMBCCTX结构体指针。

    SMBCFILE *(*open) (SMBCCTX *c, const char *fname, int flags, mode_t mode);

    打开共享服务器上的一个文件。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    fname *:*文件路径;

    flags *:*打开方式;

    mode *:*文件权限

    返回值 :

    成功打开的文件句柄,若<=0为失败,错误信息可通过errno获取。

    SMBCFILE *(*creat)(SMBCCTX *c, const char *path, mode_t mode);

    在共享服务器上的创建一个文件。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    path *:*文件路径;

    mode *:*文件权限

    返回值 :

    成功创建的文件句柄,若<=0为失败,错误信息可通过errno获取。

    ssize_t (*read)(SMBCCTX *c, SMBCFILE *file, void *buf, size_t count);

    使用一个打开的文件句柄来读取共享服务器上的文件。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    file *:*文件句柄;

    buf *:*存放读取到的数据的内存指针;

    count *:*读取长度

    返回值 :

    实际读取到的字节数,如果返回0,表示已到达文件尾或者无可读取的数据,此外文件读写位置会随读取到的字节移动,若返回-1表示有错误发生,错误信 息可通过errno获取。

    ssize_t (*write)(SMBCCTX *c, SMBCFILE *file, void *buf, size_t count);

    使用一个打开的文件句柄向共享服务器上的文件写数据。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    file *:*文件句柄;

    buf *:*需要写入的数据的指针;

    count *:*写入数据的长度

    返回值 :

    实际写入的字节数,若返回-1表示有错误发生,错误信息可通过errno获取。

    int (*unlink)(SMBCCTX *c, const char *fname);

    删除一个共享服务器上的文件或者文件夹。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    fname *:*指定路径

    返回值 :

    0为成功,-1为失败,错误信息可通过errno获取。

    int (*rename)(SMBCCTX *ocontext, const char *oname, SMBCCTX *ncontext, const char *nname);

    重命名(或移动)共享目录上的文件或者文件夹。

    参数:

    ocontext *:*已初始化(或设置)的SMBCCTX结构体指针;

    oname *:*源路径;

    ncontext *:*已初始化(或设置)的SMBCCTX结构体指针;

    nname *:*目标路径

    返回值 :

    0为成功,-1为失败,错误信息可通过errno获取。

    off_t (*lseek)(SMBCCTX *c, SMBCFILE * file, off_t offset, int whence);

    移动文件的读写位置。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    file *:*文件句柄;

    offset *:*位移量;

    whence *:*位移起始位置(SEEK_SET,SEEK_CUR,SEEK_END)

    返回值 :

    当前文件的读写位置,若返回-1表示有错误发生,错误信息可通过errno获取。

    int (*stat)(SMBCCTX *c, const char *fname, struct stat *st);

    获取共享服务器上一个文件或者文件夹的所有信息。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    fname *:*路径;

    st *:*文件属性结构体

    返回值 :

    0为成功,-1为失败,错误信息可通过errno获取。

    int (*fstat)(SMBCCTX *c, SMBCFILE *file, struct stat *st);

    通过文件句柄来获取共享服务器上一个文件的所有信息。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    file *:*文件句柄;

    st *:*文件属性结构体

    返回值 :

    0为成功,-1为失败,错误信息可通过errno获取。

    int (*close_fn)(SMBCCTX *c, SMBCFILE *file);

    关闭一个打开的文件句柄。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    file *:*文件句柄;

    返回值 :

    0为成功,-1为失败,错误信息可通过errno获取。

    SMBCFILE *(*opendir)(SMBCCTX *c, const char *fname);

    打开共享服务器上的文件夹。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    fname *:*文件夹路径;

    返回值 :

    成功打开的文件夹句柄,若NULL为失败,错误信息可通过errno获取。

    int (*closedir)(SMBCCTX *c, SMBCFILE *dir);

    关闭一个打开的文件夹句柄。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    fname *:*文件夹句柄;

    返回值 :

    0为成功,-1为失败,错误信息可通过errno获取。

    struct smbc_dirent *(*readdir)(SMBCCTX *c, SMBCFILE *dir);

    读取共享服务器上的文件夹信息。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    dir *:*文件夹句柄;

    返回值 :

    下个文件夹进入点,若NULL为失败或读取到目录文件尾,错误信息可通过errno获取。

    int (*mkdir)(SMBCCTX *c, const char *fname, mode_t mode);

    在共享服务器上创建一个文件夹。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    fname *:*文件夹路径;

    mode *:*权限;

    返回值 :

    0为成功,-1为失败,错误信息可通过errno获取。

    int (*rmdir)(SMBCCTX *c, const char *fname);

    删除共享服务器上的一个文件夹。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    fname *:*文件夹路径;

    返回值 :

    0为成功,-1为失败,错误信息可通过errno获取。

    off_t (*telldir) (SMBCCTX *c, SMBCFILE *dir);

    获取文件夹流当前的读取位置。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    dir *:*文件夹句柄;

    返回值:

    下一个读取位置,-1表示有错误发生,错误信息可通过errno获取。

    int (*chmod)(SMBCCTX *c, const char *fname, mode_t mode);

    修改共享服务器上的文件的权限。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    fname *:*文件夹路径;

    mode *:*权限;

    返回值 :

    0为成功,-1为失败,错误信息可通过errno获取。

    int (*utimes)(SMBCCTX *c, const char *fname, struct timeval *tbuf);

    修改共享服务器上的文件的最后修改时间。

    参数:

    c *:*已初始化(或设置)的SMBCCTX结构体指针;

    fname *:*文件夹路径;

    tbuf *:*时间结构体;

    返回值 :

    0为成功,-1为失败,错误信息可通过errno获取。

    范例:

    #include < stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <dirent.h>
    #include <string.h>
    #include < unistd.h>
    #include <libsmbclient.h>

    #define MAX_BUFF_SIZE   255
    char g_workgroup[MAX_BUFF_SIZE];
    char g_username[MAX_BUFF_SIZE];
    char g_password[MAX_BUFF_SIZE];
    char g_server[MAX_BUFF_SIZE];
    char g_share[MAX_BUFF_SIZE];
    SMBCCTX * context;
    SMBCSRV * srv;
    //smbc_get_cached_srv_fn get_srv;

    static void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
                    char *username, int unmaxlen, char *password, int pwmaxlen)
    {
        
        strncpy(workgroup, g_workgroup, wgmaxlen - 1);
        strncpy(username, g_username, unmaxlen - 1);
        strncpy(password, g_password, pwmaxlen - 1);
        strcpy(g_server, server);
        strcpy(g_share, share);
    //    fprintf(stderr,"server[%s],share[%s]/n",server,share);
    }

    int main(int argc, char* argv[]){
        SMBCFILE* sfd;
        SMBCFILE* fd;
        int localfd = -1,readlen = -1;
        
        struct smbc_server_cache * getServerCacheData;
        char buff[1024*1024*4] = {0};
        char url[MAX_BUFF_SIZE] = {0};
        char file[MAX_BUFF_SIZE] = {0};
        struct smbc_dirent* dirptr;
        bzero(g_workgroup,MAX_BUFF_SIZE);
        bzero(url,MAX_BUFF_SIZE);
        printf("%s/n",smbc_version());
        
        strncpy(g_workgroup,argv[1],strlen(argv[1]));
        strncpy(g_username,argv[2],strlen(argv[2]));
        strncpy(g_password,argv[3],strlen(argv[3]));
        strncpy(url,argv[4],strlen(argv[4]));
        if(url[strlen(url)-1] != '/'){
            strcat(url,"/");
        }
        context = smbc_new_context();
        if(context != NULL){
            context->debug = 10;
            context->callbacks.auth_fn = auth_fn;
            context->options.one_share_per_server = 1;
        
            if(!smbc_init_context(context)){
                perror("smbc_init_context failed");
                smbc_free_context(context,1);
                return -1;
            }
            
            sfd = context->opendir(context,url);
            struct smbc_dirent dirptr1;
            while((dirptr = context->readdir(context,sfd)) != NULL){
                if(dirptr->smbc_type == SMBC_FILE){
                    printf("name[%s]/n",dirptr->name);
                    strncpy(file,url,strlen(url));
                    strncat(file,dirptr->name,dirptr->namelen);
                    if((fd = context->open(context,file,O_RDONLY,0666)) > 0){
                        context->close_fn(context,fd);
                    }
                }
            }
            context->closedir(context,sfd);
        }
        return 0;
    }

     

    4          Smbclient 使 用的个人小结

    4.1       Smbclient 编 程需要注意的地方:

    4.1.1     使用smbclient编程需要用到的库,/usr/lib/libsmbclient.so 或者/usr/lib/libsmbclient.a。

    4.1.2     smbclient中,同一个共享目录下的所有数据交互,控制消息使用的有且只有一个connection连接(通过设置 one_share_per_server属性,可将同一个共享服务器下所有操作及数据交互都使用同一个connection连接)。

    4.1.3     smbclient向samba服务器的连接方式:smbclient的连接请求是在调用除初始化设置外的所有API接口时才发起的。这些API中,首先 会查询当前srv下是否有可用的连接,若有则使用当前可用连接,若没有可用连接则建立新的连接。

    4.1.4     smbclient的句柄是一个包含与服务器连接fd,请求文件名,共享服务器句柄等连接信息的集合。

    4.1.5     smbclient的重连机制:smbclient的内部是不提供重连机制的,也就是说,若一个请求超时后,API将直接返回错误信息。由本节点第二点可 知,在应用层下一次调用API时,smbclient层会向samba服务器再次发出连接请求。

    4.1.6     smbclient的smbc族函数使用时需要注意的的地方:

                                        i.             由A可知,smbc_init函数实质 上是对smbc_new_context()和smbc_init_context(SMBCCTX *context)进行了封装,而smbc_init函数并没有提供参数来指定smbc_new_context和smbc_init_context使 用的context指针。因此,smbc_init函数初始化的是smbclient库中的一个全局变量SMBCCTX *statcont。我们知道当一个进程中多次调用同一个库文件时,库文件的全局变量的地址是唯一的,也就是说,若我们使用smbc族API来对 smbclient进行多线程编程是不可行的。

                                      ii.             由libsmbclient.h中的声明 可知,smbc族的API没用提供对SMBCCTX结构体的参数设置接口。也就是说这种API不适合有特殊需求的程序(例如需要获取的数据为 urlcontext类型,或者需要指定同一个共享服务器下的所有共享文件夹都只使用一个连接等)

    4.1.7     由SMB协议可知,基于SMB协议的数据交互必须遵循 连接->发送命令->接收数据 ->发送命令->......->断开连接 的阻塞通信模式,又因为当smbclient是以一个连接至少对应一个共享文件的方式来进行通信的,所以若简单的对smbclient使用多线程操作,会 出现数据混乱的情况,导致不可预期的错误。

    4.1.8     管理SMBCCTX的一些小技巧:

                                        i.             首先,我们需要使用SMBCCTX结构 体函数指针API。

                                      ii.             SMBCCTX结构体中提供了一个 callbacks结构体,我们可以通过使用其中的部分函数来获取SMBCCTX的一些状态,并进行管理。

                                     iii.             get_cached_srv_fn:通 过服务器地址、共享目录名、用户名、所在域名来获取SMBCCTX中符合条件的srv,返回值将用于下面的这些函数调用。

                                    iv.             check_server_fn:使用这个函 数可以查看指定的server的健康状态(这里特别提一下,在samba3.0.X的版本中,此函数是通过向服务器端发送自定义PING包来确定当前 server的连接是否正常,以此来判断server的健康状态的;而samba3.2.4中,则是通过当前连接所用的fd所对应的 socket_addr结构体是否存在来判断server的健康状态的。或许设计者的出发点不同,但samba3.0.X更加适合我们现在的项目)。

                                      v.             remove_unsed_server_fn: 删除当前没有使用的srv

                                    vi.             remove_cached_srv_fn: 删除缓存池指定的srv。

                                   vii.             purge_cached_fn:删除缓存池 所有的srv

    4.2       多线程编程的解决方案:

    根 据samba官方消息,3.0.X版本的libsmbclient设计并未考虑成线程安全,因此最佳的多线程调用方式应该为加锁方式,至于新版本中是否为 线程安全,以及其使用方式,持续关注中。。。

    展开全文
  • smbclient 使用方法

    2019-09-29 18:33:18
    1,列出某个IP地址所提供的共享文件夹 ...smbclient -L 198.168.0.1 -U username%password 2,像FTP客户端一样使用smbclient smbclient //192.168.0.1/tmp -U username 执行smbclient命令成功后,进入smbcl...

     

       
    1,列出某个IP地址所提供的共享文件夹
    smbclient -L 198.168.0.1 -U username%password
     
    2,像FTP客户端一样使用smbclient
    smbclient //192.168.0.1/tmp  -U username
     
    执行smbclient命令成功后,进入smbclient环境,出现提示符: smb:\>
    这里有许多命令和ftp命令相似,如cd 、lcd、get、megt、put、mput等。通过这些命令,我们可以访问远程主机的共享资源。
     
    3,直接一次性使用smbclient命令
    smbclient -c "ls"  //192.168.0.1/tmp  -U username%password
    smbclient //192.168.0.1/tmp  -U username%password
    smb:\>ls
    功能一样的
     
    例,创建一个共享文件夹
    smbclient -c "mkdir share1"  //192.168.0.1/tmp  -U username%password
    如果用户共享//192.168.0.1/tmp的方式是只读的,会提示
    NT_STATUS_ACCESS_DENIED making remote directory \share1
     
    4,除了使用smbclient,还可以通过mount和smbcount挂载远程共享文件夹
    mount -t smbfs -o  username=administrator,password=123456 //192.168.0.1/tmp  /mnt/tmp
    smbmount //192.168.0.1/tmp /mnt/tmp -o username=administrator

    转载于:https://www.cnblogs.com/stephen-init/p/4310410.html

    展开全文
  • smbclient使用

    千次阅读 2014-11-01 09:48:05
    OS:debian 树莓派 挂载目录:win7  smbclient //192.168.0.136/raspberry -Uwrr
  • smbclient用法

    2013-03-14 10:11:00
    1,列出某个IP地址所提供的共享文件夹smbclient -L 198.168.0.1 -U username%password 2,像FTP客户端一样使用smbclientsmbclient //192.168.0.1/tmp -U username%password 执行smbclient命令成功后,进入smbclient...
  • smbclient 的用法

    千次阅读 2015-09-23 12:58:01
    1,列出某个IP地址所提供的共享文件夹 smbclient -L 198.168.0.1 -U username%password   ...2,像FTP客户端一样使用smbclient ...执行smbclient命令成功后,进入smbclient环境,出现提示符: s
  • import io import cv2 from PIL import Image ...class SMBClient(object): """ smb连接客户端 """ prot = None status = False samba = None def __init__(self, user_name, passwd, ip, port=1...
  • 最新kali之smbclient

    2021-01-23 14:45:29
      smbclient是可以与SMB / CIFS服务器“对话”的客户端。 它提供的接口类似于ftp程序的接口(请参阅ftp(1))。 操作包括诸如从服务器将文件获取到本地计算机,将文件从本地计算机放置到服务器,从服务器获取目录...
  • Linux 网络通讯 : smbclient 命令详解

    万次阅读 2018-09-27 15:05:33
    smbclient命令属于samba套件,它提供一种命令行使用交互式方式访问samba服务器的共享资源。 语法 smbclient(选项)(参数) 选项 -B&lt;ip地址&gt;:传送广播数据包时所用的IP地址; -d&lt;排错层级&...
  • Ubuntu 下用smbclient访问smb

    千次阅读 2019-04-19 12:19:17
    Ubuntu 下用smbclient访问smb https://blog.csdn.net/FruitDrop/article/details/66475465 Ubuntu 下用smbclient访问smb smb的配置 首先安装smbclient sudo apt-get install smbclient 1 这里写图片描述 查看要...
  • smbclient的Node.js包装器 要求 要求必须安装Node.js 10+ Smbclient。 可以使用sudo apt-get install smbclient安装在Ubuntu上。 原料药 const SambaClient = require ( 'samba-client' ) ; let client = new Samba...
  • smbclient smbclient是一个smb服务器的客户端的管理程序,可以交互式的访问samba服务器。 此命令的适用范围:RedHat、RHEL、Ubuntu、CentOS、Fedora、SUSE、openSUSE。 1、语法 smbclientservername[选项] ...
  • pecl install smbclient 二进制软件包安装 一些发行版提供了二进制软件包: Fedora / RHEL / CentOS的RPM: Debian的DEB: 适用于Ubuntu的DEB: 从源安装 通过软件包libsmbclient-dev(Debian / Ubuntu)或...
  • smbclient提供了类似FTP式的共享文件操作功能, 本篇从源码角度讲解smbclient的实现,smbclient命令的具体使用可通过help命令和互联网查到大量资料。 以下从源码角度分析一个smbclient命令是如何发到远端机器上和...
  • smbclient和挂载samba共享目录

    千次阅读 2016-10-24 16:28:03
    1,列出某个IP地址所提供的共享文件夹  smbclient -L 198.168.0.1 -U marsaber%1233211234567 2,像FTP客户端一样使用smbclient  ...执行smbclient命令成功后,进入smbclient环境,出现提示符:
  • samba使用smbclient -L命令时出现错误: Connection to 127.0.0.1 failed (Error NT_STATUS_CONNECTION_REFUSED) 请问怎么解决???挺急的
  • smbclient访问海康威视H90个人网盘

    千次阅读 2020-05-23 20:27:47
    家里有一块闲置的2T硬盘,想着网上买一个家用的存储来把硬盘利用起来,于是就买了这款,网图是这个样子的。 实物图其实跟这个差不多,...jarvis@jarvis-PC:~$ smbclient -L 192.168.0.10 -U admin%Yourpassword Un
  • 因此,我为smbclient写了一个包装器,该包装器会自动测试所有找到的共享的读写权限。 验证是通过空会话(即没有用户名和密码)完成的。 脚本smbclientmap.sh执行以下操作: 该脚本将一个IP地址作为输入。 该...
  • smbclient -c “put /test/test3f.txt ./test/test4.txt” //11.11.11.11/backup -U admin%admin echo $? FTP 无聊可以试试
  • smbclient命令行用法

    万次阅读 2009-12-10 11:03:00
    转自:http://hi.baidu.com/ilovechallenge/blog/item/53698b28bbf657f699250ae0.html1,列出某个IP地址所提供的共享文件夹 smbclient -L 198.168.0.1 -U username%password 2,像FTP客户端一样使用smbclient ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,475
精华内容 4,190
关键字:

smbclient