2 Unix SMB/CIFS implementation.
3 SMB wrapper stat functions
4 Copyright (C) Andrew Tridgell 1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /*****************************************************
26 setup basic info in a stat structure
27 *******************************************************/
28 void smbw_setup_stat(struct stat
*st
, char *fname
, size_t size
, int mode
)
32 if (IS_DOS_DIR(mode
)) {
33 st
->st_mode
= SMBW_DIR_MODE
;
35 st
->st_mode
= SMBW_FILE_MODE
;
38 if (IS_DOS_ARCHIVE(mode
)) st
->st_mode
|= S_IXUSR
;
39 if (IS_DOS_SYSTEM(mode
)) st
->st_mode
|= S_IXGRP
;
40 if (IS_DOS_HIDDEN(mode
)) st
->st_mode
|= S_IXOTH
;
41 if (!IS_DOS_READONLY(mode
)) st
->st_mode
|= S_IWUSR
;
44 #ifdef HAVE_STAT_ST_BLKSIZE
47 #ifdef HAVE_STAT_ST_BLOCKS
48 st
->st_blocks
= (size
+511)/512;
50 st
->st_uid
= getuid();
51 st
->st_gid
= getgid();
52 if (IS_DOS_DIR(mode
)) {
57 if (st
->st_ino
== 0) {
58 st
->st_ino
= smbw_inode(fname
);
63 /*****************************************************
64 try to do a QPATHINFO and if that fails then do a getatr
65 this is needed because win95 sometimes refuses the qpathinfo
66 *******************************************************/
67 BOOL
smbw_getatr(struct smbw_server
*srv
, char *path
,
68 uint16
*mode
, size_t *size
,
69 time_t *c_time
, time_t *a_time
, time_t *m_time
,
74 * "size" (size_t) is only 32 bits. Rather than change the interface
75 * in this code as we change cli_qpathinfo2() and cli_getatr() to
76 * support 64-bit file sizes, we'll use a temporary variable and
77 * maintain the interface size_t. At some point, someone may want to
78 * change the interface as well. djl
82 DEBUG(4,("sending qpathinfo\n"));
84 if (!srv
->no_pathinfo2
&&
85 cli_qpathinfo2(&srv
->cli
, path
, c_time
, a_time
, m_time
, NULL
,
86 &fullsize
, mode
, ino
)) {
87 if (size
!= NULL
) *size
= (size_t) fullsize
;
91 /* if this is NT then don't bother with the getatr */
92 if (srv
->cli
.capabilities
& CAP_NT_SMBS
) return False
;
94 if (cli_getatr(&srv
->cli
, path
, mode
, &fullsize
, &c_a_m_time
)) {
95 if (a_time
!= NULL
) *a_time
= c_a_m_time
;
96 if (c_time
!= NULL
) *a_time
= c_a_m_time
;
97 if (m_time
!= NULL
) *a_time
= c_a_m_time
;
98 if (size
!= NULL
) *size
= (size_t) fullsize
;
99 srv
->no_pathinfo2
= True
;
106 static struct print_job_info printjob
;
108 /*****************************************************
109 gather info from a printjob listing
110 *******************************************************/
111 static void smbw_printjob_stat(struct print_job_info
*job
)
113 if (strcmp(job
->name
, printjob
.name
) == 0) {
118 /*****************************************************
120 *******************************************************/
121 int smbw_stat_printjob(struct smbw_server
*srv
,char *path
,
122 size_t *size
, time_t *m_time
)
124 if (path
[0] == '\\') path
++;
126 ZERO_STRUCT(printjob
);
128 fstrcpy(printjob
.name
, path
);
129 cli_print_queue(&srv
->cli
, smbw_printjob_stat
);
132 *size
= printjob
.size
;
135 *m_time
= printjob
.t
;
141 /*****************************************************
142 a wrapper for fstat()
143 *******************************************************/
144 int smbw_fstat(int fd
, struct stat
*st
)
146 struct smbw_file
*file
;
147 time_t c_time
, a_time
, m_time
;
156 file
= smbw_file(fd
);
158 int ret
= smbw_dir_fstat(fd
, st
);
163 if (!cli_qfileinfo(&file
->srv
->cli
, file
->f
->cli_fd
,
164 &mode
, &size
, &c_time
, &a_time
, &m_time
, NULL
,
166 !cli_getattrE(&file
->srv
->cli
, file
->f
->cli_fd
,
167 &mode
, &size
, &c_time
, &a_time
, &m_time
)) {
175 smbw_setup_stat(st
, file
->f
->fname
, size
, mode
);
177 st
->st_atime
= a_time
;
178 st
->st_ctime
= c_time
;
179 st
->st_mtime
= m_time
;
180 st
->st_dev
= file
->srv
->dev
;
187 /*****************************************************
189 *******************************************************/
190 int smbw_stat(const char *fname
, struct stat
*st
)
192 struct smbw_server
*srv
;
193 fstring server
, share
;
195 time_t m_time
=0, a_time
=0, c_time
=0;
208 DEBUG(4,("stat(%s)\n", fname
));
214 /* work out what server they are after */
215 smbw_parse_path(fname
, server
, share
, path
);
217 /* get a connection to the server */
218 srv
= smbw_server(server
, share
);
221 /* For shares we aren't allowed to connect to, or no master
222 browser found, return an empty directory */
224 if ((server
[0] && share
[0] && !path
[0] && errno
== EACCES
) ||
225 (!path
[0] && errno
== ENOENT
)) {
226 mode
= aDIR
| aRONLY
;
227 smbw_setup_stat(st
, path
, size
, mode
);
231 /* smbw_server sets errno */
236 DEBUG(4,("smbw_stat\n"));
238 if (strncmp(srv
->cli
.dev
,"IPC",3) == 0) {
239 mode
= aDIR
| aRONLY
;
240 } else if (strncmp(srv
->cli
.dev
,"LPT",3) == 0) {
241 if (strcmp(path
,"\\") == 0) {
242 mode
= aDIR
| aRONLY
;
245 smbw_stat_printjob(srv
, path
, &size
, &m_time
);
246 c_time
= a_time
= m_time
;
249 if (!smbw_getatr(srv
, path
,
250 &mode
, &size
, &c_time
, &a_time
, &m_time
,
252 errno
= smbw_errno(&srv
->cli
);
260 smbw_setup_stat(st
, path
, size
, mode
);
262 st
->st_atime
= a_time
;
263 st
->st_ctime
= c_time
;
264 st
->st_mtime
= m_time
;
265 st
->st_dev
= srv
->dev
;