home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 July & August / Pcwk78a98.iso / Wtestowe / Clico / UNIX / SAMBA / SOURCE / SAMBA.TAR / samba-1.9.17 / source / locking.c < prev    next >
C/C++ Source or Header  |  1997-07-18  |  37KB  |  1,248 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.   strcpy(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",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.  
  245.       if(entry_prev_p == entry_scanner_p)
  246.       {
  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;
  252.       }
  253.       else
  254.       {
  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);
  258.       }
  259.       /* Decrement the number of share mode entries on this share mode record */
  260.       file_scanner_p->num_share_mode_entries -= 1;
  261.  
  262.       /* PARANOIA TEST */
  263.       if(file_scanner_p->num_share_mode_entries < 0)
  264.       {
  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));
  268.         return 0;
  269.       }
  270.  
  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));
  276.  
  277.       smb_shm_free(smb_shm_addr2offset(delete_entry_p));
  278.     } 
  279.     else
  280.     {
  281.        /* This is a valid share mode entry and the process that
  282.            created it still exists. Copy it into the output array.
  283.        */
  284.        share_array[num_entries_copied].pid = entry_scanner_p->pid;
  285.        share_array[num_entries_copied].share_mode = entry_scanner_p->share_mode;
  286.        memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->time,
  287.               sizeof(struct timeval));
  288.        num_entries_copied++;
  289.        DEBUG(5,("get_share_modes (FAST_SHARE_MODES): Read share mode \
  290. record mode 0x%X pid=%d\n", entry_scanner_p->share_mode, entry_scanner_p->pid));
  291.        entry_prev_p = entry_scanner_p;
  292.        entry_scanner_p = (share_mode_entry *)
  293.                            smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
  294.     }
  295.   }
  296.   
  297.   /* If no valid share mode entries were found then this record shouldn't exist ! */
  298.   if(num_entries_copied == 0)
  299.   {
  300.     DEBUG(0,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
  301. hash bucket %d has a share mode record but no entries - deleting\n", 
  302.                  dev, inode, hash_entry));
  303.     if(*old_shares)
  304.       free((char *)*old_shares);
  305.     *old_shares = 0;
  306.  
  307.     if(file_prev_p == file_scanner_p)
  308.       mode_array[hash_entry] = file_scanner_p->next_offset;
  309.     else
  310.       file_prev_p->next_offset = file_scanner_p->next_offset;
  311.     smb_shm_free(smb_shm_addr2offset(file_scanner_p));
  312.   }
  313.  
  314.   DEBUG(5,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
  315. hash bucket %d returning %d entries\n", dev, inode, hash_entry,
  316.                          num_entries_copied));
  317.  
  318.   return(num_entries_copied);
  319. }  
  320.  
  321. /*******************************************************************
  322. del the share mode of a file.
  323. ********************************************************************/
  324. void del_share_mode(share_lock_token token, int fnum)
  325. {
  326.   uint32 dev, inode;
  327.   smb_shm_offset_t *mode_array;
  328.   unsigned int hash_entry;
  329.   share_mode_record *file_scanner_p;
  330.   share_mode_record *file_prev_p;
  331.   share_mode_entry *entry_scanner_p;
  332.   share_mode_entry *entry_prev_p;
  333.   BOOL found = False;
  334.   int pid = getpid();
  335.  
  336.   dev = Files[fnum].fd_ptr->dev;
  337.   inode = Files[fnum].fd_ptr->inode;
  338.  
  339.   hash_entry = HASH_ENTRY(dev, inode);
  340.  
  341.   if(hash_entry > lp_shmem_hash_size() )
  342.   {
  343.     DEBUG(0,
  344.       ("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash_entry %d too large \
  345. (max = %d)\n",
  346.       hash_entry, lp_shmem_hash_size() ));
  347.     return;
  348.   }
  349.  
  350.   mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
  351.  
  352.   if(mode_array[hash_entry] == NULL_OFFSET)
  353.   {  
  354.     DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash bucket %d empty\n", 
  355.                   hash_entry));
  356.     return;
  357.   }  
  358.   
  359.   file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
  360.   file_prev_p = file_scanner_p;
  361.  
  362.   while(file_scanner_p)
  363.   {
  364.      if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
  365.      {
  366.     found = True;
  367.     break;
  368.      }
  369.      else
  370.      {
  371.     file_prev_p = file_scanner_p ;
  372.     file_scanner_p = (share_mode_record *)
  373.                           smb_shm_offset2addr(file_scanner_p->next_offset);
  374.      }
  375.   }
  376.     
  377.   if(!found)
  378.   {
  379.      DEBUG(0,("ERROR:del_share_mode (FAST_SHARE_MODES): no entry found for dev %d, \
  380. inode %d in hash bucket %d\n", dev, inode, hash_entry));
  381.      return;
  382.   }
  383.   
  384.   if(file_scanner_p->locking_version != LOCKING_VERSION)
  385.   {
  386.      DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): Deleting old share mode \
  387. record due to old locking version %d for file dev %d, inode %d hash bucket %d\n",
  388.        file_scanner_p->locking_version, dev, inode, hash_entry ));
  389.      if(file_prev_p == file_scanner_p)
  390.     mode_array[hash_entry] = file_scanner_p->next_offset;
  391.      else
  392.     file_prev_p->next_offset = file_scanner_p->next_offset;
  393.      smb_shm_free(smb_shm_addr2offset(file_scanner_p));
  394.      return;
  395.   }
  396.  
  397.   found = False;
  398.   entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
  399.                                            file_scanner_p->share_mode_entries);
  400.   entry_prev_p = entry_scanner_p;
  401.   while(entry_scanner_p)
  402.   {
  403.     if( (pid == entry_scanner_p->pid) && 
  404.           (memcmp(&entry_scanner_p->time, 
  405.                  &Files[fnum].open_time,sizeof(struct timeval)) == 0) )
  406.     {
  407.       found = True;
  408.       break;
  409.     }
  410.     else
  411.     {
  412.       entry_prev_p = entry_scanner_p;
  413.       entry_scanner_p = (share_mode_entry *)
  414.                           smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
  415.     }
  416.   } 
  417.  
  418.   if (found)
  419.   {
  420.     /* Decrement the number of entries in the record. */
  421.     file_scanner_p->num_share_mode_entries -= 1;
  422.  
  423.     DEBUG(2,("del_share_modes (FAST_SHARE_MODES): \
  424. Deleting share mode entry dev = %d, inode = %d in hash bucket %d (num entries now = %d)\n",
  425.               dev, inode, hash_entry, file_scanner_p->num_share_mode_entries));
  426.     if(entry_prev_p == entry_scanner_p)
  427.       /* We are at start of list */
  428.       file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
  429.     else
  430.       entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
  431.     smb_shm_free(smb_shm_addr2offset(entry_scanner_p));
  432.  
  433.     /* PARANOIA TEST */
  434.     if(file_scanner_p->num_share_mode_entries < 0)
  435.     {
  436.       DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
  437. for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries,
  438.            dev, inode, hash_entry));
  439.       return;
  440.     }
  441.  
  442.     /* If we deleted the last share mode entry then remove the share mode record. */
  443.     if(file_scanner_p->num_share_mode_entries == 0)
  444.       {
  445.       DEBUG(2,("del_share_modes (FAST_SHARE_MODES): num entries = 0, deleting share_mode \
  446. record dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
  447.       if(file_prev_p == file_scanner_p)
  448.     mode_array[hash_entry] = file_scanner_p->next_offset;
  449.       else
  450.     file_prev_p->next_offset = file_scanner_p->next_offset;
  451.       smb_shm_free(smb_shm_addr2offset(file_scanner_p));
  452.       }
  453.   }
  454.   else
  455.   {
  456.     DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): No share mode record found \
  457. dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
  458.   }
  459. }
  460.  
  461. /*******************************************************************
  462. set the share mode of a file. Return False on fail, True on success.
  463. ********************************************************************/
  464. BOOL set_share_mode(share_lock_token token, int fnum)
  465. {
  466.   files_struct *fs_p = &Files[fnum];
  467.   int32 dev, inode;
  468.   smb_shm_offset_t *mode_array;
  469.   unsigned int hash_entry;
  470.   share_mode_record *file_scanner_p;
  471.   share_mode_record *file_prev_p;
  472.   share_mode_entry *new_entry_p;
  473.   smb_shm_offset_t new_entry_offset;
  474.   BOOL found = False;
  475.  
  476.   dev = fs_p->fd_ptr->dev;
  477.   inode = fs_p->fd_ptr->inode;
  478.  
  479.   hash_entry = HASH_ENTRY(dev, inode);
  480.   if(hash_entry > lp_shmem_hash_size() )
  481.   {
  482.     DEBUG(0,
  483.       ("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): hash_entry %d too large \
  484. (max = %d)\n",
  485.       hash_entry, lp_shmem_hash_size() ));
  486.     return False;
  487.   }
  488.  
  489.   mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
  490.  
  491.   file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
  492.   file_prev_p = file_scanner_p;
  493.   
  494.   while(file_scanner_p)
  495.   {
  496.      if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
  497.      {
  498.         found = True;
  499.         break;
  500.      }
  501.      else
  502.      {
  503.         file_prev_p = file_scanner_p ;
  504.         file_scanner_p = (share_mode_record *)
  505.                           smb_shm_offset2addr(file_scanner_p->next_offset);
  506.      }
  507.   }
  508.   
  509.   if(!found)
  510.   {
  511.     /* We must create a share_mode_record */
  512.     share_mode_record *new_mode_p = NULL;
  513.     smb_shm_offset_t new_offset = smb_shm_alloc( sizeof(share_mode_record) +
  514.                                         strlen(fs_p->name) + 1);
  515.     if(new_offset == NULL_OFFSET)
  516.     {
  517.       DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail !\n"));
  518.       return False;
  519.     }
  520.     new_mode_p = smb_shm_offset2addr(new_offset);
  521.     new_mode_p->locking_version = LOCKING_VERSION;
  522.     new_mode_p->st_dev = dev;
  523.     new_mode_p->st_ino = inode;
  524.     new_mode_p->num_share_mode_entries = 0;
  525.     new_mode_p->share_mode_entries = NULL_OFFSET;
  526.     strcpy(new_mode_p->file_name, fs_p->name);
  527.  
  528.     /* Chain onto the start of the hash chain (in the hope we will be used first). */
  529.     new_mode_p->next_offset = mode_array[hash_entry];
  530.     mode_array[hash_entry] = new_offset;
  531.  
  532.     file_scanner_p = new_mode_p;
  533.  
  534.     DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share record for %s (dev %d \
  535. inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry));
  536.   }
  537.  
  538.   /* Now create the share mode entry */ 
  539.   new_entry_offset = smb_shm_alloc( sizeof(share_mode_entry));
  540.   if(new_entry_offset == NULL_OFFSET)
  541.   {
  542.     smb_shm_offset_t delete_offset = mode_array[hash_entry];
  543.     DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail 1!\n"));
  544.     /* Unlink the damaged record */
  545.     mode_array[hash_entry] = file_scanner_p->next_offset;
  546.     /* And delete it */
  547.     smb_shm_free( delete_offset );
  548.     return False;
  549.   }
  550.  
  551.   new_entry_p = smb_shm_offset2addr(new_entry_offset);
  552.  
  553.   new_entry_p->pid = getpid();
  554.   new_entry_p->share_mode = fs_p->share_mode;
  555.   memcpy( (char *)&new_entry_p->time, (char *)&fs_p->open_time, sizeof(struct timeval));
  556.  
  557.   /* Chain onto the share_mode_record */
  558.   new_entry_p->next_share_mode_entry = file_scanner_p->share_mode_entries;
  559.   file_scanner_p->share_mode_entries = new_entry_offset;
  560.  
  561.   /* PARANOIA TEST */
  562.   if(file_scanner_p->num_share_mode_entries < 0)
  563.   {
  564.     DEBUG(0,("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
  565. for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries,
  566.          dev, inode, hash_entry));
  567.     return False;
  568.   }
  569.  
  570.   /* Increment the share_mode_entries counter */
  571.   file_scanner_p->num_share_mode_entries += 1;
  572.  
  573.   DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share entry for %s with mode \
  574. 0x%X pid=%d (num_entries now = %d)\n",fs_p->name, fs_p->share_mode, new_entry_p->pid,
  575.                              file_scanner_p->num_share_mode_entries));
  576.  
  577.   return(True);
  578. }
  579.  
  580. #else /* FAST_SHARE_MODES */
  581.  
  582. /* SHARE MODE LOCKS USING SLOW DESCRIPTION FILES */
  583.  
  584. /*******************************************************************
  585.   name a share file
  586.   ******************************************************************/
  587. static BOOL share_name(int cnum, uint32 dev, uint32 inode, char *name)
  588. {
  589.   strcpy(name,lp_lockdir());
  590.   standard_sub(cnum,name);
  591.   trim_string(name,"","/");
  592.   if (!*name) return(False);
  593.   name += strlen(name);
  594.   
  595.   sprintf(name,"/share.%u.%u",dev,inode);
  596.   return(True);
  597. }
  598.  
  599. /*******************************************************************
  600.   lock a share mode file.
  601.   ******************************************************************/
  602. BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok)
  603. {
  604.   pstring fname;
  605.   int fd;
  606.  
  607.   *ptok = (share_lock_token)-1;
  608.  
  609.   if(!share_name(cnum, dev, inode, fname))
  610.     return False;
  611.  
  612.   {
  613.     int old_umask;
  614.     unbecome_user();
  615.     old_umask = umask(0);
  616. #ifdef SECURE_SHARE_MODES
  617.     fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600);
  618. #else /* SECURE_SHARE_MODES */
  619.     fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0644);
  620. #endif /* SECURE_SHARE_MODES */
  621.     umask(old_umask);
  622.     if(!become_user(cnum,Connections[cnum].vuid))
  623.     {
  624.       DEBUG(0,("lock_share_entry: Can't become connected user!\n"));
  625.       close(fd);
  626.       return False;
  627.     }
  628.     /* We need to change directory back to the connection root. */
  629.     if (ChDir(Connections[cnum].connectpath) != 0)
  630.     {
  631.       DEBUG(0,("lock_share_entry: Can't change directory to %s (%s)\n",
  632.               Connections[cnum].connectpath, strerror(errno)));
  633.       close(fd);
  634.       return False;  
  635.     }
  636.   }
  637.  
  638.   /* At this point we have an open fd to the share mode file. 
  639.      Lock the first byte exclusively to signify a lock. */
  640.   if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
  641.    {
  642.       DEBUG(0,("ERROR lock_share_entry: fcntl_lock failed with %s\n",
  643.                   strerror(errno)));   
  644.       close(fd);
  645.       return False;
  646.    }
  647.  
  648.    *ptok = (share_lock_token)fd;
  649.    return True;
  650. }
  651.  
  652. /*******************************************************************
  653.   unlock a share mode file.
  654.   ******************************************************************/
  655. BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token)
  656. {
  657.   int fd = (int)token;
  658.   int ret = True;
  659.  
  660.   /* token is the fd of the open share mode file. */
  661.   /* Unlock the first byte. */
  662.   if(fcntl_lock(fd, F_SETLKW, 0, 1, F_UNLCK) == False)
  663.    { 
  664.       DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n",
  665.                       strerror(errno)));   
  666.       ret = False;
  667.    }
  668.  
  669.   close((int)token);
  670.   return ret;
  671. }
  672.  
  673. /*******************************************************************
  674. Force a share file to be deleted.
  675. ********************************************************************/
  676.  
  677. static int delete_share_file( int cnum, char *fname )
  678. {
  679.   unbecome_user();
  680.   if(unlink(fname) != 0)
  681.   {
  682.     DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
  683.             fname, strerror(errno)));
  684.   }
  685.  
  686.   DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
  687.  
  688.   if(!become_user(cnum,Connections[cnum].vuid))
  689.   {
  690.     DEBUG(0,("delete_share_file: Can't become connected user!\n"));
  691.     return -1;
  692.   }
  693.   /* We need to change directory back to the connection root. */
  694.   if (ChDir(Connections[cnum].connectpath) != 0)
  695.   {
  696.     DEBUG(0,("delete_share_file: Can't change directory to %s (%s)\n",
  697.             Connections[cnum].connectpath, strerror(errno)));
  698.     return -1;  
  699.   }
  700.   return 0;
  701. }
  702.  
  703. /*******************************************************************
  704. Read a share file into a buffer.
  705. ********************************************************************/
  706.  
  707. static int read_share_file(int cnum, int fd, char *fname, char **out, BOOL *p_new_file)
  708. {
  709.   struct stat sb;
  710.   char *buf;
  711.   int size;
  712.  
  713.   *out = 0;
  714.   *p_new_file = False;
  715.  
  716.   if(fstat(fd, &sb) != 0)
  717.   {
  718.     DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
  719.                   fname, strerror(errno)));
  720.     return -1;
  721.   }
  722.  
  723.   if(sb.st_size == 0)
  724.   {
  725.      *p_new_file = True;
  726.      return 0;
  727.   }
  728.  
  729.   /* Allocate space for the file */
  730.   if((buf = (char *)malloc(sb.st_size)) == NULL)
  731.   {
  732.     DEBUG(0,("read_share_file: malloc for file size %d fail !\n", sb.st_size));
  733.     return -1;
  734.   }
  735.   
  736.   if(lseek(fd, 0, SEEK_SET) != 0)
  737.   {
  738.     DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \
  739. for share file %s (%s)\n", fname, strerror(errno)));
  740.     if(buf)
  741.       free(buf);
  742.     return -1;
  743.   }
  744.   
  745.   if (read(fd,buf,sb.st_size) != sb.st_size)
  746.   {
  747.     DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n",
  748.                fname, strerror(errno)));
  749.     if(buf)
  750.       free(buf);
  751.     return -1;
  752.   }
  753.   
  754.   if (IVAL(buf,0) != LOCKING_VERSION) {
  755.     DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \
  756. locking version (was %d, should be %d).\n",fname, IVAL(buf,0), LOCKING_VERSION));
  757.     if(buf)
  758.       free(buf);
  759.     delete_share_file(cnum, fname);
  760.     return -1;
  761.   }
  762.  
  763.   /* Sanity check for file contents */
  764.   size = sb.st_size;
  765.   size -= 10; /* Remove the header */
  766.  
  767.   /* Remove the filename component. */
  768.   size -= SVAL(buf, 8);
  769.  
  770.   /* The remaining size must be a multiple of 16 - error if not. */
  771.   if((size % 16) != 0)
  772.   {
  773.     DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \
  774. deleting it.\n", fname));
  775.     if(buf)
  776.       free(buf);
  777.     delete_share_file(cnum, fname);
  778.     return -1;
  779.   }
  780.  
  781.   *out = buf;
  782.   return 0;
  783. }
  784.  
  785. /*******************************************************************
  786. get all share mode entries in a share file for a dev/inode pair.
  787. ********************************************************************/
  788. int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, 
  789.                     min_share_mode_entry **old_shares)
  790. {
  791.   int fd = (int)token;
  792.   pstring fname;
  793.   int i;
  794.   int num_entries;
  795.   int num_entries_copied;
  796.   int newsize;
  797.   min_share_mode_entry *share_array;
  798.   char *buf = 0;
  799.   char *base = 0;
  800.   BOOL new_file;
  801.  
  802.   *old_shares = 0;
  803.  
  804.   /* Read the share file header - this is of the form:
  805.      0   -  locking version.
  806.      4   -  number of share mode entries.
  807.      8   -  2 byte name length
  808.      [n bytes] file name (zero terminated).
  809.  
  810.    Followed by <n> share mode entries of the form :
  811.  
  812.      0   -  tv_sec
  813.      4   -  tv_usec
  814.      8   -  share_mode
  815.     12   -  pid
  816.  
  817.   */
  818.  
  819.   share_name(cnum, dev, inode, fname);
  820.  
  821.   if(read_share_file( cnum, fd, fname, &buf, &new_file) != 0)
  822.   {
  823.     DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n",
  824.                   fname));
  825.     return 0;
  826.   }
  827.  
  828.   if(new_file == True)
  829.     return 0;
  830.  
  831.   num_entries = IVAL(buf,4);
  832.  
  833.   DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n",
  834.             fname, num_entries));
  835.  
  836.   /* PARANOIA TEST */
  837.   if(num_entries < 0)
  838.   {
  839.     DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \
  840. for share file %d\n", num_entries, fname));
  841.     return 0;
  842.   }
  843.  
  844.   if(num_entries)
  845.   {
  846.     *old_shares = share_array = (min_share_mode_entry *)
  847.                  malloc(num_entries * sizeof(min_share_mode_entry));
  848.     if(*old_shares == 0)
  849.     {
  850.       DEBUG(0,("get_share_modes: malloc fail !\n"));
  851.       return 0;
  852.     }
  853.   } 
  854.   else
  855.   {
  856.     /* No entries - just delete the file. */
  857.     DEBUG(0,("get_share_modes: share file %s has no share mode entries - deleting.\n",
  858.               fname));
  859.     if(buf)
  860.       free(buf);
  861.     delete_share_file(cnum, fname);
  862.     return 0;
  863.   }
  864.  
  865.   num_entries_copied = 0;
  866.   base = buf + 10 + SVAL(buf,8);
  867.  
  868.   for( i = 0; i < num_entries; i++)
  869.   {
  870.     int pid;
  871.     char *p = base + (i*16);
  872.  
  873.     pid = IVAL(p,12);
  874.  
  875.     if(!process_exists(pid))
  876.     {
  877.       DEBUG(0,("get_share_modes: process %d no longer exists and \
  878. it left a share mode entry with mode 0x%X in share file %s\n",
  879.             pid, IVAL(p,8), fname));
  880.       continue;
  881.     }
  882.     share_array[num_entries_copied].time.tv_sec = IVAL(p,0);
  883.     share_array[num_entries_copied].time.tv_usec = IVAL(p,4);
  884.     share_array[num_entries_copied].share_mode = IVAL(p,8);
  885.     share_array[num_entries_copied].pid = pid;
  886.  
  887.     num_entries_copied++;
  888.   }
  889.  
  890.   if(num_entries_copied == 0)
  891.   {
  892.     /* Delete the whole file. */
  893.     DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n",
  894.              fname));
  895.     if(*old_shares)
  896.       free((char *)*old_shares);
  897.     *old_shares = 0;
  898.     if(buf)
  899.       free(buf);
  900.     delete_share_file(cnum, fname);
  901.     return 0;
  902.   }
  903.  
  904.   /* If we deleted some entries we need to re-write the whole number of
  905.      share mode entries back into the file. */
  906.  
  907.   if(num_entries_copied != num_entries)
  908.   {
  909.     if(lseek(fd, 0, SEEK_SET) != 0)
  910.     {
  911.       DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \
  912. position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
  913.       if(*old_shares)
  914.         free((char *)*old_shares);
  915.       *old_shares = 0;
  916.       if(buf)
  917.         free(buf);
  918.       return 0;
  919.     }
  920.  
  921.     SIVAL(buf, 4, num_entries_copied);
  922.     for( i = 0; i < num_entries_copied; i++)
  923.     {
  924.       char *p = base + (i*16);
  925.  
  926.       SIVAL(p,12,share_array[i].pid);
  927.       SIVAL(p,8,share_array[i].share_mode);
  928.       SIVAL(p,0,share_array[i].time.tv_sec);
  929.       SIVAL(p,4,share_array[i].time.tv_usec);
  930.     }
  931.  
  932.     newsize = (base - buf) + (16*num_entries_copied);
  933.     if(write(fd, buf, newsize) != newsize)
  934.     {
  935.       DEBUG(0,("ERROR: get_share_modes: failed to re-write share \
  936. mode file %s (%s)\n", fname, strerror(errno)));
  937.       if(*old_shares)
  938.         free((char *)*old_shares);
  939.       *old_shares = 0;
  940.       if(buf)
  941.         free(buf);
  942.       return 0;
  943.     }
  944.     /* Now truncate the file at this point. */
  945.     if(ftruncate(fd, newsize)!= 0)
  946.     {
  947.       DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
  948. mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
  949.       if(*old_shares)
  950.         free((char *)*old_shares);
  951.       *old_shares = 0;
  952.       if(buf)
  953.         free(buf);
  954.       return 0;
  955.     }
  956.   }
  957.  
  958.   if(buf)
  959.     free(buf);
  960.  
  961.   DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname,
  962.             num_entries_copied));
  963.  
  964.   return num_entries_copied;
  965. }
  966.  
  967. /*******************************************************************
  968. del a share mode from a share mode file.
  969. ********************************************************************/
  970. void del_share_mode(share_lock_token token, int fnum)
  971. {
  972.   pstring fname;
  973.   int fd = (int)token;
  974.   char *buf = 0;
  975.   char *base = 0;
  976.   int num_entries;
  977.   int newsize;
  978.   int i;
  979.   files_struct *fs_p = &Files[fnum];
  980.   int pid;
  981.   BOOL deleted = False;
  982.   BOOL new_file;
  983.  
  984.   share_name(fs_p->cnum, fs_p->fd_ptr->dev, 
  985.                        fs_p->fd_ptr->inode, fname);
  986.  
  987.   if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
  988.   {
  989.     DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n",
  990.                   fname));
  991.     return;
  992.   }
  993.  
  994.   if(new_file == True)
  995.   {
  996.     DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n",
  997.               fname));
  998.     delete_share_file(fs_p->cnum, fname);
  999.     return;
  1000.   }
  1001.  
  1002.   num_entries = IVAL(buf,4);
  1003.  
  1004.   DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n",
  1005.             fname, num_entries));
  1006.  
  1007.   /* PARANOIA TEST */
  1008.   if(num_entries < 0)
  1009.   {
  1010.     DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \
  1011. for share file %d\n", num_entries, fname));
  1012.     return;
  1013.   }
  1014.  
  1015.   if(num_entries == 0)
  1016.   {
  1017.     /* No entries - just delete the file. */
  1018.     DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n",
  1019.               fname));
  1020.     if(buf)
  1021.       free(buf);
  1022.     delete_share_file(fs_p->cnum, fname);
  1023.     return;
  1024.   }
  1025.  
  1026.   pid = getpid();
  1027.  
  1028.   /* Go through the entries looking for the particular one
  1029.      we have set - delete it.
  1030.   */
  1031.  
  1032.   base = buf + 10 + SVAL(buf,8);
  1033.  
  1034.   for(i = 0; i < num_entries; i++)
  1035.   {
  1036.     char *p = base + (i*16);
  1037.  
  1038.     if((IVAL(p,0) != fs_p->open_time.tv_sec) || (IVAL(p,4) != fs_p->open_time.tv_usec) ||
  1039.         (IVAL(p,8) != fs_p->share_mode) || (IVAL(p,12) != pid))
  1040.       continue;
  1041.  
  1042.     DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
  1043.              i, num_entries, fname));
  1044.  
  1045.     /* Remove this entry. */
  1046.     if(i != num_entries - 1)
  1047.       memcpy(p, p + 16, (num_entries - i - 1)*16);
  1048.  
  1049.     deleted = True;
  1050.     break;
  1051.   }
  1052.  
  1053.   if(!deleted)
  1054.   {
  1055.     DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname));
  1056.     if(buf)
  1057.       free(buf);
  1058.     return;
  1059.   }
  1060.  
  1061.   num_entries--;
  1062.   SIVAL(buf,4, num_entries);
  1063.  
  1064.   if(num_entries == 0)
  1065.   {
  1066.     /* Deleted the last entry - remove the file. */
  1067.     DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n",
  1068.              fname));
  1069.     if(buf)
  1070.       free(buf);
  1071.     delete_share_file(fs_p->cnum,fname);
  1072.     return;
  1073.   }
  1074.  
  1075.   /* Re-write the file - and truncate it at the correct point. */
  1076.   if(lseek(fd, 0, SEEK_SET) != 0)
  1077.     {
  1078.       DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
  1079. position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
  1080.       if(buf)
  1081.         free(buf);
  1082.       return;
  1083.     }
  1084.  
  1085.   newsize = (base - buf) + (16*num_entries);
  1086.   if(write(fd, buf, newsize) != newsize)
  1087.     {
  1088.       DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
  1089. mode file %s (%s)\n", fname, strerror(errno)));
  1090.       if(buf)
  1091.         free(buf);
  1092.       return;
  1093.     }
  1094.   /* Now truncate the file at this point. */
  1095.   if(ftruncate(fd, newsize) != 0)
  1096.   {
  1097.     DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
  1098. mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
  1099.     if(buf)
  1100.       free(buf);
  1101.     return;
  1102.   }
  1103. }
  1104.   
  1105. /*******************************************************************
  1106. set the share mode of a file
  1107. ********************************************************************/
  1108. BOOL set_share_mode(share_lock_token token,int fnum)
  1109. {
  1110.   files_struct *fs_p = &Files[fnum];
  1111.   pstring fname;
  1112.   int fd = (int)token;
  1113.   int pid = (int)getpid();
  1114.   struct stat sb;
  1115.   char *buf;
  1116.   int num_entries;
  1117.   int header_size;
  1118.   char *p;
  1119.  
  1120.   share_name(fs_p->cnum, fs_p->fd_ptr->dev,
  1121.                        fs_p->fd_ptr->inode, fname);
  1122.  
  1123.   if(fstat(fd, &sb) != 0)
  1124.   {
  1125.     DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
  1126.                   fname));
  1127.     return False;
  1128.   }
  1129.  
  1130.   /* Sanity check for file contents (if it's not a new share file). */
  1131.   if(sb.st_size != 0)
  1132.   {
  1133.     int size = sb.st_size;
  1134.  
  1135.     /* Allocate space for the file plus one extra entry */
  1136.     if((buf = (char *)malloc(sb.st_size + 16)) == NULL)
  1137.     {
  1138.       DEBUG(0,("set_share_mode: malloc for file size %d fail !\n", sb.st_size + 16));
  1139.       return False;
  1140.     }
  1141.  
  1142.     if(lseek(fd, 0, SEEK_SET) != 0)
  1143.     {
  1144.       DEBUG(0,("ERROR: set_share_mode: Failed to reset position \
  1145. to 0 for share file %s (%s)\n", fname, strerror(errno)));
  1146.       if(buf)
  1147.         free(buf);
  1148.       return False;
  1149.     }
  1150.  
  1151.     if (read(fd,buf,sb.st_size) != sb.st_size)
  1152.     {
  1153.       DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n",
  1154.                   fname, strerror(errno)));
  1155.       if(buf)
  1156.         free(buf);
  1157.       return False;
  1158.     }   
  1159.   
  1160.     if (IVAL(buf,0) != LOCKING_VERSION) 
  1161.     {
  1162.       DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \
  1163. locking version (was %d, should be %d).\n",fname, IVAL(buf,0), LOCKING_VERSION));
  1164.       if(buf)
  1165.         free(buf);
  1166.       delete_share_file(fs_p->cnum, fname);
  1167.       return False;
  1168.     }   
  1169.  
  1170.     size -= (10 + SVAL(buf, 8)); /* Remove the header */
  1171.  
  1172.     /* The remaining size must be a multiple of 16 - error if not. */
  1173.     if((size % 16) != 0)
  1174.     {
  1175.       DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \
  1176. deleting it.\n", fname));
  1177.       if(buf)
  1178.         free(buf);
  1179.       delete_share_file(fs_p->cnum, fname);
  1180.       return False;
  1181.     }
  1182.  
  1183.   }
  1184.   else
  1185.   {
  1186.     /* New file - just use a single_entry. */
  1187.     if((buf = (char *)malloc(10 + strlen(fs_p->name) + 1 + 16)) == NULL)
  1188.     {
  1189.       DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
  1190.       return False;
  1191.     }
  1192.     SIVAL(buf,0,LOCKING_VERSION);
  1193.     SIVAL(buf,4,0);
  1194.     SSVAL(buf,8,strlen(fs_p->name) + 1);
  1195.     strcpy(buf + 10, fs_p->name);
  1196.   }
  1197.  
  1198.   num_entries = IVAL(buf,4);
  1199.   header_size = 10 + SVAL(buf,8);
  1200.   p = buf + header_size + (num_entries * 16);
  1201.   SIVAL(p,0,fs_p->open_time.tv_sec);
  1202.   SIVAL(p,4,fs_p->open_time.tv_usec);
  1203.   SIVAL(p,8,fs_p->share_mode);
  1204.   SIVAL(p,12,pid);
  1205.  
  1206.   num_entries++;
  1207.  
  1208.   SIVAL(buf,4,num_entries);
  1209.  
  1210.   if(lseek(fd, 0, SEEK_SET) != 0)
  1211.   {
  1212.     DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \
  1213. 0 for share file %s (%s)\n", fname, strerror(errno)));
  1214.     if(buf)
  1215.       free(buf);
  1216.     return False;
  1217.   }
  1218.  
  1219.   if (write(fd,buf,header_size + (num_entries*16)) != (header_size + (num_entries*16))) 
  1220.   {
  1221.     DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
  1222. deleting it (%s).\n",fname, strerror(errno)));
  1223.     delete_share_file(fs_p->cnum, fname);
  1224.     if(buf)
  1225.       free(buf);
  1226.     return False;
  1227.   }
  1228.  
  1229.   /* Now truncate the file at this point - just for safety. */
  1230.   if(ftruncate(fd, header_size + (16*num_entries))!= 0)
  1231.   {
  1232.     DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
  1233. mode file %s to size %d (%s)\n", fname, header_size + (16*num_entries), strerror(errno)));
  1234.     if(buf)
  1235.       free(buf);
  1236.     return False;
  1237.   }
  1238.  
  1239.   if(buf)
  1240.     free(buf);
  1241.  
  1242.   DEBUG(3,("set_share_mode: Created share file %s with \
  1243. mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid));
  1244.  
  1245.   return True;
  1246. }
  1247. #endif /* FAST_SHARE_MODES */
  1248.