This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
Creates new name (sym)linked to oldname.
****************************************************************************/
-static BOOL cli_link_internal(struct cli_state *cli, const char *oldname, const char *newname, BOOL hard_link)
+static bool cli_link_internal(struct cli_state *cli, const char *oldname, const char *newname, bool hard_link)
{
unsigned int data_len = 0;
unsigned int param_len = 0;
Do a POSIX getfacl (UNIX extensions).
****************************************************************************/
-BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf)
+bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf)
{
unsigned int param_len = 0;
unsigned int data_len = 0;
Stat a file (UNIX extensions).
****************************************************************************/
-BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf)
+bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf)
{
unsigned int param_len = 0;
unsigned int data_len = 0;
Symlink a file (UNIX extensions).
****************************************************************************/
-BOOL cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *newname)
+bool cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *newname)
{
return cli_link_internal(cli, oldname, newname, False);
}
Hard a file (UNIX extensions).
****************************************************************************/
-BOOL cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *newname)
+bool cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *newname)
{
return cli_link_internal(cli, oldname, newname, True);
}
Chmod or chown a file internal (UNIX extensions).
****************************************************************************/
-static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid)
+static bool cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid)
{
unsigned int data_len = 0;
unsigned int param_len = 0;
chmod a file (UNIX extensions).
****************************************************************************/
-BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode)
+bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode)
{
return cli_unix_chmod_chown_internal(cli, fname,
unix_perms_to_wire(mode), SMB_UID_NO_CHANGE, SMB_GID_NO_CHANGE);
chown a file (UNIX extensions).
****************************************************************************/
-BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid)
+bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid)
{
return cli_unix_chmod_chown_internal(cli, fname, SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid);
}
Rename a file.
****************************************************************************/
-BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst)
+bool cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst)
{
char *p;
NT Rename a file.
****************************************************************************/
-BOOL cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fname_dst)
+bool cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fname_dst)
{
char *p;
NT hardlink a file.
****************************************************************************/
-BOOL cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst)
+bool cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst)
{
char *p;
Delete a file.
****************************************************************************/
-BOOL cli_unlink(struct cli_state *cli, const char *fname)
+bool cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs)
{
char *p;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN);
+ SSVAL(cli->outbuf,smb_vwv0, attrs);
p = smb_buf(cli->outbuf);
*p++ = 4;
return True;
}
+/****************************************************************************
+ Delete a file.
+****************************************************************************/
+
+bool cli_unlink(struct cli_state *cli, const char *fname)
+{
+ return cli_unlink_full(cli, fname, aSYSTEM | aHIDDEN);
+}
+
/****************************************************************************
Create a directory.
****************************************************************************/
-BOOL cli_mkdir(struct cli_state *cli, const char *dname)
+bool cli_mkdir(struct cli_state *cli, const char *dname)
{
char *p;
Remove a directory.
****************************************************************************/
-BOOL cli_rmdir(struct cli_state *cli, const char *dname)
+bool cli_rmdir(struct cli_state *cli, const char *dname)
{
char *p;
Set or clear the delete on close flag.
****************************************************************************/
-int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag)
+int cli_nt_delete_on_close(struct cli_state *cli, int fnum, bool flag)
{
unsigned int data_len = 1;
unsigned int param_len = 6;
Close a file.
****************************************************************************/
-BOOL cli_close(struct cli_state *cli, int fnum)
+bool cli_close(struct cli_state *cli, int fnum)
{
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
note that timeout is in units of 2 milliseconds
****************************************************************************/
-BOOL cli_lock(struct cli_state *cli, int fnum,
+bool cli_lock(struct cli_state *cli, int fnum,
uint32 offset, uint32 len, int timeout, enum brl_type lock_type)
{
char *p;
Unlock a file.
****************************************************************************/
-BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
+bool cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
{
char *p;
Lock a file with 64 bit offsets.
****************************************************************************/
-BOOL cli_lock64(struct cli_state *cli, int fnum,
+bool cli_lock64(struct cli_state *cli, int fnum,
SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type)
{
char *p;
Unlock a file with 64 bit offsets.
****************************************************************************/
-BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len)
+bool cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len)
{
char *p;
Get/unlock a POSIX lock on a file - internal function.
****************************************************************************/
-static BOOL cli_posix_lock_internal(struct cli_state *cli, int fnum,
- SMB_BIG_UINT offset, SMB_BIG_UINT len, BOOL wait_lock, enum brl_type lock_type)
+static bool cli_posix_lock_internal(struct cli_state *cli, int fnum,
+ SMB_BIG_UINT offset, SMB_BIG_UINT len, bool wait_lock, enum brl_type lock_type)
{
unsigned int param_len = 4;
unsigned int data_len = POSIX_LOCK_DATA_SIZE;
POSIX Lock a file.
****************************************************************************/
-BOOL cli_posix_lock(struct cli_state *cli, int fnum,
+bool cli_posix_lock(struct cli_state *cli, int fnum,
SMB_BIG_UINT offset, SMB_BIG_UINT len,
- BOOL wait_lock, enum brl_type lock_type)
+ bool wait_lock, enum brl_type lock_type)
{
if (lock_type != READ_LOCK && lock_type != WRITE_LOCK) {
return False;
POSIX Unlock a file.
****************************************************************************/
-BOOL cli_posix_unlock(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len)
+bool cli_posix_unlock(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len)
{
return cli_posix_lock_internal(cli, fnum, offset, len, False, UNLOCK_LOCK);
}
POSIX Get any lock covering a file.
****************************************************************************/
-BOOL cli_posix_getlock(struct cli_state *cli, int fnum, SMB_BIG_UINT *poffset, SMB_BIG_UINT *plen)
+bool cli_posix_getlock(struct cli_state *cli, int fnum, SMB_BIG_UINT *poffset, SMB_BIG_UINT *plen)
{
return True;
}
Do a SMBgetattrE call.
****************************************************************************/
-BOOL cli_getattrE(struct cli_state *cli, int fd,
+bool cli_getattrE(struct cli_state *cli, int fd,
uint16 *attr, SMB_OFF_T *size,
time_t *change_time,
time_t *access_time,
Do a SMBgetatr call
****************************************************************************/
-BOOL cli_getatr(struct cli_state *cli, const char *fname,
+bool cli_getatr(struct cli_state *cli, const char *fname,
uint16 *attr, SMB_OFF_T *size, time_t *write_time)
{
char *p;
Do a SMBsetattrE call.
****************************************************************************/
-BOOL cli_setattrE(struct cli_state *cli, int fd,
+bool cli_setattrE(struct cli_state *cli, int fd,
time_t change_time,
time_t access_time,
time_t write_time)
Do a SMBsetatr call.
****************************************************************************/
-BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t)
+bool cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t)
{
char *p;
/****************************************************************************
Check for existance of a dir.
****************************************************************************/
-BOOL cli_chkpath(struct cli_state *cli, const char *path)
+bool cli_chkpath(struct cli_state *cli, const char *path)
{
pstring path2;
char *p;
Query disk space.
****************************************************************************/
-BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
+bool cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
{
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
return cli_nt_error(cli);
}
- *blob = data_blob(NULL, 0);
+ *blob = data_blob_null;
return NT_STATUS_OK;
}
Set an extended attribute utility fn.
*********************************************************/
-static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigned int param_len,
+static bool cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigned int param_len,
const char *ea_name, const char *ea_val, size_t ea_len)
{
unsigned int data_len = 0;
Set an extended attribute on a pathname.
*********************************************************/
-BOOL cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len)
+bool cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len)
{
uint16 setup = TRANSACT2_SETPATHINFO;
unsigned int param_len = 0;
Set an extended attribute on an fnum.
*********************************************************/
-BOOL cli_set_ea_fnum(struct cli_state *cli, int fnum, const char *ea_name, const char *ea_val, size_t ea_len)
+bool cli_set_ea_fnum(struct cli_state *cli, int fnum, const char *ea_name, const char *ea_val, size_t ea_len)
{
char param[6];
uint16 setup = TRANSACT2_SETFILEINFO;
Get an extended attribute list tility fn.
*********************************************************/
-static BOOL cli_get_ea_list(struct cli_state *cli,
+static bool cli_get_ea_list(struct cli_state *cli,
uint16 setup, char *param, unsigned int param_len,
TALLOC_CTX *ctx,
size_t *pnum_eas,
char *p;
size_t ea_size;
size_t num_eas;
- BOOL ret = False;
+ bool ret = False;
struct ea_struct *ea_list;
*pnum_eas = 0;
Get an extended attribute list from a pathname.
*********************************************************/
-BOOL cli_get_ea_list_path(struct cli_state *cli, const char *path,
+bool cli_get_ea_list_path(struct cli_state *cli, const char *path,
TALLOC_CTX *ctx,
size_t *pnum_eas,
struct ea_struct **pea_list)
Get an extended attribute list from an fnum.
*********************************************************/
-BOOL cli_get_ea_list_fnum(struct cli_state *cli, int fnum,
+bool cli_get_ea_list_fnum(struct cli_state *cli, int fnum,
TALLOC_CTX *ctx,
size_t *pnum_eas,
struct ea_struct **pea_list)
return cli_get_ea_list(cli, setup, param, 6, ctx, pnum_eas, pea_list);
}
+
+/****************************************************************************
+ Convert open "flags" arg to uint32 on wire.
+****************************************************************************/
+
+static uint32 open_flags_to_wire(int flags)
+{
+ int open_mode = flags & O_ACCMODE;
+ uint32 ret = 0;
+
+ switch (open_mode) {
+ case O_WRONLY:
+ ret |= SMB_O_WRONLY;
+ break;
+ case O_RDWR:
+ ret |= SMB_O_RDWR;
+ break;
+ default:
+ case O_RDONLY:
+ ret |= SMB_O_RDONLY;
+ break;
+ }
+
+ if (flags & O_CREAT) {
+ ret |= SMB_O_CREAT;
+ }
+ if (flags & O_EXCL) {
+ ret |= SMB_O_EXCL;
+ }
+ if (flags & O_TRUNC) {
+ ret |= SMB_O_TRUNC;
+ }
+#if defined(O_SYNC)
+ if (flags & O_SYNC) {
+ ret |= SMB_O_SYNC;
+ }
+#endif /* O_SYNC */
+ if (flags & O_APPEND) {
+ ret |= SMB_O_APPEND;
+ }
+#if defined(O_DIRECT)
+ if (flags & O_DIRECT) {
+ ret |= SMB_O_DIRECT;
+ }
+#endif
+#if defined(O_DIRECTORY)
+ if (flags & O_DIRECTORY) {
+ ret &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);
+ ret |= SMB_O_DIRECTORY;
+ }
+#endif
+ return ret;
+}
+
+/****************************************************************************
+ Open a file - POSIX semantics. Returns fnum. Doesn't request oplock.
+****************************************************************************/
+
+static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int flags, mode_t mode, bool is_dir)
+{
+ unsigned int data_len = 0;
+ unsigned int param_len = 0;
+ uint16 setup = TRANSACT2_SETPATHINFO;
+ char param[sizeof(pstring)+6];
+ char data[18];
+ char *rparam=NULL, *rdata=NULL;
+ char *p;
+ int fnum = -1;
+ uint32 wire_flags = open_flags_to_wire(flags);
+
+ memset(param, 0, sizeof(param));
+ SSVAL(param,0, SMB_POSIX_PATH_OPEN);
+ p = ¶m[6];
+
+ p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE);
+ param_len = PTR_DIFF(p, param);
+
+ if (is_dir) {
+ wire_flags &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);
+ wire_flags |= SMB_O_DIRECTORY;
+ }
+
+ p = data;
+ SIVAL(p,0,0); /* No oplock. */
+ SIVAL(p,4,wire_flags);
+ SIVAL(p,8,unix_perms_to_wire(mode));
+ SIVAL(p,12,0); /* Top bits of perms currently undefined. */
+ SSVAL(p,16,SMB_NO_INFO_LEVEL_RETURNED); /* No info level returned. */
+
+ data_len = 18;
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ (char *)&data, data_len, cli->max_xmit /* data, length, max */
+ )) {
+ return -1;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, ¶m_len,
+ &rdata, &data_len)) {
+ return -1;
+ }
+
+ fnum = SVAL(rdata,2);
+
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+
+ return fnum;
+}
+
+/****************************************************************************
+ open - POSIX semantics.
+****************************************************************************/
+
+int cli_posix_open(struct cli_state *cli, const char *fname, int flags, mode_t mode)
+{
+ return cli_posix_open_internal(cli, fname, flags, mode, False);
+}
+
+/****************************************************************************
+ mkdir - POSIX semantics.
+****************************************************************************/
+
+int cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode)
+{
+ return (cli_posix_open_internal(cli, fname, O_CREAT, mode, True) == -1) ? -1 : 0;
+}
+
+/****************************************************************************
+ unlink or rmdir - POSIX semantics.
+****************************************************************************/
+
+static bool cli_posix_unlink_internal(struct cli_state *cli, const char *fname, bool is_dir)
+{
+ unsigned int data_len = 0;
+ unsigned int param_len = 0;
+ uint16 setup = TRANSACT2_SETPATHINFO;
+ char param[sizeof(pstring)+6];
+ char data[2];
+ char *rparam=NULL, *rdata=NULL;
+ char *p;
+
+ memset(param, 0, sizeof(param));
+ SSVAL(param,0, SMB_POSIX_PATH_UNLINK);
+ p = ¶m[6];
+
+ p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE);
+ param_len = PTR_DIFF(p, param);
+
+ SSVAL(data, 0, is_dir ? SMB_POSIX_UNLINK_DIRECTORY_TARGET :
+ SMB_POSIX_UNLINK_FILE_TARGET);
+ data_len = 2;
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ (char *)&data, data_len, cli->max_xmit /* data, length, max */
+ )) {
+ return False;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, ¶m_len,
+ &rdata, &data_len)) {
+ return False;
+ }
+
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+
+ return True;
+}
+
+/****************************************************************************
+ unlink - POSIX semantics.
+****************************************************************************/
+
+bool cli_posix_unlink(struct cli_state *cli, const char *fname)
+{
+ return cli_posix_unlink_internal(cli, fname, False);
+}
+
+/****************************************************************************
+ rmdir - POSIX semantics.
+****************************************************************************/
+
+int cli_posix_rmdir(struct cli_state *cli, const char *fname)
+{
+ return cli_posix_unlink_internal(cli, fname, True);
+}