2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1996
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.
23 extern int DEBUGLEVEL
;
24 extern connection_struct Connections
[];
25 extern files_struct Files
[];
27 pstring share_del_pending
="";
30 /****************************************************************************
31 routine to do file locking
32 ****************************************************************************/
33 BOOL
fcntl_lock(int fd
,int op
,uint32 offset
,uint32 count
,int type
)
40 uint32 mask
= 0xC0000000;
42 /* make sure the count is reasonable, we might kill the lockd otherwise */
45 /* the offset is often strange - remove 2 of its bits if either of
46 the top two bits are set. Shift the top ones by two bits. This
47 still allows OLE2 apps to operate, but should stop lockd from
49 if ((offset
& mask
) != 0)
50 offset
= (offset
& ~mask
) | ((offset
& mask
) >> 2);
52 unsigned long mask
= ((unsigned)1<<31);
54 /* interpret negative counts as large numbers */
58 /* no negative offsets */
61 /* count + offset must be in range */
62 while ((offset
< 0 || (offset
+ count
< 0)) && mask
)
70 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd
,op
,(int)offset
,(int)count
,type
));
73 lock
.l_whence
= SEEK_SET
;
74 lock
.l_start
= (int)offset
;
75 lock
.l_len
= (int)count
;
80 ret
= fcntl(fd
,op
,&lock
);
83 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno
,strerror(errno
)));
89 (lock
.l_type
!= F_UNLCK
) &&
91 (lock
.l_pid
!= getpid()))
93 DEBUG(3,("fd %d is locked by pid %d\n",fd
,lock
.l_pid
));
97 /* it must be not locked or locked by me */
101 /* a lock set or unset */
104 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
105 offset
,count
,op
,type
,strerror(errno
)));
107 /* perhaps it doesn't support this sort of locking?? */
110 DEBUG(3,("locking not supported? returning True\n"));
117 /* everything went OK */
118 DEBUG(5,("Lock call successful\n"));
126 /*******************************************************************
127 lock a file - returning a open file descriptor or -1 on failure
128 The timeout is in seconds. 0 means no timeout
129 ********************************************************************/
130 int file_lock(char *name
,int timeout
)
132 int fd
= open(name
,O_RDWR
|O_CREAT
,0666);
134 if (fd
< 0) return(-1);
137 if (timeout
) t
= time(NULL
);
138 while (!timeout
|| (time(NULL
)-t
< timeout
)) {
139 if (fcntl_lock(fd
,F_SETLK
,0,1,F_WRLCK
)) return(fd
);
140 msleep(LOCK_RETRY_TIMEOUT
);
148 /*******************************************************************
149 unlock a file locked by file_lock
150 ********************************************************************/
151 void file_unlock(int fd
)
155 fcntl_lock(fd
,F_SETLK
,0,1,F_UNLCK
);
161 /****************************************************************************
162 utility function called to see if a file region is locked
163 ****************************************************************************/
164 BOOL
is_locked(int fnum
,int cnum
,uint32 count
,uint32 offset
)
166 int snum
= SNUM(cnum
);
171 if (!lp_locking(snum
) || !lp_strict_locking(snum
))
174 return(fcntl_lock(Files
[fnum
].fd
,F_GETLK
,offset
,count
,
175 (Files
[fnum
].can_write
?F_WRLCK
:F_RDLCK
)));
179 /****************************************************************************
180 utility function called by locking requests
181 ****************************************************************************/
182 BOOL
do_lock(int fnum
,int cnum
,uint32 count
,uint32 offset
,int *eclass
,uint32
*ecode
)
186 if (!lp_locking(SNUM(cnum
)))
191 *ecode
= ERRnoaccess
;
195 if (Files
[fnum
].can_lock
&& OPEN_FNUM(fnum
) && (Files
[fnum
].cnum
== cnum
))
196 ok
= fcntl_lock(Files
[fnum
].fd
,F_SETLK
,offset
,count
,
197 (Files
[fnum
].can_write
?F_WRLCK
:F_RDLCK
));
204 return True
; /* Got lock */
208 /****************************************************************************
209 utility function called by unlocking requests
210 ****************************************************************************/
211 BOOL
do_unlock(int fnum
,int cnum
,uint32 count
,uint32 offset
,int *eclass
,uint32
*ecode
)
215 if (!lp_locking(SNUM(cnum
)))
218 if (Files
[fnum
].can_lock
&& OPEN_FNUM(fnum
) && (Files
[fnum
].cnum
== cnum
))
219 ok
= fcntl_lock(Files
[fnum
].fd
,F_SETLK
,offset
,count
,F_UNLCK
);
226 return True
; /* Did unlock */
229 /*******************************************************************
231 ******************************************************************/
232 static BOOL
share_name(int cnum
,struct stat
*st
,char *name
)
234 strcpy(name
,lp_lockdir());
235 standard_sub(cnum
,name
);
236 trim_string(name
,"","/");
237 if (!*name
) return(False
);
238 name
+= strlen(name
);
240 sprintf(name
,"/share.%d.%d",(int)st
->st_dev
,(int)st
->st_ino
);
244 /*******************************************************************
245 use the fnum to get the share file name
246 ******************************************************************/
247 static BOOL
share_name_fnum(int fnum
,char *name
)
250 if (fstat(Files
[fnum
].fd
,&st
) != 0) return(False
);
251 return(share_name(Files
[fnum
].cnum
,&st
,name
));
255 /*******************************************************************
256 get the share mode of a file using the fnum
257 ******************************************************************/
258 int get_share_mode_by_fnum(int cnum
,int fnum
,int *pid
)
261 if (fstat(Files
[fnum
].fd
,&sbuf
) == -1) return(0);
262 return(get_share_mode(cnum
,&sbuf
,pid
));
265 /*******************************************************************
266 get the share mode of a file using the files name
267 ******************************************************************/
268 int get_share_mode_byname(int cnum
,char *fname
,int *pid
)
271 if (stat(fname
,&sbuf
) == -1) return(0);
272 return(get_share_mode(cnum
,&sbuf
,pid
));
276 /*******************************************************************
277 get the share mode of a file
278 ********************************************************************/
279 int get_share_mode(int cnum
,struct stat
*sbuf
,int *pid
)
289 if (!share_name(cnum
,sbuf
,fname
)) return(0);
291 fd2
= open(fname
,O_RDONLY
,0);
292 if (fd2
< 0) return(0);
294 if (read(fd2
,buf
,16) != 16) {
305 if (IVAL(buf
,12) != LOCKING_VERSION
) {
306 if (!unlink(fname
)) DEBUG(2,("Deleted old locking file %s",fname
));
311 if (*pid
&& !process_exists(*pid
)) {
316 if (! *pid
) unlink(fname
); /* XXXXX race, race */
319 DEBUG(5,("Read share file %s mode 0x%X pid=%d\n",fname
,ret
,*pid
));
325 /*******************************************************************
326 del the share mode of a file, if we set it last
327 ********************************************************************/
328 void del_share_mode(int fnum
)
337 if (!share_name_fnum(fnum
,fname
)) return;
339 fd2
= open(fname
,O_RDONLY
,0);
341 if (read(fd2
,buf
,16) != 16)
351 if (IVAL(buf
,12) != LOCKING_VERSION
|| !pid
|| !process_exists(pid
))
354 if (!del
&& t
== Files
[fnum
].open_time
&& pid
==(int)getpid())
359 DEBUG(2,("Deleted share file %s\n",fname
));
361 DEBUG(3,("Pending delete share file %s\n",fname
));
362 if (*share_del_pending
) DEBUG(0,("Share del clash!\n"));
363 strcpy(share_del_pending
,fname
);
369 /*******************************************************************
370 set the share mode of a file
371 ********************************************************************/
372 BOOL
set_share_mode(int fnum
,int mode
)
377 int pid
= (int)getpid();
379 if (!share_name_fnum(fnum
,fname
)) return(False
);
382 int old_umask
= umask(0);
383 fd2
= open(fname
,O_WRONLY
|O_CREAT
|O_TRUNC
,0644);
387 DEBUG(2,("Failed to create share file %s\n",fname
));
391 SIVAL(buf
,0,Files
[fnum
].open_time
);
394 SIVAL(buf
,12,LOCKING_VERSION
);
396 if (write(fd2
,buf
,16) != 16) {
402 write(fd2
,Files
[fnum
].name
,strlen(Files
[fnum
].name
)+1);
406 DEBUG(3,("Created share file %s with mode 0x%X pid=%d\n",fname
,mode
,pid
));
412 /*******************************************************************
413 cleanup any stale share files
414 ********************************************************************/
415 void clean_share_files(void)
417 char *lockdir
= lp_lockdir();
421 if (!*lockdir
) return;
423 dir
= opendir(lockdir
);
426 while ((s
=readdirname(dir
))) {
433 if (sscanf(s
,"share.%d.%d",&dev
,&inode
)!=2) continue;
435 strcpy(lname
,lp_lockdir());
436 trim_string(lname
,NULL
,"/");
440 fd
= open(lname
,O_RDONLY
,0);
441 if (fd
< 0) continue;
443 if (read(fd
,buf
,16) != 16) {
446 printf("Deleted corrupt share file %s\n",s
);
453 if (IVAL(buf
,12) != LOCKING_VERSION
|| !process_exists(pid
)) {
455 printf("Deleted stale share file %s\n",s
);