more OSF1 changes as well as changes to allow us to use the standard
[samba.git] / source3 / smbwrapper / smbw_stat.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.0
4    SMB wrapper stat functions
5    Copyright (C) Andrew Tridgell 1998
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26 extern int smbw_busy;
27
28
29 /***************************************************** 
30 setup basic info in a stat structure
31 *******************************************************/
32 void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode)
33 {
34         ZERO_STRUCTP(st);
35         
36         st->st_mode = 0;
37
38         if (IS_DOS_DIR(mode)) {
39                 st->st_mode = SMBW_DIR_MODE;
40         } else {
41                 st->st_mode = SMBW_FILE_MODE;
42         }
43
44         if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR;
45         if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP;
46         if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH;
47         if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR;
48
49         st->st_size = size;
50         st->st_blksize = 512;
51         st->st_blocks = (size+511)/512;
52         st->st_uid = getuid();
53         st->st_gid = getgid();
54         st->st_ino = smbw_inode(fname);
55 }
56
57
58 /***************************************************** 
59 try to do a QPATHINFO and if that fails then do a getatr
60 this is needed because win95 sometimes refuses the qpathinfo
61 *******************************************************/
62 BOOL smbw_getatr(struct smbw_server *srv, char *path, 
63                  uint32 *mode, size_t *size, 
64                  time_t *c_time, time_t *a_time, time_t *m_time)
65 {
66         DEBUG(5,("sending qpathinfo\n"));
67
68         if (cli_qpathinfo(&srv->cli, path, c_time, a_time, m_time,
69                           size, mode)) return True;
70
71         DEBUG(5,("qpathinfo OK\n"));
72
73         /* if this is NT then don't bother with the getatr */
74         if (srv->cli.capabilities & CAP_NT_SMBS) return False;
75
76         if (cli_getatr(&srv->cli, path, mode, size, m_time)) {
77                 a_time = c_time = m_time;
78                 return True;
79         }
80         return False;
81 }
82
83
84 static struct print_job_info printjob;
85
86 /***************************************************** 
87 gather info from a printjob listing
88 *******************************************************/
89 static void smbw_printjob_stat(struct print_job_info *job)
90 {
91         if (strcmp(job->name, printjob.name) == 0) {
92                 printjob = *job;
93         }
94 }
95
96 /***************************************************** 
97 stat a printjob
98 *******************************************************/
99 int smbw_stat_printjob(struct smbw_server *srv,char *path,
100                        size_t *size, time_t *m_time)
101 {
102         if (path[0] == '\\') path++;
103
104         ZERO_STRUCT(printjob);
105
106         fstrcpy(printjob.name, path);
107         cli_print_queue(&srv->cli, smbw_printjob_stat);
108
109         if (size) {
110                 *size = printjob.size;
111         }
112         if (m_time) {
113                 *m_time = printjob.t;
114         }
115         return printjob.id;
116 }
117
118
119 /***************************************************** 
120 a wrapper for fstat()
121 *******************************************************/
122 int smbw_fstat(int fd, struct stat *st)
123 {
124         struct smbw_file *file;
125         time_t c_time, a_time, m_time;
126         size_t size;
127         uint32 mode;
128
129         smbw_busy++;
130
131         file = smbw_file(fd);
132         if (!file) {
133                 int ret = smbw_dir_fstat(fd, st);
134                 smbw_busy--;
135                 return ret;
136         }
137
138         if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd, 
139                           &mode, &size, &c_time, &a_time, &m_time) &&
140             !cli_getattrE(&file->srv->cli, file->f->cli_fd, 
141                           &mode, &size, &c_time, &a_time, &m_time)) {
142                 errno = EINVAL;
143                 smbw_busy--;
144                 return -1;
145         }
146
147         smbw_setup_stat(st, file->f->fname, size, mode);
148
149         st->st_atime = a_time;
150         st->st_ctime = c_time;
151         st->st_mtime = m_time;
152         st->st_dev = file->srv->dev;
153
154         smbw_busy--;
155         return 0;
156 }
157
158
159 /***************************************************** 
160 a wrapper for stat()
161 *******************************************************/
162 int smbw_stat(const char *fname, struct stat *st)
163 {
164         struct smbw_server *srv;
165         fstring server, share;
166         pstring path;
167         time_t m_time=0, a_time=0, c_time=0;
168         size_t size=0;
169         uint32 mode=0;
170
171         if (!fname) {
172                 errno = EINVAL;
173                 return -1;
174         }
175
176         smbw_init();
177
178         smbw_busy++;
179
180         /* work out what server they are after */
181         smbw_parse_path(fname, server, share, path);
182
183         /* get a connection to the server */
184         srv = smbw_server(server, share);
185         if (!srv) {
186                 /* smbw_server sets errno */
187                 goto failed;
188         }
189
190         if (strncmp(srv->cli.dev,"IPC",3) == 0) {
191                 mode = aDIR | aRONLY;
192         } else if (strncmp(srv->cli.dev,"LPT",3) == 0) {
193                 if (strcmp(path,"\\") == 0) {
194                         mode = aDIR | aRONLY;
195                 } else {
196                         mode = aRONLY;
197                         smbw_stat_printjob(srv, path, &size, &m_time);
198                         c_time = a_time = m_time;
199                 }
200         } else {
201                 if (!smbw_getatr(srv, path, 
202                                  &mode, &size, &c_time, &a_time, &m_time)) {
203                         errno = smbw_errno(&srv->cli);
204                         goto failed;
205                 }
206         }
207
208         smbw_setup_stat(st, path, size, mode);
209
210         st->st_atime = a_time;
211         st->st_ctime = c_time;
212         st->st_mtime = m_time;
213         st->st_dev = srv->dev;
214
215         smbw_busy--;
216         return 0;
217
218  failed:
219         smbw_busy--;
220         return -1;
221 }
222
223