must add one to the extra_data size to transfer the 0 string terminator.
[Samba/gebeck_regimport.git] / source3 / smbd / close.c
blobdc52327cb45260e0587fab0145cb0220a2019e2c
1 /*
2 Unix SMB/CIFS implementation.
3 file closing
4 Copyright (C) Andrew Tridgell 1992-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 /****************************************************************************
24 run a file if it is a magic script
25 ****************************************************************************/
26 static void check_magic(files_struct *fsp,connection_struct *conn)
28 if (!*lp_magicscript(SNUM(conn)))
29 return;
31 DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
34 char *p;
35 if (!(p = strrchr_m(fsp->fsp_name,'/')))
36 p = fsp->fsp_name;
37 else
38 p++;
40 if (!strequal(lp_magicscript(SNUM(conn)),p))
41 return;
45 int ret;
46 pstring magic_output;
47 pstring fname;
48 SMB_STRUCT_STAT st;
49 int tmp_fd, outfd;
51 pstrcpy(fname,fsp->fsp_name);
52 if (*lp_magicoutput(SNUM(conn)))
53 pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
54 else
55 slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
57 chmod(fname,0755);
58 ret = smbrun(fname,&tmp_fd);
59 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
60 unlink(fname);
61 if (ret != 0 || tmp_fd == -1) {
62 if (tmp_fd != -1)
63 close(tmp_fd);
64 return;
66 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
67 if (outfd == -1) {
68 close(tmp_fd);
69 return;
72 if (sys_fstat(tmp_fd,&st) == -1) {
73 close(tmp_fd);
74 close(outfd);
75 return;
78 transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
79 close(tmp_fd);
80 close(outfd);
84 /****************************************************************************
85 Common code to close a file or a directory.
86 ****************************************************************************/
88 static int close_filestruct(files_struct *fsp)
90 connection_struct *conn = fsp->conn;
91 int ret = 0;
93 if (fsp->fd != -1) {
94 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
95 ret = -1;
97 delete_write_cache(fsp);
100 fsp->is_directory = False;
102 conn->num_files_open--;
103 SAFE_FREE(fsp->wbmpx_ptr);
105 return ret;
108 /****************************************************************************
109 Close a file.
111 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
112 operation otherwise it came as the result of some other operation such as
113 the closing of the connection. In the latter case printing and
114 magic scripts are not run.
115 ****************************************************************************/
117 static int close_normal_file(files_struct *fsp, BOOL normal_close)
119 share_mode_entry *share_entry = NULL;
120 size_t share_entry_count = 0;
121 BOOL delete_on_close = False;
122 connection_struct *conn = fsp->conn;
123 int err = 0;
124 int err1 = 0;
126 remove_pending_lock_requests_by_fid(fsp);
129 * If we're flushing on a close we can get a write
130 * error here, we must remember this.
133 if (close_filestruct(fsp) == -1)
134 err1 = -1;
136 if (fsp->print_file) {
137 print_fsp_end(fsp, normal_close);
138 file_free(fsp);
139 return 0;
143 * Lock the share entries, and determine if we should delete
144 * on close. If so delete whilst the lock is still in effect.
145 * This prevents race conditions with the file being created. JRA.
148 lock_share_entry_fsp(fsp);
149 share_entry_count = del_share_mode(fsp, &share_entry);
151 DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n",
152 share_entry_count, fsp->fsp_name ));
155 * We delete on close if it's the last open, and the
156 * delete on close flag was set in the entry we just deleted.
159 if ((share_entry_count == 0) && share_entry &&
160 GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) )
161 delete_on_close = True;
163 SAFE_FREE(share_entry);
166 * NT can set delete_on_close of the last open
167 * reference to a file.
170 if (normal_close && delete_on_close) {
171 DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
172 fsp->fsp_name));
173 if(fsp->conn->vfs_ops.unlink(conn,fsp->fsp_name) != 0) {
175 * This call can potentially fail as another smbd may have
176 * had the file open with delete on close set and deleted
177 * it when its last reference to this file went away. Hence
178 * we log this but not at debug level zero.
181 DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
182 with error %s\n", fsp->fsp_name, strerror(errno) ));
186 unlock_share_entry_fsp(fsp);
188 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
189 release_file_oplock(fsp);
191 locking_close_file(fsp);
193 err = fd_close(conn, fsp);
195 /* check for magic scripts */
196 if (normal_close) {
197 check_magic(fsp,conn);
201 * Ensure pending modtime is set after close.
204 if(fsp->pending_modtime) {
205 int saved_errno = errno;
206 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
207 errno = saved_errno;
210 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
211 conn->user,fsp->fsp_name,
212 conn->num_files_open, err ? strerror(err) : ""));
214 if (fsp->fsp_name)
215 string_free(&fsp->fsp_name);
217 file_free(fsp);
219 if (err == -1 || err1 == -1)
220 return -1;
221 else
222 return 0;
225 /****************************************************************************
226 Close a directory opened by an NT SMB call.
227 ****************************************************************************/
229 static int close_directory(files_struct *fsp, BOOL normal_close)
231 remove_pending_change_notify_requests_by_fid(fsp);
234 * NT can set delete_on_close of the last open
235 * reference to a directory also.
238 if (normal_close && fsp->directory_delete_on_close) {
239 BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
240 DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
241 fsp->fsp_name, ok ? "succeeded" : "failed" ));
244 * Ensure we remove any change notify requests that would
245 * now fail as the directory has been deleted.
248 if(ok)
249 remove_pending_change_notify_requests_by_filename(fsp);
253 * Do the code common to files and directories.
255 close_filestruct(fsp);
257 if (fsp->fsp_name)
258 string_free(&fsp->fsp_name);
260 file_free(fsp);
262 return 0;
265 /****************************************************************************
266 Close a directory opened by an NT SMB call.
267 ****************************************************************************/
269 int close_file(files_struct *fsp, BOOL normal_close)
271 if(fsp->is_directory)
272 return close_directory(fsp, normal_close);
273 return close_normal_file(fsp, normal_close);