Fixes for the problem in blocking locks with file_fsp returning the
[sfrench/samba-autobuild/.git] / source / 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 extern int DEBUGLEVEL;
25
26 extern int32 global_oplocks_open;
27
28
29 /****************************************************************************
30 run a file if it is a magic script
31 ****************************************************************************/
32 static void check_magic(files_struct *fsp,connection_struct *conn)
33 {
34   if (!*lp_magicscript(SNUM(conn)))
35     return;
36
37   DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
38
39   {
40     char *p;
41     if (!(p = strrchr(fsp->fsp_name,'/')))
42       p = fsp->fsp_name;
43     else
44       p++;
45
46     if (!strequal(lp_magicscript(SNUM(conn)),p))
47       return;
48   }
49
50   {
51     int ret;
52     pstring magic_output;
53     pstring fname;
54     pstrcpy(fname,fsp->fsp_name);
55
56     if (*lp_magicoutput(SNUM(conn)))
57       pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
58     else
59       slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
60
61     chmod(fname,0755);
62     ret = smbrun(fname,magic_output,False);
63     DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
64     unlink(fname);
65   }
66 }
67
68 /****************************************************************************
69   Common code to close a file or a directory.
70 ****************************************************************************/
71 static void close_filestruct(files_struct *fsp)
72 {   
73         connection_struct *conn = fsp->conn;
74     
75         fsp->open = False;
76         fsp->is_directory = False; 
77     
78         conn->num_files_open--;
79         if(fsp->wbmpx_ptr) {  
80                 free((char *)fsp->wbmpx_ptr);
81                 fsp->wbmpx_ptr = NULL; 
82         }  
83      
84 #if WITH_MMAP
85         if(fsp->mmap_ptr) {
86                 munmap(fsp->mmap_ptr,fsp->mmap_size);
87                 fsp->mmap_ptr = NULL;
88         }  
89 #endif 
90 }    
91
92 /****************************************************************************
93  Close a file - possibly invalidating the read prediction.
94
95  If normal_close is 1 then this came from a normal SMBclose (or equivalent)
96  operation otherwise it came as the result of some other operation such as
97  the closing of the connection. In the latter case printing and
98  magic scripts are not run.
99 ****************************************************************************/
100 void close_file(files_struct *fsp, BOOL normal_close)
101 {
102         uint32 dev = fsp->fd_ptr->dev;
103         uint32 inode = fsp->fd_ptr->inode;
104         int token;
105         connection_struct *conn = fsp->conn;
106
107         remove_pending_lock_requests_by_fid(fsp);
108
109         close_filestruct(fsp);
110
111 #if USE_READ_PREDICTION
112         invalidate_read_prediction(fsp->fd_ptr->fd);
113 #endif
114
115         if (lp_share_modes(SNUM(conn))) {
116                 lock_share_entry(conn, dev, inode, &token);
117                 del_share_mode(token, fsp);
118         }
119
120         fd_attempt_close(fsp->fd_ptr);
121
122         if (lp_share_modes(SNUM(conn)))
123                 unlock_share_entry(conn, dev, inode, token);
124
125         /* NT uses smbclose to start a print - weird */
126         if (normal_close && fsp->print_file)
127                 print_file(conn, fsp);
128
129         /* check for magic scripts */
130         if (normal_close) {
131                 check_magic(fsp,conn);
132         }
133
134         if(fsp->granted_oplock == True)
135                 global_oplocks_open--;
136
137         fsp->sent_oplock_break = False;
138
139         DEBUG(2,("%s closed file %s (numopen=%d)\n",
140                  conn->user,fsp->fsp_name,
141                  conn->num_files_open));
142
143         if (fsp->fsp_name) {
144                 string_free(&fsp->fsp_name);
145         }
146
147         file_free(fsp);
148 }
149
150 /****************************************************************************
151  Close a directory opened by an NT SMB call. 
152 ****************************************************************************/
153   
154 void close_directory(files_struct *fsp)
155 {
156         remove_pending_change_notify_requests_by_fid(fsp);
157
158         /*
159          * Do the code common to files and directories.
160          */
161         close_filestruct(fsp);
162         
163         if (fsp->fsp_name)
164                 string_free(&fsp->fsp_name);
165         
166         file_free(fsp);
167 }
168