summaryrefslogtreecommitdiff
path: root/source3/libsmb/clifile.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2004-09-26 06:27:54 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:52:48 -0500
commiteb9a09954b97f78768f07cbb921c05b06321d5ec (patch)
treee16035716a5fbae35984a8478a74e3a2a4780f5c /source3/libsmb/clifile.c
parent761dfdabfa306dd8044761b294c5a5f957f5119e (diff)
downloadsamba-eb9a09954b97f78768f07cbb921c05b06321d5ec.tar.gz
samba-eb9a09954b97f78768f07cbb921c05b06321d5ec.tar.bz2
samba-eb9a09954b97f78768f07cbb921c05b06321d5ec.zip
r2651: Added 'stat' command to smbclient to exercise the UNIX_FILE_BASIC
info level. Outputs data on the file in the same format the the stat command in Linux. Should be useful to people wanting to learn how to parse the UNIX extension output. Yes I will add the docs later :-). Jeremy. (This used to be commit b25cc596417d29815814c3968ac2627bf59ffc0b)
Diffstat (limited to 'source3/libsmb/clifile.c')
-rw-r--r--source3/libsmb/clifile.c131
1 files changed, 130 insertions, 1 deletions
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index ff0edc6bb4..d302206949 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -77,7 +77,7 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *oldname, const
Map standard UNIX permissions onto wire representations.
****************************************************************************/
-uint32 unix_perms_to_wire(mode_t perms)
+uint32 unix_perms_to_wire(mode_t perms)
{
unsigned int ret = 0;
@@ -103,6 +103,135 @@ uint32 unix_perms_to_wire(mode_t perms)
}
/****************************************************************************
+ Map wire permissions to standard UNIX.
+****************************************************************************/
+
+mode_t wire_perms_to_unix(uint32 perms)
+{
+ mode_t ret = (mode_t)0;
+
+ ret |= ((perms & UNIX_X_OTH) ? S_IXOTH : 0);
+ ret |= ((perms & UNIX_W_OTH) ? S_IWOTH : 0);
+ ret |= ((perms & UNIX_R_OTH) ? S_IROTH : 0);
+ ret |= ((perms & UNIX_X_GRP) ? S_IXGRP : 0);
+ ret |= ((perms & UNIX_W_GRP) ? S_IWGRP : 0);
+ ret |= ((perms & UNIX_R_GRP) ? S_IRGRP : 0);
+ ret |= ((perms & UNIX_X_USR) ? S_IXUSR : 0);
+ ret |= ((perms & UNIX_W_USR) ? S_IWUSR : 0);
+ ret |= ((perms & UNIX_R_USR) ? S_IRUSR : 0);
+#ifdef S_ISVTX
+ ret |= ((perms & UNIX_STICKY) ? S_ISVTX : 0);
+#endif
+#ifdef S_ISGID
+ ret |= ((perms & UNIX_SET_GID) ? S_ISGID : 0);
+#endif
+#ifdef S_ISUID
+ ret |= ((perms & UNIX_SET_UID) ? S_ISUID : 0);
+#endif
+ return ret;
+}
+
+/****************************************************************************
+ Return the file type from the wire filetype for UNIX extensions.
+****************************************************************************/
+
+static mode_t unix_filetype_from_wire(uint32 wire_type)
+{
+ switch (wire_type) {
+ case UNIX_TYPE_FILE:
+ return S_IFREG;
+ case UNIX_TYPE_DIR:
+ return S_IFDIR;
+#ifdef S_IFLNK
+ case UNIX_TYPE_SYMLINK:
+ return S_IFLNK;
+#endif
+#ifdef S_IFCHR
+ case UNIX_TYPE_CHARDEV:
+ return S_IFCHR;
+#endif
+#ifdef S_IFBLK
+ case UNIX_TYPE_BLKDEV:
+ return S_IFBLK;
+#endif
+#ifdef S_IFIFO
+ case UNIX_TYPE_FIFO:
+ return S_IFIFO;
+#endif
+#ifdef S_IFSOCK
+ case UNIX_TYPE_SOCKET:
+ return S_IFSOCK;
+#endif
+ default:
+ return (mode_t)0;
+ }
+}
+
+/****************************************************************************
+ Stat a file (UNIX extensions).
+****************************************************************************/
+
+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;
+ uint16 setup = TRANSACT2_QPATHINFO;
+ char param[sizeof(pstring)+6];
+ char *rparam=NULL, *rdata=NULL;
+ char *p;
+
+ ZERO_STRUCTP(sbuf);
+
+ p = param;
+ memset(p, 0, 6);
+ SSVAL(p, 0, SMB_QUERY_FILE_UNIX_BASIC);
+ p += 6;
+ p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE);
+ param_len = PTR_DIFF(p, param);
+
+ 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 */
+ NULL, 0, cli->max_xmit /* data, length, max */
+ )) {
+ return False;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, &param_len,
+ &rdata, &data_len)) {
+ return False;
+ }
+
+ sbuf->st_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */
+ sbuf->st_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */
+ sbuf->st_blocks /= STAT_ST_BLOCKSIZE;
+ sbuf->st_ctime = interpret_long_date(rdata + 16); /* time of last change */
+ sbuf->st_atime = interpret_long_date(rdata + 24); /* time of last access */
+ sbuf->st_mtime = interpret_long_date(rdata + 32); /* time of last modification */
+ sbuf->st_uid = IVAL(rdata,40); /* user ID of owner */
+ sbuf->st_gid = IVAL(rdata,48); /* group ID of owner */
+ sbuf->st_mode |= unix_filetype_from_wire(IVAL(rdata, 56));
+#if defined(HAVE_MAKEDEV)
+ {
+ uint32 dev_major = IVAL(rdata,60);
+ uint32 dev_minor = IVAL(rdata,68);
+ sbuf->st_rdev = makedev(dev_major, dev_minor);
+ }
+#endif
+ sbuf->st_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(rdata,76); /* inode */
+ sbuf->st_mode |= wire_perms_to_unix(IVAL(rdata,84)); /* protection */
+ sbuf->st_nlink = IVAL(rdata,92); /* number of hard links */
+
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+
+ return True;
+}
+
+/****************************************************************************
Symlink a file (UNIX extensions).
****************************************************************************/