Syncing up current oplock work in progress. #ifdef'ed out
authorJeremy Allison <jra@samba.org>
Fri, 26 Sep 1997 19:26:56 +0000 (19:26 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 26 Sep 1997 19:26:56 +0000 (19:26 +0000)
so should have no effect on other work.
Jeremy (jallison@whistle.com)

source/include/proto.h
source/include/smb.h
source/lib/util.c
source/locking/locking.c
source/smbd/pipes.c
source/smbd/reply.c
source/smbd/server.c
source/smbd/trans2.c

index 46a96a8bef7c8268fbe17147707f028ff05a250d..8903437d004ccb0d296cf82f601089c94e8e84cd 100644 (file)
@@ -299,13 +299,13 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok
 int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, 
                     min_share_mode_entry **old_shares);
 void del_share_mode(share_lock_token token, int fnum);
-BOOL set_share_mode(share_lock_token token, int fnum, uint16 port);
+BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_type);
 BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok);
 BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token);
 int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, 
                     min_share_mode_entry **old_shares);
 void del_share_mode(share_lock_token token, int fnum);
-BOOL set_share_mode(share_lock_token token,int fnum, uint16 port);
+BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type);
 
 /*The following definitions come from  mangle.c  */
 
@@ -707,8 +707,10 @@ int fd_attempt_close(file_fd_struct *fd_ptr);
 void sync_file(int fnum);
 void close_file(int fnum);
 BOOL check_file_sharing(int cnum,char *fname);
+int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname,
+                      BOOL fcbopen, int *flags);
 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
-                     int mode,int *Access,int *action);
+                     int mode,int oplock_request, int *Access,int *action);
 int seek_file(int fnum,uint32 pos);
 int read_file(int fnum,char *data,uint32 pos,int n);
 int write_file(int fnum,char *data,int n);
@@ -979,3 +981,5 @@ void file_unlock(int fd);
 BOOL is_myname(char *s);
 void set_remote_arch(enum remote_arch_types type);
 enum remote_arch_types get_remote_arch();
+void fstrcpy(char *dest, char *src);
+void pstrcpy(char *dest, char *src);
index 435b71f4dbcff56351e1f29c154013e7dfc67f03..07614194f757763672357a8fe8e442ed006487da 100644 (file)
@@ -330,6 +330,7 @@ typedef struct
   BOOL share_mode;
   BOOL print_file;
   BOOL modified;
+  BOOL granted_oplock;
   char *name;
 } files_struct;
 
@@ -454,6 +455,7 @@ typedef struct
   int pid;
 #ifdef USE_OPLOCKS
   uint16 op_port;
+  uint16 op_type;
 #endif /* USE_OPLOCKS */
   int share_mode;
   struct timeval time;
@@ -465,6 +467,7 @@ typedef struct
   int pid;
 #ifdef USE_OPLOCKS
   uint16 op_port;
+  uint16 op_type;
 #endif /* USE_OPLOCKS */
   int share_mode;
   struct timeval time;
@@ -514,7 +517,7 @@ struct connect_record
 #ifdef USE_OPLOCKS
 #define SMF_ENTRY_LENGTH 16
 #else /* USE_OPLOCKS */
-#define SMF_ENTRY_LENGTH 18
+#define SMF_ENTRY_LENGTH 20
 #endif /* USE_OPLOCKS */
 
 /*
@@ -528,6 +531,7 @@ struct connect_record
 
 #ifdef USE_OPLOCKS
 #define SME_PORT_OFFSET 16
+#define SME_OPLOCK_TYPE_OFFSET 18
 #endif /* USE_OPLOCKS */
 
 #endif /* FAST_SHARE_MODES */
@@ -971,16 +975,52 @@ enum case_handling {CASE_LOWER,CASE_UPPER};
 #define KANJI_CODEPAGE 932
 
 #ifdef KANJI
-/* Default client code page - Japanese */
+/* 
+ * Default client code page - Japanese 
+ */
 #define DEFAULT_CLIENT_CODE_PAGE KANJI_CODEPAGE
 #else /* KANJI */
