summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/client.h18
-rw-r--r--source3/include/includes.h6
-rw-r--r--source3/include/proto.h9
-rw-r--r--source3/libsmb/clientgen.c27
-rw-r--r--source3/smbd/trans2.c1
-rw-r--r--source3/smbwrapper/smbw.c4
-rw-r--r--source3/smbwrapper/smbw_dir.c12
-rw-r--r--source3/smbwrapper/smbw_stat.c34
-rw-r--r--source3/utils/torture.c9
9 files changed, 85 insertions, 35 deletions
diff --git a/source3/include/client.h b/source3/include/client.h
index a393ee25a8..1caf78bf0e 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -35,15 +35,15 @@
typedef struct file_info
{
- SMB_OFF_T size;
- int mode;
- uid_t uid;
- gid_t gid;
- /* these times are normally kept in GMT */
- time_t mtime;
- time_t atime;
- time_t ctime;
- pstring name;
+ SMB_OFF_T size;
+ int mode;
+ uid_t uid;
+ gid_t gid;
+ /* these times are normally kept in GMT */
+ time_t mtime;
+ time_t atime;
+ time_t ctime;
+ pstring name;
} file_info;
struct print_job_info
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 59d43d8a36..9d5ee28358 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -355,6 +355,12 @@
# endif
#endif
+#ifdef LARGE_SMB_INO_T
+#define SINO_T(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32))
+#else
+#define SINO_T(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0))
+#endif
+
#ifndef SMB_OFF_T
# ifdef HAVE_OFF64_T
# define SMB_OFF_T off64_t
diff --git a/source3/include/proto.h b/source3/include/proto.h
index bc9b7389db..1b81bb2038 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -407,10 +407,12 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
size_t *size, uint32 *mode);
BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
time_t *c_time, time_t *a_time, time_t *m_time,
- time_t *w_time, size_t *size, uint32 *mode);
+ time_t *w_time, size_t *size, uint32 *mode,
+ SMB_INO_T *ino);
BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
uint32 *mode, size_t *size,
- time_t *c_time, time_t *a_time, time_t *m_time);
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ time_t *w_time, SMB_INO_T *ino);
int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info *));
BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_password,
char *old_password);
@@ -2466,7 +2468,8 @@ off_t smbw_telldir(DIR *dirp);
void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode);
BOOL smbw_getatr(struct smbw_server *srv, char *path,
uint32 *mode, size_t *size,
- time_t *c_time, time_t *a_time, time_t *m_time);
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ SMB_INO_T *ino);
int smbw_stat_printjob(struct smbw_server *srv,char *path,
size_t *size, time_t *m_time);
int smbw_fstat(int fd, struct stat *st);
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index d3233f59fd..6a0818d177 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -1669,7 +1669,8 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
****************************************************************************/
BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
time_t *c_time, time_t *a_time, time_t *m_time,
- time_t *w_time, size_t *size, uint32 *mode)
+ time_t *w_time, size_t *size, uint32 *mode,
+ SMB_INO_T *ino)
{
int data_len = 0;
int param_len = 0;
@@ -1721,6 +1722,9 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
if (mode) {
*mode = IVAL(rdata, 32);
}
+ if (ino) {
+ *ino = IVAL(rdata, 64);
+ }
if (rdata) free(rdata);
if (rparam) free(rparam);
@@ -1733,7 +1737,8 @@ send a qfileinfo call
****************************************************************************/
BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
uint32 *mode, size_t *size,
- time_t *c_time, time_t *a_time, time_t *m_time)
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ time_t *w_time, SMB_INO_T *ino)
{
int data_len = 0;
int param_len = 0;
@@ -1745,7 +1750,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
memset(param, 0, param_len);
SSVAL(param, 0, fnum);
- SSVAL(param, 2, SMB_INFO_STANDARD);
+ SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO);
if (!cli_send_trans(cli, SMBtrans2,
NULL, 0, /* name, length */
@@ -1768,19 +1773,25 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
}
if (c_time) {
- *c_time = make_unix_date2(rdata+0);
+ *c_time = interpret_long_date(rdata+0) - cli->serverzone;
}
if (a_time) {
- *a_time = make_unix_date2(rdata+4);
+ *a_time = interpret_long_date(rdata+8) - cli->serverzone;
}
if (m_time) {
- *m_time = make_unix_date2(rdata+8);
+ *m_time = interpret_long_date(rdata+16) - cli->serverzone;
+ }
+ if (w_time) {
+ *w_time = interpret_long_date(rdata+24) - cli->serverzone;
}
if (size) {
- *size = IVAL(rdata, 12);
+ *size = IVAL(rdata, 40);
}
if (mode) {
- *mode = SVAL(rdata,l1_attrFile);
+ *mode = IVAL(rdata, 32);
+ }
+ if (ino) {
+ *ino = IVAL(rdata, 64);
}
if (rdata) free(rdata);
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 44e9d499e2..f0bd458798 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1432,6 +1432,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
CVAL(pdata,20) = 0;
CVAL(pdata,21) = (mode&aDIR)?1:0;
pdata += 24;
+ SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
pdata += 8; /* index number */
pdata += 4; /* EA info */
if (mode & aRONLY)
diff --git a/source3/smbwrapper/smbw.c b/source3/smbwrapper/smbw.c
index 622581b7a6..eb156ce0ef 100644
--- a/source3/smbwrapper/smbw.c
+++ b/source3/smbwrapper/smbw.c
@@ -149,6 +149,7 @@ a crude inode number generator
*******************************************************/
ino_t smbw_inode(const char *name)
{
+ if (!*name) return 2;
return (ino_t)str_checksum(name);
}
@@ -1194,7 +1195,8 @@ off_t smbw_lseek(int fd, off_t offset, int whence)
break;
case SEEK_END:
if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd,
- NULL, &size, NULL, NULL, NULL) &&
+ NULL, &size, NULL, NULL, NULL,
+ NULL, NULL) &&
!cli_getattrE(&file->srv->cli, file->f->cli_fd,
NULL, &size, NULL, NULL, NULL)) {
errno = EINVAL;
diff --git a/source3/smbwrapper/smbw_dir.c b/source3/smbwrapper/smbw_dir.c
index d374d5f179..4d1e3cc179 100644
--- a/source3/smbwrapper/smbw_dir.c
+++ b/source3/smbwrapper/smbw_dir.c
@@ -202,21 +202,31 @@ int smbw_dir_open(const char *fname)
if ((p=strstr(srv->server_name,"#1D"))) {
DEBUG(4,("doing NetServerEnum\n"));
*p = 0;
+ smbw_server_add(".",0,"");
+ smbw_server_add("..",0,"");
cli_NetServerEnum(&srv->cli, srv->server_name, SV_TYPE_ALL,
smbw_server_add);
*p = '#';
} else if (strcmp(srv->cli.dev,"IPC") == 0) {
DEBUG(4,("doing NetShareEnum\n"));
+ smbw_share_add(".",0,"");
+ smbw_share_add("..",0,"");
if (cli_RNetShareEnum(&srv->cli, smbw_share_add) < 0) {
errno = smbw_errno(&srv->cli);
goto failed;
}
} else if (strncmp(srv->cli.dev,"LPT",3) == 0) {
+ smbw_share_add(".",0,"");
+ smbw_share_add("..",0,"");
if (cli_print_queue(&srv->cli, smbw_printjob_add) < 0) {
errno = smbw_errno(&srv->cli);
goto failed;
}
} else {
+ if (strcmp(path,"\\") == 0) {
+ smbw_share_add(".",0,"");
+ smbw_share_add("..",0,"");
+ }
if (cli_list(&srv->cli, mask, aHIDDEN|aSYSTEM|aDIR,
smbw_dir_add) < 0) {
errno = smbw_errno(&srv->cli);
@@ -396,7 +406,7 @@ int smbw_chdir(const char *name)
if (strncmp(srv->cli.dev,"IPC",3) &&
strncmp(srv->cli.dev,"LPT",3) &&
!smbw_getatr(srv, path,
- &mode, NULL, NULL, NULL, NULL)) {
+ &mode, NULL, NULL, NULL, NULL, NULL)) {
errno = smbw_errno(&srv->cli);
goto failed;
}
diff --git a/source3/smbwrapper/smbw_stat.c b/source3/smbwrapper/smbw_stat.c
index adf973667f..443c898eb5 100644
--- a/source3/smbwrapper/smbw_stat.c
+++ b/source3/smbwrapper/smbw_stat.c
@@ -31,8 +31,6 @@ setup basic info in a stat structure
*******************************************************/
void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode)
{
- ZERO_STRUCTP(st);
-
st->st_mode = 0;
if (IS_DOS_DIR(mode)) {
@@ -51,7 +49,14 @@ void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode)
st->st_blocks = (size+511)/512;
st->st_uid = getuid();
st->st_gid = getgid();
- st->st_ino = smbw_inode(fname);
+ if (IS_DOS_DIR(mode)) {
+ st->st_nlink = 2;
+ } else {
+ st->st_nlink = 1;
+ }
+ if (st->st_ino == 0) {
+ st->st_ino = smbw_inode(fname);
+ }
}
@@ -61,13 +66,14 @@ this is needed because win95 sometimes refuses the qpathinfo
*******************************************************/
BOOL smbw_getatr(struct smbw_server *srv, char *path,
uint32 *mode, size_t *size,
- time_t *c_time, time_t *a_time, time_t *m_time)
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ SMB_INO_T *ino)
{
DEBUG(4,("sending qpathinfo\n"));
if (!srv->no_pathinfo2 &&
cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL,
- size, mode)) return True;
+ size, mode, ino)) return True;
/* if this is NT then don't bother with the getatr */
if (srv->cli.capabilities & CAP_NT_SMBS) return False;
@@ -125,9 +131,12 @@ int smbw_fstat(int fd, struct stat *st)
time_t c_time, a_time, m_time;
size_t size;
uint32 mode;
+ SMB_INO_T ino = 0;
smbw_busy++;
+ ZERO_STRUCTP(st);
+
file = smbw_file(fd);
if (!file) {
int ret = smbw_dir_fstat(fd, st);
@@ -135,10 +144,9 @@ int smbw_fstat(int fd, struct stat *st)
return ret;
}
- DEBUG(4,("sending qfileinfo\n"));
-
if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd,
- &mode, &size, &c_time, &a_time, &m_time) &&
+ &mode, &size, &c_time, &a_time, &m_time, NULL,
+ &ino) &&
!cli_getattrE(&file->srv->cli, file->f->cli_fd,
&mode, &size, &c_time, &a_time, &m_time)) {
errno = EINVAL;
@@ -146,6 +154,8 @@ int smbw_fstat(int fd, struct stat *st)
return -1;
}
+ st->st_ino = ino;
+
smbw_setup_stat(st, file->f->fname, size, mode);
st->st_atime = a_time;
@@ -169,6 +179,9 @@ int smbw_stat(const char *fname, struct stat *st)
time_t m_time=0, a_time=0, c_time=0;
size_t size=0;
uint32 mode=0;
+ SMB_INO_T ino = 0;
+
+ ZERO_STRUCTP(st);
if (!fname) {
errno = EINVAL;
@@ -205,12 +218,15 @@ int smbw_stat(const char *fname, struct stat *st)
}
} else {
if (!smbw_getatr(srv, path,
- &mode, &size, &c_time, &a_time, &m_time)) {
+ &mode, &size, &c_time, &a_time, &m_time,
+ &ino)) {
errno = smbw_errno(&srv->cli);
goto failed;
}
}
+ st->st_ino = ino;
+
smbw_setup_stat(st, path, size, mode);
st->st_atime = a_time;
diff --git a/source3/utils/torture.c b/source3/utils/torture.c
index 3ef4d5133f..81fa33fc75 100644
--- a/source3/utils/torture.c
+++ b/source3/utils/torture.c
@@ -864,7 +864,8 @@ static void run_trans2test(void)
cli_unlink(&cli, fname);
fnum = cli_open(&cli, fname,
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
- if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time)) {
+ if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
+ NULL, NULL)) {
printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
}
cli_close(&cli, fnum);
@@ -900,7 +901,7 @@ static void run_trans2test(void)
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
cli_close(&cli, fnum);
if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
- &w_time, &size, NULL)) {
+ &w_time, &size, NULL, NULL)) {
printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
} else {
if (w_time < 60*60*24*2) {
@@ -919,7 +920,7 @@ static void run_trans2test(void)
}
sleep(3);
if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
- &w_time, &size, NULL)) {
+ &w_time, &size, NULL, NULL)) {
printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
}
@@ -928,7 +929,7 @@ static void run_trans2test(void)
cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
cli_close(&cli, fnum);
if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
- &w_time, &size, NULL)) {
+ &w_time, &size, NULL, NULL)) {
printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
} else {
if (m_time2 == m_time)