Logo Search packages:      
Sourcecode: samba-doc-ja version File versions

smbw_stat.c

/* 
   Unix SMB/Netbios implementation.
   Version 2.0
   SMB wrapper stat functions
   Copyright (C) Andrew Tridgell 1998
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "includes.h"

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)
{
      st->st_mode = 0;

      if (IS_DOS_DIR(mode)) {
            st->st_mode = SMBW_DIR_MODE;
      } else {
            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();
      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);
      }
}


/***************************************************** 
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, 
             uint16 *mode, SMB_BIG_UINT *size, 
             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, 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,
                   SMB_BIG_UINT *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()
*******************************************************/
int smbw_fstat(int fd, struct stat *st)
{
      struct smbw_file *file;
      time_t c_time, a_time, m_time;
      SMB_BIG_UINT 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);
            smbw_busy--;
            return ret;
      }

      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;
      }

      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;

      smbw_busy--;
      return 0;
}


/***************************************************** 
a wrapper for stat()
*******************************************************/
int smbw_stat(const char *fname, struct stat *st)
{
      struct smbw_server *srv;
      fstring server, share;
      pstring path;
      time_t m_time=0, a_time=0, c_time=0;
      SMB_BIG_UINT size=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++;

      /* work out what server they are after */
      smbw_parse_path(fname, server, share, path);

      /* get a connection to the server */
      srv = smbw_server(server, share);
      if (!srv) {

            /* For shares we aren't allowed to connect to, return
               an empty directory */

            if (server[0] && share[0] && !path[0] && errno == EACCES) {
                  mode = aDIR | aRONLY;
                  smbw_setup_stat(st, path, size, mode);
                  goto done;
            }

            /* smbw_server sets errno */
            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) {
            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,
                         &ino)) {
                  errno = smbw_errno(&srv->cli);
                  result = -1;
                  goto done;
            }
      }

      st->st_ino = ino;

      smbw_setup_stat(st, path, size, mode);

      st->st_atime = a_time;
      st->st_ctime = c_time;
      st->st_mtime = m_time;
      st->st_dev = srv->dev;

 done:
      smbw_busy--;
      return result;
}

Generated by  Doxygen 1.6.0   Back to index