-/* Default client code page - 850 - Western European */
+/* 
+ * Default client code page - 850 - Western European 
+ */
 #define DEFAULT_CLIENT_CODE_PAGE 850
 #endif /* KANJI */
-/* Size of buffer to use when moving files across filesystems. */
+
+/* 
+ * Size of buffer to use when moving files across filesystems. 
+ */
 #define COPYBUF_SIZE (8*1024)
 
-/* Integers used to override error codes. */
+/* 
+ * Integers used to override error codes. 
+ */
 extern int unix_ERR_class;
 extern int unix_ERR_code;
+
+/*
+ * Map the Core and Extended Oplock requesst bits down
+ * to common bits (EXCLUSIVE_OPLOCK & BATCH_OPLOCK).
+ */
+
+/*
+ * Core protocol.
+ */
+#define CORE_OPLOCK_REQUEST(inbuf) (((CVAL(inbuf,smb_flg)|(1<<5))>>5) | \
+                                    ((CVAL(inbuf,smb_flg)|(1<<6))>>5))
+
+/*
+ * Extended protocol.
+ */
+#define EXTENDED_OPLOCK_REQUEST(inbuf) (((SVAL(inbuf,smb_vwv2)|(1<<1))>>1) | \
+                                        ((SVAL(inbuf,smb_vwv2)|(1<<2))>>1))
+
+/*
+ * Bits we test with.
+ */
+#define EXCLUSIVE_OPLOCK 1
+#define BATCH_OPLOCK 2
+
+#define CORE_OPLOCK_GRANTED (1<<5)
+#define EXTENDED_OPLOCK_GRANTED (1<<15)
+
 /* _SMB_H */
index 8ffc11068a0668d4478d5fbb695d240f209e0452..05dd6198135ac4463b86ff3db504393c506a1bd6 100644 (file)
@@ -4061,53 +4061,52 @@ enum remote_arch_types get_remote_arch()
   return ra_type;
 }
 
-
 /*******************************************************************
 safe string copy into a fstring
 ********************************************************************/
 void fstrcpy(char *dest, char *src)
 {
-       int maxlength = sizeof(fstring) - 1;
-       if (!dest) {
-               DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
-               return;
-       }
-
-       if (!src) {
-               *dest = 0;
-               return;
-       }
+    int maxlength = sizeof(fstring) - 1;
+    if (!dest) {
+        DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
+        return;
+    }
 
-       while (maxlength-- && *src)
-               *dest++ = *src++;
-       *dest = 0;
-       if (*src) {
-               DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
-                        strlen(src)));
-       }
-}
+    if (!src) {
+        *dest = 0;
+        return;
+    }  
+      
+    while (maxlength-- && *src)
+        *dest++ = *src++;
+    *dest = 0;
+    if (*src) {
+        DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
+             strlen(src)));
+    }    
+}   
 
 /*******************************************************************
 safe string copy into a pstring
 ********************************************************************/
 void pstrcpy(char *dest, char *src)
 {
-       int maxlength = sizeof(pstring) - 1; 
-       if (!dest) {
-               DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
-               return;
-       }
-
-       if (!src) {
-               *dest = 0;
-               return;
-       }
-
-       while (maxlength-- && *src)
-               *dest++ = *src++;
-       *dest = 0;
-       if (*src) {
-               DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
-                        strlen(src)));
-       }
-}
+    int maxlength = sizeof(pstring) - 1;
+    if (!dest) {
+        DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
+        return;
+    }
+   
+    if (!src) {
+        *dest = 0;
+        return;
+    }
+   
+    while (maxlength-- && *src)
+        *dest++ = *src++;
+    *dest = 0;
+    if (*src) {
+        DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
+             strlen(src)));
+    }
+}  
index 64f24fb24247e6c375a7ed07c21f58d9bdcd4627..7aa0e7dcf943cb3d58bdbdb1e6b3efe397544048 100644 (file)
@@ -285,6 +285,7 @@ bucket (number of entries now = %d)\n",
        share_array[num_entries_copied].share_mode = entry_scanner_p->share_mode;
 #ifdef USE_OPLOCKS
        share_array[num_entries_copied].op_port = entry_scanner_p->op_port;
+       share_array[num_entries_copied].op_type = entry_scanner_p->op_type;
 #endif /* USE_OPLOCKS */
        memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->time,
               sizeof(struct timeval));
@@ -464,7 +465,7 @@ dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
 /*******************************************************************
 set the share mode of a file. Return False on fail, True on success.
 ********************************************************************/
-BOOL set_share_mode(share_lock_token token, int fnum, uint16 port)
+BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_type)
 {
   files_struct *fs_p = &Files[fnum];
   int32 dev, inode;
@@ -557,6 +558,7 @@ inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry));
   new_entry_p->share_mode = fs_p->share_mode;
 #ifdef USE_OPLOCKS
   new_entry_p->op_port = port;
+  new_entry_p->op_type = op_type;
 #endif /* USE_OPLOCKS */
   memcpy( (char *)&new_entry_p->time, (char *)&fs_p->open_time, sizeof(struct timeval));
 
@@ -892,6 +894,7 @@ it left a share mode entry with mode 0x%X in share file %s\n",
     share_array[num_entries_copied].pid = pid;
 #ifdef USE_OPLOCKS
     share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET);
+    share_array[num_entries_copied].op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
 #endif /* USE_OPLOCKS */
 
     num_entries_copied++;
@@ -939,6 +942,7 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
       SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
 #ifdef USE_OPLOCKS
       SIVAL(p,SME_PORT_OFFSET,share_array[i].op_port);
+      SIVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type);
 #endif /* USE_OPLOCKS */
     }
 
@@ -1120,7 +1124,7 @@ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
 /*******************************************************************
 set the share mode of a file
 ********************************************************************/
-BOOL set_share_mode(share_lock_token token,int fnum, uint16 port)
+BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type)
 {
   files_struct *fs_p = &Files[fnum];
   pstring fname;
@@ -1222,6 +1226,7 @@ deleting it.\n", fname));
   SIVAL(p,SME_PID_OFFSET,pid);
 #ifdef USE_OPLOCKS
   SSVAL(p,SME_PORT_OFFSET,port);
+  SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
 #endif /* USE_OPLOCKS */
 
   num_entries++;
index feb8d91a5b0aff4baf14b067b7e24025d8925d88..a465e911459c84f0927aa120657d3eb3285a30f0 100644 (file)
@@ -127,7 +127,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   unixmode = unix_mode(cnum,smb_attr);
       
   open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
-                  &rmode,&smb_action);
+                  0, &rmode,&smb_action);
       
   if (!Files[fnum].open)
   {
index c1422bbcf609828162b0143ab0cd9dcec8bc5aed..94839c227afcc448fc91c86dce78f545fde1d44b 100644 (file)
@@ -1099,6 +1099,8 @@ int reply_open(char *inbuf,char *outbuf)
   int rmode=0;
   struct stat sbuf;
   BOOL bad_path = False;
+  files_struct *fsp;
+  int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
  
   cnum = SVAL(inbuf,smb_tid);
 
@@ -1123,9 +1125,12 @@ int reply_open(char *inbuf,char *outbuf)
  
   unixmode = unix_mode(cnum,aARCH);
       
-  open_file_shared(fnum,cnum,fname,share_mode,3,unixmode,&rmode,NULL);
+  open_file_shared(fnum,cnum,fname,share_mode,3,unixmode,
+                   oplock_request,&rmode,NULL);
 
-  if (!Files[fnum].open)
+  fsp = &Files[fnum];
+
+  if (!fsp->open)
   {
     if((errno == ENOENT) && bad_path)
     {
@@ -1135,7 +1140,7 @@ int reply_open(char *inbuf,char *outbuf)
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
+  if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
     close_file(fnum);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
@@ -1157,10 +1162,12 @@ int reply_open(char *inbuf,char *outbuf)
   SIVAL(outbuf,smb_vwv4,size);
   SSVAL(outbuf,smb_vwv6,rmode);
 
-  if (lp_fake_oplocks(SNUM(cnum))) {
-    CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
+  if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+    fsp->granted_oplock = True;
   }
     
+  if(fsp->granted_oplock)
+    CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
   return(outsize);
 }
 
@@ -1175,7 +1182,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   int fnum = -1;
   int smb_mode = SVAL(inbuf,smb_vwv3);
   int smb_attr = SVAL(inbuf,smb_vwv5);
-  BOOL oplock_request = BITSETW(inbuf+smb_vwv2,1);
+  BOOL oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
 #if 0
   int open_flags = SVAL(inbuf,smb_vwv2);
   int smb_sattr = SVAL(inbuf,smb_vwv4); 
@@ -1187,6 +1194,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   struct stat sbuf;
   int smb_action = 0;
   BOOL bad_path = False;
+  files_struct *fsp;
 
   /* If it's an IPC, pass off the pipe handler. */
   if (IS_IPC(cnum))
@@ -1214,9 +1222,11 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   unixmode = unix_mode(cnum,smb_attr | aARCH);
       
   open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
-                  &rmode,&smb_action);
+                  oplock_request, &rmode,&smb_action);
       
-  if (!Files[fnum].open)
+  fsp = &Files[fnum];
+
+  if (!fsp->open)
   {
     if((errno == ENOENT) && bad_path)
     {
@@ -1226,7 +1236,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
+  if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
     close_file(fnum);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
@@ -1240,9 +1250,12 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   }
 
   if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
-    smb_action |= (1<<15);
+    fsp->granted_oplock = True;
   }
 
+  if(fsp->granted_oplock)
+    smb_action |= EXTENDED_OPLOCK_GRANTED;
+
   set_message(outbuf,15,0,True);
   SSVAL(outbuf,smb_vwv2,fnum);
   SSVAL(outbuf,smb_vwv3,fmode);
@@ -1302,6 +1315,8 @@ int reply_mknew(char *inbuf,char *outbuf)
   mode_t unixmode;
   int ofun = 0;
   BOOL bad_path = False;
+  files_struct *fsp;
+  int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
  
   com = SVAL(inbuf,smb_com);
   cnum = SVAL(inbuf,smb_tid);
@@ -1343,9 +1358,12 @@ int reply_mknew(char *inbuf,char *outbuf)
   }
 
   /* Open file in dos compatibility share mode. */
-  open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, NULL, NULL);
+  open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, 
+                   oplock_request, NULL, NULL);
   
-  if (!Files[fnum].open)
+  fsp = &Files[fnum];
+
+  if (!fsp->open)
   {
     if((errno == ENOENT) && bad_path) 
     {
@@ -1358,10 +1376,13 @@ int reply_mknew(char *inbuf,char *outbuf)
   outsize = set_message(outbuf,1,0,True);
   SSVAL(outbuf,smb_vwv0,fnum);
 
-  if (lp_fake_oplocks(SNUM(cnum))) {
-    CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
+  if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+    fsp->granted_oplock = True;
   }
-  
+  if(fsp->granted_oplock)
+    CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
   DEBUG(2,("new file %s\n",fname));
   DEBUG(3,("%s mknew %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname,Files[fnum].fd_ptr->fd,fnum,cnum,createmode,unixmode));
   
@@ -1382,6 +1403,8 @@ int reply_ctemp(char *inbuf,char *outbuf)
   int createmode;
   mode_t unixmode;
   BOOL bad_path = False;
+  files_struct *fsp;
+  int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
  
   cnum = SVAL(inbuf,smb_tid);
   createmode = SVAL(inbuf,smb_vwv0);
@@ -1409,9 +1432,12 @@ int reply_ctemp(char *inbuf,char *outbuf)
 
   /* Open file in dos compatibility share mode. */
   /* We should fail if file exists. */
-  open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, NULL, NULL);
+  open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, 
+                   oplock_request, NULL, NULL);
 
-  if (!Files[fnum].open)
+  fsp = &Files[fnum];
+
+  if (!fsp->open)
   {
     if((errno == ENOENT) && bad_path)
     {
@@ -1426,10 +1452,13 @@ int reply_ctemp(char *inbuf,char *outbuf)
   CVAL(smb_buf(outbuf),0) = 4;
   strcpy(smb_buf(outbuf) + 1,fname2);
 
-  if (lp_fake_oplocks(SNUM(cnum))) {
-    CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
+  if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+    fsp->granted_oplock = True;
   }
   
+  if(fsp->granted_oplock)
+    CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+
   DEBUG(2,("created temp file %s\n",fname2));
   DEBUG(3,("%s ctemp %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname2,Files[fnum].fd_ptr->fd,fnum,cnum,createmode,unixmode));
   
@@ -2432,7 +2461,8 @@ int reply_printopen(char *inbuf,char *outbuf)
     return(ERROR(ERRDOS,ERRnoaccess));
 
   /* Open for exclusive use, write only. */
-  open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0), NULL, NULL);
+  open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0), 
+                   0, NULL, NULL);
 
   if (!Files[fnum].open)
     return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -3094,7 +3124,7 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun,
   fnum1 = find_free_file();
   if (fnum1<0) return(False);
   open_file_shared(fnum1,cnum,src,(DENY_NONE<<4),
-                  1,0,&Access,&action);
+                  1,0,0,&Access,&action);
 
   if (!Files[fnum1].open) return(False);
 
@@ -3107,7 +3137,7 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun,
     return(False);
   }
   open_file_shared(fnum2,cnum,dest,(DENY_NONE<<4)|1,
-                  ofun,st.st_mode,&Access,&action);
+                  ofun,st.st_mode,0,&Access,&action);
 
   if (!Files[fnum2].open) {
     close_file(fnum1);
@@ -3713,8 +3743,3 @@ int reply_getattrE(char *inbuf,char *outbuf)
   
   return(outsize);
 }
-
-
-
-
-
index 22c8448dde521f3bb0d9652dee891a9752c5ad6d..d2ad803c9cc309a32fbf33ac25605b7e888c9810 100644 (file)
@@ -88,6 +88,8 @@ static int num_connections_open = 0;
 /* Oplock ipc UDP socket. */
 int oplock_sock = -1;
 uint16 oplock_port = 0;
+/* Current number of oplocks we have outstanding. */
+uint32 oplocks_open = 0;
 #endif /* USE_OPLOCKS */
 
 extern fstring remote_machine;
@@ -1052,9 +1054,10 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
   pstring fname;
   struct stat statbuf;
   file_fd_struct *fd_ptr;
+  files_struct *fsp = &Files[fnum];
 
-  Files[fnum].open = False;
-  Files[fnum].fd_ptr = 0;
+  fsp->open = False;
+  fsp->fd_ptr = 0;
   errno = EPERM;
 
   pstrcpy(fname,fname1);
