2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1997
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.
31 extern int DEBUGLEVEL;
32 extern connection_struct Connections[];
33 extern files_struct Files[];
35 /****************************************************************************
36 utility function called to see if a file region is locked
37 ****************************************************************************/
38 BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset)
40 int snum = SNUM(cnum);
45 if (!lp_locking(snum) || !lp_strict_locking(snum))
48 return(fcntl_lock(Files[fnum].fd_ptr->fd,F_GETLK,offset,count,
49 (Files[fnum].can_write?F_WRLCK:F_RDLCK)));
53 /****************************************************************************
54 utility function called by locking requests
55 ****************************************************************************/
56 BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
60 if (!lp_locking(SNUM(cnum)))
69 if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
70 ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,
71 (Files[fnum].can_write?F_WRLCK:F_RDLCK));
78 return True; /* Got lock */
82 /****************************************************************************
83 utility function called by unlocking requests
84 ****************************************************************************/
85 BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
89 if (!lp_locking(SNUM(cnum)))
92 if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
93 ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,F_UNLCK);
100 return True; /* Did unlock */
103 #ifdef FAST_SHARE_MODES
104 /*******************************************************************
105 initialize the shared memory for share_mode management
106 ******************************************************************/
107 BOOL start_share_mode_mgmt(void)
109 pstring shmem_file_name;
111 pstrcpy(shmem_file_name,lp_lockdir());
112 if (!directory_exist(shmem_file_name,NULL))
113 mkdir(shmem_file_name,0755);
114 trim_string(shmem_file_name,"","/");
115 if (!*shmem_file_name) return(False);
116 strcat(shmem_file_name, "/SHARE_MEM_FILE");
117 return smb_shm_open(shmem_file_name, lp_shmem_size());
121 /*******************************************************************
122 deinitialize the shared memory for share_mode management
123 ******************************************************************/
124 BOOL stop_share_mode_mgmt(void)
126 return smb_shm_close();
129 /*******************************************************************
130 lock a hash bucket entry in shared memory for share_mode management
131 ******************************************************************/
132 BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok)
134 return smb_shm_lock_hash_entry(HASH_ENTRY(dev, inode));
137 /*******************************************************************
138 unlock a hash bucket entry in shared memory for share_mode management
139 ******************************************************************/
140 BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token)
142 return smb_shm_unlock_hash_entry(HASH_ENTRY(dev, inode));
145 /*******************************************************************
146 get all share mode entries in shared memory for a dev/inode pair.
147 ********************************************************************/
148 int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
149 min_share_mode_entry **old_shares)
151 smb_shm_offset_t *mode_array;
152 unsigned int hash_entry = HASH_ENTRY(dev, inode);
153 share_mode_record *file_scanner_p;
154 share_mode_record *file_prev_p;
155 share_mode_entry *entry_scanner_p;
156 share_mode_entry *entry_prev_p;
158 int num_entries_copied;
160 min_share_mode_entry *share_array = (min_share_mode_entry *)0;
164 if(hash_entry > lp_shmem_hash_size() )
167 ("PANIC ERROR : get_share_modes (FAST_SHARE_MODES): hash_entry %d too large \
169 hash_entry, lp_shmem_hash_size() ));
173 mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
175 if(mode_array[hash_entry] == NULL_OFFSET)
177 DEBUG(5,("get_share_modes (FAST_SHARE_MODES): hash bucket %d empty\n", hash_entry));
181 file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
182 file_prev_p = file_scanner_p;
183 while(file_scanner_p)
185 if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
192 file_prev_p = file_scanner_p ;
193 file_scanner_p = (share_mode_record *)smb_shm_offset2addr(
194 file_scanner_p->next_offset);
200 DEBUG(5,("get_share_modes (FAST_SHARE_MODES): no entry for \
201 file dev = %d, ino = %d in hash_bucket %d\n", dev, inode, hash_entry));
205 if(file_scanner_p->locking_version != LOCKING_VERSION)
207 DEBUG(0,("ERROR:get_share_modes (FAST_SHARE_MODES): Deleting old share mode \
208 record due to old locking version %d for file dev = %d, inode = %d in hash \
209 bucket %d",file_scanner_p->locking_version, dev, inode, hash_entry));
210 if(file_prev_p == file_scanner_p)
211 mode_array[hash_entry] = file_scanner_p->next_offset;
213 file_prev_p->next_offset = file_scanner_p->next_offset;
214 smb_shm_free(smb_shm_addr2offset(file_scanner_p));
218 /* Allocate the old_shares array */
219 num_entries = file_scanner_p->num_share_mode_entries;
222 *old_shares = share_array = (min_share_mode_entry *)
223 malloc(num_entries * sizeof(min_share_mode_entry));
226 DEBUG(0,("get_share_modes (FAST_SHARE_MODES): malloc fail !\n"));
231 num_entries_copied = 0;
233 entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
234 file_scanner_p->share_mode_entries);
235 entry_prev_p = entry_scanner_p;
236 while(entry_scanner_p)
238 int pid = entry_scanner_p->pid;
240 if (pid && !process_exists(pid))
242 /* Delete this share mode entry */
243 share_mode_entry *delete_entry_p = entry_scanner_p;
245 if(entry_prev_p == entry_scanner_p)
247 /* We are at start of list */
248 file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
249 entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
250 file_scanner_p->share_mode_entries);
251 entry_prev_p = entry_scanner_p;
255 entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
256 entry_scanner_p = (share_mode_entry*)
257 smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
259 /* Decrement the number of share mode entries on this share mode record */
260 file_scanner_p->num_share_mode_entries -= 1;
263 if(file_scanner_p->num_share_mode_entries < 0)
265 DEBUG(0,("PANIC ERROR:get_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
266 for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries,
267 dev, inode, hash_entry));
271 DEBUG(0,("get_share_modes (FAST_SHARE_MODES): process %d no longer exists and \
272 it left a share mode entry with mode 0x%X for file dev = %d, ino = %d in hash \
273 bucket (number of entries now = %d)\n",
274 pid, entry_scanner_p->share_mode, dev, inode, hash_entry,
275 file_scanner_p->num_share_mode_entries));
277 smb_shm_free(smb_shm_addr2offset(delete_entry_p));
281 /* This is a valid share mode entry and the process that
282 created it still exists. Copy it into the output array.
284 share_array[num_entries_copied].pid = entry_scanner_p->pid;
285 share_array[num_entries_copied].share_mode = entry_scanner_p->share_mode;
287 share_array[num_entries_copied].op_port = entry_scanner_p->op_port;
288 share_array[num_entries_copied].op_type = entry_scanner_p->op_type;
289 #endif /* USE_OPLOCKS */
290 memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->time,
291 sizeof(struct timeval));
292 num_entries_copied++;
293 DEBUG(5,("get_share_modes (FAST_SHARE_MODES): Read share mode \
294 record mode 0x%X pid=%d\n", entry_scanner_p->share_mode, entry_scanner_p->pid));
295 entry_prev_p = entry_scanner_p;
296 entry_scanner_p = (share_mode_entry *)
297 smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
301 /* If no valid share mode entries were found then this record shouldn't exist ! */
302 if(num_entries_copied == 0)
304 DEBUG(0,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
305 hash bucket %d has a share mode record but no entries - deleting\n",
306 dev, inode, hash_entry));
308 free((char *)*old_shares);
311 if(file_prev_p == file_scanner_p)
312 mode_array[hash_entry] = file_scanner_p->next_offset;
314 file_prev_p->next_offset = file_scanner_p->next_offset;
315 smb_shm_free(smb_shm_addr2offset(file_scanner_p));
318 DEBUG(5,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
319 hash bucket %d returning %d entries\n", dev, inode, hash_entry,
320 num_entries_copied));
322 return(num_entries_copied);
325 /*******************************************************************
326 del the share mode of a file.
327 ********************************************************************/
328 void del_share_mode(share_lock_token token, int fnum)
331 smb_shm_offset_t *mode_array;
332 unsigned int hash_entry;
333 share_mode_record *file_scanner_p;
334 share_mode_record *file_prev_p;
335 share_mode_entry *entry_scanner_p;
336 share_mode_entry *entry_prev_p;
340 dev = Files[fnum].fd_ptr->dev;
341 inode = Files[fnum].fd_ptr->inode;
343 hash_entry = HASH_ENTRY(dev, inode);
345 if(hash_entry > lp_shmem_hash_size() )
348 ("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash_entry %d too large \
350 hash_entry, lp_shmem_hash_size() ));
354 mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
356 if(mode_array[hash_entry] == NULL_OFFSET)
358 DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash bucket %d empty\n",
363 file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
364 file_prev_p = file_scanner_p;
366 while(file_scanner_p)
368 if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
375 file_prev_p = file_scanner_p ;
376 file_scanner_p = (share_mode_record *)
377 smb_shm_offset2addr(file_scanner_p->next_offset);
383 DEBUG(0,("ERROR:del_share_mode (FAST_SHARE_MODES): no entry found for dev %d, \
384 inode %d in hash bucket %d\n", dev, inode, hash_entry));
388 if(file_scanner_p->locking_version != LOCKING_VERSION)
390 DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): Deleting old share mode \
391 record due to old locking version %d for file dev %d, inode %d hash bucket %d\n",
392 file_scanner_p->locking_version, dev, inode, hash_entry ));
393 if(file_prev_p == file_scanner_p)
394 mode_array[hash_entry] = file_scanner_p->next_offset;
396 file_prev_p->next_offset = file_scanner_p->next_offset;
397 smb_shm_free(smb_shm_addr2offset(file_scanner_p));
402 entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
403 file_scanner_p->share_mode_entries);
404 entry_prev_p = entry_scanner_p;
405 while(entry_scanner_p)
407 if( (pid == entry_scanner_p->pid) &&
408 (memcmp(&entry_scanner_p->time,
409 &Files[fnum].open_time,sizeof(struct timeval)) == 0) )
416 entry_prev_p = entry_scanner_p;
417 entry_scanner_p = (share_mode_entry *)
418 smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
424 /* Decrement the number of entries in the record. */
425 file_scanner_p->num_share_mode_entries -= 1;
427 DEBUG(2,("del_share_modes (FAST_SHARE_MODES): \
428 Deleting share mode entry dev = %d, inode = %d in hash bucket %d (num entries now = %d)\n",
429 dev, inode, hash_entry, file_scanner_p->num_share_mode_entries));
430 if(entry_prev_p == entry_scanner_p)
431 /* We are at start of list */
432 file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
434 entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
435 smb_shm_free(smb_shm_addr2offset(entry_scanner_p));
438 if(file_scanner_p->num_share_mode_entries < 0)
440 DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
441 for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries,
442 dev, inode, hash_entry));
446 /* If we deleted the last share mode entry then remove the share mode record. */
447 if(file_scanner_p->num_share_mode_entries == 0)
449 DEBUG(2,("del_share_modes (FAST_SHARE_MODES): num entries = 0, deleting share_mode \
450 record dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
451 if(file_prev_p == file_scanner_p)
452 mode_array[hash_entry] = file_scanner_p->next_offset;
454 file_prev_p->next_offset = file_scanner_p->next_offset;
455 smb_shm_free(smb_shm_addr2offset(file_scanner_p));
460 DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): No share mode record found \
461 dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
465 /*******************************************************************
466 set the share mode of a file. Return False on fail, True on success.
467 ********************************************************************/
468 BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_type)
470 files_struct *fs_p = &Files[fnum];
472 smb_shm_offset_t *mode_array;
473 unsigned int hash_entry;
474 share_mode_record *file_scanner_p;
475 share_mode_record *file_prev_p;
476 share_mode_entry *new_entry_p;
477 smb_shm_offset_t new_entry_offset;
480 dev = fs_p->fd_ptr->dev;
481 inode = fs_p->fd_ptr->inode;
483 hash_entry = HASH_ENTRY(dev, inode);
484 if(hash_entry > lp_shmem_hash_size() )
487 ("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): hash_entry %d too large \
489 hash_entry, lp_shmem_hash_size() ));
493 mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
495 file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
496 file_prev_p = file_scanner_p;
498 while(file_scanner_p)
500 if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
507 file_prev_p = file_scanner_p ;
508 file_scanner_p = (share_mode_record *)
509 smb_shm_offset2addr(file_scanner_p->next_offset);
515 /* We must create a share_mode_record */
516 share_mode_record *new_mode_p = NULL;
517 smb_shm_offset_t new_offset = smb_shm_alloc( sizeof(share_mode_record) +
518 strlen(fs_p->name) + 1);
519 if(new_offset == NULL_OFFSET)
521 DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail !\n"));
524 new_mode_p = smb_shm_offset2addr(new_offset);
525 new_mode_p->locking_version = LOCKING_VERSION;
526 new_mode_p->st_dev = dev;
527 new_mode_p->st_ino = inode;
528 new_mode_p->num_share_mode_entries = 0;
529 new_mode_p->share_mode_entries = NULL_OFFSET;
530 strcpy(new_mode_p->file_name, fs_p->name);
532 /* Chain onto the start of the hash chain (in the hope we will be used first). */
533 new_mode_p->next_offset = mode_array[hash_entry];
534 mode_array[hash_entry] = new_offset;
536 file_scanner_p = new_mode_p;
538 DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share record for %s (dev %d \
539 inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry));
542 /* Now create the share mode entry */
543 new_entry_offset = smb_shm_alloc( sizeof(share_mode_entry));
544 if(new_entry_offset == NULL_OFFSET)
546 smb_shm_offset_t delete_offset = mode_array[hash_entry];
547 DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail 1!\n"));
548 /* Unlink the damaged record */
549 mode_array[hash_entry] = file_scanner_p->next_offset;
551 smb_shm_free( delete_offset );
555 new_entry_p = smb_shm_offset2addr(new_entry_offset);
557 new_entry_p->pid = getpid();
558 new_entry_p->share_mode = fs_p->share_mode;
560 new_entry_p->op_port = port;
561 new_entry_p->op_type = op_type;
562 #endif /* USE_OPLOCKS */
563 memcpy( (char *)&new_entry_p->time, (char *)&fs_p->open_time, sizeof(struct timeval));
565 /* Chain onto the share_mode_record */
566 new_entry_p->next_share_mode_entry = file_scanner_p->share_mode_entries;
567 file_scanner_p->share_mode_entries = new_entry_offset;
570 if(file_scanner_p->num_share_mode_entries < 0)
572 DEBUG(0,("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
573 for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries,
574 dev, inode, hash_entry));
578 /* Increment the share_mode_entries counter */
579 file_scanner_p->num_share_mode_entries += 1;
581 DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share entry for %s with mode \
582 0x%X pid=%d (num_entries now = %d)\n",fs_p->name, fs_p->share_mode, new_entry_p->pid,
583 file_scanner_p->num_share_mode_entries));
588 #else /* FAST_SHARE_MODES */
590 /* SHARE MODE LOCKS USING SLOW DESCRIPTION FILES */
592 /*******************************************************************
594 ******************************************************************/
595 static BOOL share_name(int cnum, uint32 dev, uint32 inode, char *name)
597 strcpy(name,lp_lockdir());
598 standard_sub(cnum,name);
599 trim_string(name,"","/");
600 if (!*name) return(False);
601 name += strlen(name);
603 sprintf(name,"/share.%u.%u",dev,inode);
607 /*******************************************************************
608 lock a share mode file.
609 ******************************************************************/
610 BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok)
615 *ptok = (share_lock_token)-1;
617 if(!share_name(cnum, dev, inode, fname))
623 old_umask = umask(0);
624 #ifdef SECURE_SHARE_MODES
625 fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600);
626 #else /* SECURE_SHARE_MODES */
627 fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666);
628 #endif /* SECURE_SHARE_MODES */
630 if(!become_user(cnum,Connections[cnum].vuid))
632 DEBUG(0,("lock_share_entry: Can't become connected user!\n"));
636 /* We need to change directory back to the connection root. */
637 if (ChDir(Connections[cnum].connectpath) != 0)
639 DEBUG(0,("lock_share_entry: Can't change directory to %s (%s)\n",
640 Connections[cnum].connectpath, strerror(errno)));
646 /* At this point we have an open fd to the share mode file.
647 Lock the first byte exclusively to signify a lock. */
648 if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
650 DEBUG(0,("ERROR lock_share_entry: fcntl_lock failed with %s\n",
656 *ptok = (share_lock_token)fd;
660 /*******************************************************************
661 unlock a share mode file.
662 ******************************************************************/
663 BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token)
668 /* token is the fd of the open share mode file. */
669 /* Unlock the first byte. */
670 if(fcntl_lock(fd, F_SETLKW, 0, 1, F_UNLCK) == False)
672 DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n",
681 /*******************************************************************
682 Force a share file to be deleted.
683 ********************************************************************/
685 static int delete_share_file( int cnum, char *fname )
688 if(unlink(fname) != 0)
690 DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
691 fname, strerror(errno)));
694 DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
696 if(!become_user(cnum,Connections[cnum].vuid))
698 DEBUG(0,("delete_share_file: Can't become connected user!\n"));
701 /* We need to change directory back to the connection root. */
702 if (ChDir(Connections[cnum].connectpath) != 0)
704 DEBUG(0,("delete_share_file: Can't change directory to %s (%s)\n",
705 Connections[cnum].connectpath, strerror(errno)));
711 /*******************************************************************
712 Read a share file into a buffer.
713 ********************************************************************/
715 static int read_share_file(int cnum, int fd, char *fname, char **out, BOOL *p_new_file)
724 if(fstat(fd, &sb) != 0)
726 DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
727 fname, strerror(errno)));
737 /* Allocate space for the file */
738 if((buf = (char *)malloc(sb.st_size)) == NULL)
740 DEBUG(0,("read_share_file: malloc for file size %d fail !\n", sb.st_size));
744 if(lseek(fd, 0, SEEK_SET) != 0)
746 DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \
747 for share file %s (%s)\n", fname, strerror(errno)));
753 if (read(fd,buf,sb.st_size) != sb.st_size)
755 DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n",
756 fname, strerror(errno)));
762 if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) {
763 DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \
764 locking version (was %d, should be %d).\n",fname,
765 IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION));
768 delete_share_file(cnum, fname);
772 /* Sanity check for file contents */
774 size -= SMF_HEADER_LENGTH; /* Remove the header */
776 /* Remove the filename component. */
777 size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET);
779 /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
780 if((size % SMF_ENTRY_LENGTH) != 0)
782 DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \
783 deleting it.\n", fname));
786 delete_share_file(cnum, fname);
794 /*******************************************************************
795 get all share mode entries in a share file for a dev/inode pair.
796 ********************************************************************/
797 int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
798 min_share_mode_entry **old_shares)
804 int num_entries_copied;
806 min_share_mode_entry *share_array;
813 /* Read the share file header - this is of the form:
815 4 - number of share mode entries.
816 8 - 2 byte name length
817 [n bytes] file name (zero terminated).
819 Followed by <n> share mode entries of the form :
825 16 - oplock port (if oplocks in use) - 2 bytes.
828 share_name(cnum, dev, inode, fname);
830 if(read_share_file( cnum, fd, fname, &buf, &new_file) != 0)
832 DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n",
840 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
842 DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n",
843 fname, num_entries));
848 DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \
849 for share file %d\n", num_entries, fname));
855 *old_shares = share_array = (min_share_mode_entry *)
856 malloc(num_entries * sizeof(min_share_mode_entry));
859 DEBUG(0,("get_share_modes: malloc fail !\n"));
865 /* No entries - just delete the file. */
866 DEBUG(0,("get_share_modes: share file %s has no share mode entries - deleting.\n",
870 delete_share_file(cnum, fname);
874 num_entries_copied = 0;
875 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
877 for( i = 0; i < num_entries; i++)
880 char *p = base + (i*SMF_ENTRY_LENGTH);
882 pid = IVAL(p,SME_PID_OFFSET);
884 if(!process_exists(pid))
886 DEBUG(0,("get_share_modes: process %d no longer exists and \
887 it left a share mode entry with mode 0x%X in share file %s\n",
888 pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
891 share_array[num_entries_copied].time.tv_sec = IVAL(p,SME_SEC_OFFSET);
892 share_array[num_entries_copied].time.tv_usec = IVAL(p,SME_USEC_OFFSET);
893 share_array[num_entries_copied].share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
894 share_array[num_entries_copied].pid = pid;
896 share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET);
897 share_array[num_entries_copied].op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
898 #endif /* USE_OPLOCKS */
900 num_entries_copied++;
903 if(num_entries_copied == 0)
905 /* Delete the whole file. */
906 DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n",
909 free((char *)*old_shares);
913 delete_share_file(cnum, fname);
917 /* If we deleted some entries we need to re-write the whole number of
918 share mode entries back into the file. */
920 if(num_entries_copied != num_entries)
922 if(lseek(fd, 0, SEEK_SET) != 0)
924 DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \
925 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
927 free((char *)*old_shares);
934 SIVAL(buf, SMF_NUM_ENTRIES_OFFSET, num_entries_copied);
935 for( i = 0; i < num_entries_copied; i++)
937 char *p = base + (i*SMF_ENTRY_LENGTH);
939 SIVAL(p,SME_PID_OFFSET,share_array[i].pid);
940 SIVAL(p,SME_SHAREMODE_OFFSET,share_array[i].share_mode);
941 SIVAL(p,SME_SEC_OFFSET,share_array[i].time.tv_sec);
942 SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
944 SIVAL(p,SME_PORT_OFFSET,share_array[i].op_port);
945 SIVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type);
946 #endif /* USE_OPLOCKS */
949 newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied);
950 if(write(fd, buf, newsize) != newsize)
952 DEBUG(0,("ERROR: get_share_modes: failed to re-write share \
953 mode file %s (%s)\n", fname, strerror(errno)));
955 free((char *)*old_shares);
961 /* Now truncate the file at this point. */
962 if(ftruncate(fd, newsize)!= 0)
964 DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
965 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
967 free((char *)*old_shares);
978 DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname,
979 num_entries_copied));
981 return num_entries_copied;
984 /*******************************************************************
985 del a share mode from a share mode file.
986 ********************************************************************/
987 void del_share_mode(share_lock_token token, int fnum)
996 files_struct *fs_p = &Files[fnum];
998 BOOL deleted = False;
1001 share_name(fs_p->cnum, fs_p->fd_ptr->dev,
1002 fs_p->fd_ptr->inode, fname);
1004 if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
1006 DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n",
1011 if(new_file == True)
1013 DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n",
1015 delete_share_file(fs_p->cnum, fname);
1019 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
1021 DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n",
1022 fname, num_entries));
1027 DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \
1028 for share file %d\n", num_entries, fname));
1032 if(num_entries == 0)
1034 /* No entries - just delete the file. */
1035 DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n",
1039 delete_share_file(fs_p->cnum, fname);
1045 /* Go through the entries looking for the particular one
1046 we have set - delete it.
1049 base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
1051 for(i = 0; i < num_entries; i++)
1053 char *p = base + (i*SMF_ENTRY_LENGTH);
1055 if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) ||
1056 (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
1057 (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) ||
1058 (IVAL(p,SME_PID_OFFSET) != pid))
1061 DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
1062 i, num_entries, fname));
1064 /* Remove this entry. */
1065 if(i != num_entries - 1)
1066 memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH);
1074 DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname));
1081 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries);
1083 if(num_entries == 0)
1085 /* Deleted the last entry - remove the file. */
1086 DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n",
1090 delete_share_file(fs_p->cnum,fname);
1094 /* Re-write the file - and truncate it at the correct point. */
1095 if(lseek(fd, 0, SEEK_SET) != 0)
1097 DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
1098 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
1104 newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
1105 if(write(fd, buf, newsize) != newsize)
1107 DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
1108 mode file %s (%s)\n", fname, strerror(errno)));
1113 /* Now truncate the file at this point. */
1114 if(ftruncate(fd, newsize) != 0)
1116 DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
1117 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
1124 /*******************************************************************
1125 set the share mode of a file
1126 ********************************************************************/
1127 BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type)
1129 files_struct *fs_p = &Files[fnum];
1131 int fd = (int)token;
1132 int pid = (int)getpid();
1139 share_name(fs_p->cnum, fs_p->fd_ptr->dev,
1140 fs_p->fd_ptr->inode, fname);
1142 if(fstat(fd, &sb) != 0)
1144 DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
1149 /* Sanity check for file contents (if it's not a new share file). */
1152 int size = sb.st_size;
1154 /* Allocate space for the file plus one extra entry */
1155 if((buf = (char *)malloc(sb.st_size + SMF_ENTRY_LENGTH)) == NULL)
1157 DEBUG(0,("set_share_mode: malloc for file size %d fail !\n",
1158 sb.st_size + SMF_ENTRY_LENGTH));
1162 if(lseek(fd, 0, SEEK_SET) != 0)
1164 DEBUG(0,("ERROR: set_share_mode: Failed to reset position \
1165 to 0 for share file %s (%s)\n", fname, strerror(errno)));
1171 if (read(fd,buf,sb.st_size) != sb.st_size)
1173 DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n",
1174 fname, strerror(errno)));
1180 if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION)
1182 DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \
1183 locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET),
1187 delete_share_file(fs_p->cnum, fname);
1191 size -= (SMF_HEADER_LENGTH + SVAL(buf, SMF_FILENAME_LEN_OFFSET)); /* Remove the header */
1193 /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
1194 if((size % SMF_ENTRY_LENGTH) != 0)
1196 DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \
1197 deleting it.\n", fname));
1200 delete_share_file(fs_p->cnum, fname);
1207 /* New file - just use a single_entry. */
1208 if((buf = (char *)malloc(SMF_HEADER_LENGTH +
1209 strlen(fs_p->name) + 1 + SMF_ENTRY_LENGTH)) == NULL)
1211 DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
1214 SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION);
1215 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0);
1216 SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fs_p->name) + 1);
1217 strcpy(buf + SMF_HEADER_LENGTH, fs_p->name);
1220 num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
1221 header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
1222 p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH);
1223 SIVAL(p,SME_SEC_OFFSET,fs_p->open_time.tv_sec);
1224 SIVAL(p,SME_USEC_OFFSET,fs_p->open_time.tv_usec);
1225 SIVAL(p,SME_SHAREMODE_OFFSET,fs_p->share_mode);
1226 SIVAL(p,SME_PID_OFFSET,pid);
1228 SSVAL(p,SME_PORT_OFFSET,port);
1229 SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
1230 #endif /* USE_OPLOCKS */
1234 SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries);
1236 if(lseek(fd, 0, SEEK_SET) != 0)
1238 DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \
1239 0 for share file %s (%s)\n", fname, strerror(errno)));
1245 if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) !=
1246 (header_size + (num_entries*SMF_ENTRY_LENGTH)))
1248 DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
1249 deleting it (%s).\n",fname, strerror(errno)));
1250 delete_share_file(fs_p->cnum, fname);
1256 /* Now truncate the file at this point - just for safety. */
1257 if(ftruncate(fd, header_size + (SMF_ENTRY_LENGTH*num_entries))!= 0)
1259 DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
1260 mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries),
1270 DEBUG(3,("set_share_mode: Created share file %s with \
1271 mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid));
1275 #endif /* FAST_SHARE_MODES */