first cut at using the tdb code for the connections structure, the
[ira/wip.git] / source3 / locking / locking_slow.c
index 1f8f962ac904d45b0db2519aef2d5fe7daefd046..58673d2707936a4260f7fa46149947348e28cb6f 100644 (file)
@@ -37,8 +37,6 @@
 #ifndef FAST_SHARE_MODES
 
 extern int DEBUGLEVEL;
-extern connection_struct Connections[];
-extern files_struct Files[];
 
 /* 
  * Locking file header lengths & offsets. 
@@ -82,23 +80,28 @@ static BOOL slow_stop_share_mode_mgmt(void)
 /*******************************************************************
   name a share file
   ******************************************************************/
-static BOOL share_name(int cnum, uint32 dev, uint32 inode, char *name)
+static BOOL share_name(connection_struct *conn, 
+                      SMB_DEV_T dev, SMB_INO_T inode, char *name)
 {
-  int len;
-  pstrcpy(name,lp_lockdir());
-  trim_string(name,"","/");
-  if (!*name) return(False);
-  len = strlen(name);
-  name += len;
-  
-  slprintf(name, sizeof(pstring) - len - 1, "/share.%u.%u",dev,inode);
-  return(True);
+       int len;
+       pstrcpy(name,lp_lockdir());
+       trim_string(name,"","/");
+       if (!*name) return(False);
+       len = strlen(name);
+       name += len;
+       
+#ifdef LARGE_SMB_INO_T
+       slprintf(name, sizeof(pstring) - len - 1, "/share.%u.%.0f",(unsigned int)dev,(double)inode);
+#else /* LARGE_SMB_INO_T */
+       slprintf(name, sizeof(pstring) - len - 1, "/share.%u.%lu",(unsigned int)dev,(unsigned long)inode);
+#endif /* LARGE_SMB_INO_T */
+       return(True);
 }
 
 /*******************************************************************
 Force a share file to be deleted.
 ********************************************************************/
-static int delete_share_file( int cnum, char *fname )
+static int delete_share_file(connection_struct *conn, char *fname )
 {
   if (read_only) return -1;
 
@@ -115,7 +118,7 @@ static int delete_share_file( int cnum, char *fname )
     DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
   }
 
-  /* return to our previous privilage level */
+  /* return to our previous privilege level */
   unbecome_root(False);
 
   return 0;
@@ -124,7 +127,8 @@ static int delete_share_file( int cnum, char *fname )
 /*******************************************************************
   lock a share mode file.
   ******************************************************************/
