Ok - this is the 'expose 64 bit to the clients' checkin.
[ira/wip.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         SMB_DEV_T dev = fsp->fd_ptr->dev;
103         SMB_INO_T inode = fsp->fd_ptr->inode;
104         int token;
105     BOOL last_reference = False;
106         connection_struct *conn = fsp->conn;
107
108         remove_pending_lock_requests_by_fid(fsp);
109
110         close_filestruct(fsp);
111
112 #if USE_READ_PREDICTION
113         invalidate_read_prediction(fsp->fd_ptr->fd);
114 #endif
115
116         if (lp_share_modes(SNUM(conn))) {
117                 lock_share_entry(conn, dev, inode, &token);
118                 del_share_mode(token, fsp);
119         }
120
121         if(fd_attempt_close(fsp->fd_ptr) == 0)
122                 last_reference = True;
123
124     fsp->fd_ptr = NULL;
125
126         if (lp_share_modes(SNUM(conn)))
127                 unlock_share_entry(conn, dev, inode, token);
128
129         /* NT uses smbclose to start a print - weird */
130         if (normal_close && fsp->print_file)
131                 print_file(conn, fsp);
132
133         /* check for magic scripts */
134         if (normal_close) {
135                 check_magic(fsp,conn);
136         }
137
138         /*
139          * NT can set delete_on_close of the last open
140          * reference to a file.
141          */
142
143     if (normal_close && last_reference && fsp->delete_on_close) {
144                 if(dos_unlink(fsp->fsp_name) != 0)
145           DEBUG(0,("close_file: file %s. Delete on close was set and unlink failed \
146 with error %s\n", fsp->fsp_name, strerror(errno) ));
147     }
148
149         if(fsp->granted_oplock == True)
150                 global_oplocks_open--;
151
152         fsp->sent_oplock_break = False;
153
154         DEBUG(2,("%s closed file %s (numopen=%d)\n",
155                  conn->user,fsp->fsp_name,
156                  conn->num_files_open));
157
158         if (fsp->fsp_name) {
159                 string_free(&fsp->fsp_name);
160         }
161
162         file_free(fsp);
163 }
164
165 /****************************************************************************
166  Close a directory opened by an NT SMB call. 
167 ****************************************************************************/
168   
169 void close_directory(files_struct *fsp)
170 {
171         remove_pending_change_notify_requests_by_fid(fsp);
172
173         /*
174          * Do the code common to files and directories.
175          */
176         close_filestruct(fsp);
177         
178         if (fsp->fsp_name)
179                 string_free(&fsp->fsp_name);
180         
181         file_free(fsp);
182 }
183