Fix for no master browser present.
[tprouty/samba.git] / source / smbwrapper / smbw_stat.c
index ae8671c591fb87ac88ee27ad55922c01c53b1e3b..74bf83d0dc80802f968eca457d001f6fde85da67 100644 (file)
@@ -20,7 +20,6 @@
 */
 
 #include "includes.h"
-#include "wrapper.h"
 
 extern int DEBUGLEVEL;
 
@@ -32,7 +31,7 @@ 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;
@@ -40,12 +39,24 @@ void smbw_setup_stat(struct stat *st, char *fname, size_t size, int 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);
+       }
 }
 
 
@@ -54,26 +65,63 @@ try to do a QPATHINFO and if that fails then do a getatr
 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"));
+       DEBUG(4,("sending qpathinfo\n"));
 
-       if (cli_qpathinfo(&srv->cli, path, c_time, a_time, m_time,
-                         size, mode)) return True;
-
-       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()
 *******************************************************/
@@ -81,13 +129,14 @@ int smbw_fstat(int fd, struct stat *st)
 {
        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);
@@ -96,7 +145,8 @@ int smbw_fstat(int fd, struct stat *st)
        }
 
        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;
@@ -104,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;
@@ -111,8 +163,6 @@ int smbw_fstat(int fd, struct stat *st)
        st->st_mtime = m_time;
        st->st_dev = file->srv->dev;
 
-       DEBUG(4,("%s - OK\n", __FUNCTION__));
-
        smbw_busy--;
        return 0;
 }
@@ -128,15 +178,19 @@ int smbw_stat(const char *fname, struct stat *st)
        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++;
@@ -147,33 +201,54 @@ int smbw_stat(const char *fname, struct stat *st)
        /* 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;
 }
-
-