-static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
+static BOOL slow_lock_share_entry(connection_struct *conn,
+                                 SMB_DEV_T dev, SMB_INO_T inode, int *ptok)
 {
   pstring fname;
   int fd;
@@ -132,7 +136,7 @@ static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
 
   *ptok = (int)-1;
 
-  if(!share_name(cnum, dev, inode, fname))
+  if(!share_name(conn, dev, inode, fname))
     return False;
 
   if (read_only) return True;
@@ -159,10 +163,9 @@ static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
 
     do
     {
-      struct stat dummy_stat;
+      SMB_STRUCT_STAT dummy_stat;
 
-      fd = (int)open(fname,read_only?O_RDONLY:(O_RDWR|O_CREAT),
-                    SHARE_FILE_MODE);
+      fd = sys_open(fname,read_only?O_RDONLY:(O_RDWR|O_CREAT), SHARE_FILE_MODE);
 
       if(fd < 0)
       {
@@ -174,7 +177,7 @@ static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
 
        /* At this point we have an open fd to the share mode file. 
          Lock the first byte exclusively to signify a lock. */
-      if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
+      if(fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False)
       {
         DEBUG(0,("ERROR lock_share_entry: fcntl_lock on file %s failed with %s\n",
                   fname, strerror(errno)));   
@@ -188,7 +191,7 @@ static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
        * the open and the lock call. Back out and try again.
        */
 
-      if(stat(fname, &dummy_stat)!=0)
+      if(sys_stat(fname, &dummy_stat)!=0)
       {
         DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n",
                 fname, strerror(errno)));
@@ -207,7 +210,7 @@ static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
 
   *ptok = (int)fd;
 
-  /* return to our previous privilage level */
+  /* return to our previous privilege level */
   unbecome_root(False);
 
   return ret;
@@ -216,11 +219,12 @@ static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
 /*******************************************************************
   unlock a share mode file.
   ******************************************************************/
-static BOOL slow_unlock_share_entry(int cnum, uint32 dev, uint32 inode, int token)
+static BOOL slow_unlock_share_entry(connection_struct *conn, 
+                                   SMB_DEV_T dev, SMB_INO_T inode, int token)
 {
-  int fd = (int)token;
+  int fd = token;
   int ret = True;
-  struct stat sb;
+  SMB_STRUCT_STAT sb;
   pstring fname;
 
   if (read_only) return True;
@@ -228,10 +232,10 @@ static BOOL slow_unlock_share_entry(int cnum, uint32 dev, uint32 inode, int toke
   /* Fix for zero length share files from
      Gerald Werner <wernerg@mfldclin.edu> */
     
-  share_name(cnum, dev, inode, fname);
+  share_name(conn, dev, inode, fname);
 
   /* get the share mode file size */
-  if(fstat((int)token, &sb) != 0)
+  if(sys_fstat((int)token, &sb) != 0)
   {
     DEBUG(0,("ERROR: unlock_share_entry: Failed to do stat on share file %s (%s)\n",
               fname, strerror(errno)));
@@ -246,11 +250,11 @@ static BOOL slow_unlock_share_entry(int cnum, uint32 dev, uint32 inode, int toke
 
   /* remove the share file if zero length */    
   if(sb.st_size == 0)  
-    delete_share_file(cnum, fname);
+    delete_share_file(conn, fname);
 
   /* token is the fd of the open share mode file. */
   /* Unlock the first byte. */
-  if(fcntl_lock(fd, F_SETLKW, 0, 1, F_UNLCK) == False)
+  if(fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_UNLCK) == False)
    { 
       DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n",
                       strerror(errno)));   
@@ -264,16 +268,16 @@ static BOOL slow_unlock_share_entry(int cnum, uint32 dev, uint32 inode, int toke
 /*******************************************************************
 Read a share file into a buffer.
 ********************************************************************/
-static int read_share_file(int cnum, int fd, char *fname, char **out, BOOL *p_new_file)
+static int read_share_file(connection_struct *conn, int fd, char *fname, char **out, BOOL *p_new_file)
 {
-  struct stat sb;
+  SMB_STRUCT_STAT sb;
   char *buf;
-  int size;
+  SMB_OFF_T size;
 
   *out = 0;
   *p_new_file = False;
 
-  if(fstat(fd, &sb) != 0)
+  if(sys_fstat(fd, &sb) != 0)
   {
     DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
                   fname, strerror(errno)));
@@ -287,13 +291,14 @@ static int read_share_file(int cnum, int fd, char *fname, char **out, BOOL *p_ne
   }
 
   /* Allocate space for the file */
-  if((buf = (char *)malloc(sb.st_size)) == NULL)
+  if((buf = (char *)malloc((size_t)sb.st_size)) == NULL)
   {
-    DEBUG(0,("read_share_file: malloc for file size %d fail !\n", sb.st_size));
+    DEBUG(0,("read_share_file: malloc for file size %d fail !\n", 
+            (int)sb.st_size));
     return -1;
   }
   
-  if(lseek(fd, 0, SEEK_SET) != 0)
+  if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
   {
     DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \
 for share file %s (%s)\n", fname, strerror(errno)));
@@ -302,7 +307,7 @@ for share file %s (%s)\n", fname, strerror(errno)));
     return -1;
   }
   
-  if (read(fd,buf,sb.st_size) != sb.st_size)
+  if (read(fd,buf,(size_t)sb.st_size) != (size_t)sb.st_size)
   {
     DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n",
                fname, strerror(errno)));
@@ -317,7 +322,7 @@ locking version (was %d, should be %d).\n",fname,
                     IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION));
    if(buf)
       free(buf);
-    delete_share_file(cnum, fname);
+    delete_share_file(conn, fname);
     return -1;
   }
 
@@ -335,7 +340,7 @@ locking version (was %d, should be %d).\n",fname,
 deleting it.\n", fname));
     if(buf)
       free(buf);
-    delete_share_file(cnum, fname);
+    delete_share_file(conn, fname);
     return -1;
   }
 
@@ -346,10 +351,11 @@ deleting it.\n", fname));
 /*******************************************************************
 get all share mode entries in a share file for a dev/inode pair.
 ********************************************************************/
-static int slow_get_share_modes(int cnum, int token, uint32 dev, uint32 inode, 
+static int slow_get_share_modes(connection_struct *conn, int token, 
+                SMB_DEV_T dev, SMB_INO_T inode, 
                                share_mode_entry **old_shares)
 {
-  int fd = (int)token;
+  int fd = token;
   pstring fname;
   int i;
   int num_entries;
@@ -377,9 +383,9 @@ static int slow_get_share_modes(int cnum, int token, uint32 dev, uint32 inode,
     16   -  oplock port (if oplocks in use) - 2 bytes.
   */
 
-  share_name(cnum, dev, inode, fname);
+  share_name(conn, dev, inode, fname);
 
-  if(read_share_file( cnum, fd, fname, &buf, &new_file) != 0)
+  if(read_share_file( conn, fd, fname, &buf, &new_file) != 0)
   {
     DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n",
                   fname));
@@ -398,7 +404,7 @@ static int slow_get_share_modes(int cnum, int token, uint32 dev, uint32 inode,
   if(num_entries < 0)
   {
     DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \
-for share file %d\n", num_entries, fname));
+for share file %s\n", num_entries, fname));
     return 0;
   }
 
@@ -419,7 +425,7 @@ for share file %d\n", num_entries, fname));
               fname));
     if(buf)
       free(buf);
-    delete_share_file(cnum, fname);
+    delete_share_file(conn, fname);
     return 0;
   }
 
@@ -428,16 +434,16 @@ for share file %d\n", num_entries, fname));
 
   for( i = 0; i < num_entries; i++)
   {
-    int pid;
+    pid_t pid;
     char *p = base + (i*SMF_ENTRY_LENGTH);
 
-    pid = IVAL(p,SME_PID_OFFSET);
+    pid = (pid_t)IVAL(p,SME_PID_OFFSET);
 
     if(!process_exists(pid))
     {
       DEBUG(0,("get_share_modes: process %d no longer exists and \
 it left a share mode entry with mode 0x%X in share file %s\n",
-            pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
+            (int)pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
       continue;
     }
     share_array[num_entries_copied].time.tv_sec = IVAL(p,SME_SEC_OFFSET);
@@ -460,7 +466,7 @@ it left a share mode entry with mode 0x%X in share file %s\n",
     *old_shares = 0;
     if(buf)
       free(buf);
-    delete_share_file(cnum, fname);
+    delete_share_file(conn, fname);
     return 0;
   }
 
@@ -469,7 +475,7 @@ it left a share mode entry with mode 0x%X in share file %s\n",
 
   if(num_entries_copied != num_entries)
   {
-    if(lseek(fd, 0, SEEK_SET) != 0)
+    if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
     {
       DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \
 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
@@ -486,7 +492,7 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
     {
       char *p = base + (i*SMF_ENTRY_LENGTH);
 
-      SIVAL(p,SME_PID_OFFSET,share_array[i].pid);
+      SIVAL(p,SME_PID_OFFSET,(uint32)share_array[i].pid);
       SIVAL(p,SME_SHAREMODE_OFFSET,share_array[i].share_mode);
       SIVAL(p,SME_SEC_OFFSET,share_array[i].time.tv_sec);
       SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
@@ -507,8 +513,18 @@ mode file %s (%s)\n", fname, strerror(errno)));
       return 0;
     }
     /* Now truncate the file at this point. */
-    if(ftruncate(fd, newsize)!= 0)
+#ifdef FTRUNCATE_NEEDS_ROOT
+    become_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
+    if(sys_ftruncate(fd, (SMB_OFF_T)newsize)!= 0)
     {
+#ifdef FTRUNCATE_NEEDS_ROOT
+      int saved_errno = errno;
+      unbecome_root(False);
+      errno = saved_errno;
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
       DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
       if(*old_shares)
@@ -520,6 +536,10 @@ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
     }
   }
 
+#ifdef FTRUNCATE_NEEDS_ROOT
+      unbecome_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
   if(buf)
     free(buf);
 
@@ -532,7 +552,7 @@ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
 /*******************************************************************
 del a share mode from a share mode file.
 ********************************************************************/
-static void slow_del_share_mode(int token, int fnum)
+static void slow_del_share_mode(int token, files_struct *fsp)
 {
   pstring fname;
   int fd = (int)token;
@@ -541,15 +561,14 @@ static void slow_del_share_mode(int token, int fnum)
   int num_entries;
   int newsize;
   int i;
-  files_struct *fs_p = &Files[fnum];
-  int pid;
+  pid_t pid;
   BOOL deleted = False;
   BOOL new_file;
 
-  share_name(fs_p->cnum, fs_p->fd_ptr->dev, 
-                       fs_p->fd_ptr->inode, fname);
+  share_name(fsp->conn, fsp->fd_ptr->dev, 
+                       fsp->fd_ptr->inode, fname);
 
-  if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
+  if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0)
   {
     DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n",
                   fname));
@@ -560,7 +579,7 @@ static void slow_del_share_mode(int token, int fnum)
   {
     DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n",
               fname));
-    delete_share_file(fs_p->cnum, fname);
+    delete_share_file(fsp->conn, fname);
     return;
   }
 
@@ -573,7 +592,7 @@ static void slow_del_share_mode(int token, int fnum)
   if(num_entries < 0)
   {
     DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \
-for share file %d\n", num_entries, fname));
+for share file %s\n", num_entries, fname));
     return;
   }
 
@@ -584,7 +603,7 @@ for share file %d\n", num_entries, fname));
               fname));
     if(buf)
       free(buf);
