⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libsmbclient.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Set file info on an SMB server.  Use setpathinfo call first.  If that * fails, use setattrE.. * * Access and modification time parameters are always used and must be * provided.  Create time, if zero, will be determined from the actual create * time of the file.  If non-zero, the create time will be set as well. * * "mode" (attributes) parameter may be set to -1 if it is not to be set. */static BOOLsmbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,             time_t c_time, time_t a_time, time_t m_time,            uint16 mode){        int fd;        int ret;        /*         * Get the create time of the file (if not provided); we'll need it in         * the set call.         */        if (! srv->no_pathinfo && c_time == 0) {                if (! cli_qpathinfo(&srv->cli, path,                                    &c_time, NULL, NULL, NULL, NULL)) {                        /* qpathinfo not available */                        srv->no_pathinfo = True;                } else {                        /*                         * We got a creation time.  Some OS versions don't                         * return a valid create time, though.  If we got an                         * invalid time, start with the current time instead.                         */                        if (c_time == 0 || c_time == (time_t) -1) {                                c_time = time(NULL);                        }                        /*                         * We got a creation time.  For sanity sake, since                         * there is no POSIX function to set the create time                         * of a file, if the existing create time is greater                         * than either of access time or modification time,                         * set create time to the smallest of those.  This                         * ensure that the create time of a file is never                         * greater than its last access or modification time.                         */                        if (c_time > a_time) c_time = a_time;                        if (c_time > m_time) c_time = m_time;                }        }        /*         * First, try setpathinfo (if qpathinfo succeeded), for it is the         * modern function for "new code" to be using, and it works given a         * filename rather than requiring that the file be opened to have its         * attributes manipulated.         */        if (srv->no_pathinfo ||            ! cli_setpathinfo(&srv->cli, path, c_time, a_time, m_time, mode)) {                /*                 * setpathinfo is not supported; go to plan B.                  *                 * cli_setatr() does not work on win98, and it also doesn't                 * support setting the access time (only the modification                 * time), so in all cases, we open the specified file and use                 * cli_setattrE() which should work on all OS versions, and                 * supports both times.                 */                /* Don't try {q,set}pathinfo() again, with this server */                srv->no_pathinfo = True;                /* Open the file */                if ((fd = cli_open(&srv->cli, path, O_RDWR, DENY_NONE)) < 0) {                        errno = smbc_errno(context, &srv->cli);                        return -1;                }                /*                 * Get the creat time of the file (if it wasn't provided).                 * We'll need it in the set call                 */                if (c_time == 0) {                        ret = cli_getattrE(&srv->cli, fd,                                           NULL, NULL,                                           &c_time, NULL, NULL);                } else {                        ret = True;                }                                    /* If we got create time, set times */                if (ret) {                        /* Some OS versions don't support create time */                        if (c_time == 0 || c_time == -1) {                                c_time = time(NULL);                        }                        /*                         * For sanity sake, since there is no POSIX function                         * to set the create time of a file, if the existing                         * create time is greater than either of access time                         * or modification time, set create time to the                         * smallest of those.  This ensure that the create                         * time of a file is never greater than its last                         * access or modification time.                         */                        if (c_time > a_time) c_time = a_time;                        if (c_time > m_time) c_time = m_time;                                                /* Set the new attributes */                        ret = cli_setattrE(&srv->cli, fd,                                           c_time, a_time, m_time);                        cli_close(&srv->cli, fd);                }                /*                 * Unfortunately, setattrE() doesn't have a provision for                 * setting the access mode (attributes).  We'll have to try                 * cli_setatr() for that, and with only this parameter, it                 * seems to work on win98.                 */                if (ret && mode != (uint16) -1) {                        ret = cli_setatr(&srv->cli, path, mode, 0);                }                if (! ret) {                        errno = smbc_errno(context, &srv->cli);                        return False;                }        }        return True;} /*  * Routine to unlink() a file  */static intsmbc_unlink_ctx(SMBCCTX *context,                const char *fname){	fstring server, share, user, password, workgroup;	pstring path, targetpath;	struct cli_state *targetcli;	SMBCSRV *srv = NULL;	if (!context || !context->internal ||	    !context->internal->_initialized) {		errno = EINVAL;  /* Best I can think of ... */		return -1;	}	if (!fname) {		errno = EINVAL;		return -1;	}	if (smbc_parse_path(context, fname,                            server, sizeof(server),                            share, sizeof(share),                            path, sizeof(path),                            user, sizeof(user),                            password, sizeof(password),                            NULL, 0)) {                errno = EINVAL;                return -1;        }	if (user[0] == (char)0) fstrcpy(user, context->user);	fstrcpy(workgroup, context->workgroup);	srv = smbc_server(context, True,                          server, share, workgroup, user, password);	if (!srv) {		return -1;  /* smbc_server sets errno */	}	/*d_printf(">>>unlink: resolving %s\n", path);*/	if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath))	{		d_printf("Could not resolve %s\n", path);		return -1;	}	/*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/	if (!cli_unlink(targetcli, targetpath)) {		errno = smbc_errno(context, targetcli);		if (errno == EACCES) { /* Check if the file is a directory */			int saverr = errno;			SMB_OFF_T size = 0;			uint16 mode = 0;			time_t m_time = 0, a_time = 0, c_time = 0;			SMB_INO_T ino = 0;			if (!smbc_getatr(context, srv, path, &mode, &size,					 &c_time, &a_time, &m_time, &ino)) {				/* Hmmm, bad error ... What? */				errno = smbc_errno(context, targetcli);				return -1;			}			else {				if (IS_DOS_DIR(mode))					errno = EISDIR;				else					errno = saverr;  /* Restore this */			}		}		return -1;	}	return 0;  /* Success ... */}/* * Routine to rename() a file */static intsmbc_rename_ctx(SMBCCTX *ocontext,                const char *oname,                 SMBCCTX *ncontext,                const char *nname){	fstring server1;        fstring share1;        fstring server2;        fstring share2;        fstring user1;        fstring user2;        fstring password1;        fstring password2;        fstring workgroup;	pstring path1;        pstring path2;        pstring targetpath1;        pstring targetpath2;	struct cli_state *targetcli1;        struct cli_state *targetcli2;	SMBCSRV *srv = NULL;	if (!ocontext || !ncontext || 	    !ocontext->internal || !ncontext->internal ||	    !ocontext->internal->_initialized || 	    !ncontext->internal->_initialized) {		errno = EINVAL;  /* Best I can think of ... */		return -1;	}		if (!oname || !nname) {		errno = EINVAL;		return -1;	}		DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname));	smbc_parse_path(ocontext, oname,                        server1, sizeof(server1),                        share1, sizeof(share1),                        path1, sizeof(path1),                        user1, sizeof(user1),                        password1, sizeof(password1),                        NULL, 0);	if (user1[0] == (char)0) fstrcpy(user1, ocontext->user);	smbc_parse_path(ncontext, nname,                        server2, sizeof(server2),                        share2, sizeof(share2),                        path2, sizeof(path2),                        user2, sizeof(user2),                        password2, sizeof(password2),                        NULL, 0);	if (user2[0] == (char)0) fstrcpy(user2, ncontext->user);	if (strcmp(server1, server2) || strcmp(share1, share2) ||	    strcmp(user1, user2)) {		/* Can't rename across file systems, or users?? */		errno = EXDEV;		return -1;	}	fstrcpy(workgroup, ocontext->workgroup);	srv = smbc_server(ocontext, True,                          server1, share1, workgroup, user1, password1);	if (!srv) {		return -1;	}	/*d_printf(">>>rename: resolving %s\n", path1);*/	if (!cli_resolve_path( "", &srv->cli, path1, &targetcli1, targetpath1))	{		d_printf("Could not resolve %s\n", path1);		return -1;	}	/*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/	/*d_printf(">>>rename: resolving %s\n", path2);*/	if (!cli_resolve_path( "", &srv->cli, path2, &targetcli2, targetpath2))	{		d_printf("Could not resolve %s\n", path2);		return -1;	}	/*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/		if (strcmp(targetcli1->desthost, targetcli2->desthost) ||            strcmp(targetcli1->share, targetcli2->share))	{		/* can't rename across file systems */				errno = EXDEV;		return -1;	}	if (!cli_rename(targetcli1, targetpath1, targetpath2)) {		int eno = smbc_errno(ocontext, targetcli1);		if (eno != EEXIST ||		    !cli_unlink(targetcli1, targetpath2) ||		    !cli_rename(targetcli1, targetpath1, targetpath2)) {			errno = eno;			return -1;		}	}	return 0; /* Success */}/* * A routine to lseek() a file */static off_tsmbc_lseek_ctx(SMBCCTX *context,               SMBCFILE *file,               off_t offset,               int whence){	SMB_OFF_T size;	fstring server, share, user, password;	pstring path, targetpath;	struct cli_state *targetcli;	if (!context || !context->internal ||	    !context->internal->_initialized) {		errno = EINVAL;		return -1;			}	if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {		errno = EBADF;		return -1;	}	if (!file->file) {		errno = EINVAL;		return -1;      /* Can't lseek a dir ... */	}	switch (whence) {	case SEEK_SET:		file->offset = offset;		break;	case SEEK_CUR:		file->offset += offset;		break;	case SEEK_END:		/*d_printf(">>>lseek: parsing %s\n", file->fname);*/		if (smbc_parse_path(context, file->fname,                                    server, sizeof(server),                                    share, sizeof(share),                                    path, sizeof(path),                                    user, sizeof(user),                                    password, sizeof(password),                                    NULL, 0)) {                        					errno = EINVAL;					return -1;			}				/*d_printf(">>>lseek: resolving %s\n", path);*/		if (!cli_resolve_path("", &file->srv->cli, path,                                      &targetcli, targetpath))		{			d_printf("Could not resolve %s\n", path);			return -1;		}		/*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/				if (!cli_qfileinfo(targetcli, file->cli_fd, NULL,                                   &size, NULL, NULL, NULL, NULL, NULL)) 		{		    SMB_OFF_T b_size = size;			if (!cli_getattrE(targetcli, file->cli_fd,                                          NULL, &b_size, NULL, NULL, NULL)) 		    {			errno = EINVAL;			return -1;		    } else			size = b_size;		}		file->offset = size + offset;		break;	default:		errno = EINVAL;		break;	}	return file->offset;}/*  * Generate an inode number from file name for those things that need it */static ino_tsmbc_inode(SMBCCTX *context,           const char *name){	if (!context || !context->internal ||	    !context->internal->_initialized) {		errno = EINVAL;		return -1;	}	if (!*name) return 2; /* FIXME, why 2 ??? */	return (ino_t)str_checksum(name);}/* * Routine to put basic stat info into a stat structure ... Used by stat and * fstat below. */static intsmbc_setup_stat(SMBCCTX *context,                struct stat *st,                char *fname,                SMB_OFF_T size,                int mode){		st->st_mode = 0;	if (IS_DOS_DIR(mode)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -