home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Networking / SambaManager / samba-1.9.17p4 / source / locking.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-30  |  37.6 KB  |  1,302 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    Locking functions
  5.    Copyright (C) Andrew Tridgell 1992-1997
  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.    Revision History:
  22.  
  23.    12 aug 96: Erik.Devriendt@te6.siemens.be
  24.    added support for shared memory implementation of share mode locking
  25.  
  26.    May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
  27.    locking to deal with multiple share modes per open file.
  28. */
  29.  
  30. #include "includes.h"
  31. extern int DEBUGLEVEL;
  32. extern connection_struct Connections[];
  33. extern files_struct Files[];
  34.  
  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)
  39. {
  40.   int snum = SNUM(cnum);
  41.  
  42.   if (count == 0)
  43.     return(False);
  44.  
  45.   if (!lp_locking(snum) || !lp_strict_locking(snum))
  46.     return(False);
  47.  
  48.   return(fcntl_lock(Files[fnum].fd_ptr->fd,F_GETLK,offset,count,
  49.             (Files[fnum].can_write?F_WRLCK:F_RDLCK)));
  50. }
  51.  
  52.  
  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)
  57. {
  58.   BOOL ok = False;
  59.  
  60.   if (!lp_locking(SNUM(cnum)))
  61.     return(True);
  62.  
  63.   if (count == 0) {
  64.     *eclass = ERRDOS;
  65.     *ecode = ERRnoaccess;
  66.     return False;
  67.   }
  68.  
  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));
  72.  
  73.   if (!ok) {
  74.     *eclass = ERRDOS;
  75.     *ecode = ERRlock;
  76.     return False;
  77.   }
  78.   return True; /* Got lock */
  79. }
  80.  
  81.  
  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)
  86. {
  87.   BOOL ok = False;
  88.  
  89.   if (!lp_locking(SNUM(cnum)))
  90.     return(True);
  91.  
  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);
  94.    
  95.   if (!ok) {
  96.     *eclass = ERRDOS;
  97.     *ecode = ERRlock;
  98.     return False;
  99.   }
  100.   return True; /* Did unlock */
  101. }
  102.  
  103. #ifdef FAST_SHARE_MODES
  104. /*******************************************************************
  105.   initialize the shared memory for share_mode management 
  106.   ******************************************************************/
  107. BOOL start_share_mode_mgmt(void)
  108. {
  109.    pstring shmem_file_name;
  110.    
  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());
  118. }
  119.  
  120.  
  121. /*******************************************************************
  122.   deinitialize the shared memory for share_mode management 
  123.   ******************************************************************/
  124. BOOL stop_share_mode_mgmt(void)
  125. {
  126.    return smb_shm_close();
  127. }
  128.  
  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)
  133. {
  134.   return smb_shm_lock_hash_entry(HASH_ENTRY(dev, inode));
  135. }
  136.  
  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)
  141. {
  142.   return smb_shm_unlock_hash_entry(HASH_ENTRY(dev, inode));
  143. }
  144.  
  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)
  150. {
  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;
  157.   int num_entries;
  158.   int num_entries_copied;
  159.   BOOL found = False;
  160.   min_share_mode_entry *share_array = (min_share_mode_entry *)0;
  161.  
  162.   *old_shares = 0;
  163.  
  164.   if(hash_entry > lp_shmem_hash_size() )
  165.   {
  166.     DEBUG(0, 
  167.       ("PANIC ERROR : get_share_modes (FAST_SHARE_MODES): hash_entry %d too large \
  168. (max = %d)\n",
  169.       hash_entry, lp_shmem_hash_size() ));
  170.     return 0;
  171.   }
  172.  
  173.   mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
  174.   
  175.   if(mode_array[hash_entry] == NULL_OFFSET)
  176.   {
  177.     DEBUG(5,("get_share_modes (FAST_SHARE_MODES): hash bucket %d empty\n", hash_entry));
  178.     return 0;
  179.   }
  180.  
  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)
  184.   {
  185.      if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
  186.      {
  187.     found = True;
  188.     break;
  189.      }
  190.      else
  191.      {
  192.     file_prev_p = file_scanner_p ;
  193.     file_scanner_p = (share_mode_record *)smb_shm_offset2addr(
  194.                                                 file_scanner_p->next_offset);
  195.      }
  196.   }
  197.   
  198.   if(!found)
  199.   {
  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));
  202.      return (0);
  203.   }
  204.   
  205.   if(file_scanner_p->locking_version != LOCKING_VERSION)
  206.   {
  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\n",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;
  212.      else
  213.     file_prev_p->next_offset = file_scanner_p->next_offset;
  214.      smb_shm_free(smb_shm_addr2offset(file_scanner_p));
  215.      return (0);
  216.   }
  217.  
  218.   /* Allocate the old_shares array */
  219.   num_entries = file_scanner_p->num_share_mode_entries;
  220.   if(num_entries)
  221.   {
  222.     *old_shares = share_array = (min_share_mode_entry *)
  223.                  malloc(num_entries * sizeof(min_share_mode_entry));
  224.     if(*old_shares == 0)
  225.     {
  226.       DEBUG(0,("get_share_modes (FAST_SHARE_MODES): malloc fail !\n"));
  227.       return 0;
  228.     }
  229.   }
  230.  
  231.   num_entries_copied = 0;
  232.   
  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)
  237.   {
  238.     int pid = entry_scanner_p->pid;
  239.  
  240.     if (pid && !process_exists(pid))
  241.     {
  242.       /* Delete this share mode entry */
  243.       share_mode_entry *delete_entry_p = entry_scanner_p;
  244.       int share_mode = entry_scanner_p->share_mode;
  245.  
  246.       if(entry_prev_p == entry_scanner_p)
  247.       {
  248.         /* We are at start of list */
  249.         file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
  250.         entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
  251.                                            file_scanner_p->share_mode_entries);
  252.         entry_prev_p = entry_scanner_p;
  253.       }
  254.       else
  255.       {
  256.         entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
  257.         entry_scanner_p = (share_mode_entry*)
  258.                            smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
  259.       }
  260.       /* Decrement the number of share mode entries on this share mode record */
  261.       file_scanner_p->num_share_mode_entries -= 1;
  262.  
  263.       /* PARANOIA TEST */
  264.       if(file_scanner_p->num_share_mode_entries < 0)
  265.       {
  266.         DEBUG(0,("PANIC ERROR:get_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
  267. for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries,
  268.              dev, inode, hash_entry));
  269.         return 0;
  270.       }
  271.  
  272.       DEBUG(0,("get_share_modes (FAST_SHARE_MODES): process %d no longer exists and \
  273. it left a share mode entry with mode 0x%X for file dev = %d, ino = %d in hash \
  274. bucket %d (number of entries now = %d)\n", 
  275.             pid, share_mode, dev, inode, hash_entry,
  276.             file_scanner_p->num_share_mode_entries));
  277.  
  278.       smb_shm_free(smb_shm_addr2offset(delete_entry_p));
  279.     } 
  280.     else
  281.     {
  282.        /* This is a valid share mode entry and the process that
  283.            created it still exists. Copy it into the output array.
  284.        */
  285.        share_array[num_entries_copied].pid = entry_scanner_p->pid;
  286.        share_array[num_entries_copied].share_mode = entry_scanner_p->share_mode;
  287.        memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->time,
  288.               sizeof(struct timeval));
  289.        num_entries_copied++;
  290.        DEBUG(5,("get_share_modes (FAST_SHARE_MODES): Read share mode \
  291. record mode 0x%X pid=%d\n", entry_scanner_p->share_mode, entry_scanner_p->pid));
  292.        entry_prev_p = entry_scanner_p;
  293.        entry_scanner_p = (share_mode_entry *)
  294.                            smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
  295.     }
  296.   }
  297.   
  298.   /* If no valid share mode entries were found then this record shouldn't exist ! */
  299.   if(num_entries_copied == 0)
  300.   {
  301.     DEBUG(0,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
  302. hash bucket %d has a share mode record but no entries - deleting\n", 
  303.                  dev, inode, hash_entry));
  304.     if(*old_shares)
  305.       free((char *)*old_shares);
  306.     *old_shares = 0;
  307.  
  308.     if(file_prev_p == file_scanner_p)
  309.       mode_array[hash_entry] = file_scanner_p->next_offset;
  310.     else
  311.       file_prev_p->next_offset = file_scanner_p->next_offset;
  312.     smb_shm_free(smb_shm_addr2offset(file_scanner_p));
  313.   }
  314.  
  315.   DEBUG(5,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
  316. hash bucket %d returning %d entries\n", dev, inode, hash_entry,
  317.                          num_entries_copied));
  318.  
  319.   return(num_entries_copied);
  320. }  
  321.  
  322. /*******************************************************************
  323. del the share mode of a file.
  324. ********************************************************************/
  325. void del_share_mode(share_lock_token token, int fnum)
  326. {
  327.   uint32 dev, inode;
  328.   smb_shm_offset_t *mode_array;
  329.   unsigned int hash_entry;
  330.   share_mode_record *file_scanner_p;
  331.   share_mode_record *file_prev_p;
  332.   share_mode_entry *entry_scanner_p;
  333.   share_mode_entry *entry_prev_p;
  334.   BOOL found = False;
  335.   int pid = getpid();
  336.  
  337.   dev = Files[fnum].fd_ptr->dev;
  338.   inode = Files[fnum].fd_ptr->inode;
  339.  
  340.   hash_entry = HASH_ENTRY(dev, inode);
  341.  
  342.   if(hash_entry > lp_shmem_hash_size() )
  343.   {
  344.     DEBUG(0,
  345.       ("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash_entry %d too large \
  346. (max = %d)\n",
  347.       hash_entry, lp_shmem_hash_size() ));
  348.     return;
  349.   }
  350.  
  351.   mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
  352.  
  353.   if(mode_array[hash_entry] == NULL_OFFSET)
  354.   {  
  355.     DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash bucket %d empty\n", 
  356.                   hash_entry));
  357.     return;
  358.   }  
  359.   
  360.   file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
  361.   file_prev_p = file_scanner_p;
  362.  
  363.   while(file_scanner_p)
  364.   {
  365.      if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
  366.      {
  367.     found = True;
  368.     break;
  369.      }
  370.      else
  371.      {
  372.     file_prev_p = file_scanner_p ;
  373.     file_scanner_p = (share_mode_record *)
  374.                           smb_shm_offset2addr(file_scanner_p->next_offset);
  375.      }
  376.   }
  377.     
  378.   if(!found)
  379.   {
  380.      DEBUG(0,("ERROR:del_share_mode (FAST_SHARE_MODES): no entry found for dev %d, \
  381. inode %d in hash bucket %d\n", dev, inode, hash_entry));
  382.      return;
  383.   }
  384.   
  385.   if(file_scanner_p->locking_version != LOCKING_VERSION)
  386.   {
  387.      DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): Deleting old share mode \
  388. record due to old locking version %d for file dev %d, inode %d hash bucket %d\n",
  389.        file_scanner_p->locking_version, dev, inode, hash_entry ));
  390.      if(file_prev_p == file_scanner_p)
  391.     mode_array[hash_entry] = file_scanner_p->next_offset;
  392.      else
  393.     file_prev_p->next_offset = file_scanner_p->next_offset;
  394.      smb_shm_free(smb_shm_addr2offset(file_scanner_p));
  395.      return;
  396.   }
  397.  
  398.   found = False;
  399.   entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
  400.                                            file_scanner_p->share_mode_entries);
  401.   entry_prev_p = entry_scanner_p;
  402.   while(entry_scanner_p)
  403.   {
  404.     if( (pid == entry_scanner_p->pid) && 
  405.           (memcmp(&entry_scanner_p->time, 
  406.                  &Files[fnum].open_time,sizeof(struct timeval)) == 0) )
  407.     {
  408.       found = True;
  409.       break;
  410.     }
  411.     else
  412.     {
  413.       entry_prev_p = entry_scanner_p;
  414.       entry_scanner_p = (share_mode_entry *)
  415.                           smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
  416.     }
  417.   } 
  418.  
  419.   if (found)
  420.   {
  421.     /* Decrement the number of entries in the record. */
  422.     file_scanner_p->num_share_mode_entries -= 1;
  423.  
  424.     DEBUG(2,("del_share_modes (FAST_SHARE_MODES): \
  425. Deleting share mode entry dev = %d, inode = %d in hash bucket %d (num entries now = %d)\n",
  426.               dev, inode, hash_entry, file_scanner_p->num_share_mode_entries));
  427.     if(entry_prev_p == entry_scanner_p)
  428.       /* We are at start of list */
  429.       file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
  430.     else
  431.       entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
  432.     smb_shm_free(smb_shm_addr2offset(entry_scanner_p));
  433.  
  434.     /* PARANOIA TEST */
  435.     if(file_scanner_p->num_share_mode_entries < 0)
  436.     {
  437.       DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
  438. for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries,
  439.            dev, inode, hash_entry));
  440.       return;
  441.     }
  442.  
  443.     /* If we deleted the last share mode entry then remove the share mode record. */
  444.     if(file_scanner_p->num_share_mode_entries == 0)
  445.       {
  446.       DEBUG(2,("del_share_modes (FAST_SHARE_MODES): num entries = 0, deleting share_mode \
  447. record dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
  448.       if(file_prev_p == file_scanner_p)
  449.     mode_array[hash_entry] = file_scanner_p->next_offset;
  450.       else
  451.     file_prev_p->next_offset = file_scanner_p->next_offset;
  452.       smb_shm_free(smb_shm_addr2offset(file_scanner_p));
  453.       }
  454.   }
  455.   else
  456.   {
  457.     DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): No share mode record found \
  458. dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
  459.   }
  460. }
  461.  
  462. /*******************************************************************
  463. set the share mode of a file. Return False on fail, True on success.
  464. ********************************************************************/
  465. BOOL set_share_mode(share_lock_token token, int fnum)
  466. {
  467.   files_struct *fs_p = &Files[fnum];
  468.   int32 dev, inode;
  469.   smb_shm_offset_t *mode_array;
  470.   unsigned int hash_entry;
  471.   share_mode_record *file_scanner_p;
  472.   share_mode_record *file_prev_p;
  473.   share_mode_entry *new_entry_p;
  474.   smb_shm_offset_t new_entry_offset;
  475.   BOOL found = False;
  476.  
  477.   dev = fs_p->fd_ptr->dev;
  478.   inode = fs_p->fd_ptr->inode;
  479.  
  480.   hash_entry = HASH_ENTRY(dev, inode);
  481.   if(hash_entry > lp_shmem_hash_size() )
  482.   {
  483.     DEBUG(0,
  484.       ("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): hash_entry %d too large \
  485. (max = %d)\n",
  486.       hash_entry, lp_shmem_hash_size() ));
  487.     return False;
  488.   }
  489.  
  490.   mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
  491.  
  492.   file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
  493.   file_prev_p = file_scanner_p;
  494.   
  495.   while(file_scanner_p)
  496.   {
  497.      if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
  498.      {
  499.         found = True;
  500.         break;
  501.      }
  502.      else
  503.      {
  504.         file_prev_p = file_scanner_p ;
  505.         file_scanner_p = (share_mode_record *)
  506.                           smb_shm_offset2addr(file_scanner_p->next_offset);
  507.      }
  508.   }
  509.   
  510.   if(!found)
  511.   {
  512.     /* We must create a share_mode_record */
  513.     share_mode_record *new_mode_p = NULL;
  514.     smb_shm_offset_t new_offset = smb_shm_alloc( sizeof(share_mode_record) +
  515.                                         strlen(fs_p->name) + 1);
  516.     if(new_offset == NULL_OFFSET)
  517.     {
  518.       DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail !\n"));
  519.       return False;
  520.     }
  521.     new_mode_p = smb_shm_offset2addr(new_offset);
  522.     new_mode_p->locking_version = LOCKING_VERSION;
  523.     new_mode_p->st_dev = dev;
  524.     new_mode_p->st_ino = inode;
  525.     new_mode_p->num_share_mode_entries = 0;
  526.     new_mode_p->share_mode_entries = NULL_OFFSET;
  527.     strcpy(new_mode_p->file_name, fs_p->name);
  528.  
  529.     /* Chain onto the start of the hash chain (in the hope we will be used first). */
  530.     new_mode_p->next_offset = mode_array[hash_entry];
  531.     mode_array[hash_entry] = new_offset;
  532.  
  533.     file_scanner_p = new_mode_p;
  534.  
  535.     DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share record for %s (dev %d \
  536. inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry));
  537.   }
  538.  
  539.   /* Now create the share mode entry */ 
  540.   new_entry_offset = smb_shm_alloc( sizeof(share_mode_entry));
  541.   if(new_entry_offset == NULL_OFFSET)
  542.   {
  543.     smb_shm_offset_t delete_offset = mode_array[hash_entry];
  544.     DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail 1!\n"));
  545.     /* Unlink the damaged record */
  546.     mode_array[hash_entry] = file_scanner_p->next_offset;
  547.     /* And delete it */
  548.     smb_shm_free( delete_offset );
  549.     return False;
  550.   }
  551.  
  552.   new_entry_p = smb_shm_offset2addr(new_entry_offset);
  553.  
  554.   new_entry_p->pid = getpid();
  555.   new_entry_p->share_mode = fs_p->share_mode;
  556.   memcpy( (char *)&new_entry_p->time, (char *)&fs_p->open_time, sizeof(struct timeval));
  557.  
  558.   /* Chain onto the share_mode_record */
  559.   new_entry_p->next_share_mode_entry = file_scanner_p->share_mode_entries;
  560.   file_scanner_p->share_mode_entries = new_entry_offset;
  561.  
  562.   /* PARANOIA TEST */
  563.   if(file_scanner_p->num_share_mode_entries < 0)
  564.   {
  565.     DEBUG(0,("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
  566. for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries,
  567.          dev, inode, hash_entry));
  568.     return False;
  569.   }
  570.  
  571.   /* Increment the share_mode_entries counter */
  572.   file_scanner_p->num_share_mode_entries += 1;
  573.  
  574.   DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share entry for %s with mode \
  575. 0x%X pid=%d (num_entries now = %d)\n",fs_p->name, fs_p->share_mode, new_entry_p->pid,
  576.                              file_scanner_p->num_share_mode_entries));
  577.  
  578.   return(True);
  579. }
  580.  
  581. #else /* FAST_SHARE_MODES */
  582.  
  583. /* SHARE MODE LOCKS USING SLOW DESCRIPTION FILES */
  584.  
  585. /*******************************************************************
  586.   name a share file
  587.   ******************************************************************/
  588. static BOOL share_name(int cnum, uint32 dev, uint32 inode, char *name)
  589. {
  590.   strcpy(name,lp_lockdir());
  591.   standard_sub(cnum,name);
  592.   trim_string(name,"","/");
  593.   if (!*name) return(False);
  594.   name += strlen(name);
  595.   
  596.   sprintf(name,"/share.%u.%u",dev,inode);
  597.   return(True);
  598. }
  599.  
  600. /*******************************************************************
  601. Force a share file to be deleted.
  602. ********************************************************************/
  603. static int delete_share_file( int cnum, char *fname )
  604. {
  605.     /* the share file could be owned by anyone, so do this as root */
  606.     become_root(0);
  607.  
  608.     if(unlink(fname) != 0) {
  609.         DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
  610.              fname, strerror(errno)));
  611.     } else {
  612.         DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
  613.     }
  614.  
  615.     unbecome_root(0);
  616.     
  617.     return 0;
  618. }
  619.  
  620. /*******************************************************************
  621.   lock a share mode file.
  622.   ******************************************************************/
  623. BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok)
  624. {
  625.   pstring fname;
  626.   int fd;
  627.   int ret = True;
  628.  
  629.   *ptok = (share_lock_token)-1;
  630.  
  631.   if(!share_name(cnum, dev, inode, fname))
  632.     return False;
  633.  
  634.   /* we need to do this as root */
  635.   become_root(0);
  636.  
  637.   {
  638.     int old_umask;
  639.     BOOL gotlock = False;
  640.     old_umask = umask(0);
  641.  
  642.     /*
  643.      * There was a race condition in the original slow share mode code.
  644.      * A smbd could open a share mode file, and before getting
  645.      * the lock, another smbd could delete the last entry for
  646.      * the share mode file and delete the file entry from the
  647.      * directory. Thus this smbd would be left with a locked
  648.      * share mode fd attached to a file that no longer had a
  649.      * directory entry. Thus another smbd would think that
  650.      * there were no outstanding opens on the file. To fix
  651.      * this we now check we can do a stat() call on the filename
  652.      * before allowing the lock to proceed, and back out completely
  653.      * and try the open again if we cannot.
  654.      * Jeremy Allison (jallison@whistle.com).
  655.      */
  656.      
  657.     do
  658.     {
  659.       struct stat dummy_stat;
  660. #ifdef SECURE_SHARE_MODES
  661.       fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600);
  662. #else /* SECURE_SHARE_MODES */
  663.       fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666);
  664. #endif /* SECURE_SHARE_MODES */
  665.  
  666.       if(fd < 0)
  667.       {
  668.         DEBUG(0,("ERROR lock_share_entry: failed to open share file %s. Error was %s\n",
  669.                   fname, strerror(errno)));
  670.         ret = False;
  671.         break;
  672.       }
  673.  
  674.       /* At this point we have an open fd to the share mode file. 
  675.          Lock the first byte exclusively to signify a lock. */
  676.       if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
  677.       {
  678.         DEBUG(0,("ERROR lock_share_entry: fcntl_lock failed with %s\n",
  679.                   strerror(errno)));   
  680.         close(fd);
  681.         ret = False;
  682.         break;
  683.       }
  684.  
  685.       /*
  686.        * If we cannot stat the filename, the file was deleted between
  687.        * the open and the lock call. Back out and try again.
  688.        */
  689.      
  690.       if(stat(fname, &dummy_stat)!=0)
  691.       {
  692.         DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n",
  693.                 fname, strerror(errno)));
  694.         close(fd);
  695.       }
  696.       else
  697.         gotlock = True;
  698.     } while(!gotlock);
  699.  
  700.     umask(old_umask);
  701.   }
  702.  
  703.   *ptok = (share_lock_token)fd;
  704.  
  705.   /* return to our previous privilage level */
  706.   unbecome_root(0);
  707.  
  708.   return ret;
  709. }
  710.  
  711. /*******************************************************************
  712.   unlock a share mode file.
  713.   ******************************************************************/
  714. BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token)
  715. {
  716.   int fd = (int)token;
  717.   int ret = True;
  718.   struct stat sb;
  719.   pstring fname;
  720.     
  721.   /* Fix for zero length share files from  
  722.      Gerald Werner <wernerg@mfldclin.edu> */
  723.  
  724.   share_name(cnum, dev, inode, fname);
  725.  
  726.   /* get the share mode file size */
  727.   if(fstat((int)token, &sb) != 0)
  728.   {
  729.     DEBUG(0,("ERROR: unlock_share_entry: Failed to do stat on share file %s (%s)\n",
  730.               fname, strerror(errno)));
  731.     sb.st_size = 1;
  732.     ret = False;
  733.   }
  734.  
  735.   /* If the file was zero length, we must delete before
  736.      doing the unlock to avoid a race condition (see
  737.      the code in lock_share_mode_entry for details.
  738.    */
  739.  
  740.   /* remove the share file if zero length */
  741.   if(sb.st_size == 0)
  742.     delete_share_file(cnum, fname);
  743.  
  744.   /* token is the fd of the open share mode file. */
  745.   /* Unlock the first byte. */
  746.   if(fcntl_lock(fd, F_SETLKW, 0, 1, F_UNLCK) == False)
  747.    { 
  748.       DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n",
  749.                       strerror(errno)));   
  750.       ret = False;
  751.    }
  752.  
  753.   close((int)token);
  754.   return ret;
  755. }
  756.  
  757. /*******************************************************************
  758. Read a share file into a buffer.
  759. ********************************************************************/
  760.  
  761. static int read_share_file(int cnum, int fd, char *fname, char **out, BOOL *p_new_file)
  762. {
  763.   struct stat sb;
  764.   char *buf;
  765.   int size;
  766.  
  767.   *out = 0;
  768.   *p_new_file = False;
  769.  
  770.   if(fstat(fd, &sb) != 0)
  771.   {
  772.     DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
  773.                   fname, strerror(errno)));
  774.     return -1;
  775.   }
  776.  
  777.   if(sb.st_size == 0)
  778.   {
  779.      *p_new_file = True;
  780.      return 0;
  781.   }
  782.  
  783.   /* Allocate space for the file */
  784.   if((buf = (char *)malloc(sb.st_size)) == NULL)
  785.   {
  786.     DEBUG(0,("read_share_file: malloc for file size %d fail !\n", sb.st_size));
  787.     return -1;
  788.   }
  789.   
  790.   if(lseek(fd, 0, SEEK_SET) != 0)
  791.   {
  792.     DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \
  793. for share file %s (%s)\n", fname, strerror(errno)));
  794.     if(buf)
  795.       free(buf);
  796.     return -1;
  797.   }
  798.   
  799.   if (read(fd,buf,sb.st_size) != sb.st_size)
  800.   {
  801.     DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n",
  802.                fname, strerror(errno)));
  803.     if(buf)
  804.       free(buf);
  805.     return -1;
  806.   }
  807.   
  808.   if (IVAL(buf,0) != LOCKING_VERSION) {
  809.     DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \
  810. locking version (was %d, should be %d).\n",fname, IVAL(buf,0), LOCKING_VERSION));
  811.     if(buf)
  812.       free(buf);
  813.     delete_share_file(cnum, fname);
  814.     return -1;
  815.   }
  816.  
  817.   /* Sanity check for file contents */
  818.   size = sb.st_size;
  819.   size -= 10; /* Remove the header */
  820.  
  821.   /* Remove the filename component. */
  822.   size -= SVAL(buf, 8);
  823.  
  824.   /* The remaining size must be a multiple of 16 - error if not. */
  825.   if((size % 16) != 0)
  826.   {
  827.     DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \
  828. deleting it.\n", fname));
  829.     if(buf)
  830.       free(buf);
  831.     delete_share_file(cnum, fname);
  832.     return -1;
  833.   }
  834.  
  835.   *out = buf;
  836.   return 0;
  837. }
  838.  
  839. /*******************************************************************
  840. get all share mode entries in a share file for a dev/inode pair.
  841. ********************************************************************/
  842. int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, 
  843.                     min_share_mode_entry **old_shares)
  844. {
  845.   int fd = (int)token;
  846.   pstring fname;
  847.   int i;
  848.   int num_entries;
  849.   int num_entries_copied;
  850.   int newsize;
  851.   min_share_mode_entry *share_array;
  852.   char *buf = 0;
  853.   char *base = 0;
  854.   BOOL new_file;
  855.  
  856.   *old_shares = 0;
  857.  
  858.   /* Read the share file header - this is of the form:
  859.      0   -  locking version.
  860.      4   -  number of share mode entries.
  861.      8   -  2 byte name length
  862.      [n bytes] file name (zero terminated).
  863.  
  864.    Followed by <n> share mode entries of the form :
  865.  
  866.      0   -  tv_sec
  867.      4   -  tv_usec
  868.      8   -  share_mode
  869.     12   -  pid
  870.  
  871.   */
  872.  
  873.   share_name(cnum, dev, inode, fname);
  874.  
  875.   if(read_share_file( cnum, fd, fname, &buf, &new_file) != 0)
  876.   {
  877.     DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n",
  878.                   fname));
  879.     return 0;
  880.   }
  881.  
  882.   if(new_file == True)
  883.     return 0;
  884.  
  885.   num_entries = IVAL(buf,4);
  886.  
  887.   DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n",
  888.             fname, num_entries));
  889.  
  890.   /* PARANOIA TEST */
  891.   if(num_entries < 0)
  892.   {
  893.     DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \
  894. for share file %d\n", num_entries, fname));
  895.     return 0;
  896.   }
  897.  
  898.   if(num_entries)
  899.   {
  900.     *old_shares = share_array = (min_share_mode_entry *)
  901.                  malloc(num_entries * sizeof(min_share_mode_entry));
  902.     if(*old_shares == 0)
  903.     {
  904.       DEBUG(0,("get_share_modes: malloc fail !\n"));
  905.       return 0;
  906.     }
  907.   } 
  908.   else
  909.   {
  910.     /* No entries - just delete the file. */
  911.     DEBUG(0,("get_share_modes: share file %s has no share mode entries - deleting.\n",
  912.               fname));
  913.     if(buf)
  914.       free(buf);
  915.     delete_share_file(cnum, fname);
  916.     return 0;
  917.   }
  918.  
  919.   num_entries_copied = 0;
  920.   base = buf + 10 + SVAL(buf,8);
  921.  
  922.   for( i = 0; i < num_entries; i++)
  923.   {
  924.     int pid;
  925.     char *p = base + (i*16);
  926.  
  927.     pid = IVAL(p,12);
  928.  
  929.     if(!process_exists(pid))
  930.     {
  931.       DEBUG(0,("get_share_modes: process %d no longer exists and \
  932. it left a share mode entry with mode 0x%X in share file %s\n",
  933.             pid, IVAL(p,8), fname));
  934.       continue;
  935.     }
  936.     share_array[num_entries_copied].time.tv_sec = IVAL(p,0);
  937.     share_array[num_entries_copied].time.tv_usec = IVAL(p,4);
  938.     share_array[num_entries_copied].share_mode = IVAL(p,8);
  939.     share_array[num_entries_copied].pid = pid;
  940.  
  941.     num_entries_copied++;
  942.   }
  943.  
  944.   if(num_entries_copied == 0)
  945.   {
  946.     /* Delete the whole file. */
  947.     DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n",
  948.              fname));
  949.     if(*old_shares)
  950.       free((char *)*old_shares);
  951.     *old_shares = 0;
  952.     if(buf)
  953.       free(buf);
  954.     delete_share_file(cnum, fname);
  955.     return 0;
  956.   }
  957.  
  958.   /* If we deleted some entries we need to re-write the whole number of
  959.      share mode entries back into the file. */
  960.  
  961.   if(num_entries_copied != num_entries)
  962.   {
  963.     if(lseek(fd, 0, SEEK_SET) != 0)
  964.     {
  965.       DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \
  966. position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
  967.       if(*old_shares)
  968.         free((char *)*old_shares);
  969.       *old_shares = 0;
  970.       if(buf)
  971.         free(buf);
  972.       return 0;
  973.     }
  974.  
  975.     SIVAL(buf, 4, num_entries_copied);
  976.     for( i = 0; i < num_entries_copied; i++)
  977.     {
  978.       char *p = base + (i*16);
  979.  
  980.       SIVAL(p,12,share_array[i].pid);
  981.       SIVAL(p,8,share_array[i].share_mode);
  982.       SIVAL(p,0,share_array[i].time.tv_sec);
  983.       SIVAL(p,4,share_array[i].time.tv_usec);
  984.     }
  985.  
  986.     newsize = (base - buf) + (16*num_entries_copied);
  987.     if(write(fd, buf, newsize) != newsize)
  988.     {
  989.       DEBUG(0,("ERROR: get_share_modes: failed to re-write share \
  990. mode file %s (%s)\n", fname, strerror(errno)));
  991.       if(*old_shares)
  992.         free((char *)*old_shares);
  993.       *old_shares = 0;
  994.       if(buf)
  995.         free(buf);
  996.       return 0;
  997.     }
  998.     /* Now truncate the file at this point. */
  999.     if(ftruncate(fd, newsize)!= 0)
  1000.     {
  1001.       DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
  1002. mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
  1003.       if(*old_shares)
  1004.         free((char *)*old_shares);
  1005.       *old_shares = 0;
  1006.       if(buf)
  1007.         free(buf);
  1008.       return 0;
  1009.     }
  1010.   }
  1011.  
  1012.   if(buf)
  1013.     free(buf);
  1014.  
  1015.   DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname,
  1016.             num_entries_copied));
  1017.  
  1018.   return num_entries_copied;
  1019. }
  1020.  
  1021. /*******************************************************************
  1022. del a share mode from a share mode file.
  1023. ********************************************************************/
  1024. void del_share_mode(share_lock_token token, int fnum)
  1025. {
  1026.   pstring fname;
  1027.   int fd = (int)token;
  1028.   char *buf = 0;
  1029.   char *base = 0;
  1030.   int num_entries;
  1031.   int newsize;
  1032.   int i;
  1033.   files_struct *fs_p = &Files[fnum];
  1034.   int pid;
  1035.   BOOL deleted = False;
  1036.   BOOL new_file;
  1037.  
  1038.   share_name(fs_p->cnum, fs_p->fd_ptr->dev, 
  1039.                        fs_p->fd_ptr->inode, fname);
  1040.  
  1041.   if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
  1042.   {
  1043.     DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n",
  1044.                   fname));
  1045.     return;
  1046.   }
  1047.  
  1048.   if(new_file == True)
  1049.   {
  1050.     DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n",
  1051.               fname));
  1052.     delete_share_file(fs_p->cnum, fname);
  1053.     return;
  1054.   }
  1055.  
  1056.   num_entries = IVAL(buf,4);
  1057.  
  1058.   DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n",
  1059.             fname, num_entries));
  1060.  
  1061.   /* PARANOIA TEST */
  1062.   if(num_entries < 0)
  1063.   {
  1064.     DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \
  1065. for share file %d\n", num_entries, fname));
  1066.     return;
  1067.   }
  1068.  
  1069.   if(num_entries == 0)
  1070.   {
  1071.     /* No entries - just delete the file. */
  1072.     DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n",
  1073.               fname));
  1074.     if(buf)
  1075.       free(buf);
  1076.     delete_share_file(fs_p->cnum, fname);
  1077.     return;
  1078.   }
  1079.  
  1080.   pid = getpid();
  1081.  
  1082.   /* Go through the entries looking for the particular one
  1083.      we have set - delete it.
  1084.   */
  1085.  
  1086.   base = buf + 10 + SVAL(buf,8);
  1087.  
  1088.   for(i = 0; i < num_entries; i++)
  1089.   {
  1090.     char *p = base + (i*16);
  1091.  
  1092.     if((IVAL(p,0) != fs_p->open_time.tv_sec) || (IVAL(p,4) != fs_p->open_time.tv_usec) ||
  1093.         (IVAL(p,8) != fs_p->share_mode) || (IVAL(p,12) != pid))
  1094.       continue;
  1095.  
  1096.     DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
  1097.              i, num_entries, fname));
  1098.  
  1099.     /* Remove this entry. */
  1100.     if(i != num_entries - 1)
  1101.       memcpy(p, p + 16, (num_entries - i - 1)*16);
  1102.  
  1103.     deleted = True;
  1104.     break;
  1105.   }
  1106.  
  1107.   if(!deleted)
  1108.   {
  1109.     DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname));
  1110.     if(buf)
  1111.       free(buf);
  1112.     return;
  1113.   }
  1114.  
  1115.   num_entries--;
  1116.   SIVAL(buf,4, num_entries);
  1117.  
  1118.   if(num_entries == 0)
  1119.   {
  1120.     /* Deleted the last entry - remove the file. */
  1121.     DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n",
  1122.              fname));
  1123.     if(buf)
  1124.       free(buf);
  1125.     delete_share_file(fs_p->cnum,fname);
  1126.     return;
  1127.   }
  1128.  
  1129.   /* Re-write the file - and truncate it at the correct point. */
  1130.   if(lseek(fd, 0, SEEK_SET) != 0)
  1131.     {
  1132.       DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
  1133. position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
  1134.       if(buf)
  1135.         free(buf);
  1136.       return;
  1137.     }
  1138.  
  1139.   newsize = (base - buf) + (16*num_entries);
  1140.   if(write(fd, buf, newsize) != newsize)
  1141.     {
  1142.       DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
  1143. mode file %s (%s)\n", fname, strerror(errno)));
  1144.       if(buf)
  1145.         free(buf);
  1146.       return;
  1147.     }
  1148.   /* Now truncate the file at this point. */
  1149.   if(ftruncate(fd, newsize) != 0)
  1150.   {
  1151.     DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
  1152. mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
  1153.     if(buf)
  1154.       free(buf);
  1155.     return;
  1156.   }
  1157. }
  1158.   
  1159. /*******************************************************************
  1160. set the share mode of a file
  1161. ********************************************************************/
  1162. BOOL set_share_mode(share_lock_token token,int fnum)
  1163. {
  1164.   files_struct *fs_p = &Files[fnum];
  1165.   pstring fname;
  1166.   int fd = (int)token;
  1167.   int pid = (int)getpid();
  1168.   struct stat sb;
  1169.   char *buf;
  1170.   int num_entries;
  1171.   int header_size;
  1172.   char *p;
  1173.  
  1174.   share_name(fs_p->cnum, fs_p->fd_ptr->dev,
  1175.                        fs_p->fd_ptr->inode, fname);
  1176.  
  1177.   if(fstat(fd, &sb) != 0)
  1178.   {
  1179.     DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
  1180.                   fname));
  1181.     return False;
  1182.   }
  1183.  
  1184.   /* Sanity check for file contents (if it's not a new share file). */
  1185.   if(sb.st_size != 0)
  1186.   {
  1187.     int size = sb.st_size;
  1188.  
  1189.     /* Allocate space for the file plus one extra entry */
  1190.     if((buf = (char *)malloc(sb.st_size + 16)) == NULL)
  1191.     {
  1192.       DEBUG(0,("set_share_mode: malloc for file size %d fail !\n", sb.st_size + 16));
  1193.       return False;
  1194.     }
  1195.  
  1196.     if(lseek(fd, 0, SEEK_SET) != 0)
  1197.     {
  1198.       DEBUG(0,("ERROR: set_share_mode: Failed to reset position \
  1199. to 0 for share file %s (%s)\n", fname, strerror(errno)));
  1200.       if(buf)
  1201.         free(buf);
  1202.       return False;
  1203.     }
  1204.  
  1205.     if (read(fd,buf,sb.st_size) != sb.st_size)
  1206.     {
  1207.       DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n",
  1208.                   fname, strerror(errno)));
  1209.       if(buf)
  1210.         free(buf);
  1211.       return False;
  1212.     }   
  1213.   
  1214.     if (IVAL(buf,0) != LOCKING_VERSION) 
  1215.     {
  1216.       DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \
  1217. locking version (was %d, should be %d).\n",fname, IVAL(buf,0), LOCKING_VERSION));
  1218.       if(buf)
  1219.         free(buf);
  1220.       delete_share_file(fs_p->cnum, fname);
  1221.       return False;
  1222.     }   
  1223.  
  1224.     size -= (10 + SVAL(buf, 8)); /* Remove the header */
  1225.  
  1226.     /* The remaining size must be a multiple of 16 - error if not. */
  1227.     if((size % 16) != 0)
  1228.     {
  1229.       DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \
  1230. deleting it.\n", fname));
  1231.       if(buf)
  1232.         free(buf);
  1233.       delete_share_file(fs_p->cnum, fname);
  1234.       return False;
  1235.     }
  1236.  
  1237.   }
  1238.   else
  1239.   {
  1240.     /* New file - just use a single_entry. */
  1241.     if((buf = (char *)malloc(10 + strlen(fs_p->name) + 1 + 16)) == NULL)
  1242.     {
  1243.       DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
  1244.       return False;
  1245.     }
  1246.     SIVAL(buf,0,LOCKING_VERSION);
  1247.     SIVAL(buf,4,0);
  1248.     SSVAL(buf,8,strlen(fs_p->name) + 1);
  1249.     strcpy(buf + 10, fs_p->name);
  1250.   }
  1251.  
  1252.   num_entries = IVAL(buf,4);
  1253.   header_size = 10 + SVAL(buf,8);
  1254.   p = buf + header_size + (num_entries * 16);
  1255.   SIVAL(p,0,fs_p->open_time.tv_sec);
  1256.   SIVAL(p,4,fs_p->open_time.tv_usec);
  1257.   SIVAL(p,8,fs_p->share_mode);
  1258.   SIVAL(p,12,pid);
  1259.  
  1260.   num_entries++;
  1261.  
  1262.   SIVAL(buf,4,num_entries);
  1263.  
  1264.   if(lseek(fd, 0, SEEK_SET) != 0)
  1265.   {
  1266.     DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \
  1267. 0 for share file %s (%s)\n", fname, strerror(errno)));
  1268.     if(buf)
  1269.       free(buf);
  1270.     return False;
  1271.   }
  1272.  
  1273.   if (write(fd,buf,header_size + (num_entries*16)) != (header_size + (num_entries*16))) 
  1274.   {
  1275.     DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
  1276. deleting it (%s).\n",fname, strerror(errno)));
  1277.     delete_share_file(fs_p->cnum, fname);
  1278.     if(buf)
  1279.       free(buf);
  1280.     return False;
  1281.   }
  1282.  
  1283.   /* Now truncate the file at this point - just for safety. */
  1284.   if(ftruncate(fd, header_size + (16*num_entries))!= 0)
  1285.   {
  1286.     DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
  1287. mode file %s to size %d (%s)\n", fname, header_size + (16*num_entries), strerror(errno)));
  1288.     if(buf)
  1289.       free(buf);
  1290.     return False;
  1291.   }
  1292.  
  1293.   if(buf)
  1294.     free(buf);
  1295.  
  1296.   DEBUG(3,("set_share_mode: Created share file %s with \
  1297. mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid));
  1298.  
  1299.   return True;
  1300. }
  1301. #endif /* FAST_SHARE_MODES */
  1302.