-    delete_share_file(fs_p->cnum, fname);
+    delete_share_file(fsp->conn, fname);
     return;
   }
 
@@ -600,10 +619,10 @@ for share file %d\n", num_entries, fname));
   {
     char *p = base + (i*SMF_ENTRY_LENGTH);
 
-    if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) || 
-       (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
-       (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) || 
-       (IVAL(p,SME_PID_OFFSET) != pid))
+    if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) || 
+       (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) ||
+       (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) || 
+       (((pid_t)IVAL(p,SME_PID_OFFSET)) != pid))
       continue;
 
     DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
@@ -635,12 +654,12 @@ for share file %d\n", num_entries, fname));
              fname));
     if(buf)
       free(buf);
-    delete_share_file(fs_p->cnum,fname);
+    delete_share_file(fsp->conn,fname);
     return;
   }
 
   /* Re-write the file - and truncate it at the correct point. */
-  if(lseek(fd, 0, SEEK_SET) != 0)
+  if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
   {
     DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
@@ -660,35 +679,50 @@ mode file %s (%s)\n", fname, strerror(errno)));
   }
 
   /* Now truncate the file at this point. */
-  if(ftruncate(fd, newsize) != 0)
+#ifdef FTRUNCATE_NEEDS_ROOT
+  become_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
+  if(sys_ftruncate(fd, (SMB_OFF_T)newsize) != 0)
   {
+#ifdef FTRUNCATE_NEEDS_ROOT
+    int saved_errno = errno;
+    unbecome_root(False);
+    errno = saved_errno;
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
+
     DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
     if(buf)
       free(buf);
     return;
   }