@@ -1192,7 +1195,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
     if (sys_disk_free(dname,&dum1,&dum2,&dum3) < 
        lp_minprintspace(SNUM(cnum))) {
       fd_attempt_close(fd_ptr);
-      Files[fnum].fd_ptr = 0;
+      fsp->fd_ptr = 0;
       if(fd_ptr->ref_count == 0)
         sys_unlink(fname);
       errno = ENOSPC;
@@ -1228,25 +1231,26 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
       fd_ptr->dev = (uint32)sbuf->st_dev;
       fd_ptr->inode = (uint32)sbuf->st_ino;
 
-      Files[fnum].fd_ptr = fd_ptr;
+      fsp->fd_ptr = fd_ptr;
       Connections[cnum].num_files_open++;
-      Files[fnum].mode = sbuf->st_mode;
-      GetTimeOfDay(&Files[fnum].open_time);
-      Files[fnum].uid = current_user.id;
-      Files[fnum].size = 0;
-      Files[fnum].pos = -1;
-      Files[fnum].open = True;
-      Files[fnum].mmap_ptr = NULL;
-      Files[fnum].mmap_size = 0;
-      Files[fnum].can_lock = True;
-      Files[fnum].can_read = ((flags & O_WRONLY)==0);
-      Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
-      Files[fnum].share_mode = 0;
-      Files[fnum].print_file = Connections[cnum].printer;
-      Files[fnum].modified = False;
-      Files[fnum].cnum = cnum;
-      string_set(&Files[fnum].name,dos_to_unix(fname,False));
-      Files[fnum].wbmpx_ptr = NULL;      
+      fsp->mode = sbuf->st_mode;
+      GetTimeOfDay(&fsp->open_time);
+      fsp->uid = current_user.id;
+      fsp->size = 0;
+      fsp->pos = -1;
+      fsp->open = True;
+      fsp->mmap_ptr = NULL;
+      fsp->mmap_size = 0;
+      fsp->can_lock = True;
+      fsp->can_read = ((flags & O_WRONLY)==0);
+      fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
+      fsp->share_mode = 0;
+      fsp->print_file = Connections[cnum].printer;
+      fsp->modified = False;
+      fsp->granted_oplock = False;
+      fsp->cnum = cnum;
+      string_set(&fsp->name,dos_to_unix(fname,False));
+      fsp->wbmpx_ptr = NULL;      
 
       /*
        * If the printer is marked as postscript output a leading
@@ -1255,8 +1259,8 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
        * This has a similar effect as CtrlD=0 in WIN.INI file.
        * tim@fsg.com 09/06/94
        */
-      if (Files[fnum].print_file && POSTSCRIPT(cnum) && 
-         Files[fnum].can_write) 
+      if (fsp->print_file && POSTSCRIPT(cnum) && 
+         fsp->can_write) 
        {
          DEBUG(3,("Writing postscript line\n"));
          write_file(fnum,"%!\n",3);
@@ -1264,23 +1268,23 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
       
       DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
               timestring(),Connections[cnum].user,fname,
-              BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
+              BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
               Connections[cnum].num_files_open,fnum));
 
     }
 
 #if USE_MMAP
   /* mmap it if read-only */
-  if (!Files[fnum].can_write)
+  if (!fsp->can_write)
     {
-      Files[fnum].mmap_size = file_size(fname);
-      Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
-                                         PROT_READ,MAP_SHARED,Files[fnum].fd_ptr->fd,0);
+      fsp->mmap_size = file_size(fname);
+      fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
+                                         PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
 
-      if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
+      if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
        {
          DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
-         Files[fnum].mmap_ptr = NULL;
+         fsp->mmap_ptr = NULL;
        }
     }
 #endif
@@ -1512,12 +1516,52 @@ static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
   }
 }
 
+/****************************************************************************
+check if we can open a file with a share mode
+****************************************************************************/
+int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname,
+                      BOOL fcbopen, int *flags)
+{
+  int old_open_mode = share->share_mode &0xF;
+  int old_deny_mode = (share->share_mode >>4)&7;
+
+  if (old_deny_mode > 4 || old_open_mode > 2)
+  {
+    DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
+               deny_mode,old_deny_mode,old_open_mode,fname));
+    return False;
+  }
+
+  {
+    int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
+                                share->pid,fname);
+
+    if ((access_allowed == AFAIL) ||
+        (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
+        (access_allowed == AREAD && *flags == O_WRONLY) ||
+        (access_allowed == AWRITE && *flags == O_RDONLY))
+    {
+      DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
+                deny_mode,old_deny_mode,old_open_mode,
+                share->pid,fname, access_allowed));
+      return False;
+    }
+
+    if (access_allowed == AREAD)
+      *flags = O_RDONLY;
+
+    if (access_allowed == AWRITE)
+      *flags = O_WRONLY;
+
+  }
+  return True;
+}
 
 /****************************************************************************
 open a file with a share mode
 ****************************************************************************/
 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
