Formatting fixes only.
[ira/wip.git] / source3 / smbd / close.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    file closing
5    Copyright (C) Andrew Tridgell 1992-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 /****************************************************************************
25 run a file if it is a magic script
26 ****************************************************************************/
27 static void check_magic(files_struct *fsp,connection_struct *conn)
28 {
29   if (!*lp_magicscript(SNUM(conn)))
30     return;
31
32   DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
33
34   {
35     char *p;
36     if (!(p = strrchr_m(fsp->fsp_name,'/')))
37       p = fsp->fsp_name;
38     else
39       p++;
40
41     if (!strequal(lp_magicscript(SNUM(conn)),p))
42       return;
43   }
44
45   {
46     int ret;
47     pstring magic_output;
48     pstring fname;
49         SMB_STRUCT_STAT st;
50         int tmp_fd, outfd;
51
52     pstrcpy(fname,fsp->fsp_name);
53     if (*lp_magicoutput(SNUM(conn)))
54       pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
55     else
56       slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
57
58     chmod(fname,0755);
59     ret = smbrun(fname,&tmp_fd);
60     DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
61     unlink(fname);
62         if (ret != 0 || tmp_fd == -1) {
63                 if (tmp_fd != -1)
64                         close(tmp_fd);
65                 return;
66         }
67         outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
68         if (outfd == -1) {
69                 close(tmp_fd);
70                 return;
71         }
72
73         if (sys_fstat(tmp_fd,&st) == -1) {
74                 close(tmp_fd);
75                 close(outfd);
76                 return;
77         }
78
79         transfer_file(tmp_fd,outfd,st.st_size);
80         close(tmp_fd);
81         close(outfd);
82   }
83 }
84
85 /****************************************************************************
86   Common code to close a file or a directory.
87 ****************************************************************************/
88
89 static int close_filestruct(files_struct *fsp)
90 {   
91         connection_struct *conn = fsp->conn;
92         int ret = 0;
93     
94         if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
95                 ret = -1;
96
97         delete_write_cache(fsp);
98
99         fsp->is_directory = False; 
100         fsp->stat_open = False; 
101     
102         conn->num_files_open--;
103
104         return ret;
105 }    
106
107 /****************************************************************************
108  Close a file.
109
110  If normal_close is 1 then this came from a normal SMBclose (or equivalent)
111  operation otherwise it came as the result of some other operation such as
112  the closing of the connection. In the latter case printing and
113  magic scripts are not run.
114 ****************************************************************************/
115
116 static int close_normal_file(files_struct *fsp, BOOL normal_close)
117 {
118         share_mode_entry *share_entry = NULL;
119         size_t share_entry_count = 0;
120         BOOL delete_on_close = False;
121         connection_struct *conn = fsp->conn;
122         int err = 0;
123         int err1 = 0;
124
125         remove_pending_lock_requests_by_fid(fsp);
126
127         /*
128          * If we're flushing on a close we can get a write
129          * error here, we must remember this.
130          */
131
132         if (close_filestruct(fsp) == -1)
133                 err1 = -1;
134
135         if (fsp->print_file) {
136                 print_fsp_end(fsp, normal_close);
137                 file_free(fsp);
138                 return 0;
139         }
140
141         /*
142          * Lock the share entries, and determine if we should delete
143          * on close. If so delete whilst the lock is still in effect.
144          * This prevents race conditions with the file being created. JRA.
145          */
146
147         lock_share_entry_fsp(fsp);
148         share_entry_count = del_share_mode(fsp, &share_entry);
149
150         DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n",
151                 share_entry_count, fsp->fsp_name ));
152
153         /*
154          * We delete on close if it's the last open, and the
155          * delete on close flag was set in the entry we just deleted.
156          */
157
158         if ((share_entry_count == 0) && share_entry && 
159                         GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) )
160                 delete_on_close = True;
161
162         SAFE_FREE(share_entry);
163
164         /*
165          * NT can set delete_on_close of the last open
166          * reference to a file.
167          */
168
169         if (normal_close && delete_on_close) {
170                 DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
171                         fsp->fsp_name));
172                 if(fsp->conn->vfs_ops.unlink(conn,fsp->fsp_name) != 0) {
173                         /*
174                          * This call can potentially fail as another smbd may have
175                          * had the file open with delete on close set and deleted
176                          * it when its last reference to this file went away. Hence
177                          * we log this but not at debug level zero.
178                          */
179
180                 DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
181 with error %s\n", fsp->fsp_name, strerror(errno) ));
182                 }
183         }
184
185         unlock_share_entry_fsp(fsp);
186
187         if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
188                 release_file_oplock(fsp);
189
190         locking_close_file(fsp);
191
192         err = fd_close(conn, fsp);
193
194         /* check for magic scripts */
195         if (normal_close) {
196                 check_magic(fsp,conn);
197         }
198
199
200         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
201                  conn->user,fsp->fsp_name,
202                  conn->num_files_open, err ? strerror(err) : ""));
203
204         if (fsp->fsp_name) {
205                 string_free(&fsp->fsp_name);
206         }
207
208         file_free(fsp);
209
210         if (err == -1 || err1 == -1)
211                 return -1;
212         else
213                 return 0;
214 }
215
216 /****************************************************************************
217  Close a directory opened by an NT SMB call. 
218 ****************************************************************************/
219   
220 static int close_directory(files_struct *fsp, BOOL normal_close)
221 {
222         remove_pending_change_notify_requests_by_fid(fsp);
223
224         /*
225          * NT can set delete_on_close of the last open
226          * reference to a directory also.
227          */
228
229         if (normal_close && fsp->directory_delete_on_close) {
230                 BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
231                 DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
232                         fsp->fsp_name, ok ? "succeeded" : "failed" ));
233
234                 /*
235                  * Ensure we remove any change notify requests that would
236                  * now fail as the directory has been deleted.
237                  */
238
239                 if(ok)
240                         remove_pending_change_notify_requests_by_filename(fsp);
241         }
242
243         /*
244          * Do the code common to files and directories.
245          */
246         close_filestruct(fsp);
247         
248         if (fsp->fsp_name)
249                 string_free(&fsp->fsp_name);
250         
251         file_free(fsp);
252
253         return 0;
254 }
255
256 /****************************************************************************
257  Close a file opened with null permissions in order to read permissions.
258 ****************************************************************************/
259
260 static int close_statfile(files_struct *fsp, BOOL normal_close)
261 {
262         close_filestruct(fsp);
263         
264         if (fsp->fsp_name)
265                 string_free(&fsp->fsp_name);
266         
267         file_free(fsp);
268
269         return 0;
270 }
271
272 /****************************************************************************
273  Close a directory opened by an NT SMB call. 
274 ****************************************************************************/
275   
276 int close_file(files_struct *fsp, BOOL normal_close)
277 {
278         if(fsp->is_directory)
279                 return close_directory(fsp, normal_close);
280         else if(fsp->stat_open)
281                 return close_statfile(fsp, normal_close);
282         return close_normal_file(fsp, normal_close);
283 }