+
+#ifdef FTRUNCATE_NEEDS_ROOT
+  unbecome_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
 }
   
 /*******************************************************************
 set the share mode of a file
 ********************************************************************/
-static BOOL slow_set_share_mode(int token,int fnum, uint16 port, uint16 op_type)
+static BOOL slow_set_share_mode(int token,files_struct *fsp, uint16 port, uint16 op_type)
 {
-  files_struct *fs_p = &Files[fnum];
   pstring fname;
   int fd = (int)token;
-  int pid = (int)getpid();
-  struct stat sb;
+  pid_t pid = getpid();
+  SMB_STRUCT_STAT sb;
   char *buf;
   int num_entries;
   int header_size;
   char *p;
 
-  share_name(fs_p->cnum, fs_p->fd_ptr->dev,
-                       fs_p->fd_ptr->inode, fname);
+  share_name(fsp->conn, fsp->fd_ptr->dev,
+                       fsp->fd_ptr->inode, fname);
 
-  if(fstat(fd, &sb) != 0)
+  if(sys_fstat(fd, &sb) != 0)
   {
     DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
                   fname));
@@ -698,17 +732,17 @@ static BOOL slow_set_share_mode(int token,int fnum, uint16 port, uint16 op_type)
   /* Sanity check for file contents (if it's not a new share file). */
   if(sb.st_size != 0)
   {
-    int size = sb.st_size;
+    SMB_OFF_T size = sb.st_size;
 
     /* Allocate space for the file plus one extra entry */
-    if((buf = (char *)malloc(sb.st_size + SMF_ENTRY_LENGTH)) == NULL)
+    if((buf = (char *)malloc((size_t)(sb.st_size + SMF_ENTRY_LENGTH))) == NULL)
     {
       DEBUG(0,("set_share_mode: malloc for file size %d fail !\n", 
-                  sb.st_size + SMF_ENTRY_LENGTH));
+              (int)(sb.st_size + SMF_ENTRY_LENGTH)));
       return False;
     }
  
