r6303: Setting up for 3.0.15pre1
[Samba.git] / source / smbwrapper / smbw_stat.c
blob6effc9a71bcfa85f2bc0fbf90673b296690c4991
1 /*
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.
21 #include "includes.h"
23 extern int smbw_busy;
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)
30 st->st_mode = 0;
32 if (IS_DOS_DIR(mode)) {
33 st->st_mode = SMBW_DIR_MODE;
34 } else {
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;
43 st->st_size = size;
44 #ifdef HAVE_STAT_ST_BLKSIZE
45 st->st_blksize = 512;
46 #endif
47 #ifdef HAVE_STAT_ST_BLOCKS
48 st->st_blocks = (size+511)/512;
49 #endif
50 st->st_uid = getuid();
51 st->st_gid = getgid();
52 if (IS_DOS_DIR(mode)) {
53 st->st_nlink = 2;
54 } else {
55 st->st_nlink = 1;
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,
70 SMB_INO_T *ino)
72 time_t c_a_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
80 SMB_OFF_T fullsize;
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;
88 return True;
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;
100 return True;
102 return False;
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) {
114 printjob = *job;
118 /*****************************************************
119 stat a printjob
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);
131 if (size) {
132 *size = printjob.size;
134 if (m_time) {
135 *m_time = printjob.t;
137 return printjob.id;
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;
148 SMB_OFF_T size;
149 uint16 mode;
150 SMB_INO_T ino = 0;
152 smbw_busy++;
154 ZERO_STRUCTP(st);
156 file = smbw_file(fd);
157 if (!file) {
158 int ret = smbw_dir_fstat(fd, st);
159 smbw_busy--;
160 return ret;
163 if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd,
164 &mode, &size, &c_time, &a_time, &m_time, NULL,
165 &ino) &&
166 !cli_getattrE(&file->srv->cli, file->f->cli_fd,
167 &mode, &size, &c_time, &a_time, &m_time)) {
168 errno = EINVAL;
169 smbw_busy--;
170 return -1;
173 st->st_ino = ino;
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;
182 smbw_busy--;
183 return 0;
187 /*****************************************************
188 a wrapper for stat()
189 *******************************************************/
190 int smbw_stat(const char *fname, struct stat *st)
192 struct smbw_server *srv;
193 fstring server, share;
194 pstring path;
195 time_t m_time=0, a_time=0, c_time=0;
196 size_t size=0;
197 uint16 mode=0;
198 SMB_INO_T ino = 0;
199 int result = 0;
201 ZERO_STRUCTP(st);
203 if (!fname) {
204 errno = EINVAL;
205 return -1;
208 DEBUG(4,("stat(%s)\n", fname));
210 smbw_init();
212 smbw_busy++;
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);
219 if (!srv) {
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);
228 goto done;
231 /* smbw_server sets errno */
232 result = -1;
233 goto done;
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;
243 } else {
244 mode = aRONLY;
245 smbw_stat_printjob(srv, path, &size, &m_time);
246 c_time = a_time = m_time;
248 } else {
249 if (!smbw_getatr(srv, path,
250 &mode, &size, &c_time, &a_time, &m_time,
251 &ino)) {
252 errno = smbw_errno(&srv->cli);
253 result = -1;
254 goto done;
258 st->st_ino = ino;
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;
267 done:
268 smbw_busy--;
269 return result;