From fb556e14f3b47d5a1f465589084e8b30d84af8ca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 24 Oct 1998 08:08:05 +0000 Subject: volker was concerned about unique inode numbers and smbsh. This set of changes uses the unique index number from a SMB_QUERY_FILE_ALL_INFO to try to provide inode numbers. If it is 0 then use the hash of the filename as before. (This used to be commit 2565ccf9de9d5e80fdb5bcadbc7130faba386d95) --- source3/include/client.h | 18 +++++++++--------- source3/include/includes.h | 6 ++++++ source3/include/proto.h | 9 ++++++--- source3/libsmb/clientgen.c | 27 +++++++++++++++++++-------- source3/smbd/trans2.c | 1 + source3/smbwrapper/smbw.c | 4 +++- source3/smbwrapper/smbw_dir.c | 12 +++++++++++- source3/smbwrapper/smbw_stat.c | 34 +++++++++++++++++++++++++--------- source3/utils/torture.c | 9 +++++---- 9 files changed, 85 insertions(+), 35 deletions(-) (limited to 'source3') 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) -- cgit