-    if(lseek(fd, 0, SEEK_SET) != 0)
+    if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
     {
       DEBUG(0,("ERROR: set_share_mode: Failed to reset position \
 to 0 for share file %s (%s)\n", fname, strerror(errno)));
@@ -717,7 +751,7 @@ to 0 for share file %s (%s)\n", fname, strerror(errno)));
       return False;
     }
 
-    if (read(fd,buf,sb.st_size) != sb.st_size)
+    if (read(fd,buf,(size_t)sb.st_size) != (size_t)sb.st_size)
     {
       DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n",
                   fname, strerror(errno)));
@@ -733,7 +767,7 @@ locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET),
                     LOCKING_VERSION));
       if(buf)
         free(buf);
-      delete_share_file(fs_p->cnum, fname);
+      delete_share_file(fsp->conn, fname);
       return False;
     }   
 
@@ -746,7 +780,7 @@ locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET),
 deleting it.\n", fname));
       if(buf)
         free(buf);
-      delete_share_file(fs_p->cnum, fname);
+      delete_share_file(fsp->conn, fname);
       return False;
     }
 
@@ -755,24 +789,26 @@ deleting it.\n", fname));
   {
     /* New file - just use a single_entry. */
     if((buf = (char *)malloc(SMF_HEADER_LENGTH + 
-                  strlen(fs_p->name) + 1 + SMF_ENTRY_LENGTH)) == NULL)
+                  strlen(fsp->fsp_name) + strlen(fsp->conn->connectpath) + 2 + SMF_ENTRY_LENGTH)) == NULL)
     {
       DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
       return False;
     }
     SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION);
     SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0);
-    SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fs_p->name) + 1);
-    pstrcpy(buf + SMF_HEADER_LENGTH, fs_p->name);
+    SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fsp->fsp_name) + strlen(fsp->conn->connectpath) + 2);
+    pstrcpy(buf + SMF_HEADER_LENGTH, fsp->conn->connectpath);
+    pstrcat(buf + SMF_HEADER_LENGTH, "/");
+    pstrcat(buf + SMF_HEADER_LENGTH, fsp->fsp_name);
   }
 
   num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
   header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
   p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH);