-                     int mode,int *Access,int *action)
+                     int mode,int oplock_request, int *Access,int *action)
 {
   files_struct *fs_p = &Files[fnum];
   int flags=0;
@@ -1605,7 +1649,6 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
     int i;
     min_share_mode_entry *old_shares = 0;
 
-
     if (file_existed)
     {
       dev = (uint32)sbuf.st_dev;
@@ -1615,55 +1658,61 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
       num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
     }
 
-    for(i = 0; i < num_shares; i++)
-    {
-      /* someone else has a share lock on it, check to see 
-        if we can too */
-      int old_open_mode = old_shares[i].share_mode &0xF;
-      int old_deny_mode = (old_shares[i].share_mode >>4)&7;
+    /*
+     * Check if the share modes will give us access.
+     */
 
-      if (old_deny_mode > 4 || old_open_mode > 2) 
-      {
-       DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
-                deny_mode,old_deny_mode,old_open_mode,fname));
-        free((char *)old_shares);
-        if(share_locked)
-          unlock_share_entry(cnum, dev, inode, token);
-       errno = EACCES;
-       unix_ERR_class = ERRDOS;
-       unix_ERR_code = ERRbadshare;
-       return;
-      }
+    if(share_locked && (num_shares != 0))
+    {
+      BOOL broke_oplock;
 
+      do
       {
-       int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
-                                         old_shares[i].pid,fname);
-
-       if ((access_allowed == AFAIL) ||
-           (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
-           (access_allowed == AREAD && flags == O_WRONLY) ||
-           (access_allowed == AWRITE && flags == O_RDONLY)) 
+        broke_oplock = False;
+        for(i = 0; i < num_shares; i++)
         {
-         DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
-                  deny_mode,old_deny_mode,old_open_mode,
-                  old_shares[i].pid,fname,
-                  access_allowed));
-          free((char *)old_shares);
-          if(share_locked)
+          /* someone else has a share lock on it, check to see 
+             if we can too */
+          if(check_share_mode(&old_shares[i], deny_mode, fname, fcbopen, &flags) == False)
+          {
+            free((char *)old_shares);
             unlock_share_entry(cnum, dev, inode, token);
-         errno = EACCES;
-         unix_ERR_class = ERRDOS;
-         unix_ERR_code = ERRbadshare;
-         return;
+            errno = EACCES;
+            unix_ERR_class = ERRDOS;
+            unix_ERR_code = ERRbadshare;
+            return;
+          }
+#ifdef USE_OPLOCKS
+          /* 
+           * The share modes would give us access. Check if someone
+           * has an oplock on this file. If so we must break it before
+           * continuing. 
+           */
+          if(old_shares[i].op_type != 0)
+          {
+            /* Oplock break.... */
+            unlock_share_entry(cnum, dev, inode, token);
+#if 0 /* Work in progress..... */
+            if(break_oplock())
+            {
+              free((char *)old_shares);
+              /* Error condition here... */
+            }
+            lock_share_entry(cnum, dev, inode, &token);
+            broke_oplock = True;
+            break;
+#endif
+          }
+#endif /* USE_OPLOCKS */
         }
-       
-       if (access_allowed == AREAD)
-         flags = O_RDONLY;
-       
-       if (access_allowed == AWRITE)
-         flags = O_WRONLY;
-      }
+        if(broke_oplock)
+        {
+          free((char *)old_shares);
+          num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
+        }
+      } while(broke_oplock);
     }
+
     if(old_shares != 0)
       free((char *)old_shares);
   }
@@ -1720,7 +1769,7 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
        file (which expects the share_mode_entry to be there).
      */
     if (lp_share_modes(SNUM(cnum)))
