/*
- Unix SMB/Netbios implementation.
- Version 2.0
+ Unix SMB/CIFS implementation.
SMB wrapper stat functions
Copyright (C) Andrew Tridgell 1998
*/
#include "includes.h"
-#include "wrapper.h"
-
-extern int DEBUGLEVEL;
extern int smbw_busy;
-
/*****************************************************
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)) {
st->st_mode = SMBW_DIR_MODE;
st->st_mode = SMBW_FILE_MODE;
}
+ if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR;
+ if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP;
+ if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH;
+ if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR;
+
st->st_size = size;
st->st_blksize = 512;
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);
+ }
}
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)
+ uint16 *mode, size_t *size,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ SMB_INO_T *ino)
{
- DEBUG(5,("sending qpathinfo\n"));
-
- if (cli_qpathinfo(&srv->cli, path, c_time, a_time, m_time,
- size, mode)) return True;
+ DEBUG(4,("sending qpathinfo\n"));
- DEBUG(5,("qpathinfo OK\n"));
+ if (!srv->no_pathinfo2 &&
+ cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL,
+ 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;
if (cli_getatr(&srv->cli, path, mode, size, m_time)) {
a_time = c_time = m_time;
+ srv->no_pathinfo2 = True;
return True;
}
return False;
}
+
+static struct print_job_info printjob;
+
+/*****************************************************
+gather info from a printjob listing
+*******************************************************/
+static void smbw_printjob_stat(struct print_job_info *job)
+{
+ if (strcmp(job->name, printjob.name) == 0) {
+ printjob = *job;
+ }
+}
+
+/*****************************************************
+stat a printjob
+*******************************************************/
+int smbw_stat_printjob(struct smbw_server *srv,char *path,
+ size_t *size, time_t *m_time)
+{
+ if (path[0] == '\\') path++;
+
+ ZERO_STRUCT(printjob);
+
+ fstrcpy(printjob.name, path);
+ cli_print_queue(&srv->cli, smbw_printjob_stat);
+
+ if (size) {
+ *size = printjob.size;
+ }
+ if (m_time) {
+ *m_time = printjob.t;
+ }
+ return printjob.id;
+}
+
+
/*****************************************************
a wrapper for fstat()
*******************************************************/
{
struct smbw_file *file;
time_t c_time, a_time, m_time;
- uint32 size;
- int mode;
-
- DEBUG(4,("%s\n", __FUNCTION__));
+ size_t size;
+ uint16 mode;
+ SMB_INO_T ino = 0;
smbw_busy++;
+ ZERO_STRUCTP(st);
+
file = smbw_file(fd);
if (!file) {
int ret = smbw_dir_fstat(fd, st);
return ret;
}
- if (!cli_qfileinfo(&file->srv->cli, file->cli_fd,
- &mode, &size, &c_time, &a_time, &m_time) &&
- !cli_getattrE(&file->srv->cli, file->cli_fd,
+ if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd,
+ &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;
smbw_busy--;
return -1;
}
- smbw_setup_stat(st, file->fname, size, mode);
+ st->st_ino = ino;
+
+ smbw_setup_stat(st, file->f->fname, size, mode);
st->st_atime = a_time;
st->st_ctime = c_time;
st->st_mtime = m_time;
st->st_dev = file->srv->dev;
- DEBUG(4,("%s - OK\n", __FUNCTION__));
-
smbw_busy--;
return 0;
}
pstring path;
time_t m_time=0, a_time=0, c_time=0;
size_t size=0;
- uint32 mode=0;
+ uint16 mode=0;
+ SMB_INO_T ino = 0;
+ int result = 0;
- DEBUG(4,("%s (%s)\n", __FUNCTION__, fname));
+ ZERO_STRUCTP(st);
if (!fname) {
errno = EINVAL;
return -1;
}
+ DEBUG(4,("stat(%s)\n", fname));
+
smbw_init();
smbw_busy++;
/* get a connection to the server */
srv = smbw_server(server, share);
if (!srv) {
+
+ /* For shares we aren't allowed to connect to, or no master
+ browser found, return an empty directory */
+
+ if ((server[0] && share[0] && !path[0] && errno == EACCES) ||
+ (!path[0] && errno == ENOENT)) {
+ mode = aDIR | aRONLY;
+ smbw_setup_stat(st, path, size, mode);
+ goto done;
+ }
+
/* smbw_server sets errno */
- goto failed;
+ result = -1;
+ goto done;
}
- if (strcmp(share,"IPC$") == 0) {
+ DEBUG(4,("smbw_stat\n"));
+
+ if (strncmp(srv->cli.dev,"IPC",3) == 0) {
mode = aDIR | aRONLY;
+ } else if (strncmp(srv->cli.dev,"LPT",3) == 0) {
+ if (strcmp(path,"\\") == 0) {
+ mode = aDIR | aRONLY;
+ } else {
+ mode = aRONLY;
+ smbw_stat_printjob(srv, path, &size, &m_time);
+ c_time = a_time = m_time;
+ }
} 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;
+ result = -1;
+ goto done;
}
}
+ st->st_ino = ino;
+
smbw_setup_stat(st, path, size, mode);
- st->st_atime = time(NULL);
- st->st_ctime = m_time;
+ st->st_atime = a_time;
+ st->st_ctime = c_time;
st->st_mtime = m_time;
st->st_dev = srv->dev;
+ done:
smbw_busy--;
- return 0;
-
- failed:
- smbw_busy--;
- return -1;
+ return result;
}
-
-