-  SIVAL(p,SME_SEC_OFFSET,fs_p->open_time.tv_sec);
-  SIVAL(p,SME_USEC_OFFSET,fs_p->open_time.tv_usec);
-  SIVAL(p,SME_SHAREMODE_OFFSET,fs_p->share_mode);
-  SIVAL(p,SME_PID_OFFSET,pid);
+  SIVAL(p,SME_SEC_OFFSET,fsp->open_time.tv_sec);
+  SIVAL(p,SME_USEC_OFFSET,fsp->open_time.tv_usec);
+  SIVAL(p,SME_SHAREMODE_OFFSET,fsp->share_mode);
+  SIVAL(p,SME_PID_OFFSET,(uint32)pid);
   SSVAL(p,SME_PORT_OFFSET,port);
   SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
 
@@ -780,7 +816,7 @@ deleting it.\n", fname));
 
   SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries);
 
-  if(lseek(fd, 0, SEEK_SET) != 0)
+  if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
   {
     DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \
 0 for share file %s (%s)\n", fname, strerror(errno)));
@@ -794,7 +830,7 @@ deleting it.\n", fname));
   {
     DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
 deleting it (%s).\n",fname, strerror(errno)));
-    delete_share_file(fs_p->cnum, fname);
+    delete_share_file(fsp->conn, fname);
     if(buf)
       free(buf);
     return False;
@@ -802,8 +838,19 @@ deleting it (%s).\n",fname, strerror(errno)));
 
   /* Now truncate the file at this point - just for safety. */
 
-  if(ftruncate(fd, header_size + (SMF_ENTRY_LENGTH*num_entries))!= 0)
+#ifdef FTRUNCATE_NEEDS_ROOT
+  become_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
+  if(sys_ftruncate(fd, (SMB_OFF_T)(header_size + (SMF_ENTRY_LENGTH*num_entries)))!= 0)
   {
+
+#ifdef FTRUNCATE_NEEDS_ROOT
+    int saved_errno = errno;
+    unbecome_root(False);
+    errno = saved_errno;
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
     DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
 mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries), 
                 strerror(errno)));
@@ -812,19 +859,26 @@ mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entr
     return False;
   }
 
