few edits
[Samba.git] / source / smbwrapper / smbw_stat.c
blobcf2d19cdf0919de8c9a42a4684627cd037fc8da3
1 /*
2 Unix SMB/Netbios implementation.
3 Version 2.0
4 SMB wrapper stat functions
5 Copyright (C) Andrew Tridgell 1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 extern int smbw_busy;
27 /*****************************************************
28 setup basic info in a stat structure
29 *******************************************************/
30 void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode)
32 st->st_mode = 0;
34 if (IS_DOS_DIR(mode)) {
35 st->st_mode = SMBW_DIR_MODE;
36 } else {
37 st->st_mode = SMBW_FILE_MODE;
40 if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR;
41 if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP;
42 if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH;
43 if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR;
45 st->st_size = size;
46 st->st_blksize = 512;
47 st->st_blocks = (size+511)/512;
48 st->st_uid = getuid();
49 st->st_gid = getgid();
50 if (IS_DOS_DIR(mode)) {
51 st->st_nlink = 2;
52 } else {
53 st->st_nlink = 1;
55 if (st->st_ino == 0) {
56 st->st_ino = smbw_inode(fname);
61 /*****************************************************
62 try to do a QPATHINFO and if that fails then do a getatr
63 this is needed because win95 sometimes refuses the qpathinfo
64 *******************************************************/
65 BOOL smbw_getatr(struct smbw_server *srv, char *path,
66 uint16 *mode, size_t *size,
67 time_t *c_time, time_t *a_time, time_t *m_time,
68 SMB_INO_T *ino)
70 DEBUG(4,("sending qpathinfo\n"));
72 if (!srv->no_pathinfo2 &&
73 cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL,
74 size, mode, ino)) return True;
76 /* if this is NT then don't bother with the getatr */
77 if (srv->cli.capabilities & CAP_NT_SMBS) return False;
79 if (cli_getatr(&srv->cli, path, mode, size, m_time)) {
80 a_time = c_time = m_time;
81 srv->no_pathinfo2 = True;
82 return True;
84 return False;
88 static struct print_job_info printjob;
90 /*****************************************************
91 gather info from a printjob listing
92 *******************************************************/
93 static void smbw_printjob_stat(struct print_job_info *job)
95 if (strcmp(job->name, printjob.name) == 0) {
96 printjob = *job;
100 /*****************************************************
101 stat a printjob
102 *******************************************************/
103 int smbw_stat_printjob(struct smbw_server *srv,char *path,
104 size_t *size, time_t *m_time)
106 if (path[0] == '\\') path++;
108 ZERO_STRUCT(printjob);
110 fstrcpy(printjob.name, path);
111 cli_print_queue(&srv->cli, smbw_printjob_stat);
113 if (size) {
114 *size = printjob.size;
116 if (m_time) {
117 *m_time = printjob.t;
119 return printjob.id;
123 /*****************************************************
124 a wrapper for fstat()
125 *******************************************************/
126 int smbw_fstat(int fd, struct stat *st)
128 struct smbw_file *file;
129 time_t c_time, a_time, m_time;
130 size_t size;
131 uint16 mode;
132 SMB_INO_T ino = 0;
134 smbw_busy++;
136 ZERO_STRUCTP(st);
138 file = smbw_file(fd);
139 if (!file) {
140 int ret = smbw_dir_fstat(fd, st);
141 smbw_busy--;
142 return ret;
145 if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd,
146 &mode, &size, &c_time, &a_time, &m_time, NULL,
147 &ino) &&
148 !cli_getattrE(&file->srv->cli, file->f->cli_fd,
149 &mode, &size, &c_time, &a_time, &m_time)) {
150 errno = EINVAL;
151 smbw_busy--;
152 return -1;
155 st->st_ino = ino;
157 smbw_setup_stat(st, file->f->fname, size, mode);
159 st->st_atime = a_time;
160 st->st_ctime = c_time;
161 st->st_mtime = m_time;
162 st->st_dev = file->srv->dev;
164 smbw_busy--;
165 return 0;
169 /*****************************************************
170 a wrapper for stat()
171 *******************************************************/
172 int smbw_stat(const char *fname, struct stat *st)
174 struct smbw_server *srv;
175 fstring server, share;
176 pstring path;
177 time_t m_time=0, a_time=0, c_time=0;
178 size_t size=0;
179 uint16 mode=0;
180 SMB_INO_T ino = 0;
181 int result = 0;
183 ZERO_STRUCTP(st);
185 if (!fname) {
186 errno = EINVAL;
187 return -1;
190 DEBUG(4,("stat(%s)\n", fname));
192 smbw_init();
194 smbw_busy++;
196 /* work out what server they are after */
197 smbw_parse_path(fname, server, share, path);
199 /* get a connection to the server */
200 srv = smbw_server(server, share);
201 if (!srv) {
203 /* For shares we aren't allowed to connect to, return
204 an empty directory */
206 if (server[0] && share[0] && !path[0] && errno == EACCES) {
207 mode = aDIR | aRONLY;
208 smbw_setup_stat(st, path, size, mode);
209 goto done;
212 /* smbw_server sets errno */
213 result = -1;
214 goto done;
217 DEBUG(4,("smbw_stat\n"));
219 if (strncmp(srv->cli.dev,"IPC",3) == 0) {
220 mode = aDIR | aRONLY;
221 } else if (strncmp(srv->cli.dev,"LPT",3) == 0) {
222 if (strcmp(path,"\\") == 0) {
223 mode = aDIR | aRONLY;
224 } else {
225 mode = aRONLY;
226 smbw_stat_printjob(srv, path, &size, &m_time);
227 c_time = a_time = m_time;
229 } else {
230 if (!smbw_getatr(srv, path,
231 &mode, &size, &c_time, &a_time, &m_time,
232 &ino)) {
233 errno = smbw_errno(&srv->cli);
234 result = -1;
235 goto done;
239 st->st_ino = ino;
241 smbw_setup_stat(st, path, size, mode);
243 st->st_atime = a_time;
244 st->st_ctime = c_time;
245 st->st_mtime = m_time;
246 st->st_dev = srv->dev;
248 done:
249 smbw_busy--;
250 return result;