2 Unix SMB/Netbios implementation.
4 slow (lockfile) locking 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.
23 12 aug 96: Erik.Devriendt@te6.siemens.be
24 added support for shared memory implementation of share mode locking
26 May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27 locking to deal with multiple share modes per open file.
29 September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
32 October 1997 - split into separate file (tridge)
37 #ifndef FAST_SHARE_MODES
39 extern int DEBUGLEVEL;
42 * Locking file header lengths & offsets.
44 #define SMF_VERSION_OFFSET 0
45 #define SMF_NUM_ENTRIES_OFFSET 4
46 #define SMF_FILENAME_LEN_OFFSET 8
47 #define SMF_HEADER_LENGTH 10
49 #define SMF_ENTRY_LENGTH 20
52 * Share mode record offsets.
55 #define SME_SEC_OFFSET 0
56 #define SME_USEC_OFFSET 4
57 #define SME_SHAREMODE_OFFSET 8
58 #define SME_PID_OFFSET 12
59 #define SME_PORT_OFFSET 16
60 #define SME_OPLOCK_TYPE_OFFSET 18
62 /* we need world read for smbstatus to function correctly */
63 #ifdef SECURE_SHARE_MODES
64 #define SHARE_FILE_MODE 0600
66 #define SHARE_FILE_MODE 0644
71 /*******************************************************************
72 deinitialize share_mode management
73 ******************************************************************/
74 static BOOL slow_stop_share_mode_mgmt(void)
80 /*******************************************************************
82 ******************************************************************/
83 static BOOL share_name(connection_struct *conn,
84 SMB_DEV_T dev, SMB_INO_T inode, char *name)
87 pstrcpy(name,lp_lockdir());
88 trim_string(name,"","/");
89 if (!*name) return(False);
93 #ifdef LARGE_SMB_INO_T
94 slprintf(name, sizeof(pstring) - len - 1, "/share.%u.%.0f",(unsigned int)dev,(double)inode);
95 #else /* LARGE_SMB_INO_T */
96 slprintf(name, sizeof(pstring) - len - 1, "/share.%u.%lu",(unsigned int)dev,(unsigned long)inode);
97 #endif /* LARGE_SMB_INO_T */
101 /*******************************************************************
102 Force a share file to be deleted.
103 ********************************************************************/
104 static int delete_share_file(connection_struct *conn, char *fname )
106 if (read_only) return -1;
108 /* the share file could be owned by anyone, so do this as root */
111 if(unlink(fname) != 0)
113 DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
114 fname, strerror(errno)));
118 DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
121 /* return to our previous privilage level */
122 unbecome_root(False);
127 /*******************************************************************
128 lock a share mode file.
129 ******************************************************************/
130 static BOOL slow_lock_share_entry(connection_struct *conn,
131 SMB_DEV_T dev, SMB_INO_T inode, int *ptok)
139 if(!share_name(conn, dev, inode, fname))
142 if (read_only) return True;
144 /* we need to do this as root */
148 BOOL gotlock = False;
150 * There was a race condition in the original slow share mode code.
151 * A smbd could open a share mode file, and before getting
152 * the lock, another smbd could delete the last entry for
153 * the share mode file and delete the file entry from the
154 * directory. Thus this smbd would be left with a locked
155 * share mode fd attached to a file that no longer had a
156 * directory entry. Thus another smbd would think that
157 * there were no outstanding opens on the file. To fix
158 * this we now check we can do a stat() call on the filename
159 * before allowing the lock to proceed, and back out completely
160 * and try the open again if we cannot.
161 * Jeremy Allison (jallison@whistle.com).
166 SMB_STRUCT_STAT dummy_stat;
168 fd = (int)open(fname,read_only?O_RDONLY:(O_RDWR|O_CREAT),
173 DEBUG(0,("ERROR lock_share_entry: failed to open share file %s. Error was %s\n",
174 fname, strerror(errno)));
179 /* At this point we have an open fd to the share mode file.
180 Lock the first byte exclusively to signify a lock. */
181 if(fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False)
183 DEBUG(0,("ERROR lock_share_entry: fcntl_lock on file %s failed with %s\n",
184 fname, strerror(errno)));
191 * If we cannot stat the filename, the file was deleted between
192 * the open and the lock call. Back out and try again.
195 if(sys_stat(fname, &dummy_stat)!=0)
197 DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n",
198 fname, strerror(errno)));
206 * We have to come here if any of the above calls fail
207 * as we don't want to return and leave ourselves running
214 /* return to our previous privilage level */
215 unbecome_root(False);
220 /*******************************************************************
221 unlock a share mode file.
222 ******************************************************************/
223 static BOOL slow_unlock_share_entry(connection_struct *conn,
224 SMB_DEV_T dev, SMB_INO_T inode, int token)
231 if (read_only) return True;
233 /* Fix for zero length share files from
234 Gerald Werner <wernerg@mfldclin.edu> */
236 share_name(conn, dev, inode, fname);
238 /* get the share mode file size */
239 if(sys_fstat((int)token, &sb) != 0)
241 DEBUG(0,("ERROR: unlock_share_entry: Failed to do stat on share file %s (%s)\n",
242 fname, strerror(errno)));
247 /* If the file was zero length, we must delete before
248 doing the unlock to avoid a race condition (see
249 the code in lock_share_mode_entry for details.
252 /* remove the share file if zero length */
254 delete_share_file(conn, fname);
256 /* token is the fd of the open share mode file. */
257 /* Unlock the first byte. */
258 if(fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_UNLCK) == False)
260 DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n",
269 /*******************************************************************
270 Read a share file into a buffer.
271 ********************************************************************/
272 static int read_share_file(connection_struct *conn, int fd, char *fname, char **out, BOOL *p_new_file)
281 if(sys_fstat(fd, &sb) != 0)
283 DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
284 fname, strerror(errno)));
294 /* Allocate space for the file */
295 if((buf = (char *)malloc((size_t)sb.st_size)) == NULL)
297 DEBUG(0,("read_share_file: malloc for file size %d fail !\n",
302 if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
304 DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \
305 for share file %s (%s)\n", fname, strerror(errno)));
311 if (read(fd,buf,(size_t)sb.st_size) != (size_t)sb.st_size)
313 DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n",
314 fname, strerror(errno)));
320 if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) {
321 DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \
322 locking version (was %d, should be %d).\n",fname,
323 IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION));
326 delete_share_file(conn, fname);
330 /* Sanity check for file contents */
332 size -= SMF_HEADER_LENGTH; /* Remove the header */
334 /* Remove the filename component. */
335 size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET);
337 /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
338 if((size % SMF_ENTRY_LENGTH) != 0)
340 DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \
341 deleting it.\n", fname));
344 delete_share_file(conn, fname);
352 /*******************************************************************
353 get all share mode entries in a share file for a dev/inode pair.
354 ********************************************************************/
355 static int slow_get_share_modes(connection_struct *conn, int token,
356 SMB_DEV_T dev, SMB_INO_T inode,
357 share_mode_entry **old_shares)
363 int num_entries_copied;
365 share_mode_entry *share_array;
372 /* Read the share file header - this is of the form:
374 4 - number of share mode entries.
375 8 - 2 byte name length
376 [n bytes] file name (zero terminated).
378 Followed by <n> share mode entries of the form :
384 16 - oplock port (if oplocks in use) - 2 bytes.
387 share_name(conn, dev, inode, fname);
389 if(read_share_file( conn, fd, fname, &buf, &new_file) != 0)
391 DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n",
399 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
401 DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n",
402 fname, num_entries));
407 DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \
408 for share file %s\n", num_entries, fname));
414 *old_shares = share_array = (share_mode_entry *)
415 malloc(num_entries * sizeof(share_mode_entry));
418 DEBUG(0,("get_share_modes: malloc fail !\n"));
424 /* No entries - just delete the file. */
425 DEBUG(0,("get_share_modes: share file %s has no share mode entries - deleting.\n",
429 delete_share_file(conn, fname);
433 num_entries_copied = 0;
434 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
436 for( i = 0; i < num_entries; i++)
439 char *p = base + (i*SMF_ENTRY_LENGTH);
441 pid = IVAL(p,SME_PID_OFFSET);
443 if(!process_exists(pid))
445 DEBUG(0,("get_share_modes: process %d no longer exists and \
446 it left a share mode entry with mode 0x%X in share file %s\n",
447 pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
450 share_array[num_entries_copied].time.tv_sec = IVAL(p,SME_SEC_OFFSET);
451 share_array[num_entries_copied].time.tv_usec = IVAL(p,SME_USEC_OFFSET);
452 share_array[num_entries_copied].share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
453 share_array[num_entries_copied].pid = pid;
454 share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET);
455 share_array[num_entries_copied].op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
457 num_entries_copied++;
460 if(num_entries_copied == 0)
462 /* Delete the whole file. */
463 DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n",
466 free((char *)*old_shares);
470 delete_share_file(conn, fname);
474 /* If we deleted some entries we need to re-write the whole number of
475 share mode entries back into the file. */
477 if(num_entries_copied != num_entries)
479 if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
481 DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \
482 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
484 free((char *)*old_shares);
491 SIVAL(buf, SMF_NUM_ENTRIES_OFFSET, num_entries_copied);
492 for( i = 0; i < num_entries_copied; i++)
494 char *p = base + (i*SMF_ENTRY_LENGTH);
496 SIVAL(p,SME_PID_OFFSET,share_array[i].pid);
497 SIVAL(p,SME_SHAREMODE_OFFSET,share_array[i].share_mode);
498 SIVAL(p,SME_SEC_OFFSET,share_array[i].time.tv_sec);
499 SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
500 SSVAL(p,SME_PORT_OFFSET,share_array[i].op_port);
501 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type);
504 newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied);
505 if(write(fd, buf, newsize) != newsize)
507 DEBUG(0,("ERROR: get_share_modes: failed to re-write share \
508 mode file %s (%s)\n", fname, strerror(errno)));
510 free((char *)*old_shares);
516 /* Now truncate the file at this point. */
517 if(sys_ftruncate(fd, (SMB_OFF_T)newsize)!= 0)
519 DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
520 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
522 free((char *)*old_shares);
533 DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname,
534 num_entries_copied));
536 return num_entries_copied;
539 /*******************************************************************
540 del a share mode from a share mode file.
541 ********************************************************************/
542 static void slow_del_share_mode(int token, files_struct *fsp)
552 BOOL deleted = False;
555 share_name(fsp->conn, fsp->fd_ptr->dev,
556 fsp->fd_ptr->inode, fname);
558 if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0)
560 DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n",
567 DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n",
569 delete_share_file(fsp->conn, fname);
573 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
575 DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n",
576 fname, num_entries));
581 DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \
582 for share file %s\n", num_entries, fname));
588 /* No entries - just delete the file. */
589 DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n",
593 delete_share_file(fsp->conn, fname);
599 /* Go through the entries looking for the particular one
600 we have set - delete it.
603 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
605 for(i = 0; i < num_entries; i++)
607 char *p = base + (i*SMF_ENTRY_LENGTH);
609 if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) ||
610 (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) ||
611 (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) ||
612 (IVAL(p,SME_PID_OFFSET) != pid))
615 DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
616 i, num_entries, fname));
618 /* Remove this entry. */
619 if(i != num_entries - 1)
620 memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH);
628 DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname));
635 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries);
639 /* Deleted the last entry - remove the file. */
640 DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n",
644 delete_share_file(fsp->conn,fname);
648 /* Re-write the file - and truncate it at the correct point. */
649 if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
651 DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
652 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
658 newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
659 if(write(fd, buf, newsize) != newsize)
661 DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
662 mode file %s (%s)\n", fname, strerror(errno)));
668 /* Now truncate the file at this point. */
669 if(sys_ftruncate(fd, (SMB_OFF_T)newsize) != 0)
671 DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
672 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
679 /*******************************************************************
680 set the share mode of a file
681 ********************************************************************/
682 static BOOL slow_set_share_mode(int token,files_struct *fsp, uint16 port, uint16 op_type)
686 int pid = (int)getpid();
693 share_name(fsp->conn, fsp->fd_ptr->dev,
694 fsp->fd_ptr->inode, fname);
696 if(sys_fstat(fd, &sb) != 0)
698 DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
703 /* Sanity check for file contents (if it's not a new share file). */
706 SMB_OFF_T size = sb.st_size;
708 /* Allocate space for the file plus one extra entry */
709 if((buf = (char *)malloc((size_t)(sb.st_size + SMF_ENTRY_LENGTH))) == NULL)
711 DEBUG(0,("set_share_mode: malloc for file size %d fail !\n",
712 (int)(sb.st_size + SMF_ENTRY_LENGTH)));
716 if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
718 DEBUG(0,("ERROR: set_share_mode: Failed to reset position \
719 to 0 for share file %s (%s)\n", fname, strerror(errno)));
725 if (read(fd,buf,(size_t)sb.st_size) != (size_t)sb.st_size)
727 DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n",
728 fname, strerror(errno)));
734 if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION)
736 DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \
737 locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET),
741 delete_share_file(fsp->conn, fname);
745 size -= (SMF_HEADER_LENGTH + SVAL(buf, SMF_FILENAME_LEN_OFFSET)); /* Remove the header */
747 /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
748 if((size % SMF_ENTRY_LENGTH) != 0)
750 DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \
751 deleting it.\n", fname));
754 delete_share_file(fsp->conn, fname);
761 /* New file - just use a single_entry. */
762 if((buf = (char *)malloc(SMF_HEADER_LENGTH +
763 strlen(fsp->fsp_name) + 1 + SMF_ENTRY_LENGTH)) == NULL)
765 DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
768 SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION);
769 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0);
770 SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fsp->fsp_name) + 1);
771 pstrcpy(buf + SMF_HEADER_LENGTH, fsp->fsp_name);
774 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
775 header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
776 p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH);
777 SIVAL(p,SME_SEC_OFFSET,fsp->open_time.tv_sec);
778 SIVAL(p,SME_USEC_OFFSET,fsp->open_time.tv_usec);
779 SIVAL(p,SME_SHAREMODE_OFFSET,fsp->share_mode);
780 SIVAL(p,SME_PID_OFFSET,pid);
781 SSVAL(p,SME_PORT_OFFSET,port);
782 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
786 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries);
788 if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
790 DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \
791 0 for share file %s (%s)\n", fname, strerror(errno)));
797 if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) !=
798 (header_size + (num_entries*SMF_ENTRY_LENGTH)))
800 DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
801 deleting it (%s).\n",fname, strerror(errno)));
802 delete_share_file(fsp->conn, fname);
808 /* Now truncate the file at this point - just for safety. */
810 if(sys_ftruncate(fd, (SMB_OFF_T)(header_size + (SMF_ENTRY_LENGTH*num_entries)))!= 0)
812 DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
813 mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries),
823 DEBUG(3,("set_share_mode: Created share file %s with \
824 mode 0x%X pid=%d\n",fname,fsp->share_mode,pid));
829 /*******************************************************************
830 Call a generic modify function for a share mode entry.
831 ********************************************************************/
833 static BOOL slow_mod_share_entry(int token, files_struct *fsp,
834 void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
847 share_mode_entry entry;
849 share_name(fsp->conn, fsp->fd_ptr->dev,
850 fsp->fd_ptr->inode, fname);
852 if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0)
854 DEBUG(0,("ERROR: slow_mod_share_entry: Failed to read share file %s\n",
861 DEBUG(0,("ERROR: slow_mod_share_entry: share file %s is new (size zero), \
862 deleting it.\n", fname));
863 delete_share_file(fsp->conn, fname);
867 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
869 DEBUG(5,("slow_mod_share_entry: share file %s has %d share mode entries.\n",
870 fname, num_entries));
875 DEBUG(0,("PANIC ERROR:slow_mod_share_entry: num_share_mode_entries < 0 (%d) \
876 for share file %s\n", num_entries, fname));
882 /* No entries - just delete the file. */
883 DEBUG(0,("slow_mod_share_entry: share file %s has no share mode entries - deleting.\n",
887 delete_share_file(fsp->conn, fname);
893 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
895 for(i = 0; i < num_entries; i++)
897 char *p = base + (i*SMF_ENTRY_LENGTH);
899 if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) ||
900 (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) ||
901 (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) ||
902 (IVAL(p,SME_PID_OFFSET) != pid))
905 DEBUG(5,("slow_mod_share_entry: Calling generic function to modify entry number %d (of %d) \
906 from the share file %s\n", i, num_entries, fname));
909 * Copy into the share_mode_entry structure and then call
910 * the generic function with the given parameter.
913 entry.pid = IVAL(p,SME_PID_OFFSET);
914 entry.op_port = SVAL(p,SME_PORT_OFFSET);
915 entry.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
916 entry.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
917 entry.time.tv_sec = IVAL(p,SME_SEC_OFFSET)
918 entry.time.tv_sec = IVAL(p,SME_USEC_OFFSET);
920 (*mod_fn)( &entry, fsp->fd_ptr->dev, fsp->fd_ptr->inode, param);
923 * Now copy any changes the function made back into the buffer.
926 SIVAL(p,SME_PID_OFFSET, entry.pid)
927 SSVAL(p,SME_PORT_OFFSET,entry.op_port);
928 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,entry.op_type);
929 SIVAL(p,SME_SHAREMODE_OFFSET,entry.share_mode);
930 SIVAL(p,SME_SEC_OFFSET,entry.time.tv_sec)
931 SIVAL(p,SME_USEC_OFFSET,entry.time.tv_sec);
939 DEBUG(0,("slow_mod_share_entry: entry not found in share file %s\n", fname));
945 /* Re-write the file - and truncate it at the correct point. */
946 if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
948 DEBUG(0,("ERROR: slow_mod_share_entry: lseek failed to reset to \
949 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
955 fsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
956 if(write(fd, buf, fsize) != fsize)
958 DEBUG(0,("ERROR: slow_mod_share_entry: failed to re-write share \
959 mode file %s (%s)\n", fname, strerror(errno)));
970 /*******************************************************************
971 call the specified function on each entry under management by the
973 ********************************************************************/
974 static int slow_share_forall(void (*fn)(share_mode_entry *, char *))
981 dir = opendir(lp_lockdir());
986 while ((s=readdirname(dir))) {
996 #ifdef LARGE_SMB_INO_T
998 if (sscanf(s,"share.%u.%lf",&dev,&inode_ascii)!=2) continue;
999 inode = (SMB_INO_T)inode_ascii;
1000 #else /* LARGE_SMB_INO_T */
1001 unsigned long inode_long;
1002 if (sscanf(s,"share.%u.%lu",&dev,&inode_long)!=2) continue;
1003 inode = (SMB_INO_T)inode_long;
1004 #endif /* LARGE_SMB_INO_T */
1006 pstrcpy(lname,lp_lockdir());
1007 trim_string(lname,NULL,"/");
1011 fd = open(lname,read_only?O_RDONLY:O_RDWR,0);
1016 /* Lock the share mode file while we read it. */
1018 fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False) {
1023 if(read_share_file( 0, fd, lname, &buf, &new_file)) {
1027 pstrcpy( fname, &buf[10]);
1030 base = buf + SMF_HEADER_LENGTH +
1031 SVAL(buf,SMF_FILENAME_LEN_OFFSET);
1032 for( i = 0; i < IVAL(buf, SMF_NUM_ENTRIES_OFFSET); i++) {
1033 char *p = base + (i*SMF_ENTRY_LENGTH);
1034 e.pid = IVAL(p,SME_PID_OFFSET);
1035 e.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
1036 e.time.tv_sec = IVAL(p,SME_SEC_OFFSET);
1037 e.time.tv_usec = IVAL(p,SME_USEC_OFFSET);
1038 e.op_port = SVAL(p,SME_PORT_OFFSET);
1039 e.pid = SVAL(p,SME_PID_OFFSET);
1040 e.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
1042 if (process_exists(e.pid)) {
1058 /*******************************************************************
1059 dump the state of the system
1060 ********************************************************************/
1061 static void slow_share_status(FILE *f)
1067 static struct share_ops share_ops = {
1068 slow_stop_share_mode_mgmt,
1069 slow_lock_share_entry,
1070 slow_unlock_share_entry,
1071 slow_get_share_modes,
1072 slow_del_share_mode,
1073 slow_set_share_mode,
1074 slow_mod_share_entry,
1079 /*******************************************************************
1080 initialize the slow share_mode management
1081 ******************************************************************/
1082 struct share_ops *locking_slow_init(int ronly)
1087 if (!directory_exist(lp_lockdir(),NULL)) {
1089 mkdir(lp_lockdir(),0755);
1090 if (!directory_exist(lp_lockdir(),NULL))
1097 int locking_slow_dummy_procedure(void);
1098 int locking_slow_dummy_procedure(void) {return 0;}
1099 #endif /* !FAST_SHARE_MODES */