+#ifdef FTRUNCATE_NEEDS_ROOT
+  unbecome_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
   if(buf)
     free(buf);
 
   DEBUG(3,("set_share_mode: Created share file %s with \
-mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid));
+mode 0x%X pid=%d\n",fname,fsp->share_mode,(int)pid));
 
   return True;
 }
 
 /*******************************************************************
-Remove an oplock port and mode entry from a share mode.
+ Call a generic modify function for a share mode entry.
 ********************************************************************/
-static BOOL slow_remove_share_oplock(int fnum, int token)
+
+static BOOL slow_mod_share_entry(int token, files_struct *fsp,
+                                void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
+                                void *param)
 {
   pstring fname;
   int fd = (int)token;
@@ -833,92 +887,111 @@ static BOOL slow_remove_share_oplock(int fnum, int token)
   int num_entries;
   int fsize;
   int i;
-  files_struct *fs_p = &Files[fnum];
-  int pid;
+  pid_t pid;
   BOOL found = False;
   BOOL new_file;
+  share_mode_entry entry;
 
-  share_name(fs_p->cnum, fs_p->fd_ptr->dev, 
-                       fs_p->fd_ptr->inode, fname);
+  share_name(fsp->conn, fsp->fd_ptr->dev, 
+                       fsp->fd_ptr->inode, fname);
 
-  if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
+  if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0)
   {
-    DEBUG(0,("ERROR: remove_share_oplock: Failed to read share file %s\n",
+    DEBUG(0,("ERROR: slow_mod_share_entry: Failed to read share file %s\n",
                   fname));
     return False;
   }
 
   if(new_file == True)
   {
-    DEBUG(0,("ERROR: remove_share_oplock: share file %s is new (size zero), \
+    DEBUG(0,("ERROR: slow_mod_share_entry: share file %s is new (size zero), \
 deleting it.\n", fname));
-    delete_share_file(fs_p->cnum, fname);
+    delete_share_file(fsp->conn, fname);
     return False;
   }
 
   num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
 
-  DEBUG(5,("remove_share_oplock: share file %s has %d share mode entries.\n",
+  DEBUG(5,("slow_mod_share_entry: share file %s has %d share mode entries.\n",
             fname, num_entries));
 
   /* PARANOIA TEST */
   if(num_entries < 0)
   {
-    DEBUG(0,("PANIC ERROR:remove_share_oplock: num_share_mode_entries < 0 (%d) \
-for share file %d\n", num_entries, fname));
+    DEBUG(0,("PANIC ERROR:slow_mod_share_entry: num_share_mode_entries < 0 (%d) \
+for share file %s\n", num_entries, fname));
     return False;
   }
 
   if(num_entries == 0)
   {
     /* No entries - just delete the file. */
-    DEBUG(0,("remove_share_oplock: share file %s has no share mode entries - deleting.\n",
+    DEBUG(0,("slow_mod_share_entry: share file %s has no share mode entries - deleting.\n",
               fname));
     if(buf)
       free(buf);
-    delete_share_file(fs_p->cnum, fname);
+    delete_share_file(fsp->conn, fname);
     return False;
   }
 
   pid = getpid();
 
-  /* Go through the entries looking for the particular one
-     we have set - remove the oplock settings on it.
-  */
-
   base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
 
   for(i = 0; i < num_entries; i++)
   {
     char *p = base + (i*SMF_ENTRY_LENGTH);
 
-    if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) || 
-       (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
-       (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) || 
-       (IVAL(p,SME_PID_OFFSET) != pid))
+    if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) || 
+       (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) ||
+       (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) || 
+       (((pid_t)IVAL(p,SME_PID_OFFSET)) != pid))
       continue;
 
-    DEBUG(5,("remove_share_oplock: clearing oplock on entry number %d (of %d) \
+    DEBUG(5,("slow_mod_share_entry: Calling generic function to modify entry number %d (of %d) \
 from the share file %s\n", i, num_entries, fname));
 
-    SSVAL(p,SME_PORT_OFFSET,0);
-    SSVAL(p,SME_OPLOCK_TYPE_OFFSET,0);
+    /*
+     * Copy into the share_mode_entry structure and then call 
+     * the generic function with the given parameter.
+     */
+
+    entry.pid = (pid_t)IVAL(p,SME_PID_OFFSET);
+    entry.op_port = SVAL(p,SME_PORT_OFFSET);
+    entry.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
+    entry.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
+    entry.time.tv_sec = IVAL(p,SME_SEC_OFFSET);
+    entry.time.tv_usec = IVAL(p,SME_USEC_OFFSET);
+
+    (*mod_fn)( &entry, fsp->fd_ptr->dev, fsp->fd_ptr->inode, param);
+
+    /*
+     * Now copy any changes the function made back into the buffer.
+     */
+
+    SIVAL(p,SME_PID_OFFSET, (uint32)entry.pid);
+    SSVAL(p,SME_PORT_OFFSET,entry.op_port);
+    SSVAL(p,SME_OPLOCK_TYPE_OFFSET,entry.op_type);
+    SIVAL(p,SME_SHAREMODE_OFFSET,entry.share_mode);
+    SIVAL(p,SME_SEC_OFFSET,entry.time.tv_sec);
+    SIVAL(p,SME_USEC_OFFSET,entry.time.tv_usec);
+
     found = True;
     break;
   }
 
   if(!found)
   {
-    DEBUG(0,("remove_share_oplock: entry not found in share file %s\n", fname));
+    DEBUG(0,("slow_mod_share_entry: entry not found in share file %s\n", fname));
     if(buf)
       free(buf);
     return False;
   }
 
   /* Re-write the file - and truncate it at the correct point. */
-  if(lseek(fd, 0, SEEK_SET) != 0)
+  if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
   {
-    DEBUG(0,("ERROR: remove_share_oplock: lseek failed to reset to \
+    DEBUG(0,("ERROR: slow_mod_share_entry: lseek failed to reset to \
 position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
     if(buf)
       free(buf);
@@ -928,7 +1001,7 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
   fsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
   if(write(fd, buf, fsize) != fsize)
   {
-    DEBUG(0,("ERROR: remove_share_oplock: failed to re-write share \
+    DEBUG(0,("ERROR: slow_mod_share_entry: failed to re-write share \
 mode file %s (%s)\n", fname, strerror(errno)));
     if(buf)
       free(buf);
@@ -942,12 +1015,12 @@ mode file %s (%s)\n", fname, strerror(errno)));
 
 /*******************************************************************
 call the specified function on each entry under management by the
-share ode system
+share mode system
 ********************************************************************/
 static int slow_share_forall(void (*fn)(share_mode_entry *, char *))
 {
        int i, count=0;
-       void *dir;
+       DIR *dir;
        char *s;
        share_mode_entry e;
 
@@ -961,25 +1034,34 @@ static int slow_share_forall(void (*fn)(share_mode_entry *, char *))
                char *base;
                int fd;
                pstring lname;
-               uint32 dev,inode;
+               SMB_DEV_T dev;
+        SMB_INO_T inode;
                BOOL new_file;
                pstring fname;
 
-               if (sscanf(s,"share.%u.%u",&dev,&inode)!=2) continue;
-       
+#ifdef LARGE_SMB_INO_T
+        double inode_ascii;
+               if (sscanf(s,"share.%u.%lf",&dev,&inode_ascii)!=2) continue;
+        inode = (SMB_INO_T)inode_ascii;
+#else /* LARGE_SMB_INO_T */
+        unsigned long inode_long;
+               if (sscanf(s,"share.%u.%lu",&dev,&inode_long)!=2) continue;
+        inode = (SMB_INO_T)inode_long;
+#endif /* LARGE_SMB_INO_T */       
+
                pstrcpy(lname,lp_lockdir());
                trim_string(lname,NULL,"/");
                pstrcat(lname,"/");
                pstrcat(lname,s);
        
-               fd = open(lname,read_only?O_RDONLY:O_RDWR,0);
+               fd = sys_open(lname,read_only?O_RDONLY:O_RDWR,0);
                if (fd < 0) {
                        continue;
                }
 
                /* Lock the share mode file while we read it. */
                if(!read_only &&
-                  fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False) {
+                  fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False) {
                        close(fd);
                        continue;
                }
@@ -995,12 +1077,11 @@ static int slow_share_forall(void (*fn)(share_mode_entry *, char *))
                        SVAL(buf,SMF_FILENAME_LEN_OFFSET); 
                for( i = 0; i < IVAL(buf, SMF_NUM_ENTRIES_OFFSET); i++) {
                        char *p = base + (i*SMF_ENTRY_LENGTH);
-                       e.pid = IVAL(p,SME_PID_OFFSET);
+                       e.pid = (pid_t)IVAL(p,SME_PID_OFFSET);
                        e.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
                        e.time.tv_sec = IVAL(p,SME_SEC_OFFSET);
                        e.time.tv_usec = IVAL(p,SME_USEC_OFFSET);
                        e.op_port = SVAL(p,SME_PORT_OFFSET);
-                       e.pid = SVAL(p,SME_PID_OFFSET);
                        e.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
 
                        if (process_exists(e.pid)) {
@@ -1035,7 +1116,7 @@ static struct share_ops share_ops = {
        slow_get_share_modes,
        slow_del_share_mode,
        slow_set_share_mode,
-       slow_remove_share_oplock,
+       slow_mod_share_entry,
        slow_share_forall,
        slow_share_status,
 };
@@ -1058,6 +1139,6 @@ struct share_ops *locking_slow_init(int ronly)
        return &share_ops;
 }
 #else
- int locking_slow_dummy_procedure(void)
-{return 0;}
+ int locking_slow_dummy_procedure(void);
+ int locking_slow_dummy_procedure(void) {return 0;}
 #endif /* !FAST_SHARE_MODES */