Removed version number from file header.
[samba.git] / source / smbwrapper / smbw_stat.c
index d9e2aa250c7c9149f001cef6bb50c89eb11ee1fe..6c476a8a67b0070d74f912fc9f1e857a4c3b191f 100644 (file)
@@ -1,6 +1,5 @@
 /* 
-   Unix SMB/Netbios implementation.
-   Version 2.0
+   Unix SMB/CIFS implementation.
    SMB wrapper stat functions
    Copyright (C) Andrew Tridgell 1998
    
 
 #include "includes.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)) {
@@ -51,7 +45,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);
+       }
 }
 
 
@@ -60,14 +61,15 @@ 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 (!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;
@@ -124,10 +126,13 @@ int smbw_fstat(int fd, struct stat *st)
        struct smbw_file *file;
        time_t c_time, a_time, m_time;
        size_t size;
-       uint32 mode;
+       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);
@@ -136,7 +141,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;
@@ -144,6 +150,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;
@@ -166,13 +174,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;
+
+       ZERO_STRUCTP(st);
 
        if (!fname) {
                errno = EINVAL;
                return -1;
        }
 
+       DEBUG(4,("stat(%s)\n", fname));
+
        smbw_init();
 
        smbw_busy++;
@@ -183,10 +197,24 @@ 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;
        }
 
+       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) {
@@ -199,12 +227,16 @@ 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;
+                       result = -1;
+                       goto done;
                }
        }
 
+       st->st_ino = ino;
+
        smbw_setup_stat(st, path, size, mode);
 
        st->st_atime = a_time;
@@ -212,12 +244,7 @@ int smbw_stat(const char *fname, struct stat *st)
        st->st_mtime = m_time;
        st->st_dev = srv->dev;
 
+ done:
        smbw_busy--;
-       return 0;
-
- failed:
-       smbw_busy--;
-       return -1;
+       return result;
 }
-
-