2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-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.
24 extern int DEBUGLEVEL;
26 /****************************************************************************
27 run a file if it is a magic script
28 ****************************************************************************/
29 static void check_magic(files_struct *fsp,connection_struct *conn)
31 if (!*lp_magicscript(SNUM(conn)))
34 DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
38 if (!(p = strrchr(fsp->fsp_name,'/')))
43 if (!strequal(lp_magicscript(SNUM(conn)),p))
51 pstrcpy(fname,fsp->fsp_name);
53 if (*lp_magicoutput(SNUM(conn)))
54 pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
56 slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
59 ret = smbrun(fname,magic_output,False);
60 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
65 /****************************************************************************
66 Common code to close a file or a directory.
67 ****************************************************************************/
68 static void close_filestruct(files_struct *fsp)
70 connection_struct *conn = fsp->conn;
72 flush_write_cache(fsp, CLOSE_FLUSH);
75 fsp->is_directory = False;
77 conn->num_files_open--;
79 free((char *)fsp->wbmpx_ptr);
80 fsp->wbmpx_ptr = NULL;
84 /****************************************************************************
85 Close a file - possibly invalidating the read prediction.
87 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
88 operation otherwise it came as the result of some other operation such as
89 the closing of the connection. In the latter case printing and
90 magic scripts are not run.
91 ****************************************************************************/
93 static int close_normal_file(files_struct *fsp, BOOL normal_close)
95 SMB_DEV_T dev = fsp->fd_ptr->dev;
96 SMB_INO_T inode = fsp->fd_ptr->inode;
97 BOOL last_reference = False;
98 BOOL delete_on_close = fsp->fd_ptr->delete_on_close;
99 connection_struct *conn = fsp->conn;
102 remove_pending_lock_requests_by_fid(fsp);
104 close_filestruct(fsp);
106 #if USE_READ_PREDICTION
107 invalidate_read_prediction(fsp->fd_ptr->fd);
110 if (lp_share_modes(SNUM(conn))) {
111 lock_share_entry(conn, dev, inode);
115 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
116 release_file_oplock(fsp);
118 locking_close_file(fsp);
120 if(fd_attempt_close(fsp, &err) == 0)
121 last_reference = True;
125 if (lp_share_modes(SNUM(conn)))
126 unlock_share_entry(conn, dev, inode);
128 /* NT uses smbclose to start a print - weird */
129 if (normal_close && fsp->print_file)
130 print_file(conn, fsp);
132 /* check for magic scripts */
134 check_magic(fsp,conn);
138 * NT can set delete_on_close of the last open
139 * reference to a file.
142 if (normal_close && last_reference && delete_on_close) {
143 DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
145 if(fsp->conn->vfs_ops.unlink(dos_to_unix(fsp->fsp_name, False)) != 0) {
147 * This call can potentially fail as another smbd may have
148 * had the file open with delete on close set and deleted
149 * it when its last reference to this file went away. Hence
150 * we log this but not at debug level zero.
153 DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
154 with error %s\n", fsp->fsp_name, strerror(errno) ));
158 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
159 conn->user,fsp->fsp_name,
160 conn->num_files_open, err ? strerror(err) : ""));
163 string_free(&fsp->fsp_name);
171 /****************************************************************************
172 Close a directory opened by an NT SMB call.
173 ****************************************************************************/
175 static int close_directory(files_struct *fsp, BOOL normal_close)
177 remove_pending_change_notify_requests_by_fid(fsp);
180 * NT can set delete_on_close of the last open
181 * reference to a directory also.
184 if (normal_close && fsp->directory_delete_on_close) {
185 BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
186 DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
187 fsp->fsp_name, ok ? "succeeded" : "failed" ));
190 * Ensure we remove any change notify requests that would
191 * now fail as the directory has been deleted.
195 remove_pending_change_notify_requests_by_filename(fsp);
199 * Do the code common to files and directories.
201 close_filestruct(fsp);
204 string_free(&fsp->fsp_name);
211 /****************************************************************************
212 Close a file opened with null permissions in order to read permissions.
213 ****************************************************************************/
215 static int close_statfile(files_struct *fsp, BOOL normal_close)
217 close_filestruct(fsp);
220 string_free(&fsp->fsp_name);
227 /****************************************************************************
228 Close a directory opened by an NT SMB call.
229 ****************************************************************************/
231 int close_file(files_struct *fsp, BOOL normal_close)
233 if(fsp->is_directory)
234 return close_directory(fsp, normal_close);
235 else if(fsp->stat_open)
236 return close_statfile(fsp, normal_close);
237 return close_normal_file(fsp, normal_close);