2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1995
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;
25 extern connection_struct Connections[];
26 extern files_struct Files[];
28 pstring share_del_pending="";
31 /****************************************************************************
32 utility function called to see if a file region is locked
33 ****************************************************************************/
34 BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset)
36 int snum = SNUM(cnum);
41 if (!lp_locking(snum) || !lp_strict_locking(snum))
44 return(fcntl_lock(Files[fnum].fd,F_GETLK,offset,count,
45 (Files[fnum].can_write?F_WRLCK:F_RDLCK)));
49 /****************************************************************************
50 utility function called by locking requests
51 ****************************************************************************/
52 BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
56 if (!lp_locking(SNUM(cnum)))
65 if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
66 ok = fcntl_lock(Files[fnum].fd,F_SETLK,offset,count,
67 (Files[fnum].can_write?F_WRLCK:F_RDLCK));
74 return True; /* Got lock */
78 /****************************************************************************
79 utility function called by unlocking requests
80 ****************************************************************************/
81 BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
85 if (!lp_locking(SNUM(cnum)))
88 if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
89 ok = fcntl_lock(Files[fnum].fd,F_SETLK,offset,count,F_UNLCK);
96 return True; /* Did unlock */
99 /*******************************************************************
101 ******************************************************************/
102 static BOOL share_name(int cnum,struct stat *st,char *name)
104 strcpy(name,lp_lockdir());
105 standard_sub(cnum,name);
106 trim_string(name,"","/");
107 if (!*name) return(False);
108 name += strlen(name);
110 sprintf(name,"/share.%d.%d",(int)st->st_dev,(int)st->st_ino);
114 /*******************************************************************
115 use the fnum to get the share file name
116 ******************************************************************/
117 static BOOL share_name_fnum(int fnum,char *name)
120 if (fstat(Files[fnum].fd,&st) != 0) return(False);
121 return(share_name(Files[fnum].cnum,&st,name));
125 /*******************************************************************
126 get the share mode of a file using the fnum
127 ******************************************************************/
128 int get_share_mode_by_fnum(int cnum,int fnum,int *pid)
131 if (fstat(Files[fnum].fd,&sbuf) == -1) return(0);
132 return(get_share_mode(cnum,&sbuf,pid));
135 /*******************************************************************
136 get the share mode of a file using the files name
137 ******************************************************************/
138 int get_share_mode_byname(int cnum,char *fname,int *pid)
141 if (stat(fname,&sbuf) == -1) return(0);
142 return(get_share_mode(cnum,&sbuf,pid));
146 /*******************************************************************
147 get the share mode of a file
148 ********************************************************************/
149 int get_share_mode(int cnum,struct stat *sbuf,int *pid)
159 if (!share_name(cnum,sbuf,fname)) return(0);
161 fd2 = open(fname,O_RDONLY,0);
162 if (fd2 < 0) return(0);
164 if (read(fd2,buf,16) != 16) {
175 if (IVAL(buf,12) != LOCKING_VERSION) {
176 if (!unlink(fname)) DEBUG(2,("Deleted old locking file %s",fname));
181 if (*pid && !process_exists(*pid)) {
186 if (! *pid) unlink(fname); /* XXXXX race, race */
189 DEBUG(5,("Read share file %s mode 0x%X pid=%d\n",fname,ret,*pid));
195 /*******************************************************************
196 del the share mode of a file, if we set it last
197 ********************************************************************/
198 void del_share_mode(int fnum)
207 if (!share_name_fnum(fnum,fname)) return;
209 fd2 = open(fname,O_RDONLY,0);
211 if (read(fd2,buf,16) != 16)
221 if (IVAL(buf,12) != LOCKING_VERSION || !pid || !process_exists(pid))
224 if (!del && t == Files[fnum].open_time && pid==(int)getpid())
229 DEBUG(2,("Deleted share file %s\n",fname));
231 DEBUG(3,("Pending delete share file %s\n",fname));
232 if (*share_del_pending) DEBUG(0,("Share del clash!\n"));
233 strcpy(share_del_pending,fname);
239 /*******************************************************************
240 set the share mode of a file
241 ********************************************************************/
242 BOOL set_share_mode(int fnum,int mode)
247 int pid = (int)getpid();
249 if (!share_name_fnum(fnum,fname)) return(False);
252 int old_umask = umask(0);
253 fd2 = open(fname,O_WRONLY|O_CREAT|O_TRUNC,0644);
257 DEBUG(2,("Failed to create share file %s\n",fname));
261 SIVAL(buf,0,Files[fnum].open_time);
264 SIVAL(buf,12,LOCKING_VERSION);
266 if (write(fd2,buf,16) != 16) {
272 write(fd2,Files[fnum].name,strlen(Files[fnum].name)+1);
276 DEBUG(3,("Created share file %s with mode 0x%X pid=%d\n",fname,mode,pid));
282 /*******************************************************************
283 cleanup any stale share files
284 ********************************************************************/
285 void clean_share_files(void)
287 char *lockdir = lp_lockdir();
291 if (!*lockdir) return;
293 dir = opendir(lockdir);
296 while ((s=readdirname(dir))) {
303 if (sscanf(s,"share.%d.%d",&dev,&inode)!=2) continue;
305 strcpy(lname,lp_lockdir());
306 trim_string(lname,NULL,"/");
310 fd = open(lname,O_RDONLY,0);
311 if (fd < 0) continue;
313 if (read(fd,buf,16) != 16) {
316 printf("Deleted corrupt share file %s\n",s);
323 if (IVAL(buf,12) != LOCKING_VERSION || !process_exists(pid)) {
325 printf("Deleted stale share file %s\n",s);