-      set_share_mode(token, fnum, 0);
+      set_share_mode(token, fnum, 0, 0);
 
     if ((flags2&O_TRUNC) && file_existed)
       truncate_unless_locked(fnum,cnum,token,&share_locked);
@@ -2279,7 +2328,8 @@ static BOOL open_oplock_ipc()
   if (oplock_sock == -1)
   {
     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
-address %x. Error was %s\n", INADDR_LOOPBACK, strerror(errno)));
+address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
+    oplock_port = 0;
     return(False);
   }
 
@@ -2290,6 +2340,7 @@ address %x. Error was %s\n", INADDR_LOOPBACK, strerror(errno)));
             strerror(errno)));
     close(oplock_sock);
     oplock_sock = -1;
+    oplock_port = 0;
     return False;
   }
   oplock_port = ntohs(sock_name.sin_port);
@@ -2324,7 +2375,7 @@ static BOOL process_local_message(int oplock_sock, char *buffer, int buf_size)
   /* Validate message from address (must be localhost). */
   if(from_addr.s_addr != htonl(INADDR_LOOPBACK))
   {
-    DEBUG(0,("process_local_message: invalid from address \
+    DEBUG(0,("process_local_message: invalid 'from' address \
 (was %x should be 127.0.0.1\n", from_addr.s_addr));
    return False;
   }
@@ -4010,20 +4061,20 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
   it can be used by the oplock break code.
 ****************************************************************************/
 
-static void process_smb(char *InBuffer, char *OutBuffer)
+static void process_smb(char *inbuf, char *outbuf)
 {
   extern int Client;
   static int trans_num = 0;
 
-  int msg_type = CVAL(InBuffer,0);
-  int32 len = smb_len(InBuffer);
+  int msg_type = CVAL(inbuf,0);
+  int32 len = smb_len(outbuf);
   int nread = len + 4;
 
   DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
   DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
 
 #ifdef WITH_VTP
-  if(trans_num == 1 && VT_Check(InBuffer)) 
+  if(trans_num == 1 && VT_Check(inbuf)) 
   {
     VT_Process();
     return;
@@ -4031,22 +4082,22 @@ static void process_smb(char *InBuffer, char *OutBuffer)
 #endif
 
   if (msg_type == 0)
-    show_msg(InBuffer);
+    show_msg(inbuf);
 
-  nread = construct_reply(InBuffer,OutBuffer,nread,max_send);
+  nread = construct_reply(inbuf,outbuf,nread,max_send);
       
   if(nread > 0) 
   {
-    if (CVAL(OutBuffer,0) == 0)
-      show_msg(OutBuffer);
+    if (CVAL(outbuf,0) == 0)
+      show_msg(outbuf);
        
-    if (nread != smb_len(OutBuffer) + 4) 
+    if (nread != smb_len(outbuf) + 4) 
     {
       DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
-                 nread, smb_len(OutBuffer)));
+                 nread, smb_len(outbuf)));
     }
     else
-      send_smb(Client,OutBuffer);
+      send_smb(Client,outbuf);
   }
   trans_num++;
 }
index 59e9ef21b0ef8b2b126b4232875ac1ab042dc3bb..8ab024ded28e2702e6bc7c25a2a2d188ce31b2e3 100644 (file)
@@ -166,7 +166,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
   char *params = *pparams;
   int16 open_mode = SVAL(params, 2);
   int16 open_attr = SVAL(params,6);
-  BOOL oplock_request = BITSETW(params,1);
+  BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
 #if 0
   BOOL return_additional_info = BITSETW(params,0);
   int16 open_sattr = SVAL(params, 4);
@@ -213,7 +213,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
       
       
   open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode,
-                  &rmode,&smb_action);
+                  oplock_request, &rmode,&smb_action);
       
   if (!Files[fnum].open)
   {
@@ -252,7 +252,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
   SSVAL(params,12,rmode);
 
   if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
-    smb_action |= (1<<15);
+    smb_action |= EXTENDED_OPLOCK_GRANTED;
   }
 
   SSVAL(params,18,smb_action);