this checkin gets rid of the global Files[] array and makes it local
authorAndrew Tridgell <tridge@samba.org>
Sat, 15 Aug 1998 07:27:34 +0000 (07:27 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sat, 15 Aug 1998 07:27:34 +0000 (07:27 +0000)
in files.c

it should now be faily easy to expand the default MAX_OPEN_FILES to
many thousands.

18 files changed:
source/Makefile.in
source/include/local.h
source/include/proto.h
source/include/smb.h
source/locking/locking.c
source/locking/locking_shm.c
source/locking/locking_slow.c
source/rpc_server/srv_pipe_hnd.c
source/script/mkproto.awk
source/smbd/files.c [new file with mode: 0644]
source/smbd/ipc.c
source/smbd/nttrans.c
source/smbd/pipes.c
source/smbd/reply.c
source/smbd/server.c
source/smbd/trans2.c
source/utils/status.c
source/web/swat.c

index d79873f7e8d9d69e212bc9eaa6d2cea604411a04..51cf4feec1801576355c4a0a7ac8ff91bb2c9626 100644 (file)
@@ -120,7 +120,7 @@ LOCKING_OBJ = locking/locking.o locking/locking_shm.o locking/locking_slow.o \
 PASSDB_OBJ = passdb/passdb.o passdb/smbpassfile.o passdb/smbpass.o \
              passdb/pass_check.o passdb/ldap.o passdb/nispass.o 
 
-SMBD_OBJ1 = smbd/server.o smbd/chgpasswd.o smbd/connection.o \
+SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
             smbd/dfree.o smbd/dir.o smbd/password.o \
             smbd/groupname.o smbd/ipc.o smbd/mangle.o \
             smbd/message.o smbd/nttrans.o smbd/pipes.o smbd/predict.o \
@@ -294,7 +294,7 @@ uninstallcp:
        @$(SHELL) $(srcdir)/script/uninstallcp.sh $(CODEPAGEDIR) $(CODEPAGELIST)
 
 clean: 
-       rm -f core */*.o */*~ *~ config.cache bin/[!C]*
+       rm -f core */*.o */*~ *~ config.cache $(PROGS)
 
 proto:
        @echo rebuilding include/proto.h
index fb67babcda2806b7d6d0c6d6975a1e2b1d7b607c..af12f835515aeb8d4a2c6352f58579b0f7773e86 100644 (file)
 /* to a maximum of 8 if old smb clients break because of long printer names. */
 #define MAXPRINTERLEN 15
 
+/* max number of directories open at once */
+/* note that with the new directory code this no longer requires a
+   file handle per directory, but large numbers do use more memory */
+#define MAX_OPEN_DIRECTORIES 64
 
 /* define what facility to use for syslog */
 #ifndef SYSLOG_FACILITY
    MAX_CONNECTIONS services, but any number of machines may connect at
    one time. */
 #define MAX_CONNECTIONS 127
-#define MAX_OPEN_FILES 100
-
-/* max number of directories open at once */
-/* note that with the new directory code this no longer requires a
-   file handle per directory, but large numbers do use more memory */
-#define MAX_OPEN_DIRECTORIES 64
 
-#define MAX_FNUMS (MAX_OPEN_FILES+MAX_OPEN_DIRECTORIES)
+/* this must be larger than the sum of the open files and directories */
+#define PIPE_HANDLE_OFFSET 0x7000
 
 /* Default size of shared memory used for share mode locking */
 #ifndef SHMEM_SIZE
-#define SHMEM_SIZE (1024*(MAX_OPEN_FILES+MAX_OPEN_DIRECTORIES))
+#define SHMEM_SIZE (1024*1024)
 #endif
 
 /* the max number of simultanous connections to the server by all clients */
index 49d078b78acd3e0f59de68e8881efb62d63c9985..9587828ea94b6842a8dade741d3c9c211c7ceca3 100644 (file)
@@ -474,12 +474,12 @@ char *smb_errstr(char *inbuf);
 
 BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num);
 void process_blocking_lock_queue(time_t t);
-BOOL is_locked(int fnum,connection_struct *conn,
+BOOL is_locked(files_struct *fsp,connection_struct *conn,
               uint32 count,uint32 offset, int lock_type);
-BOOL do_lock(int fnum,connection_struct *conn,
+BOOL do_lock(files_struct *fsp,connection_struct *conn,
             uint32 count,uint32 offset,int lock_type,
              int *eclass,uint32 *ecode);
-BOOL do_unlock(int fnum,connection_struct *conn,
+BOOL do_unlock(files_struct *fsp,connection_struct *conn,
               uint32 count,uint32 offset,int *eclass,uint32 *ecode);
 BOOL locking_init(int read_only);
 BOOL locking_end(void);
@@ -490,9 +490,9 @@ BOOL unlock_share_entry(connection_struct *conn,
 int get_share_modes(connection_struct *conn, 
                    int token, uint32 dev, uint32 inode, 
                    share_mode_entry **shares);
-void del_share_mode(int token, int fnum);
-BOOL set_share_mode(int token, int fnum, uint16 port, uint16 op_type);
-BOOL remove_share_oplock(int fnum, int token);
+void del_share_mode(int token, files_struct *fsp);
+BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type);
+BOOL remove_share_oplock(files_struct *fsp, int token);
 int share_mode_forall(void (*fn)(share_mode_entry *, char *));
 void share_status(FILE *f);
 
@@ -1941,6 +1941,20 @@ void DirCacheAdd( char *path, char *name, char *dname, int snum );
 char *DirCacheCheck( char *path, char *name, int snum );
 void DirCacheFlush(int snum);
 
+/*The following definitions come from  smbd/files.c  */
+
+files_struct *find_free_file(void );
+file_fd_struct *fd_get_already_open(struct stat *sbuf);
+file_fd_struct *fd_get_new(void);
+void file_close_conn(connection_struct *conn);
+void file_init(void);
+files_struct *file_fsp(int fnum);
+void file_close_user(int vuid);
+files_struct *file_find_dit(int dev, int inode, struct timeval *tval);
+files_struct *file_find_print(void);
+void file_sync_all(connection_struct *conn);
+void file_free(files_struct *fsp);
+
 /*The following definitions come from  smbd/groupname.c  */
 
 void load_groupname_map(void);
@@ -1979,7 +1993,7 @@ int reply_ntcancel(connection_struct *conn,
                   char *inbuf,char *outbuf,int length,int bufsize);
 int reply_nttranss(connection_struct *conn,
                   char *inbuf,char *outbuf,int length,int bufsize);
-void remove_pending_change_notify_requests_by_fid(int fnum);
+void remove_pending_change_notify_requests_by_fid(files_struct *fsp);
 void remove_pending_change_notify_requests_by_mid(int mid);
 void process_pending_change_notify_queue(time_t t);
 int reply_nttrans(connection_struct *conn,
@@ -2114,22 +2128,23 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times);
 BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime);
 BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component, BOOL *bad_path);
 BOOL check_name(char *name,connection_struct *conn);
-void sync_file(connection_struct *conn, int fnum);
-void close_file(int fnum, BOOL normal_close);
-void close_directory(int fnum);
-int open_directory(int fnum,connection_struct *conn,
+void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u);
+void sync_file(connection_struct *conn, files_struct *fsp);
+void close_file(files_struct *fsp, BOOL normal_close);
+void close_directory(files_struct *fsp);
+int open_directory(files_struct *fsp,connection_struct *conn,
                   char *fname, int smb_ofun, int unixmode, int *action);
 BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op);
 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
                       BOOL fcbopen, int *flags);
-void open_file_shared(int fnum,connection_struct *conn,char *fname,int share_mode,int ofun,
+void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
                      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);
+int seek_file(files_struct *fsp,uint32 pos);
+int read_file(files_struct *fsp,char *data,uint32 pos,int n);
+int write_file(files_struct *fsp,char *data,int n);
 BOOL become_service(connection_struct *conn,BOOL do_chdir);
 int find_service(char *service);
-int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line);
+int cached_error_packet(char *inbuf,char *outbuf,files_struct *fsp,int line);
 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line);
 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line);
 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval);
@@ -2139,7 +2154,7 @@ BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int tim
 BOOL snum_used(int snum);
 BOOL reload_services(BOOL test);
 connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode);
-int find_free_file(void );
+BOOL attempt_close_oplocked_file(files_struct *fsp);
 int reply_corep(char *outbuf);
 int reply_coreplus(char *outbuf);
 int reply_lanman1(char *outbuf);
index fa5d496ceb805b5afe3e77e2a0ea9a55085ad551..801e1344354936dc69e8a17f7cd0e5fddf1fd588 100644 (file)
@@ -575,6 +575,7 @@ struct current_user
 
 typedef struct
 {
+       int fnum;
        connection_struct *conn;
        file_fd_struct *fd_ptr;
        int pos;
@@ -599,6 +600,10 @@ typedef struct
        char *fsp_name;
 } files_struct;
 
+/* this macro should always be used to extract an fnum (smb_fid) from
+   a packet to ensure chaining works correctly */
+#define GETFSP(buf,where) (chain_fsp?chain_fsp:file_fsp(SVAL(buf,where)))
+
 
 /* Domain controller authentication protocol info */
 struct dcinfo
@@ -695,9 +700,9 @@ struct share_ops {
        BOOL (*lock_entry)(connection_struct *, uint32 , uint32 , int *);
        BOOL (*unlock_entry)(connection_struct *, uint32 , uint32 , int );
        int (*get_entries)(connection_struct *, int , uint32 , uint32 , share_mode_entry **);
-       void (*del_entry)(int , int );
-       BOOL (*set_entry)(int , int , uint16 , uint16 );
-       BOOL (*remove_oplock)(int , int);
+       void (*del_entry)(int , files_struct *);
+       BOOL (*set_entry)(int, files_struct *, uint16 , uint16 );
+       BOOL (*remove_oplock)(files_struct *, int);
        int (*forall)(void (*)(share_mode_entry *, char *));
        void (*status)(FILE *);
 };
@@ -858,22 +863,21 @@ struct parm_struct
 #endif /* LOCKING_VERSION */
 
 /* these are useful macros for checking validity of handles */
-#define VALID_FNUM(fnum)   (((fnum) >= 0) && ((fnum) < MAX_FNUMS))
-#define OPEN_FNUM(fnum)    (VALID_FNUM(fnum) && Files[fnum].open && !Files[fnum].is_directory)
+#define OPEN_FSP(fsp)    ((fsp) && (fsp)->open && !(fsp)->is_directory)
 #define VALID_CNUM(cnum)   (((cnum) >= 0) && ((cnum) < MAX_CONNECTIONS))
-#define OPEN_CNUM(conn)    ((conn) && (conn)->open)
+#define OPEN_CONN(conn)    ((conn) && (conn)->open)
 #define IS_IPC(conn)       ((conn) && (conn)->ipc)
 #define IS_PRINT(conn)       ((conn) && (conn)->printer)
-#define FNUM_OK(fnum,c) (OPEN_FNUM(fnum) && (c)==Files[fnum].conn)
+#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn)
 
-#define CHECK_FNUM(fnum,conn) if (!FNUM_OK(fnum,conn)) \
+#define CHECK_FSP(fsp,conn) if (!FNUM_OK(fsp,conn)) \
                                return(ERROR(ERRDOS,ERRbadfid))
-#define CHECK_READ(fnum) if (!Files[fnum].can_read) \
+#define CHECK_READ(fsp) if (!(fsp)->can_read) \
                                return(ERROR(ERRDOS,ERRbadaccess))
-#define CHECK_WRITE(fnum) if (!Files[fnum].can_write) \
+#define CHECK_WRITE(fsp) if (!(fsp)->can_write) \
                                return(ERROR(ERRDOS,ERRbadaccess))
-#define CHECK_ERROR(fnum) if (HAS_CACHED_ERROR(fnum)) \
-                               return(CACHED_ERROR(fnum))
+#define CHECK_ERROR(fsp) if (HAS_CACHED_ERROR(fsp)) \
+                               return(CACHED_ERROR(fsp))
 
 /* translates a connection number into a service number */
 #define SNUM(conn)         ((conn)?(conn)->service:-1)
@@ -883,7 +887,7 @@ struct parm_struct
 #define PRINTCAP           (lp_printcapname())
 #define PRINTCOMMAND(snum) (lp_printcommand(snum))
 #define PRINTERNAME(snum)  (lp_printername(snum))
-#define CAN_WRITE(conn)    (OPEN_CNUM(conn) && !conn->read_only)
+#define CAN_WRITE(conn)    (OPEN_CONN(conn) && !conn->read_only)
 #define VALID_SNUM(snum)   (lp_snum_ok(snum))
 #define GUEST_OK(snum)     (VALID_SNUM(snum) && lp_guest_ok(snum))
 #define GUEST_ONLY(snum)   (VALID_SNUM(snum) && lp_guest_only(snum))
@@ -1432,11 +1436,10 @@ enum ssl_version_enum {SMB_SSL_V2,SMB_SSL_V3,SMB_SSL_V23,SMB_SSL_TLS1};
 #define CACHE_ERROR(w,c,e) ((w)->wr_errclass = (c), (w)->wr_error = (e), \
                            w->wr_discard = True, -1)
 /* Macro to test if an error has been cached for this fnum */
-#define HAS_CACHED_ERROR(fnum) (Files[(fnum)].open && \
-                               Files[(fnum)].wbmpx_ptr && \
-                               Files[(fnum)].wbmpx_ptr->wr_discard)
+#define HAS_CACHED_ERROR(fsp) ((fsp)->open && (fsp)->wbmpx_ptr && \
+                               (fsp)->wbmpx_ptr->wr_discard)
 /* Macro to turn the cached error into an error packet */
-#define CACHED_ERROR(fnum) cached_error_packet(inbuf,outbuf,fnum,__LINE__)
+#define CACHED_ERROR(fsp) cached_error_packet(inbuf,outbuf,fsp,__LINE__)
 
 /* these are the datagram types */
 #define DGRAM_DIRECT_UNIQUE 0x10
index bb852b07d66945a615d636ef0dda455a15294446..50c4af2265dfbeb8763b74f87e62e6598acbde7e 100644 (file)
@@ -33,7 +33,6 @@
 
 #include "includes.h"
 extern int DEBUGLEVEL;
-extern files_struct Files[];
 extern int Client;
 
 static struct share_ops *share_ops;
@@ -62,7 +61,7 @@ static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_qu
 BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num)
 {
   blocking_lock_record *blr;
-  int fnum = GETFNUM(inbuf,smb_vwv2);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv2);
 
   /*
    * Now queue an entry on the blocking lock queue. We setup
@@ -88,7 +87,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int
   ubi_slAddTail(&blocking_lock_queue, blr);
 
   DEBUG(3,("push_blocking_lock_request: lock request blocked with expiry time %d \
-for fnum = %d, name = %s\n", blr->expire_time, fnum, Files[fnum].name ));
+for fnum = %d, name = %s\n", blr->expire_time, fsp->fnum, fsp->name ));
 
   return True;
 }
@@ -96,16 +95,15 @@ for fnum = %d, name = %s\n", blr->expire_time, fnum, Files[fnum].name ));
 /****************************************************************************
  Return a blocking lock success SMB.
 *****************************************************************************/
-
 static void blocking_lock_reply_success(blocking_lock_record *blr)
 {
   extern int chain_size;
-  extern int chain_fnum;
+  extern files_struct *chain_fsp;
   extern char *OutBuffer;
   char *outbuf = OutBuffer;
   int bufsize = BUFFER_SIZE;
   char *inbuf = blr->inbuf;
-  int fnum = GETFNUM(inbuf,smb_vwv2);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv2);
   int outsize = 0;
 
   construct_reply_common(inbuf, outbuf);
@@ -119,7 +117,7 @@ static void blocking_lock_reply_success(blocking_lock_record *blr)
    * that here and must set up the chain info manually.
    */
 
-  chain_fnum = fnum;
+  chain_fsp = fsp;
   chain_size = 0;
 
   outsize = chain_reply(inbuf,outbuf,blr->length,bufsize);
@@ -142,7 +140,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int
   char *outbuf = OutBuffer;
   int bufsize = BUFFER_SIZE;
   char *inbuf = blr->inbuf;
-  int fnum = GETFNUM(inbuf,smb_vwv2);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv2);
   uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
   uint16 num_locks = SVAL(inbuf,smb_vwv7);
   uint32 count, offset;
@@ -160,7 +158,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int
   for(i = blr->lock_num; i >= 0; i--) {
     count = IVAL(data,SMB_LKLEN_OFFSET(i));
     offset = IVAL(data,SMB_LKOFF_OFFSET(i));
-    do_unlock(fnum,conn,count,offset,&dummy1,&dummy2);
+    do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
   }
 
   construct_reply_common(inbuf, outbuf);
@@ -177,7 +175,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr)
 {
   char *inbuf = blr->inbuf;
   unsigned char locktype = CVAL(inbuf,smb_vwv3);
-  int fnum = GETFNUM(inbuf,smb_vwv2);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv2);
   uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
   uint16 num_locks = SVAL(inbuf,smb_vwv7);
   uint32 count, offset;
@@ -196,7 +194,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr)
   for(; blr->lock_num < num_locks; blr->lock_num++) {
     count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num));
     offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num));
-    if(!do_lock(fnum,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
+    if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
                 &eclass, &ecode))
       break;
   }
@@ -208,7 +206,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr)
      */
 
     DEBUG(3,("blocking_lock_record_process fnum=%d type=%d num_locks=%d\n",
-          fnum, (unsigned int)locktype, num_locks) );
+          fsp->fnum, (unsigned int)locktype, num_locks) );
 
     blocking_lock_reply_success(blr);
     return True;
@@ -230,7 +228,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr)
    */
 
   DEBUG(10,("blocking_lock_record_process: only got %d locks of %d needed for fnum = %d. \
-Waiting..\n", blr->lock_num, num_locks, fnum ));
+Waiting..\n", blr->lock_num, num_locks, fsp->fnum));
 
   return False;
 }
@@ -252,13 +250,12 @@ void process_blocking_lock_queue(time_t t)
    */
 
   while(blr != NULL) {
-    int fnum = GETFNUM(blr->inbuf,smb_vwv2);
-    files_struct *fsp = &Files[fnum];
+    files_struct *fsp = GETFSP(blr->inbuf,smb_vwv2);
     uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
                   SVAL(blr->inbuf,smb_uid);
 
     DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n",
-          fnum, fsp->name ));
+          fsp->fnum, fsp->name ));
 
     if((blr->expire_time != -1) && (blr->expire_time > t)) {
       /*
@@ -266,7 +263,7 @@ void process_blocking_lock_queue(time_t t)
        * obtained locks and return lock error.
        */
       DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n",
-          fnum, fsp->name ));
+          fsp->fnum, fsp->name ));
 
       blocking_lock_reply_error(blr,ERRSRV,ERRaccess);
       free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
@@ -356,11 +353,10 @@ static int map_lock_type( files_struct *fsp, int lock_type)
 /****************************************************************************
  Utility function called to see if a file region is locked.
 ****************************************************************************/
-BOOL is_locked(int fnum,connection_struct *conn,
+BOOL is_locked(files_struct *fsp,connection_struct *conn,
               uint32 count,uint32 offset, int lock_type)
 {
        int snum = SNUM(conn);
-       files_struct *fsp = &Files[fnum];
 
        if (count == 0)
                return(False);
@@ -381,12 +377,11 @@ BOOL is_locked(int fnum,connection_struct *conn,
 /****************************************************************************
  Utility function called by locking requests.
 ****************************************************************************/
-BOOL do_lock(int fnum,connection_struct *conn,
+BOOL do_lock(files_struct *fsp,connection_struct *conn,
             uint32 count,uint32 offset,int lock_type,
              int *eclass,uint32 *ecode)
 {
   BOOL ok = False;
-  files_struct *fsp = &Files[fnum];
 
   if (!lp_locking(SNUM(conn)))
     return(True);
@@ -397,7 +392,7 @@ BOOL do_lock(int fnum,connection_struct *conn,
     return False;
   }
 
-  if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->conn == conn))
+  if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
     ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,
                     map_lock_type(fsp,lock_type));
 
@@ -413,16 +408,15 @@ BOOL do_lock(int fnum,connection_struct *conn,
 /****************************************************************************
  Utility function called by unlocking requests.
 ****************************************************************************/
-BOOL do_unlock(int fnum,connection_struct *conn,
+BOOL do_unlock(files_struct *fsp,connection_struct *conn,
               uint32 count,uint32 offset,int *eclass,uint32 *ecode)
 {
   BOOL ok = False;
-  files_struct *fsp = &Files[fnum];
 
   if (!lp_locking(SNUM(conn)))
     return(True);
 
-  if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->conn == conn))
+  if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
     ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK);
    
   if (!ok) {
@@ -501,26 +495,26 @@ int get_share_modes(connection_struct *conn,
  Del the share mode of a file.
 ********************************************************************/
 
-void del_share_mode(int token, int fnum)
+void del_share_mode(int token, files_struct *fsp)
 {
-       share_ops->del_entry(token, fnum);
+       share_ops->del_entry(token, fsp);
 }
 
 /*******************************************************************
  Set the share mode of a file. Return False on fail, True on success.
 ********************************************************************/
 
-BOOL set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
+BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type)
 {
-       return share_ops->set_entry(token, fnum, port, op_type);
+       return share_ops->set_entry(token, fsp, port, op_type);
 }
 
 /*******************************************************************
  Remove an oplock port and mode entry from a share mode.
 ********************************************************************/
-BOOL remove_share_oplock(int fnum, int token)
+BOOL remove_share_oplock(files_struct *fsp, int token)
 {
-       return share_ops->remove_oplock(fnum, token);
+       return share_ops->remove_oplock(fsp, token);
 }
 
 /*******************************************************************
index 84310d3a3326f93f6af8c2efb5e4d87283f00010..cded5e628dc20c32c2e06fde7186a7607eb40493 100644 (file)
@@ -37,7 +37,6 @@
 #ifdef FAST_SHARE_MODES
 
 extern int DEBUGLEVEL;
-extern files_struct Files[];
 
 static struct shmem_ops *shmops;
 
@@ -258,7 +257,7 @@ static int shm_get_share_modes(connection_struct *conn,
 /*******************************************************************
 del the share mode of a file.
 ********************************************************************/
-static void shm_del_share_mode(int token, int fnum)
+static void shm_del_share_mode(int token, files_struct *fsp)
 {
   uint32 dev, inode;
   int *mode_array;
@@ -270,8 +269,8 @@ static void shm_del_share_mode(int token, int fnum)
   BOOL found = False;
   int pid = getpid();
 
-  dev = Files[fnum].fd_ptr->dev;
-  inode = Files[fnum].fd_ptr->inode;
+  dev = fsp->fd_ptr->dev;
+  inode = fsp->fd_ptr->inode;
 
   hash_entry = HASH_ENTRY(dev, inode);
 
@@ -329,7 +328,7 @@ static void shm_del_share_mode(int token, int fnum)
   {
     if( (pid == entry_scanner_p->e.pid) && 
           (memcmp(&entry_scanner_p->e.time, 
-                 &Files[fnum].open_time,sizeof(struct timeval)) == 0) )
+                 &fsp->open_time,sizeof(struct timeval)) == 0) )
     {
       found = True;
       break;
@@ -386,9 +385,8 @@ static void shm_del_share_mode(int token, int fnum)
 /*******************************************************************
 set the share mode of a file. Return False on fail, True on success.
 ********************************************************************/
-static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
+static BOOL shm_set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type)
 {
-  files_struct *fs_p = &Files[fnum];
   int32 dev, inode;
   int *mode_array;
   unsigned int hash_entry;
@@ -398,8 +396,8 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
   int new_entry_offset;
   BOOL found = False;
 
-  dev = fs_p->fd_ptr->dev;
-  inode = fs_p->fd_ptr->inode;
+  dev = fsp->fd_ptr->dev;
+  inode = fsp->fd_ptr->inode;
 
   hash_entry = HASH_ENTRY(dev, inode);
 
@@ -428,7 +426,7 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
     /* We must create a share_mode_record */
     share_mode_record *new_mode_p = NULL;
     int new_offset = shmops->shm_alloc(sizeof(share_mode_record) +
-                                  strlen(fs_p->fsp_name) + 1);
+                                  strlen(fsp->fsp_name) + 1);
     if(new_offset == 0) {
            DEBUG(0,("ERROR:set_share_mode shmops->shm_alloc fail!\n"));
            return False;
@@ -439,7 +437,7 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
     new_mode_p->st_ino = inode;
     new_mode_p->num_share_mode_entries = 0;
     new_mode_p->share_mode_entries = 0;
-    pstrcpy(new_mode_p->file_name, fs_p->fsp_name);
+    pstrcpy(new_mode_p->file_name, fsp->fsp_name);
 
     /* Chain onto the start of the hash chain (in the hope we will be used first). */
     new_mode_p->next_offset = mode_array[hash_entry];
@@ -448,7 +446,7 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
     file_scanner_p = new_mode_p;
 
     DEBUG(3,("set_share_mode: Created share record for %s (dev %d inode %d)\n", 
-            fs_p->fsp_name, dev, inode));
+            fsp->fsp_name, dev, inode));
   }
  
   /* Now create the share mode entry */ 
@@ -466,10 +464,10 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
   new_entry_p = shmops->offset2addr(new_entry_offset);
 
   new_entry_p->e.pid = getpid();
-  new_entry_p->e.share_mode = fs_p->share_mode;
+  new_entry_p->e.share_mode = fsp->share_mode;
   new_entry_p->e.op_port = port;
   new_entry_p->e.op_type = op_type;
-  memcpy( (char *)&new_entry_p->e.time, (char *)&fs_p->open_time, sizeof(struct timeval));
+  memcpy( (char *)&new_entry_p->e.time, (char *)&fsp->open_time, sizeof(struct timeval));
 
   /* Chain onto the share_mode_record */
   new_entry_p->next_share_mode_entry = file_scanner_p->share_mode_entries;
@@ -487,7 +485,7 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
   file_scanner_p->num_share_mode_entries += 1;
 
   DEBUG(3,("set_share_mode: Created share entry for %s with mode 0x%X pid=%d\n",
-          fs_p->fsp_name, fs_p->share_mode, new_entry_p->e.pid));
+          fsp->fsp_name, fsp->share_mode, new_entry_p->e.pid));
 
   return(True);
 }
@@ -495,7 +493,7 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
 /*******************************************************************
 Remove an oplock port and mode entry from a share mode.
 ********************************************************************/
-static BOOL shm_remove_share_oplock(int fnum, int token)
+static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
 {
   uint32 dev, inode;
   int *mode_array;
@@ -507,8 +505,8 @@ static BOOL shm_remove_share_oplock(int fnum, int token)
   BOOL found = False;
   int pid = getpid();
 
-  dev = Files[fnum].fd_ptr->dev;
-  inode = Files[fnum].fd_ptr->inode;
+  dev = fsp->fd_ptr->dev;
+  inode = fsp->fd_ptr->inode;
 
   hash_entry = HASH_ENTRY(dev, inode);
 
@@ -565,9 +563,9 @@ static BOOL shm_remove_share_oplock(int fnum, int token)
   while(entry_scanner_p)
   {
     if( (pid == entry_scanner_p->e.pid) && 
-        (entry_scanner_p->e.share_mode == Files[fnum].share_mode) &&
+        (entry_scanner_p->e.share_mode == fsp->share_mode) &&
         (memcmp(&entry_scanner_p->e.time, 
-                &Files[fnum].open_time,sizeof(struct timeval)) == 0) )
+                &fsp->open_time,sizeof(struct timeval)) == 0) )
     {
       /* Delete the oplock info. */
       entry_scanner_p->e.op_port = 0;
index 9135ae29d2c2ab52401393920376a35d2424a752..8b56e7599b722525dae8cb6323320575b2b007d6 100644 (file)
@@ -37,7 +37,6 @@
 #ifndef FAST_SHARE_MODES
 
 extern int DEBUGLEVEL;
-extern files_struct Files[];
 
 /* 
  * Locking file header lengths & offsets. 
@@ -534,7 +533,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;
@@ -543,15 +542,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;
   BOOL deleted = False;
   BOOL new_file;
 
-  share_name(fs_p->conn, 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->conn, 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));
@@ -562,7 +560,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->conn, fname);
+    delete_share_file(fsp->conn, fname);
     return;
   }
 
@@ -586,7 +584,7 @@ for share file %d\n", num_entries, fname));
               fname));
     if(buf)
       free(buf);
-    delete_share_file(fs_p->conn, fname);
+    delete_share_file(fsp->conn, fname);
     return;
   }
 
@@ -602,9 +600,9 @@ 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) || 
+    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) || 
        (IVAL(p,SME_PID_OFFSET) != pid))
       continue;
 
@@ -637,7 +635,7 @@ for share file %d\n", num_entries, fname));
              fname));
     if(buf)
       free(buf);
-    delete_share_file(fs_p->conn,fname);
+    delete_share_file(fsp->conn,fname);
     return;
   }
 
@@ -675,9 +673,8 @@ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
 /*******************************************************************
 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();
@@ -687,8 +684,8 @@ static BOOL slow_set_share_mode(int token,int fnum, uint16 port, uint16 op_type)
   int header_size;
   char *p;
 
-  share_name(fs_p->conn, 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)
   {
@@ -735,7 +732,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->conn, fname);
+      delete_share_file(fsp->conn, fname);
       return False;
     }   
 
@@ -748,7 +745,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->conn, fname);
+      delete_share_file(fsp->conn, fname);
       return False;
     }
 
@@ -757,23 +754,23 @@ 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->name) + 1 + 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->name) + 1);
+    pstrcpy(buf + SMF_HEADER_LENGTH, 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_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,pid);
   SSVAL(p,SME_PORT_OFFSET,port);
   SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
@@ -796,7 +793,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->conn, fname);
+    delete_share_file(fsp->conn, fname);
     if(buf)
       free(buf);
     return False;
@@ -818,7 +815,7 @@ mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entr
     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,pid));
 
   return True;
 }
@@ -826,7 +823,7 @@ mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid));
 /*******************************************************************
 Remove an oplock port and mode entry from a share mode.
 ********************************************************************/
-static BOOL slow_remove_share_oplock(int fnum, int token)
+static BOOL slow_remove_share_oplock(files_struct *fsp, int token)
 {
   pstring fname;
   int fd = (int)token;
@@ -835,15 +832,14 @@ 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;
   BOOL found = False;
   BOOL new_file;
 
-  share_name(fs_p->conn, 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->conn, 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",
                   fname));
@@ -854,7 +850,7 @@ static BOOL slow_remove_share_oplock(int fnum, int token)
   {
     DEBUG(0,("ERROR: remove_share_oplock: share file %s is new (size zero), \
 deleting it.\n", fname));
-    delete_share_file(fs_p->conn, fname);
+    delete_share_file(fsp->conn, fname);
     return False;
   }
 
@@ -878,7 +874,7 @@ for share file %d\n", num_entries, fname));
               fname));
     if(buf)
       free(buf);
-    delete_share_file(fs_p->conn, fname);
+    delete_share_file(fsp->conn, fname);
     return False;
   }
 
@@ -894,9 +890,9 @@ 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) || 
+    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) || 
        (IVAL(p,SME_PID_OFFSET) != pid))
       continue;
 
index d792a16426b3edf45d403740dacba540bee1e770..bd29578f0e3ebf86c76b9fb29eb09afc271cde03 100644 (file)
@@ -35,8 +35,6 @@ static int chain_pnum = -1;
 #define MAX_OPEN_PIPES 50
 #endif
 
-#define PIPE_HANDLE_OFFSET 0x800
-
 pipes_struct Pipes[MAX_OPEN_PIPES];
 
 #define P_OPEN(p) ((p)->open)
index 28a68e29e263403ca247dbca28a71ef0e2657d58..0b963cbc80ab1ec64256a194ada48816ea9a3e6f 100644 (file)
@@ -80,7 +80,7 @@ END {
   next;
 }
 
-!/^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE/ {
+!/^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE/ {
   next;
 }
 
diff --git a/source/smbd/files.c b/source/smbd/files.c
new file mode 100644 (file)
index 0000000..a37d190
--- /dev/null
@@ -0,0 +1,321 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   Files[] structure handling
+   Copyright (C) Andrew Tridgell 1998
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+#define MAX_OPEN_FILES 100
+
+#define MAX_FNUMS (MAX_OPEN_FILES+MAX_OPEN_DIRECTORIES)
+#define VALID_FNUM(fnum)   (((fnum) >= 0) && ((fnum) < MAX_FNUMS))
+
+static files_struct Files[MAX_FNUMS];
+
+/*
+ * Indirection for file fd's. Needed as POSIX locking
+ * is based on file/process, not fd/process.
+ */
+static file_fd_struct FileFd[MAX_OPEN_FILES];
+static int max_file_fd_used = 0;
+
+
+/****************************************************************************
+  find first available file slot
+****************************************************************************/
+files_struct *find_free_file(void )
+{
+       int i;
+       static int first_file;
+
+       /* we want to give out file handles differently on each new
+          connection because of a common bug in MS clients where they try to
+          reuse a file descriptor from an earlier smb connection. This code
+          increases the chance that the errant client will get an error rather
+          than causing corruption */
+       if (first_file == 0) {
+               first_file = (getpid() ^ (int)time(NULL)) % MAX_FNUMS;
+               if (first_file == 0) first_file = 1;
+       }
+
+       if (first_file >= MAX_FNUMS)
+               first_file = 1;
+
+       for (i=first_file;i<MAX_FNUMS;i++)
+               if (!Files[i].open && !Files[i].reserved) {
+                       memset(&Files[i], 0, sizeof(Files[i]));
+                       first_file = i+1;
+                       Files[i].reserved = True;
+                       Files[i].fnum = i;
+                       return &Files[i];
+               }
+
+       /* returning a file handle of 0 is a bad idea - so we start at 1 */
+       for (i=1;i<first_file;i++)
+               if (!Files[i].open && !Files[i].reserved) {
+                       memset(&Files[i], 0, sizeof(Files[i]));
+                       first_file = i+1;
+                       Files[i].reserved = True;
+                       Files[i].fnum = i;
+                       return &Files[i];
+               }
+
+        /* 
+         * Before we give up, go through the open files 
+         * and see if there are any files opened with a
+         * batch oplock. If so break the oplock and then
+         * re-use that entry (if it becomes closed).
+         * This may help as NT/95 clients tend to keep
+         * files batch oplocked for quite a long time
+         * after they have finished with them.
+         */
+        for (i=first_file;i<MAX_FNUMS;i++) {
+          if(attempt_close_oplocked_file( &Files[i])) {
+            memset(&Files[i], 0, sizeof(Files[i]));
+            first_file = i+1;
+            Files[i].reserved = True;
+           Files[i].fnum = i;
+           return &Files[i];
+          }
+        }
+
+        for (i=1;i<MAX_FNUMS;i++) {
+          if(attempt_close_oplocked_file( &Files[i])) {
+            memset(&Files[i], 0, sizeof(Files[i]));
+            first_file = i+1;
+            Files[i].reserved = True;
+           Files[i].fnum = i;
+           return &Files[i];
+          }
+        }
+
+       DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
+       return NULL;
+}
+
+
+
+/****************************************************************************
+fd support routines - attempt to find an already open file by dev
+and inode - increments the ref_count of the returned file_fd_struct *.
+****************************************************************************/
+file_fd_struct *fd_get_already_open(struct stat *sbuf)
+{
+  int i;
+  file_fd_struct *fd_ptr;
+
+  if(sbuf == 0)
+    return 0;
+
+  for(i = 0; i <= max_file_fd_used; i++) {
+    fd_ptr = &FileFd[i];
+    if((fd_ptr->ref_count > 0) &&
+       (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
+       (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
+      fd_ptr->ref_count++;
+      DEBUG(3,
+       ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
+        i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
+      return fd_ptr;
+    }
+  }
+  return 0;
+}
+
+/****************************************************************************
+fd support routines - attempt to find a empty slot in the FileFd array.
+Increments the ref_count of the returned entry.
+****************************************************************************/
+file_fd_struct *fd_get_new(void)
+{
+  extern struct current_user current_user;
+  int i;
+  file_fd_struct *fd_ptr;
+
+  for(i = 0; i < MAX_OPEN_FILES; i++) {
+    fd_ptr = &FileFd[i];
+    if(fd_ptr->ref_count == 0) {
+      fd_ptr->dev = (uint32)-1;
+      fd_ptr->inode = (uint32)-1;
+      fd_ptr->fd = -1;
+      fd_ptr->fd_readonly = -1;
+      fd_ptr->fd_writeonly = -1;
+      fd_ptr->real_open_flags = -1;
+      fd_ptr->uid_cache_count = 0;
+      fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
+      fd_ptr->ref_count++;
+      /* Increment max used counter if neccessary, cuts down
+         on search time when re-using */
+      if(i > max_file_fd_used)
+        max_file_fd_used = i;
+      DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
+               i, fd_ptr->dev, fd_ptr->inode));
+      return fd_ptr;
+    }
+  }
+  DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\n"));
+  return 0;
+}
+
+
+/****************************************************************************
+close all open files for a connection
+****************************************************************************/
+void file_close_conn(connection_struct *conn)
+{
+  int i;
+  for (i=0;i<MAX_FNUMS;i++)
+    if (Files[i].conn == conn && Files[i].open) {
+      if(Files[i].is_directory)
+        close_directory(&Files[i]); 
+      else                  
+        close_file(&Files[i],False); 
+    }
+}
+
+/****************************************************************************
+initialise file structures
+****************************************************************************/
+void file_init(void)
+{
+       int i;
+
+#ifdef HAVE_GETRLIMIT
+#ifdef RLIMIT_NOFILE
+       {
+               struct rlimit rlp;
+               getrlimit(RLIMIT_NOFILE, &rlp);
+               /* Set the fd limit to be MAX_OPEN_FILES + 10 to
+                * account for the extra fd we need to read
+                * directories, as well as the log files and standard
+                * handles etc.  */
+               rlp.rlim_cur = (MAX_FNUMS+10>rlp.rlim_max)? 
+                       rlp.rlim_max:MAX_FNUMS+10;
+               setrlimit(RLIMIT_NOFILE, &rlp);
+               getrlimit(RLIMIT_NOFILE, &rlp);
+               DEBUG(3,("Maximum number of open files per session is %d\n",
+                        (int)rlp.rlim_cur));
+       }
+#endif
+#endif
+
+  
+
+       for (i=0;i<MAX_FNUMS;i++) {
+               Files[i].open = False;
+               string_init(&Files[i].fsp_name,"");
+       }
+
+       for (i=0;i<MAX_OPEN_FILES;i++) {
+               file_fd_struct *fd_ptr = &FileFd[i];
+               fd_ptr->ref_count = 0;
+               fd_ptr->dev = (int32)-1;
+               fd_ptr->inode = (int32)-1;
+               fd_ptr->fd = -1;
+               fd_ptr->fd_readonly = -1;
+               fd_ptr->fd_writeonly = -1;
+               fd_ptr->real_open_flags = -1;
+       }
+}
+
+/****************************************************************************
+find a fsp given a fnum
+****************************************************************************/
+files_struct *file_fsp(int fnum)
+{
+       if (!VALID_FNUM(fnum)) return NULL;
+       return &Files[fnum];
+}
+
+
+/****************************************************************************
+close files open by a specified vuid
+****************************************************************************/
+void file_close_user(int vuid)
+{
+       int i;
+       for (i=0;i<MAX_FNUMS;i++) {
+               files_struct *fsp = &Files[i];
+               if ((fsp->vuid == vuid) && fsp->open) {
+                       if(!fsp->is_directory)
+                               close_file(fsp,False);
+                       else
+                               close_directory(fsp);
+               }
+       }
+}
+
+
+/****************************************************************************
+find a fsp given a device, inode and timevalue
+****************************************************************************/
+files_struct *file_find_dit(int dev, int inode, struct timeval *tval)
+{
+       int i;
+       for (i=0;i<MAX_FNUMS;i++) {
+               files_struct *fsp = &Files[i];
+               if (fsp->open && 
+                   fsp->fd_ptr->dev == dev && 
+                   fsp->fd_ptr->inode == inode &&
+                   fsp->open_time.tv_sec == tval->tv_sec &&
+                   fsp->open_time.tv_usec == tval->tv_usec) {
+                       return fsp;
+               }
+       } 
+       return NULL;
+}
+
+/****************************************************************************
+find a fsp that is open for printing
+****************************************************************************/
+files_struct *file_find_print(void)
+{
+       int i;
+
+       for (i=0;i<MAX_FNUMS;i++) {
+               files_struct *fsp = &Files[i];
+               if (fsp->open && fsp->print_file) {
+                       return fsp;
+               }
+       } 
+       return NULL;
+}
+
+
+/****************************************************************************
+sync open files on a connection
+****************************************************************************/
+void file_sync_all(connection_struct *conn)
+{
+       int i;
+       for (i=0;i<MAX_FNUMS;i++) {
+               files_struct *fsp = &Files[i];
+               if (fsp->open && conn == fsp->conn) {
+                       sync_file(conn,fsp);
+               }
+       }
+}
+
+
+void file_free(files_struct *fsp)
+{
+       memset(fsp, 0, sizeof(*fsp));
+}
index 63495f0479bbfca6e3e5a5741fbb074f272b32ea..ae225956a23a7c344bf986d89ebf8f8a3a8fe770 100644 (file)
@@ -36,7 +36,6 @@
 
 extern int DEBUGLEVEL;
 extern int max_send;
-extern files_struct Files[];
 
 extern fstring local_machine;
 extern fstring global_myworkgroup;
@@ -1913,108 +1912,105 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
                             char **rdata,char **rparam,
                             int *rdata_len,int *rparam_len)
 {
-  struct pack_desc desc;
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int jobid, snum;
-  int uLevel = SVAL(p,2);
-  int function = SVAL(p,4);    /* what is this ?? */
-  int i;
-  char *s = data;
+       struct pack_desc desc;
+       char *str1 = param+2;
+       char *str2 = skip_string(str1,1);
+       char *p = skip_string(str2,1);
+       int jobid, snum;
+       int uLevel = SVAL(p,2);
+       int function = SVAL(p,4);       /* what is this ?? */
+       int i;
+       char *s = data;
+       files_struct *fsp;
 
-  printjob_decode(SVAL(p,0), &snum, &jobid);
+       printjob_decode(SVAL(p,0), &snum, &jobid);
    
-  *rparam_len = 4;
-  *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam_len = 4;
+       *rparam = REALLOC(*rparam,*rparam_len);
   
-  *rdata_len = 0;
-  
-  /* check it's a supported varient */
-  if ((strcmp(str1,"WWsTP")) || (!check_printjob_info(&desc,uLevel,str2)))
-    return(False);
+       *rdata_len = 0;
+       
+       /* check it's a supported varient */
+       if ((strcmp(str1,"WWsTP")) || 
+           (!check_printjob_info(&desc,uLevel,str2)))
+               return(False);
    
-  switch (function) {
-  case 0x6:    /* change job place in the queue, data gives the new place */
-    if (snum >= 0 && VALID_SNUM(snum))
-      {
-       print_queue_struct *queue=NULL;
-       int count;
+       switch (function) {
+       case 0x6:       /* change job place in the queue, 
+                          data gives the new place */
+               if (snum >= 0 && VALID_SNUM(snum)) {
+                       print_queue_struct *queue=NULL;
+                       int count;
   
-       lpq_reset(snum);
-       count = get_printqueue(snum,conn,&queue,NULL);
-       for (i=0;i<count;i++)   /* find job */
-         if ((queue[i].job&0xFF) == jobid) break;
+                       lpq_reset(snum);
+                       count = get_printqueue(snum,conn,&queue,NULL);
+                       for (i=0;i<count;i++)   /* find job */
+                               if ((queue[i].job&0xFF) == jobid) break;
            
-       if (i==count) {
-         desc.errcode=NERR_JobNotFound;
-         if (queue) free(queue);
-       }
-       else {
-         desc.errcode=NERR_Success;
-         i++;
+                       if (i==count) {
+                               desc.errcode=NERR_JobNotFound;
+                               if (queue) free(queue);
+                       } else {
+                               desc.errcode=NERR_Success;
+                               i++;
 #if 0  
-         {
-           int place= SVAL(data,0);
-           /* we currently have no way of doing this. Can any unix do it? */
-           if (i < place)      /* move down */;
-           else if (i > place )        /* move up */;
-         }
+                               {
+                                       int place= SVAL(data,0);
+                                       /* we currently have no way of
+                                          doing this. Can any unix do it? */
+                                       if (i < place)  /* move down */;
+                                       else if (i > place )    /* move up */;
+                               }
 #endif
-         desc.errcode=NERR_notsupported; /* not yet supported */
-         if (queue) free(queue);
-       }
-      }
-    else desc.errcode=NERR_JobNotFound;
-    break;
-  case 0xb:   /* change print job name, data gives the name */
-    /* jobid, snum should be zero */
-    if (isalpha((int)*s))
-      {
-       pstring name;
-       int l = 0;
-       while (l<64 && *s)
-         {
-           if (issafe(*s)) name[l++] = *s;
-           s++;
-         }      
-       name[l] = 0;
+                               desc.errcode=NERR_notsupported; /* not yet 
+                                                                  supported */
+                               if (queue) free(queue);
+                       }
+               } else {
+                       desc.errcode=NERR_JobNotFound;
+               }
+               break;
+
+       case 0xb:   /* change print job name, data gives the name */
+               /* jobid, snum should be zero */
+               if (isalpha((int)*s)) {
+                       pstring name;
+                       int l = 0;
+                       while (l<64 && *s) {
+                               if (issafe(*s)) name[l++] = *s;
+                               s++;
+                       }      
+                       name[l] = 0;
        
-       DEBUG(3,("Setting print name to %s\n",name));
+                       DEBUG(3,("Setting print name to %s\n",name));
        
-        become_root(True);
-
-       for (i=0;i<MAX_FNUMS;i++)
-         if (Files[i].open && Files[i].print_file)
-           {
-             pstring wd;
-             connection_struct *fconn = Files[i].conn;
-             GetWd(wd);
-             unbecome_user();
+                       fsp = file_find_print();        
+
+                       if (fsp) {
+                               connection_struct *fconn = fsp->conn;
+                               unbecome_user();
              
-             if (!become_user(fconn,vuid) || 
-                 !become_service(fconn,True))
-               break;
+                               if (!become_user(fconn,vuid) || 
+                                   !become_service(fconn,True))
+                                       break;
              
-             if (sys_rename(Files[i].fsp_name,name) == 0) {
-                     string_set(&Files[i].fsp_name,name);
-             }
-             break;
-           }
+                               if (sys_rename(fsp->fsp_name,name) == 0) {
+                                       string_set(&fsp->fsp_name,name);
+                               }
+                               break;
+                       }
+               }
+               desc.errcode=NERR_Success;
+               break;
 
-         unbecome_root(True);
-      }
-    desc.errcode=NERR_Success;
-  
-    break;
-  default:                     /* not implemented */
-    return False;
-  }
+       default:                        /* not implemented */
+               return False;
+       }
  
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);          /* converter word */
-  
-  return(True);
+       SSVALS(*rparam,0,desc.errcode);
+       SSVAL(*rparam,2,0);             /* converter word */
+       
+       return(True);
 }
 
 
index 94ecbfea4945a41df101ae8183b2c3d77412faf0..d396b05a629cda302c0bf1e10a95510708ae8a69 100644 (file)
@@ -24,8 +24,7 @@
 
 extern int DEBUGLEVEL;
 extern int Protocol;
-extern int chain_fnum;
-extern files_struct Files[];
+extern files_struct *chain_fsp;
 extern int Client;  
 extern int oplock_sock;
 extern int smb_read_error;
@@ -388,7 +387,8 @@ static int nt_open_pipe(char *fname, connection_struct *conn,
   if (pnum < 0)
     return(ERROR(ERRSRV,ERRnofids));
 
-  *ppnum = pnum + 0x800; /* Mark file handle up into high range. */
+  *ppnum = pnum + PIPE_HANDLE_OFFSET; /* Mark file handle up into high
+                                        range. */
   return 0;
 }
 
@@ -399,7 +399,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
                         char *inbuf,char *outbuf,int length,int bufsize)
 {  
        pstring fname;
-       int fnum = -1;
        uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
        uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
        uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
@@ -413,7 +412,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
        /* Breakout the oplock request bits so we can set the
           reply bits separately. */
        int oplock_request = 0;
-       int unixmode;
+       int unixmode, pnum = -1;
        int fmode=0,mtime=0,rmode=0;
        off_t file_len = 0;
        struct stat sbuf;
@@ -449,10 +448,9 @@ int reply_ntcreate_and_X(connection_struct *conn,
        
        /* If it's an IPC, use the pipe handler. */
        if (IS_IPC(conn)) {
-               int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &fnum);
+               int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum);
                if(ret != 0)
                        return ret;
-               fsp = &Files[fnum];
                smb_action = FILE_WAS_OPENED;
        } else {
 
@@ -468,20 +466,18 @@ int reply_ntcreate_and_X(connection_struct *conn,
                
                unix_convert(fname,conn,0,&bad_path);
                
-               fnum = find_free_file();
-               if (fnum < 0) {
+               fsp = find_free_file();
+               if (!fsp) {
                        restore_case_semantics(file_attributes);
                        return(ERROR(ERRSRV,ERRnofids));
                }
                
-               fsp = &Files[fnum];
-               
                if (!check_name(fname,conn)) { 
                        if((errno == ENOENT) && bad_path) {
                                unix_ERR_class = ERRDOS;
                                unix_ERR_code = ERRbadpath;
                        }
-                       fsp->reserved = False;
+                       file_free(fsp);
                        
                        restore_case_semantics(file_attributes);
                        
@@ -500,13 +496,13 @@ int reply_ntcreate_and_X(connection_struct *conn,
                if(flags & OPEN_DIRECTORY) {
                        oplock_request = 0;
                        
-                       open_directory(fnum, conn, fname, smb_ofun, 
+                       open_directory(fsp, conn, fname, smb_ofun, 
                                       unixmode, &smb_action);
                        
                        restore_case_semantics(file_attributes);
 
                        if(!fsp->open) {
-                               fsp->reserved = False;
+                               file_free(fsp);
                                return(UNIXERROR(ERRDOS,ERRnoaccess));
                        }
                } else {
@@ -527,7 +523,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
                         * before issuing an oplock break request to
                         * our client. JRA.  */
 
-                       open_file_shared(fnum,conn,fname,smb_open_mode,
+                       open_file_shared(fsp,conn,fname,smb_open_mode,
                                         smb_ofun,unixmode,
                                         oplock_request,&rmode,&smb_action);
 
@@ -551,10 +547,10 @@ int reply_ntcreate_and_X(connection_struct *conn,
                                if(errno == EISDIR) {
                                        oplock_request = 0;
                                        
-                                       open_directory(fnum, conn, fname, smb_ofun, unixmode, &smb_action);
+                                       open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action);
                                        
                                        if(!fsp->open) {
-                                               fsp->reserved = False;
+                                               file_free(fsp);
                                                restore_case_semantics(file_attributes);
                                                return(UNIXERROR(ERRDOS,ERRnoaccess));
                                        }
@@ -564,7 +560,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
                                                unix_ERR_code = ERRbadpath;
                                        }
                                        
-                                       fsp->reserved = False;
+                                       file_free(fsp);
                                        
                                        restore_case_semantics(file_attributes);
                                        
@@ -575,13 +571,13 @@ int reply_ntcreate_and_X(connection_struct *conn,
                
                if(fsp->is_directory) {
                        if(sys_stat(fsp->fsp_name, &sbuf) != 0) {
-                               close_directory(fnum);
+                               close_directory(fsp);
                                restore_case_semantics(file_attributes);
                                return(ERROR(ERRDOS,ERRnoaccess));
                        }
                } else {
                        if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
-                               close_file(fnum,False);
+                               close_file(fsp,False);
                                restore_case_semantics(file_attributes);
                                return(ERROR(ERRDOS,ERRnoaccess));
                        } 
@@ -595,7 +591,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
                        fmode = FILE_ATTRIBUTE_NORMAL;
                mtime = sbuf.st_mtime;
                if (!fsp->is_directory && (fmode & aDIR)) {
-                       close_file(fnum,False);
+                       close_file(fsp,False);
                        return(ERROR(ERRDOS,ERRnoaccess));
                } 
                
@@ -623,7 +619,11 @@ int reply_ntcreate_and_X(connection_struct *conn,
        
        SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
        p++;
-       SSVAL(p,0,fnum);
+       if (IS_IPC(conn)) {
+               SSVAL(p,0,pnum);
+       } else {
+               SSVAL(p,0,fsp->fnum);
+       }
        p += 2;
        SIVAL(p,0,smb_action);
        p += 4;
@@ -664,11 +664,10 @@ int reply_ntcreate_and_X(connection_struct *conn,
                SCVAL(p,0,fsp->is_directory ? 1 : 0);
        }
        
-       chain_fnum = fnum;
+       chain_fsp = fsp;
 
-       
-       DEBUG(5,("reply_ntcreate_and_X: open fnum = %d, name = %s\n",
-                fnum, fsp->fsp_name));
+       DEBUG(5,("reply_ntcreate_and_X: open name = %s\n",
+                fsp->fsp_name));
 
        return chain_reply(inbuf,outbuf,length,bufsize);
 }
@@ -683,7 +682,6 @@ static int call_nt_transact_create(connection_struct *conn,
                                   char **ppdata)
 {
   pstring fname;
-  int fnum = -1;
   char *params = *ppparams;
   uint32 flags = IVAL(params,0);
   uint32 desired_access = IVAL(params,8);
@@ -698,7 +696,7 @@ static int call_nt_transact_create(connection_struct *conn,
   /* Breakout the oplock request bits so we can set the
      reply bits separately. */
   int oplock_request = 0;
-  int unixmode;
+  int unixmode, pnum = -1;
   int fmode=0,mtime=0,rmode=0;
   off_t file_len = 0;
   struct stat sbuf;
@@ -732,7 +730,7 @@ static int call_nt_transact_create(connection_struct *conn,
 
   /* If it's an IPC, use the pipe handler. */
   if (IS_IPC(conn)) {
-    int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &fnum);
+    int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum);
     if(ret != 0)
       return ret;
     smb_action = FILE_WAS_OPENED;
@@ -745,14 +743,12 @@ static int call_nt_transact_create(connection_struct *conn,
 
     unix_convert(fname,conn,0,&bad_path);
     
-    fnum = find_free_file();
-    if (fnum < 0) {
-      restore_case_semantics(file_attributes);
-      return(ERROR(ERRSRV,ERRnofids));
+    fsp = find_free_file();
+    if (!fsp) {
+           restore_case_semantics(file_attributes);
+           return(ERROR(ERRSRV,ERRnofids));
     }
 
-    fsp = &Files[fnum];
-
     if (!check_name(fname,conn)) { 
       if((errno == ENOENT) && bad_path) {
         unix_ERR_class = ERRDOS;
@@ -784,10 +780,10 @@ static int call_nt_transact_create(connection_struct *conn,
        * CreateDirectory() call.
        */
 
-      open_directory(fnum, conn, fname, smb_ofun, unixmode, &smb_action);
+      open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action);
 
       if(!fsp->open) {
-        fsp->reserved = False;
+        file_free(fsp);
         return(UNIXERROR(ERRDOS,ERRnoaccess));
       }
     } else {
@@ -796,7 +792,7 @@ static int call_nt_transact_create(connection_struct *conn,
        * Ordinary file case.
        */
 
-      open_file_shared(fnum,conn,fname,smb_open_mode,smb_ofun,unixmode,
+      open_file_shared(fsp,conn,fname,smb_open_mode,smb_ofun,unixmode,
                        oplock_request,&rmode,&smb_action);
 
       if (!fsp->open) { 
@@ -804,7 +800,7 @@ static int call_nt_transact_create(connection_struct *conn,
           unix_ERR_class = ERRDOS;
           unix_ERR_code = ERRbadpath;
         }
-        fsp->reserved = False;
+        file_free(fsp);
 
         restore_case_semantics(file_attributes);
 
@@ -812,7 +808,7 @@ static int call_nt_transact_create(connection_struct *conn,
       } 
   
       if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
-        close_file(fnum,False);
+        close_file(fsp,False);
 
         restore_case_semantics(file_attributes);
 
@@ -826,7 +822,7 @@ static int call_nt_transact_create(connection_struct *conn,
       mtime = sbuf.st_mtime;
 
       if (fmode & aDIR) {
-        close_file(fnum,False);
+        close_file(fsp,False);
         restore_case_semantics(file_attributes);
         return(ERROR(ERRDOS,ERRnoaccess));
       } 
@@ -855,7 +851,11 @@ static int call_nt_transact_create(connection_struct *conn,
   p = params;
   SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
   p += 2;
-  SSVAL(p,0,fnum);
+  if (IS_IPC(conn)) {
+         SSVAL(p,0,pnum);
+  } else {
+         SSVAL(p,0,fsp->fnum);
+  }
   p += 2;
   SIVAL(p,0,smb_action);
   p += 8;
@@ -940,17 +940,17 @@ static int call_nt_transact_rename(connection_struct *conn,
 {
   char *params = *ppparams;
   pstring new_name;
-  int fnum = SVAL(params, 0);
+  files_struct *fsp = GETFSP(params, 0);
   BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
   uint32 fname_len = MIN((((uint32)IVAL(inbuf,smb_nt_TotalParameterCount)-4)),
                          ((uint32)sizeof(new_name)-1));
   int outsize = 0;
 
-  CHECK_FNUM(fnum, conn);
+  CHECK_FSP(fsp, conn);
   StrnCpy(new_name,params+4,fname_len);
   new_name[fname_len] = '\0';
 
-  outsize = rename_internals(conn, inbuf, outbuf, Files[fnum].fsp_name,
+  outsize = rename_internals(conn, inbuf, outbuf, fsp->fsp_name,
                              new_name, replace_if_exists);
   if(outsize == 0) {
     /*
@@ -959,7 +959,7 @@ static int call_nt_transact_rename(connection_struct *conn,
     send_nt_replies(outbuf, bufsize, NULL, 0, NULL, 0);
 
     DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", 
-          Files[fnum].fsp_name, new_name));
+          fsp->fsp_name, new_name));
 
     outsize = -1;
   }
@@ -976,7 +976,7 @@ static int call_nt_transact_rename(connection_struct *conn,
 
 typedef struct {
   ubi_slNode msg_next;
-  int fnum;
+  files_struct *fsp;
   connection_struct *conn;
   time_t next_check_time;
   time_t modify_time; /* Info from the directory we're monitoring. */ 
@@ -1023,14 +1023,13 @@ static void change_notify_reply_packet(char *inbuf, int error_class, uint32 erro
 /****************************************************************************
  Delete entries by fnum from the change notify pending queue.
 *****************************************************************************/
-
-void remove_pending_change_notify_requests_by_fid(int fnum)
+void remove_pending_change_notify_requests_by_fid(files_struct *fsp)
 {
   change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
   change_notify_buf *prev = NULL;
 
   while(cnbp != NULL) {
-    if(cnbp->fnum == fnum) {
+    if(cnbp->fsp == fsp) {
       free((char *)ubi_slRemNext( &change_notify_queue, prev));
       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
       continue;
@@ -1085,9 +1084,8 @@ void process_pending_change_notify_queue(time_t t)
 
   while((cnbp != NULL) && (cnbp->next_check_time <= t)) {
     struct stat st;
-    int fnum = cnbp->fnum;
+    files_struct *fsp = cnbp->fsp;
     connection_struct *conn = cnbp->conn;
-    files_struct *fsp = &Files[fnum];
     uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : 
                   SVAL(cnbp->request_buf,smb_uid);
 
@@ -1133,8 +1131,8 @@ Error was %s.\n", fsp->fsp_name, strerror(errno) ));
       /*
        * Remove the entry and return a change notify to the client.
        */
-      DEBUG(5,("process_pending_change_notify_queue: directory fnum = %d, name = %s changed\n",
-            fnum, fsp->fsp_name ));
+      DEBUG(5,("process_pending_change_notify_queue: directory name = %s changed\n",
+            fsp->fsp_name ));
       change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_NOTIFY_ENUM_DIR);
       free((char *)ubi_slRemNext( &change_notify_queue, prev));
       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
@@ -1164,19 +1162,16 @@ static int call_nt_transact_notify_change(connection_struct *conn,
 {
   char *setup = *ppsetup;
   files_struct *fsp;
-  int fnum = -1;
   change_notify_buf *cnbp;
   struct stat st;
 
-  fnum = SVAL(setup,4);
+  fsp = GETFSP(setup,4);
 
-  DEBUG(3,("call_nt_transact_notify_change: fnum = %d.\n", fnum));
+  DEBUG(3,("call_nt_transact_notify_change\n"));
 
-  if(!VALID_FNUM(fnum))
+  if(!fsp)
     return(ERROR(ERRDOS,ERRbadfid));
 
-  fsp = &Files[fnum];
-
   if((!fsp->open) || (!fsp->is_directory) || (conn != fsp->conn))
     return(ERROR(ERRDOS,ERRbadfid));
 
@@ -1198,14 +1193,14 @@ static int call_nt_transact_notify_change(connection_struct *conn,
    */
 
   if(sys_stat(fsp->fsp_name, &st) < 0) {
-    DEBUG(0,("call_nt_transact_notify_change: Unable to stat fnum = %d, name = %s. \
-Error was %s\n", fnum, fsp->fsp_name, strerror(errno) ));
+    DEBUG(0,("call_nt_transact_notify_change: Unable to stat name = %s. \
+Error was %s\n", fsp->fsp_name, strerror(errno) ));
     free((char *)cnbp);
     return(UNIXERROR(ERRDOS,ERRbadfid));
   }
  
   memcpy(cnbp->request_buf, inbuf, smb_size);
-  cnbp->fnum = fnum;
+  cnbp->fsp = fsp;
   cnbp->conn = conn;
   cnbp->modify_time = st.st_mtime;
   cnbp->status_time = st.st_ctime;
@@ -1221,7 +1216,7 @@ Error was %s\n", fnum, fsp->fsp_name, strerror(errno) ));
   ubi_slAddTail(&change_notify_queue, cnbp);
 
   DEBUG(3,("call_nt_transact_notify_change: notify change called on directory \
-fid=%d, name = %s\n", fnum, fsp->fsp_name ));
+name = %s\n", fsp->fsp_name ));
 
   return -1;
 }
index 2a51e83946aa59e75dd4441f9c50b10b8275ad9d..9ec77c08ca68c11074aa91259143b53023a3a638 100644 (file)
@@ -44,7 +44,6 @@ extern int Client;
 
 #define VALID_PNUM(pnum)   (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES))
 #define OPEN_PNUM(pnum)    (VALID_PNUM(pnum) && Pipes[pnum].open)
-#define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum)
 
 /* this macro should always be used to extract an pnum (smb_fid) from
    a packet to ensure chaining works correctly */
@@ -84,7 +83,7 @@ int reply_open_pipe_and_X(connection_struct *conn,
     if( strequal(fname,pipe_names[i].client_pipe) )
       break;
 
-  if ( pipe_names[i].client_pipe == NULL )
+  if (pipe_names[i].client_pipe == NULL)
     return(ERROR(ERRSRV,ERRaccess));
 
   /* Strip \PIPE\ off the name. */
@@ -111,7 +110,9 @@ int reply_open_pipe_and_X(connection_struct *conn,
     rmode = 1;
   }
 
-  SSVAL(outbuf,smb_vwv2, pnum + 0x800); /* mark file handle up into high range */
+  SSVAL(outbuf,smb_vwv2, pnum + PIPE_HANDLE_OFFSET); /* mark file
+                                                       handle up into
+                                                       high range */
   SSVAL(outbuf,smb_vwv3,fmode);
   put_dos_date3(outbuf,smb_vwv4,mtime);
   SIVAL(outbuf,smb_vwv6,size);
@@ -138,12 +139,6 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   char *data;
   BOOL ok = False;
 
-/*
-  CHECK_FNUM(fnum,cnum);
-  CHECK_READ(fnum);
-  CHECK_ERROR(fnum);
-*/
-
   set_message(outbuf,12,0,True);
   data = smb_buf(outbuf);
 
index 626d2e9617db8301929ddccbdd0d9d8a0299fc84..e9a25ea79ac53d8675c4c4da2cec73c7c1aff1ef 100644 (file)
@@ -33,9 +33,8 @@ extern int Protocol;
 extern int DEBUGLEVEL;
 extern int max_send;
 extern int max_recv;
-extern int chain_fnum;
+extern files_struct *chain_fsp;
 extern char magic_char;
-extern files_struct Files[];
 extern BOOL case_sensitive;
 extern BOOL case_preserve;
 extern BOOL short_case_preserve;
@@ -44,11 +43,6 @@ extern fstring global_myworkgroup;
 extern int Client;
 extern int global_oplock_break;
 
-/* this macro should always be used to extract an fnum (smb_fid) from
-a packet to ensure chaining works correctly */
-#define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where))
-
-
 /****************************************************************************
 report a possible attack via the password buffer overflow bug
 ****************************************************************************/
@@ -1232,7 +1226,6 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
   pstring fname;
-  int fnum = -1;
   int outsize = 0;
   int fmode=0;
   int share_mode;
@@ -1250,12 +1243,10 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   pstrcpy(fname,smb_buf(inbuf)+1);
   unix_convert(fname,conn,0,&bad_path);
     
-  fnum = find_free_file();
-  if (fnum < 0)
+  fsp = find_free_file();
+  if (!fsp)
     return(ERROR(ERRSRV,ERRnofids));
 
-  fsp = &Files[fnum];
-
   if (!check_name(fname,conn))
   {
     if((errno == ENOENT) && bad_path)
@@ -1263,13 +1254,13 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
-    fsp->reserved = False;
+    file_free(fsp);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
  
   unixmode = unix_mode(conn,aARCH);
       
-  open_file_shared(fnum,conn,fname,share_mode,3,unixmode,
+  open_file_shared(fsp,conn,fname,share_mode,3,unixmode,
                    oplock_request,&rmode,NULL);
 
   if (!fsp->open)
@@ -1279,12 +1270,12 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
-    fsp->reserved = False;
+    file_free(fsp);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
   if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
-    close_file(fnum,False);
+    close_file(fsp,False);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
     
@@ -1294,12 +1285,12 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
   if (fmode & aDIR) {
     DEBUG(3,("attempt to open a directory %s\n",fname));
-    close_file(fnum,False);
+    close_file(fsp,False);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
   
   outsize = set_message(outbuf,7,0,True);
-  SSVAL(outbuf,smb_vwv0,fnum);
+  SSVAL(outbuf,smb_vwv0,fsp->fnum);
   SSVAL(outbuf,smb_vwv1,fmode);
   if(lp_dos_filetime_resolution(SNUM(conn)) )
     put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
@@ -1324,7 +1315,6 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
   pstring fname;
-  int fnum = -1;
   int smb_mode = SVAL(inbuf,smb_vwv3);
   int smb_attr = SVAL(inbuf,smb_vwv5);
   /* Breakout the oplock request bits so we can set the
@@ -1354,12 +1344,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   pstrcpy(fname,smb_buf(inbuf));
   unix_convert(fname,conn,0,&bad_path);
     
-  fnum = find_free_file();
-  if (fnum < 0)
+  fsp = find_free_file();
+  if (!fsp)
     return(ERROR(ERRSRV,ERRnofids));
 
-  fsp = &Files[fnum];
-
   if (!check_name(fname,conn))
   {
     if((errno == ENOENT) && bad_path)
@@ -1367,13 +1355,13 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
-    fsp->reserved = False;
+    file_free(fsp);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
   unixmode = unix_mode(conn,smb_attr | aARCH);
       
-  open_file_shared(fnum,conn,fname,smb_mode,smb_ofun,unixmode,
+  open_file_shared(fsp,conn,fname,smb_mode,smb_ofun,unixmode,
                   oplock_request, &rmode,&smb_action);
       
   if (!fsp->open)
@@ -1383,12 +1371,12 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
-    fsp->reserved = False;
+    file_free(fsp);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
   if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
-    close_file(fnum,False);
+    close_file(fsp,False);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
 
@@ -1396,7 +1384,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   fmode = dos_mode(conn,fname,&sbuf);
   mtime = sbuf.st_mtime;
   if (fmode & aDIR) {
-    close_file(fnum,False);
+    close_file(fsp,False);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
 
@@ -1427,7 +1415,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   }
 
   set_message(outbuf,15,0,True);
-  SSVAL(outbuf,smb_vwv2,fnum);
+  SSVAL(outbuf,smb_vwv2,fsp->fnum);
   SSVAL(outbuf,smb_vwv3,fmode);
   if(lp_dos_filetime_resolution(SNUM(conn)) )
     put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
@@ -1437,7 +1425,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   SSVAL(outbuf,smb_vwv8,rmode);
   SSVAL(outbuf,smb_vwv11,smb_action);
 
-  chain_fnum = fnum;
+  chain_fsp = fsp;
 
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
@@ -1458,16 +1446,7 @@ int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,
   /* in user level security we are supposed to close any files
      open by this user */
   if ((vuser != 0) && (lp_security() != SEC_SHARE)) {
-    int i;
-    for (i=0;i<MAX_FNUMS;i++) {
-      files_struct *fsp = &Files[i];
-      if ((fsp->vuid == vuid) && fsp->open) {
-        if(!fsp->is_directory)
-          close_file(i,False);
-        else
-          close_directory(i);
-      }
-    }
+         file_close_user(vuid);
   }
 
   invalidate_vuid(vuid);
@@ -1487,7 +1466,6 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 {
   pstring fname;
   int com;
-  int fnum = -1;
   int outsize = 0;
   int createmode;
   mode_t unixmode;
@@ -1509,12 +1487,10 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   
   unixmode = unix_mode(conn,createmode);
   
-  fnum = find_free_file();
-  if (fnum < 0)
+  fsp = find_free_file();
+  if (!fsp)
     return(ERROR(ERRSRV,ERRnofids));
 
-  fsp = &Files[fnum];
-
   if (!check_name(fname,conn))
   {
     if((errno == ENOENT) && bad_path)
@@ -1522,7 +1498,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
-    fsp->reserved = False;
+    file_free(fsp);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
@@ -1538,7 +1514,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   }
 
   /* Open file in dos compatibility share mode. */
-  open_file_shared(fnum,conn,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, 
+  open_file_shared(fsp,conn,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, 
                    oplock_request, NULL, NULL);
   
   if (!fsp->open)
@@ -1548,12 +1524,12 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
-    fsp->reserved = False;
+    file_free(fsp);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
  
   outsize = set_message(outbuf,1,0,True);
-  SSVAL(outbuf,smb_vwv0,fnum);
+  SSVAL(outbuf,smb_vwv0,fsp->fnum);
 
   if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
     CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
@@ -1563,8 +1539,8 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
  
   DEBUG( 2, ( "new file %s\n", fname ) );
-  DEBUG( 3, ( "mknew %s fd=%d fnum=%d dmode=%d umode=%o\n",
-        fname, fsp->fd_ptr->fd, fnum, createmode, (int)unixmode ) );
+  DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n",
+        fname, fsp->fd_ptr->fd, createmode, (int)unixmode ) );
 
   return(outsize);
 }
@@ -1577,7 +1553,6 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 {
   pstring fname;
   pstring fname2;
-  int fnum = -1;
   int outsize = 0;
   int createmode;
   mode_t unixmode;
@@ -1592,12 +1567,10 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   
   unixmode = unix_mode(conn,createmode);
   
-  fnum = find_free_file();
-  if (fnum < 0)
+  fsp = find_free_file();
+  if (fsp)
     return(ERROR(ERRSRV,ERRnofids));
 
-  fsp = &Files[fnum];
-
   if (!check_name(fname,conn))
   {
     if((errno == ENOENT) && bad_path)
@@ -1605,7 +1578,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
-    fsp->reserved = False;
+    file_free(fsp);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
@@ -1613,7 +1586,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
   /* Open file in dos compatibility share mode. */
   /* We should fail if file exists. */
-  open_file_shared(fnum,conn,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, 
+  open_file_shared(fsp,conn,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, 
                    oplock_request, NULL, NULL);
 
   if (!fsp->open)
@@ -1623,12 +1596,12 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
-    fsp->reserved = False;
+    file_free(fsp);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
   outsize = set_message(outbuf,1,2 + strlen(fname2),True);
-  SSVAL(outbuf,smb_vwv0,fnum);
+  SSVAL(outbuf,smb_vwv0,fsp->fnum);
   CVAL(smb_buf(outbuf),0) = 4;
   pstrcpy(smb_buf(outbuf) + 1,fname2);
 
@@ -1640,8 +1613,8 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
 
   DEBUG( 2, ( "created temp file %s\n", fname2 ) );
-  DEBUG( 3, ( "ctemp %s fd=%d fnum=%d dmode=%d umode=%o\n",
-        fname2, fsp->fd_ptr->fd, fnum, createmode, (int)unixmode ) );
+  DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
+        fname2, fsp->fd_ptr->fd, createmode, (int)unixmode ) );
 
   return(outsize);
 }
@@ -1777,7 +1750,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 ****************************************************************************/
 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
 {
-  int maxcount,mincount,fnum;
+  int maxcount,mincount;
   int nread = 0;
   uint32 startpos;
   char *header = outbuf;
@@ -1800,7 +1773,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
     return -1;
   }
 
-  fnum = GETFNUM(inbuf,smb_vwv0);
+  fsp = GETFSP(inbuf,smb_vwv0);
 
   startpos = IVAL(inbuf,smb_vwv1);
   maxcount = SVAL(inbuf,smb_vwv3);
@@ -1810,23 +1783,18 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
   maxcount = MIN(65535,maxcount);
   maxcount = MAX(mincount,maxcount);
 
-  if (!FNUM_OK(fnum,conn) || !Files[fnum].can_read)
-  {
-    DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",fnum));
-    _smb_setlen(header,0);
-    transfer_file(0,Client,0,header,4,0);
-    return(-1);
-  }
-  else
-  {
-    fsp = &Files[fnum];
-
-    fd = fsp->fd_ptr->fd;
-    fname = fsp->fsp_name;
+  if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
+         DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",fsp->fnum));
+         _smb_setlen(header,0);
+         transfer_file(0,Client,0,header,4,0);
+         return(-1);
+  } else {
+         fd = fsp->fd_ptr->fd;
+         fname = fsp->fsp_name;
   }
 
 
-  if (!is_locked(fnum,conn,maxcount,startpos, F_RDLCK))
+  if (!is_locked(fsp,conn,maxcount,startpos, F_RDLCK))
   {
     int size = fsp->size;
     int sizeneeded = startpos + maxcount;
@@ -1846,7 +1814,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
     nread = 0;
   
   DEBUG( 3, ( "readbraw fnum=%d start=%d max=%d min=%d nread=%d\n",
-             fnum, startpos,
+             fsp->fnum, startpos,
              maxcount, mincount, nread ) );
   
 #if UNSAFE_READRAW
@@ -1860,7 +1828,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
 #endif
 
     if ((nread-predict) > 0)
-      seek_file(fnum,startpos + predict);
+      seek_file(fsp,startpos + predict);
     
     ret = transfer_file(fd,Client,nread-predict,header,4+predict,
                        startpos+predict);
@@ -1871,7 +1839,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
             fname,startpos,nread,ret));
 
 #else
-  ret = read_file(fnum,header+4,startpos,nread);
+  ret = read_file(fsp,header+4,startpos,nread);
   if (ret < mincount) ret = 0;
 
   _smb_setlen(header,ret);
@@ -1888,19 +1856,17 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
 ****************************************************************************/
 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsiz)
 {
-  int fnum;
   int nread = -1;
   char *data;
   int outsize = 0;
   uint32 startpos, numtoread;
   int eclass;
   uint32 ecode;
-  
-  fnum = GETFNUM(inbuf,smb_vwv0);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-  CHECK_FNUM(fnum,conn);
-  CHECK_READ(fnum);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_READ(fsp);
+  CHECK_ERROR(fsp);
 
   numtoread = SVAL(inbuf,smb_vwv1);
   startpos = IVAL(inbuf,smb_vwv2);
@@ -1909,10 +1875,10 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
   numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
   data = smb_buf(outbuf) + 3;
   
-  if(!do_lock( fnum, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode))
+  if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode))
     return (ERROR(eclass,ecode));
 
-  nread = read_file(fnum,data,startpos,numtoread);
+  nread = read_file(fsp,data,startpos,numtoread);
 
   if (nread < 0)
     return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -1923,7 +1889,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
   SSVAL(smb_buf(outbuf),1,nread);
 
   DEBUG( 3, ( "lockread fnum=%d num=%d nread=%d\n",
-            fnum, numtoread, nread ) );
+            fsp->fnum, numtoread, nread ) );
 
   return(outsize);
 }
@@ -1934,17 +1900,16 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
 ****************************************************************************/
 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int numtoread,fnum;
+  int numtoread;
   int nread = 0;
   char *data;
   uint32 startpos;
   int outsize = 0;
-  
-  fnum = GETFNUM(inbuf,smb_vwv0);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-  CHECK_FNUM(fnum,conn);
-  CHECK_READ(fnum);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_READ(fsp);
+  CHECK_ERROR(fsp);
 
   numtoread = SVAL(inbuf,smb_vwv1);
   startpos = IVAL(inbuf,smb_vwv2);
@@ -1953,11 +1918,11 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
   data = smb_buf(outbuf) + 3;
   
-  if (is_locked(fnum,conn,numtoread,startpos, F_RDLCK))
+  if (is_locked(fsp,conn,numtoread,startpos, F_RDLCK))
     return(ERROR(ERRDOS,ERRlock));     
 
   if (numtoread > 0)
-    nread = read_file(fnum,data,startpos,numtoread);
+    nread = read_file(fsp,data,startpos,numtoread);
   
   if (nread < 0)
     return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -1969,7 +1934,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   SSVAL(smb_buf(outbuf),1,nread);
   
   DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
-            fnum, numtoread, nread ) );
+            fsp->fnum, numtoread, nread ) );
 
   return(outsize);
 }
@@ -1980,7 +1945,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 ****************************************************************************/
 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
-  int fnum = GETFNUM(inbuf,smb_vwv2);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv2);
   uint32 smb_offs = IVAL(inbuf,smb_vwv3);
   int smb_maxcnt = SVAL(inbuf,smb_vwv5);
   int smb_mincnt = SVAL(inbuf,smb_vwv6);
@@ -1992,16 +1957,16 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   if (IS_IPC(conn))
     return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
 
-  CHECK_FNUM(fnum,conn);
-  CHECK_READ(fnum);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_READ(fsp);
+  CHECK_ERROR(fsp);
 
   set_message(outbuf,12,0,True);
   data = smb_buf(outbuf);
 
-  if (is_locked(fnum,conn,smb_maxcnt,smb_offs, F_RDLCK))
+  if (is_locked(fsp,conn,smb_maxcnt,smb_offs, F_RDLCK))
     return(ERROR(ERRDOS,ERRlock));
-  nread = read_file(fnum,data,smb_offs,smb_maxcnt);
+  nread = read_file(fsp,data,smb_offs,smb_maxcnt);
   ok = True;
   
   if (nread < 0)
@@ -2012,9 +1977,9 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   SSVAL(smb_buf(outbuf),-2,nread);
   
   DEBUG( 3, ( "readX fnum=%d min=%d max=%d nread=%d\n",
-           fnum, smb_mincnt, smb_maxcnt, nread ) );
+             fsp->fnum, smb_mincnt, smb_maxcnt, nread ) );
 
-  chain_fnum = fnum;
+  chain_fsp = fsp;
 
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
@@ -2028,18 +1993,16 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   int nwritten=0;
   int total_written=0;
   int numtowrite=0;
-  int fnum;
   int outsize = 0;
   long startpos;
   char *data=NULL;
   BOOL write_through;
   int tcount;
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-  fnum = GETFNUM(inbuf,smb_vwv0);
-
-  CHECK_FNUM(fnum,conn);
-  CHECK_WRITE(fnum);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_WRITE(fsp);
+  CHECK_ERROR(fsp);
   
   tcount = IVAL(inbuf,smb_vwv1);
   startpos = IVAL(inbuf,smb_vwv3);
@@ -2059,17 +2022,17 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   CVAL(inbuf,smb_com) = SMBwritec;
   CVAL(outbuf,smb_com) = SMBwritec;
 
-  if (is_locked(fnum,conn,tcount,startpos, F_WRLCK))
+  if (is_locked(fsp,conn,tcount,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
-  if (seek_file(fnum,startpos) != startpos)
+  if (seek_file(fsp,startpos) != startpos)
     DEBUG(0,("couldn't seek to %ld in writebraw\n",startpos));
 
   if (numtowrite>0)
-    nwritten = write_file(fnum,data,numtowrite);
+    nwritten = write_file(fsp,data,numtowrite);
   
   DEBUG(3,("writebraw1 fnum=%d start=%ld num=%d wrote=%d sync=%d\n",
-          fnum, startpos, numtowrite, nwritten, write_through));
+          fsp->fnum, startpos, numtowrite, nwritten, write_through));
 
   if (nwritten < numtowrite) 
     return(UNIXERROR(ERRHRD,ERRdiskfull));
@@ -2097,7 +2060,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
             tcount,nwritten,numtowrite));
   }
 
-  nwritten = transfer_file(Client,Files[fnum].fd_ptr->fd,numtowrite,NULL,0,
+  nwritten = transfer_file(Client,fsp->fd_ptr->fd,numtowrite,NULL,0,
                           startpos+nwritten);
   total_written += nwritten;
   
@@ -2112,10 +2075,10 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   }
 
   if (lp_syncalways(SNUM(conn)) || write_through)
-    sync_file(conn,fnum);
+    sync_file(conn,fsp);
 
   DEBUG(3,("writebraw2 fnum=%d start=%ld num=%d wrote=%d\n",
-          fnum, startpos, numtowrite, total_written));
+          fsp->fnum, startpos, numtowrite, total_written));
 
   /* we won't return a status if write through is not selected - this 
      follows what WfWg does */
@@ -2131,28 +2094,26 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
 ****************************************************************************/
 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int fnum;
   int nwritten = -1;
   int outsize = 0;
   char *data;
   uint32 numtowrite,startpos;
   int eclass;
   uint32 ecode;
-  
-  fnum = GETFNUM(inbuf,smb_vwv0);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-  CHECK_FNUM(fnum,conn);
-  CHECK_WRITE(fnum);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_WRITE(fsp);
+  CHECK_ERROR(fsp);
 
   numtowrite = SVAL(inbuf,smb_vwv1);
   startpos = IVAL(inbuf,smb_vwv2);
   data = smb_buf(inbuf) + 3;
   
-  if (is_locked(fnum,conn,numtowrite,startpos, F_WRLCK))
+  if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
-  seek_file(fnum,startpos);
+  seek_file(fsp,startpos);
 
   /* The special X/Open SMB protocol handling of
      zero length writes is *NOT* done for
@@ -2160,15 +2121,15 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum
   if(numtowrite == 0)
     nwritten = 0;
   else
-    nwritten = write_file(fnum,data,numtowrite);
+    nwritten = write_file(fsp,data,numtowrite);
   
   if (lp_syncalways(SNUM(conn)))
-    sync_file(conn,fnum);
+    sync_file(conn,fsp);
 
   if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
 
-  if(!do_unlock(fnum, conn, numtowrite, startpos, &eclass, &ecode))
+  if(!do_unlock(fsp, conn, numtowrite, startpos, &eclass, &ecode))
     return(ERROR(eclass,ecode));
 
   outsize = set_message(outbuf,1,0,True);
@@ -2176,7 +2137,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum
   SSVAL(outbuf,smb_vwv0,nwritten);
   
   DEBUG( 3, ( "writeunlock fnum=%d num=%d wrote=%d\n",
-           fnum, numtowrite, nwritten ) );
+             fsp->fnum, numtowrite, nwritten ) );
 
   return(outsize);
 }
@@ -2187,37 +2148,36 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum
 ****************************************************************************/
 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,int dum_buffsize)
 {
-  int numtowrite,fnum;
+  int numtowrite;
   int nwritten = -1;
   int outsize = 0;
   int startpos;
   char *data;
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-  fnum = GETFNUM(inbuf,smb_vwv0);
-
-  CHECK_FNUM(fnum,conn);
-  CHECK_WRITE(fnum);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_WRITE(fsp);
+  CHECK_ERROR(fsp);
 
   numtowrite = SVAL(inbuf,smb_vwv1);
   startpos = IVAL(inbuf,smb_vwv2);
   data = smb_buf(inbuf) + 3;
   
-  if (is_locked(fnum,conn,numtowrite,startpos, F_WRLCK))
+  if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
-  seek_file(fnum,startpos);
+  seek_file(fsp,startpos);
 
   /* X/Open SMB protocol says that if smb_vwv1 is
      zero then the file size should be extended or
      truncated to the size given in smb_vwv[2-3] */
   if(numtowrite == 0)
-    nwritten = set_filelen(Files[fnum].fd_ptr->fd, startpos);
+    nwritten = set_filelen(fsp->fd_ptr->fd, startpos);
   else
-    nwritten = write_file(fnum,data,numtowrite);
+    nwritten = write_file(fsp,data,numtowrite);
   
   if (lp_syncalways(SNUM(conn)))
-    sync_file(conn,fnum);
+    sync_file(conn,fsp);
 
   if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2232,7 +2192,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,i
   }
   
   DEBUG(3,("write fnum=%d num=%d wrote=%d\n",
-          fnum, numtowrite, nwritten));
+          fsp->fnum, numtowrite, nwritten));
 
   return(outsize);
 }
@@ -2243,7 +2203,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,i
 ****************************************************************************/
 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
-  int fnum = GETFNUM(inbuf,smb_vwv2);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv2);
   uint32 smb_offs = IVAL(inbuf,smb_vwv3);
   int smb_dsize = SVAL(inbuf,smb_vwv10);
   int smb_doff = SVAL(inbuf,smb_vwv11);
@@ -2251,16 +2211,16 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   int nwritten = -1;
   char *data;
 
-  CHECK_FNUM(fnum,conn);
-  CHECK_WRITE(fnum);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_WRITE(fsp);
+  CHECK_ERROR(fsp);
 
   data = smb_base(inbuf) + smb_doff;
 
-  if (is_locked(fnum,conn,smb_dsize,smb_offs, F_WRLCK))
+  if (is_locked(fsp,conn,smb_dsize,smb_offs, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
-  seek_file(fnum,smb_offs);
+  seek_file(fsp,smb_offs);
   
   /* X/Open SMB protocol says that, unlike SMBwrite
      if the length is zero then NO truncation is
@@ -2269,7 +2229,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   if(smb_dsize == 0)
     nwritten = 0;
   else
-    nwritten = write_file(fnum,data,smb_dsize);
+    nwritten = write_file(fsp,data,smb_dsize);
   
   if(((nwritten == 0) && (smb_dsize != 0))||(nwritten < 0))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2284,12 +2244,12 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   }
 
   DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
-          fnum, smb_dsize, nwritten));
+          fsp->fnum, smb_dsize, nwritten));
 
-  chain_fnum = fnum;
+  chain_fsp = fsp;
 
   if (lp_syncalways(SNUM(conn)) || write_through)
-    sync_file(conn,fnum);
+    sync_file(conn,fsp);
 
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
@@ -2300,17 +2260,14 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
 ****************************************************************************/
 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int fnum;
   uint32 startpos;
   int32 res= -1;
   int mode,umode;
   int outsize = 0;
-  files_struct *fsp;
-  fnum = GETFNUM(inbuf,smb_vwv0);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-  CHECK_FNUM(fnum,conn);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_ERROR(fsp);
 
   mode = SVAL(inbuf,smb_vwv1) & 3;
   startpos = IVAL(inbuf,smb_vwv2);
@@ -2324,8 +2281,6 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       umode = SEEK_SET; break;
     }
 
-  fsp = &Files[fnum];
-  
   res = lseek(fsp->fd_ptr->fd,startpos,umode);
   fsp->pos = res;
   
@@ -2333,7 +2288,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   SIVALS(outbuf,smb_vwv0,res);
   
   DEBUG(3,("lseek fnum=%d ofs=%d mode=%d\n",
-          fnum, startpos, mode));
+          fsp->fnum, startpos, mode));
 
   return(outsize);
 }
@@ -2344,28 +2299,21 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 ****************************************************************************/
 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int fnum;
   int outsize = set_message(outbuf,0,0,True);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-  fnum = GETFNUM(inbuf,smb_vwv0);
-
-  if (fnum != 0xFFFF) {
-    CHECK_FNUM(fnum,conn);
-    CHECK_ERROR(fnum);
+  if (fsp) {
+         CHECK_FSP(fsp,conn);
+         CHECK_ERROR(fsp);
   }
 
-  if (fnum == 0xFFFF) {
-         int i;
-         for (i=0;i<MAX_FNUMS;i++) {
-                 if (OPEN_FNUM(i)) {
-                         sync_file(conn,i);
-                 }
-         }
+  if (!fsp) {
+         file_sync_all(conn);
   } else {
-         sync_file(conn,fnum);
+         sync_file(conn,fsp);
   }
 
-  DEBUG( 3, ( "flush fnum=%d\n", fnum ) );
+  DEBUG(3,("flush\n"));
   return(outsize);
 }
 
@@ -2389,7 +2337,6 @@ int reply_exit(connection_struct *conn,
 int reply_close(connection_struct *conn,
                char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-       int fnum;
        int outsize = 0;
        time_t mtime;
        int32 eclass = 0, err = 0;
@@ -2402,18 +2349,16 @@ int reply_close(connection_struct *conn,
                return reply_pipe_close(conn, inbuf,outbuf);
        }
 
-       fnum = GETFNUM(inbuf,smb_vwv0);
+       fsp = GETFSP(inbuf,smb_vwv0);
 
        /*
-        * We can only use CHECK_FNUM if we know it's not a directory.
+        * We can only use CHECK_FSP if we know it's not a directory.
         */
 
-       if(!(VALID_FNUM(fnum) && Files[fnum].open && Files[fnum].is_directory))
-               CHECK_FNUM(fnum,conn);
+       if(!(fsp && fsp->open && fsp->is_directory))
+               CHECK_FSP(fsp,conn);
 
-       fsp = &Files[fnum];
-
-       if(HAS_CACHED_ERROR(fnum)) {
+       if(HAS_CACHED_ERROR(fsp)) {
                eclass = fsp->wbmpx_ptr->wr_errclass;
                err = fsp->wbmpx_ptr->wr_error;
        }
@@ -2423,8 +2368,8 @@ int reply_close(connection_struct *conn,
                 * Special case - close NT SMB directory
                 * handle.
                 */
-               DEBUG(3,("close directory fnum=%d\n", fnum));
-               close_directory(fnum);
+               DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
+               close_directory(fsp);
        } else {
                /*
                 * Close ordinary file.
@@ -2435,10 +2380,10 @@ int reply_close(connection_struct *conn,
                set_filetime(conn, fsp->fsp_name,mtime);
 
                DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
-                        fsp->fd_ptr->fd, fnum,
+                        fsp->fd_ptr->fd, fsp->fnum,
                         conn->num_files_open));
   
-               close_file(fnum,True);
+               close_file(fsp,True);
        }  
 
        /* We have a cached error */
@@ -2455,37 +2400,36 @@ int reply_close(connection_struct *conn,
 int reply_writeclose(connection_struct *conn,
                     char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-       int numtowrite,fnum;
+       int numtowrite;
        int nwritten = -1;
        int outsize = 0;
        int startpos;
        char *data;
        time_t mtime;
-  
-       fnum = GETFNUM(inbuf,smb_vwv0);
+       files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-       CHECK_FNUM(fnum,conn);
-       CHECK_WRITE(fnum);
-       CHECK_ERROR(fnum);
+       CHECK_FSP(fsp,conn);
+       CHECK_WRITE(fsp);
+       CHECK_ERROR(fsp);
 
        numtowrite = SVAL(inbuf,smb_vwv1);
        startpos = IVAL(inbuf,smb_vwv2);
        mtime = make_unix_date3(inbuf+smb_vwv4);
        data = smb_buf(inbuf) + 1;
   
-       if (is_locked(fnum,conn,numtowrite,startpos, F_WRLCK))
+       if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
                return(ERROR(ERRDOS,ERRlock));
       
-       seek_file(fnum,startpos);
+       seek_file(fsp,startpos);
       
-       nwritten = write_file(fnum,data,numtowrite);
+       nwritten = write_file(fsp,data,numtowrite);
 
-       set_filetime(conn, Files[fnum].fsp_name,mtime);
+       set_filetime(conn, fsp->fsp_name,mtime);
   
-       close_file(fnum,True);
+       close_file(fsp,True);
 
        DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
-                fnum, numtowrite, nwritten,
+                fsp->fnum, numtowrite, nwritten,
                 conn->num_files_open));
   
        if (nwritten <= 0)
@@ -2504,24 +2448,22 @@ int reply_writeclose(connection_struct *conn,
 int reply_lock(connection_struct *conn,
               char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-       int fnum;
        int outsize = set_message(outbuf,0,0,True);
        uint32 count,offset;
        int eclass;
        uint32 ecode;
+       files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-       fnum = GETFNUM(inbuf,smb_vwv0);
-
-       CHECK_FNUM(fnum,conn);
-       CHECK_ERROR(fnum);
+       CHECK_FSP(fsp,conn);
+       CHECK_ERROR(fsp);
 
        count = IVAL(inbuf,smb_vwv1);
        offset = IVAL(inbuf,smb_vwv3);
 
        DEBUG(3,("lock fd=%d fnum=%d ofs=%d cnt=%d\n",
-                Files[fnum].fd_ptr->fd, fnum, offset, count));
+                fsp->fd_ptr->fd, fsp->fnum, offset, count));
 
-       if (!do_lock(fnum, conn, count, offset, F_WRLCK, &eclass, &ecode))
+       if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode))
                return (ERROR(eclass,ecode));
 
        return(outsize);
@@ -2533,25 +2475,23 @@ int reply_lock(connection_struct *conn,
 ****************************************************************************/
 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int fnum;
   int outsize = set_message(outbuf,0,0,True);
   uint32 count,offset;
   int eclass;
   uint32 ecode;
-  
-  fnum = GETFNUM(inbuf,smb_vwv0);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-  CHECK_FNUM(fnum,conn);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_ERROR(fsp);
 
   count = IVAL(inbuf,smb_vwv1);
   offset = IVAL(inbuf,smb_vwv3);
 
-  if(!do_unlock(fnum, conn, count, offset, &eclass, &ecode))
+  if(!do_unlock(fsp, conn, count, offset, &eclass, &ecode))
     return (ERROR(eclass,ecode));
 
   DEBUG( 3, ( "unlock fd=%d fnum=%d ofs=%d cnt=%d\n",
-        Files[fnum].fd_ptr->fd, fnum, offset, count ) );
+        fsp->fd_ptr->fd, fsp->fnum, offset, count ) );
   
   return(outsize);
 }
@@ -2624,7 +2564,6 @@ int reply_printopen(connection_struct *conn,
 {
        pstring fname;
        pstring fname2;
-       int fnum = -1;
        int outsize = 0;
        files_struct *fsp;
        
@@ -2649,26 +2588,24 @@ int reply_printopen(connection_struct *conn,
                slprintf(fname,sizeof(fname)-1, "%s.XXXXXX",s);  
        }
 
-       fnum = find_free_file();
-       if (fnum < 0)
+       fsp = find_free_file();
+       if (!fsp)
                return(ERROR(ERRSRV,ERRnofids));
-
-       fsp = &Files[fnum];
        
        pstrcpy(fname2,(char *)mktemp(fname));
 
        if (!check_name(fname2,conn)) {
-               fsp->reserved = False;
+               file_free(fsp);
                return(ERROR(ERRDOS,ERRnoaccess));
        }
 
        /* Open for exclusive use, write only. */
-       open_file_shared(fnum,conn,fname2,
+       open_file_shared(fsp,conn,fname2,
                         (DENY_ALL<<4)|1, 0x12, unix_mode(conn,0), 
                         0, NULL, NULL);
 
        if (!fsp->open) {
-               fsp->reserved = False;
+               file_free(fsp);
                return(UNIXERROR(ERRDOS,ERRnoaccess));
        }
 
@@ -2676,10 +2613,10 @@ int reply_printopen(connection_struct *conn,
        fsp->print_file = True;
   
        outsize = set_message(outbuf,1,0,True);
-       SSVAL(outbuf,smb_vwv0,fnum);
+       SSVAL(outbuf,smb_vwv0,fsp->fnum);
   
        DEBUG(3,("openprint %s fd=%d fnum=%d\n",
-                  fname2, fsp->fd_ptr->fd, fnum));
+                  fname2, fsp->fd_ptr->fd, fsp->fnum));
 
        return(outsize);
 }
@@ -2691,21 +2628,19 @@ int reply_printopen(connection_struct *conn,
 int reply_printclose(connection_struct *conn,
                     char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-       int fnum;
        int outsize = set_message(outbuf,0,0,True);
-  
-       fnum = GETFNUM(inbuf,smb_vwv0);
+       files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-       CHECK_FNUM(fnum,conn);
-       CHECK_ERROR(fnum);
+       CHECK_FSP(fsp,conn);
+       CHECK_ERROR(fsp);
 
        if (!CAN_PRINT(conn))
                return(ERROR(ERRDOS,ERRnoaccess));
   
        DEBUG(3,("printclose fd=%d fnum=%d\n",
-                Files[fnum].fd_ptr->fd,fnum));
+                fsp->fd_ptr->fd,fsp->fnum));
   
-       close_file(fnum,True);
+       close_file(fsp,True);
 
        return(outsize);
 }
@@ -2786,26 +2721,25 @@ int reply_printqueue(connection_struct *conn,
 ****************************************************************************/
 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int numtowrite,fnum;
+  int numtowrite;
   int outsize = set_message(outbuf,0,0,True);
   char *data;
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
   
   if (!CAN_PRINT(conn))
     return(ERROR(ERRDOS,ERRnoaccess));
 
-  fnum = GETFNUM(inbuf,smb_vwv0);
-
-  CHECK_FNUM(fnum,conn);
-  CHECK_WRITE(fnum);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_WRITE(fsp);
+  CHECK_ERROR(fsp);
 
   numtowrite = SVAL(smb_buf(inbuf),1);
   data = smb_buf(inbuf) + 3;
   
-  if (write_file(fnum,data,numtowrite) != numtowrite)
+  if (write_file(fsp,data,numtowrite) != numtowrite)
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   
-  DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fnum, numtowrite ) );
+  DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
   
   return(outsize);
 }
@@ -3323,7 +3257,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
   int Access,action;
   struct stat st;
   int ret=0;
-  int fnum1,fnum2;
+  files_struct *fsp1,*fsp2;
   pstring dest;
   
   pstrcpy(dest,dest1);
@@ -3339,43 +3273,43 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
 
   if (!file_exist(src,&st)) return(False);
 
-  fnum1 = find_free_file();
-  if (fnum1<0) return(False);
-  open_file_shared(fnum1,conn,src,(DENY_NONE<<4),
+  fsp1 = find_free_file();
+  if (!fsp1) return(False);
+  open_file_shared(fsp1,conn,src,(DENY_NONE<<4),
                   1,0,0,&Access,&action);
 
-  if (!Files[fnum1].open) {
-         Files[fnum1].reserved = False;
+  if (!fsp1->open) {
+         fsp1->reserved = False;
          return(False);
   }
 
   if (!target_is_directory && count)
     ofun = 1;
 
-  fnum2 = find_free_file();
-  if (fnum2<0) {
-    close_file(fnum1,False);
-    return(False);
+  fsp2 = find_free_file();
+  if (!fsp2) {
+         close_file(fsp1,False);
+         return(False);
   }
-  open_file_shared(fnum2,conn,dest,(DENY_NONE<<4)|1,
+  open_file_shared(fsp2,conn,dest,(DENY_NONE<<4)|1,
                   ofun,st.st_mode,0,&Access,&action);
 
-  if (!Files[fnum2].open) {
-    close_file(fnum1,False);
-    Files[fnum2].reserved = False;
+  if (!fsp2->open) {
+    close_file(fsp1,False);
+    fsp2->reserved = False;
     return(False);
   }
 
   if ((ofun&3) == 1) {
-    lseek(Files[fnum2].fd_ptr->fd,0,SEEK_END);
+    lseek(fsp2->fd_ptr->fd,0,SEEK_END);
   }
   
   if (st.st_size)
-    ret = transfer_file(Files[fnum1].fd_ptr->fd,
-                        Files[fnum2].fd_ptr->fd,st.st_size,NULL,0,0);
+    ret = transfer_file(fsp1->fd_ptr->fd,
+                        fsp2->fd_ptr->fd,st.st_size,NULL,0,0);
 
-  close_file(fnum1,False);
-  close_file(fnum2,False);
+  close_file(fsp1,False);
+  close_file(fsp2,False);
 
   return(ret == st.st_size);
 }
@@ -3556,7 +3490,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 ****************************************************************************/
 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
-  int fnum = GETFNUM(inbuf,smb_vwv2);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv2);
   unsigned char locktype = CVAL(inbuf,smb_vwv3);
 #if 0
   unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
@@ -3570,8 +3504,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
   uint32 ecode=0, dummy2;
   int eclass=0, dummy1;
 
-  CHECK_FNUM(fnum,conn);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_ERROR(fsp);
 
   data = smb_buf(inbuf);
 
@@ -3581,28 +3515,27 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
   if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE))
   {
     int token;
-    files_struct *fsp = &Files[fnum];
     uint32 dev = fsp->fd_ptr->dev;
     uint32 inode = fsp->fd_ptr->inode;
 
     DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n",
-              fnum));
+              fsp->fnum));
     /*
      * Make sure we have granted an oplock on this file.
      */
     if(!fsp->granted_oplock)
     {
       DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
-no oplock granted on this file.\n", fnum));
+no oplock granted on this file.\n", fsp->fnum));
       return ERROR(ERRDOS,ERRlock);
     }
 
     /* Remove the oplock flag from the sharemode. */
     lock_share_entry(fsp->conn, dev, inode, &token);
-    if(remove_share_oplock( fnum, token)==False) {
+    if(remove_share_oplock(fsp, token)==False) {
            DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
 dev = %x, inode = %x\n", 
-                    fnum, dev, inode));
+                    fsp->fnum, dev, inode));
            unlock_share_entry(fsp->conn, dev, inode, token);
     } else {
            unlock_share_entry(fsp->conn, dev, inode, token);
@@ -3628,7 +3561,7 @@ dev = %x, inode = %x\n",
   for(i = 0; i < (int)num_ulocks; i++) {
     count = IVAL(data,SMB_LKLEN_OFFSET(i));
     offset = IVAL(data,SMB_LKOFF_OFFSET(i));
-    if(!do_unlock(fnum,conn,count,offset,&eclass, &ecode))
+    if(!do_unlock(fsp,conn,count,offset,&eclass, &ecode))
       return ERROR(eclass,ecode);
   }
 
@@ -3642,7 +3575,7 @@ dev = %x, inode = %x\n",
   for(i = 0; i < (int)num_locks; i++) {
     count = IVAL(data,SMB_LKLEN_OFFSET(i)); 
     offset = IVAL(data,SMB_LKOFF_OFFSET(i)); 
-    if(!do_lock(fnum,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
+    if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
                 &eclass, &ecode))
 #if 0 /* JRATEST - blocking lock code. */
       if((ecode == ERRlock) && (lock_timeout != 0)) {
@@ -3663,7 +3596,7 @@ dev = %x, inode = %x\n",
     for(; i >= 0; i--) {
       count = IVAL(data,SMB_LKLEN_OFFSET(i));  
       offset = IVAL(data,SMB_LKOFF_OFFSET(i)); 
-      do_unlock(fnum,conn,count,offset,&dummy1,&dummy2);
+      do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
     }
     return ERROR(eclass,ecode);
   }
@@ -3671,9 +3604,9 @@ dev = %x, inode = %x\n",
   set_message(outbuf,2,0,True);
   
   DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
-       fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
+       fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
 
-  chain_fnum = fnum;
+  chain_fsp = fsp;
 
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
@@ -3684,7 +3617,6 @@ dev = %x, inode = %x\n",
 ****************************************************************************/
 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
-  int fnum;
   int nread = -1;
   int total_read;
   char *data;
@@ -3693,6 +3625,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
   int max_per_packet;
   int tcount;
   int pad;
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
   /* this function doesn't seem to work - disable by default */
   if (!lp_readbmpx())
@@ -3700,11 +3633,9 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
 
   outsize = set_message(outbuf,8,0,True);
 
-  fnum = GETFNUM(inbuf,smb_vwv0);
-
-  CHECK_FNUM(fnum,conn);
-  CHECK_READ(fnum);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_READ(fsp);
+  CHECK_ERROR(fsp);
 
   startpos = IVAL(inbuf,smb_vwv1);
   maxcount = SVAL(inbuf,smb_vwv3);
@@ -3719,14 +3650,14 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
   tcount = maxcount;
   total_read = 0;
 
-  if (is_locked(fnum,conn,maxcount,startpos, F_RDLCK))
+  if (is_locked(fsp,conn,maxcount,startpos, F_RDLCK))
     return(ERROR(ERRDOS,ERRlock));
        
   do
     {
       int N = MIN(max_per_packet,tcount-total_read);
   
-      nread = read_file(fnum,data,startpos,N);
+      nread = read_file(fsp,data,startpos,N);
 
       if (nread <= 0) nread = 0;
 
@@ -3755,18 +3686,17 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
 ****************************************************************************/
 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int numtowrite,fnum;
+  int numtowrite;
   int nwritten = -1;
   int outsize = 0;
   uint32 startpos;
   int tcount, write_through, smb_doff;
   char *data;
-  
-  fnum = GETFNUM(inbuf,smb_vwv0);
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
-  CHECK_FNUM(fnum,conn);
-  CHECK_WRITE(fnum);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_WRITE(fsp);
+  CHECK_ERROR(fsp);
 
   tcount = SVAL(inbuf,smb_vwv1);
   startpos = IVAL(inbuf,smb_vwv3);
@@ -3780,14 +3710,14 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
      not an SMBwritebmpx - set this up now so we don't forget */
   CVAL(outbuf,smb_com) = SMBwritec;
 
-  if (is_locked(fnum,conn,tcount,startpos,F_WRLCK))
+  if (is_locked(fsp,conn,tcount,startpos,F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
-  seek_file(fnum,startpos);
-  nwritten = write_file(fnum,data,numtowrite);
+  seek_file(fsp,startpos);
+  nwritten = write_file(fsp,data,numtowrite);
 
   if(lp_syncalways(SNUM(conn)) || write_through)
-    sync_file(conn,fnum);
+    sync_file(conn,fsp);
   
   if(nwritten < numtowrite)
     return(UNIXERROR(ERRHRD,ERRdiskfull));
@@ -3799,8 +3729,8 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   if(tcount > nwritten) 
     {
       write_bmpx_struct *wbms;
-      if(Files[fnum].wbmpx_ptr != NULL)
-       wbms = Files[fnum].wbmpx_ptr; /* Use an existing struct */
+      if(fsp->wbmpx_ptr != NULL)
+       wbms = fsp->wbmpx_ptr; /* Use an existing struct */
       else
        wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
       if(!wbms)
@@ -3813,7 +3743,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
       wbms->wr_total_written = nwritten;
       wbms->wr_errclass = 0;
       wbms->wr_error = 0;
-      Files[fnum].wbmpx_ptr = wbms;
+      fsp->wbmpx_ptr = wbms;
     }
 
   /* We are returning successfully, set the message type back to
@@ -3825,7 +3755,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
   
   DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
-           fnum, numtowrite, nwritten ) );
+           fsp->fnum, numtowrite, nwritten ) );
 
   if (write_through && tcount==nwritten) {
     /* we need to send both a primary and a secondary response */
@@ -3847,18 +3777,18 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
 ****************************************************************************/
 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int numtowrite,fnum;
+  int numtowrite;
   int nwritten = -1;
   int outsize = 0;
   int32 startpos;
   int tcount, write_through, smb_doff;
   char *data;
   write_bmpx_struct *wbms;
-  BOOL send_response = False;
-  
-  fnum = GETFNUM(inbuf,smb_vwv0);
-  CHECK_FNUM(fnum,conn);
-  CHECK_WRITE(fnum);
+  BOOL send_response = False; 
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+
+  CHECK_FSP(fsp,conn);
+  CHECK_WRITE(fsp);
 
   tcount = SVAL(inbuf,smb_vwv1);
   startpos = IVAL(inbuf,smb_vwv2);
@@ -3872,7 +3802,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
 
   /* This fd should have an auxiliary struct attached,
      check that it does */
-  wbms = Files[fnum].wbmpx_ptr;
+  wbms = fsp->wbmpx_ptr;
   if(!wbms) return(-1);
 
   /* If write through is set we can return errors, else we must
@@ -3883,18 +3813,18 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
   if(wbms->wr_discard)
     return -1; /* Just discard the packet */
 
-  seek_file(fnum,startpos);
-  nwritten = write_file(fnum,data,numtowrite);
+  seek_file(fsp,startpos);
+  nwritten = write_file(fsp,data,numtowrite);
 
   if(lp_syncalways(SNUM(conn)) || write_through)
-    sync_file(conn,fnum);
+    sync_file(conn,fsp);
   
   if (nwritten < numtowrite)
     {
       if(write_through)        {
        /* We are returning an error - we can delete the aux struct */
        if (wbms) free((char *)wbms);
-       Files[fnum].wbmpx_ptr = NULL;
+       fsp->wbmpx_ptr = NULL;
        return(ERROR(ERRHRD,ERRdiskfull));
       }
       return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
@@ -3912,7 +3842,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
       }
 
       free((char *)wbms);
-      Files[fnum].wbmpx_ptr = NULL;
+      fsp->wbmpx_ptr = NULL;
     }
 
   if(send_response)
@@ -3927,16 +3857,14 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
 ****************************************************************************/
 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int fnum;
   struct utimbuf unix_times;
   int outsize = 0;
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
   outsize = set_message(outbuf,0,0,True);
 
-  fnum = GETFNUM(inbuf,smb_vwv0);
-
-  CHECK_FNUM(fnum,conn);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_ERROR(fsp);
 
   /* Convert the DOS times into unix times. Ignore create
      time as UNIX can't set this.
@@ -3954,7 +3882,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
     /* Ignore request */
     if( DEBUGLVL( 3 ) )
       {
-      dbgtext( "reply_setattrE fnum=%d ", fnum);
+      dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
       dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
       }
     return(outsize);
@@ -3966,11 +3894,11 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
   }
 
   /* Set the date on this file */
-  if(file_utime(conn, Files[fnum].fsp_name, &unix_times))
+  if(file_utime(conn, fsp->fsp_name, &unix_times))
     return(ERROR(ERRDOS,ERRnoaccess));
   
   DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
-            fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
+            fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
 
   return(outsize);
 }
@@ -3981,23 +3909,21 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
 ****************************************************************************/
 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int fnum;
   struct stat sbuf;
   int outsize = 0;
   int mode;
+  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
 
   outsize = set_message(outbuf,11,0,True);
 
-  fnum = GETFNUM(inbuf,smb_vwv0);
-
-  CHECK_FNUM(fnum,conn);
-  CHECK_ERROR(fnum);
+  CHECK_FSP(fsp,conn);
+  CHECK_ERROR(fsp);
 
   /* Do an fstat on this file */
-  if(fstat(Files[fnum].fd_ptr->fd, &sbuf))
+  if(fstat(fsp->fd_ptr->fd, &sbuf))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   
-  mode = dos_mode(conn,Files[fnum].fsp_name,&sbuf);
+  mode = dos_mode(conn,fsp->fsp_name,&sbuf);
   
   /* Convert the times into dos times. Set create
      date to be last modify date as UNIX doesn't save
@@ -4017,7 +3943,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
     }
   SSVAL(outbuf,smb_vwv10, mode);
   
-  DEBUG( 3, ( "reply_getattrE fnum=%d\n", fnum));
+  DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
   
   return(outsize);
 }
index ba93ceaa16f526822d2e7219a0f90de1f2faf3a9..8b656ab264641bf6d99642b66ebbca986f689b14 100644 (file)
@@ -66,14 +66,6 @@ extern int dcelogin_atmost_once;
 extern DOM_SID global_machine_sid;
 
 static connection_struct Connections[MAX_CONNECTIONS];
-files_struct Files[MAX_FNUMS];
-
-/*
- * Indirection for file fd's. Needed as POSIX locking
- * is based on file/process, not fd/process.
- */
-file_fd_struct FileFd[MAX_OPEN_FILES];
-int max_file_fd_used = 0;
 
 extern int Protocol;
 
@@ -89,8 +81,8 @@ int max_send = BUFFER_SIZE;
  */
 int max_recv = BUFFER_SIZE;
 
-/* a fnum to use when chaining */
-int chain_fnum = -1;
+/* a fsp to use when chaining */
+files_struct *chain_fsp = NULL;
 
 /* number of open connections */
 static int num_connections_open = 0;
@@ -807,7 +799,7 @@ static int fd_attempt_open(char *fname, int flags, int mode)
 Cache a uid_t currently with this file open. This is an optimization only
 used when multiple sessionsetup's have been done to one smbd.
 ****************************************************************************/
-static void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
+void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
 {
   if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t))
     return;
@@ -844,67 +836,6 @@ static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
   return False;
 }
 
-/****************************************************************************
-fd support routines - attempt to find an already open file by dev
-and inode - increments the ref_count of the returned file_fd_struct *.
-****************************************************************************/
-static file_fd_struct *fd_get_already_open(struct stat *sbuf)
-{
-  int i;
-  file_fd_struct *fd_ptr;
-
-  if(sbuf == 0)
-    return 0;
-
-  for(i = 0; i <= max_file_fd_used; i++) {
-    fd_ptr = &FileFd[i];
-    if((fd_ptr->ref_count > 0) &&
-       (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
-       (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
-      fd_ptr->ref_count++;
-      DEBUG(3,
-       ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
-        i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
-      return fd_ptr;
-    }
-  }
-  return 0;
-}
-
-/****************************************************************************
-fd support routines - attempt to find a empty slot in the FileFd array.
-Increments the ref_count of the returned entry.
-****************************************************************************/
-static file_fd_struct *fd_get_new(void)
-{
-  extern struct current_user current_user;
-  int i;
-  file_fd_struct *fd_ptr;
-
-  for(i = 0; i < MAX_OPEN_FILES; i++) {
-    fd_ptr = &FileFd[i];
-    if(fd_ptr->ref_count == 0) {
-      fd_ptr->dev = (uint32)-1;
-      fd_ptr->inode = (uint32)-1;
-      fd_ptr->fd = -1;
-      fd_ptr->fd_readonly = -1;
-      fd_ptr->fd_writeonly = -1;
-      fd_ptr->real_open_flags = -1;
-      fd_ptr->uid_cache_count = 0;
-      fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
-      fd_ptr->ref_count++;
-      /* Increment max used counter if neccessary, cuts down
-         on search time when re-using */
-      if(i > max_file_fd_used)
-        max_file_fd_used = i;
-      DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
-               i, fd_ptr->dev, fd_ptr->inode));
-      return fd_ptr;
-    }
-  }
-  DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\n"));
-  return 0;
-}
 
 /****************************************************************************
 fd support routines - attempt to re-open an already open fd as O_RDWR.
@@ -934,8 +865,7 @@ static int fd_attempt_close(file_fd_struct *fd_ptr)
 {
   extern struct current_user current_user;
 
-  DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
-          fd_ptr - &FileFd[0],
+  DEBUG(3,("fd_attempt_close fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
           fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
           fd_ptr->real_open_flags,
           fd_ptr->ref_count));
@@ -1034,14 +964,13 @@ static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
 /****************************************************************************
 open a file
 ****************************************************************************/
-static void open_file(int fnum,connection_struct *conn,
+static void open_file(files_struct *fsp,connection_struct *conn,
                      char *fname1,int flags,int mode, struct stat *sbuf)
 {
   extern struct current_user current_user;
   pstring fname;
   struct stat statbuf;
   file_fd_struct *fd_ptr;
-  files_struct *fsp = &Files[fnum];
   int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
 
   fsp->open = False;
@@ -1296,13 +1225,13 @@ static void open_file(int fnum,connection_struct *conn,
      */
     if (fsp->print_file && lp_postscript(SNUM(conn)) && fsp->can_write) {
            DEBUG(3,("Writing postscript line\n"));
-           write_file(fnum,"%!\n",3);
+           write_file(fsp,"%!\n",3);
     }
       
-    DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
+    DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
             *sesssetup_user ? sesssetup_user : conn->user,fname,
             BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
-            conn->num_files_open,fnum));
+            conn->num_files_open));
 
   }
 
@@ -1325,28 +1254,28 @@ static void open_file(int fnum,connection_struct *conn,
 /*******************************************************************
 sync a file
 ********************************************************************/
-void sync_file(connection_struct *conn, int fnum)
+void sync_file(connection_struct *conn, files_struct *fsp)
 {
 #ifdef HAVE_FSYNC
     if(lp_strict_sync(SNUM(conn)))
-      fsync(Files[fnum].fd_ptr->fd);
+      fsync(fsp->fd_ptr->fd);
 #endif
 }
 
 /****************************************************************************
 run a file if it is a magic script
 ****************************************************************************/
-static void check_magic(int fnum,connection_struct *conn)
+static void check_magic(files_struct *fsp,connection_struct *conn)
 {
   if (!*lp_magicscript(SNUM(conn)))
     return;
 
-  DEBUG(5,("checking magic for %s\n",Files[fnum].fsp_name));
+  DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
 
   {
     char *p;
-    if (!(p = strrchr(Files[fnum].fsp_name,'/')))
-      p = Files[fnum].fsp_name;
+    if (!(p = strrchr(fsp->fsp_name,'/')))
+      p = fsp->fsp_name;
     else
       p++;
 
@@ -1358,7 +1287,7 @@ static void check_magic(int fnum,connection_struct *conn)
     int ret;
     pstring magic_output;
     pstring fname;
-    pstrcpy(fname,Files[fnum].fsp_name);
+    pstrcpy(fname,fsp->fsp_name);
 
     if (*lp_magicoutput(SNUM(conn)))
       pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
@@ -1379,7 +1308,7 @@ static void close_filestruct(files_struct *fsp)
 {   
        connection_struct *conn = fsp->conn;
     
-       fsp->reserved = False
+       file_free(fsp)
        fsp->open = False;
        fsp->is_directory = False; 
     
@@ -1405,69 +1334,66 @@ static void close_filestruct(files_struct *fsp)
  the closing of the connection. In the latter case printing and
  magic scripts are not run.
 ****************************************************************************/
-void close_file(int fnum, BOOL normal_close)
+void close_file(files_struct *fsp, BOOL normal_close)
 {
-       files_struct *fs_p = &Files[fnum];
-       uint32 dev = fs_p->fd_ptr->dev;
-       uint32 inode = fs_p->fd_ptr->inode;
+       uint32 dev = fsp->fd_ptr->dev;
+       uint32 inode = fsp->fd_ptr->inode;
        int token;
-       connection_struct *conn = fs_p->conn;
+       connection_struct *conn = fsp->conn;
 
-       close_filestruct(fs_p);
+       close_filestruct(fsp);
 
 #if USE_READ_PREDICTION
-       invalidate_read_prediction(fs_p->fd_ptr->fd);
+       invalidate_read_prediction(fsp->fd_ptr->fd);
 #endif
 
        if (lp_share_modes(SNUM(conn))) {
                lock_share_entry(conn, dev, inode, &token);
-               del_share_mode(token, fnum);
+               del_share_mode(token, fsp);
        }
 
-       fd_attempt_close(fs_p->fd_ptr);
+       fd_attempt_close(fsp->fd_ptr);
 
        if (lp_share_modes(SNUM(conn)))
                unlock_share_entry(conn, dev, inode, token);
 
        /* NT uses smbclose to start a print - weird */
-       if (normal_close && fs_p->print_file)
-               print_file(conn, fs_p);
+       if (normal_close && fsp->print_file)
+               print_file(conn, fsp);
 
        /* check for magic scripts */
        if (normal_close) {
-               check_magic(fnum,conn);
+               check_magic(fsp,conn);
        }
 
-       if(fs_p->granted_oplock == True)
+       if(fsp->granted_oplock == True)
                global_oplocks_open--;
 
-       fs_p->sent_oplock_break = False;
+       fsp->sent_oplock_break = False;
 
        DEBUG(2,("%s closed file %s (numopen=%d)\n",
-                conn->user,fs_p->fsp_name,
+                conn->user,fsp->fsp_name,
                 conn->num_files_open));
 
-       if (fs_p->fsp_name) {
-               string_free(&fs_p->fsp_name);
+       if (fsp->fsp_name) {
+               string_free(&fsp->fsp_name);
        }
 
-       /* we will catch bugs faster by zeroing this structure */
-       memset(fs_p, 0, sizeof(*fs_p));
+       file_free(fsp);
 }
 
 /****************************************************************************
  Close a directory opened by an NT SMB call. 
 ****************************************************************************/
   
-void close_directory(int fnum)
+void close_directory(files_struct *fsp)
 {
-  files_struct *fsp = &Files[fnum];
 
   /* TODO - walk the list of pending
      change notify requests and free
-     any pertaining to this fnum. */
+     any pertaining to this fsp. */
 
-  remove_pending_change_notify_requests_by_fid(fnum);
+  remove_pending_change_notify_requests_by_fid(fsp);
 
   /*
    * Do the code common to files and directories.
@@ -1477,18 +1403,16 @@ void close_directory(int fnum)
   if (fsp->fsp_name)
     string_free(&fsp->fsp_name);
 
-  /* we will catch bugs faster by zeroing this structure */
-  memset(fsp, 0, sizeof(*fsp));
+  file_free(fsp);
 }
 
 /****************************************************************************
  Open a directory from an NT SMB call.
 ****************************************************************************/
-int open_directory(int fnum,connection_struct *conn,
+int open_directory(files_struct *fsp,connection_struct *conn,
                   char *fname, int smb_ofun, int unixmode, int *action)
 {
        extern struct current_user current_user;
-       files_struct *fsp = &Files[fnum];
        struct stat st;
 
        if (smb_ofun & 0x10) {
@@ -1521,8 +1445,8 @@ int open_directory(int fnum,connection_struct *conn,
                *action = FILE_WAS_OPENED;
        }
        
-       DEBUG(5,("open_directory: opening directory %s, fnum = %d\n",
-                fname, fnum ));
+       DEBUG(5,("open_directory: opening directory %s\n",
+                fname));
 
        /*
         * Setup the files_struct for it.
@@ -1745,19 +1669,17 @@ free_and_exit:
   Helper for open_file_shared. 
   Truncate a file after checking locking; close file if locked.
   **************************************************************************/
-static void truncate_unless_locked(int fnum, connection_struct *conn, int token, 
+static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, int token, 
                                   BOOL *share_locked)
 {
-  files_struct *fsp = &Files[fnum];
-
   if (fsp->can_write){
-    if (is_locked(fnum,conn,0x3FFFFFFF,0,F_WRLCK)){
+    if (is_locked(fsp,conn,0x3FFFFFFF,0,F_WRLCK)){
       /* If share modes are in force for this connection we
          have the share entry locked. Unlock it before closing. */
       if (*share_locked && lp_share_modes(SNUM(conn)))
         unlock_share_entry( conn, fsp->fd_ptr->dev, 
                             fsp->fd_ptr->inode, token);
-      close_file(fnum,False);   
+      close_file(fsp,False);   
       /* Share mode no longer locked. */
       *share_locked = False;
       errno = EACCES;
@@ -1813,10 +1735,9 @@ int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
 /****************************************************************************
 open a file with a share mode
 ****************************************************************************/
-void open_file_shared(int fnum,connection_struct *conn,char *fname,int share_mode,int ofun,
+void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
                      int mode,int oplock_request, int *Access,int *action)
 {
-  files_struct *fs_p = &Files[fnum];
   int flags=0;
   int flags2=0;
   int deny_mode = (share_mode>>4)&7;
@@ -1829,8 +1750,8 @@ void open_file_shared(int fnum,connection_struct *conn,char *fname,int share_mod
   uint32 inode = 0;
   int num_share_modes = 0;
 
-  fs_p->open = False;
-  fs_p->fd_ptr = 0;
+  fsp->open = False;
+  fsp->fd_ptr = 0;
 
   /* this is for OS/2 EAs - try and say we don't support them */
   if (strstr(fname,".+,;=[].")) 
@@ -1992,22 +1913,22 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
           flags,flags2,mode));
 
-  open_file(fnum,conn,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
-  if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
+  open_file(fsp,conn,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
+  if (!fsp->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
   {
     flags = O_RDONLY;
-    open_file(fnum,conn,fname,flags,mode,file_existed ? &sbuf : 0 );
+    open_file(fsp,conn,fname,flags,mode,file_existed ? &sbuf : 0 );
   }
 
-  if (fs_p->open) 
+  if (fsp->open) 
   {
     int open_mode=0;
 
     if((share_locked == False) && lp_share_modes(SNUM(conn)))
     {
       /* We created the file - thus we must now lock the share entry before creating it. */
-      dev = fs_p->fd_ptr->dev;
-      inode = fs_p->fd_ptr->inode;
+      dev = fsp->fd_ptr->dev;
+      inode = fsp->fd_ptr->inode;
       lock_share_entry(conn, dev, inode, &token);
       share_locked = True;
     }
@@ -2025,7 +1946,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
         break;
     }
 
-    fs_p->share_mode = (deny_mode<<4) | open_mode;
+    fsp->share_mode = (deny_mode<<4) | open_mode;
 
     if (Access)
       (*Access) = open_mode;
@@ -2051,8 +1972,8 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) && 
              !IS_VETO_OPLOCK_PATH(conn,fname))
       {
-        fs_p->granted_oplock = True;
-        fs_p->sent_oplock_break = False;
+        fsp->granted_oplock = True;
+        fsp->sent_oplock_break = False;
         global_oplocks_open++;
         port = oplock_port;
 
@@ -2065,11 +1986,11 @@ dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
         port = 0;
         oplock_request = 0;
       }
-      set_share_mode(token, fnum, port, oplock_request);
+      set_share_mode(token, fsp, port, oplock_request);
     }
 
     if ((flags2&O_TRUNC) && file_existed)
-      truncate_unless_locked(fnum,conn,token,&share_locked);
+      truncate_unless_locked(fsp,conn,token,&share_locked);
   }
 
   if (share_locked && lp_share_modes(SNUM(conn)))
@@ -2079,10 +2000,9 @@ dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
 /****************************************************************************
 seek a file. Try to avoid the seek if possible
 ****************************************************************************/
-int seek_file(int fnum,uint32 pos)
+int seek_file(files_struct *fsp,uint32 pos)
 {
   uint32 offset = 0;
-  files_struct *fsp = &Files[fnum];
 
   if (fsp->print_file && lp_postscript(fsp->conn->service))
     offset = 3;
@@ -2094,10 +2014,9 @@ int seek_file(int fnum,uint32 pos)
 /****************************************************************************
 read from a file
 ****************************************************************************/
-int read_file(int fnum,char *data,uint32 pos,int n)
+int read_file(files_struct *fsp,char *data,uint32 pos,int n)
 {
   int ret=0,readret;
-  files_struct *fsp = &Files[fnum];
 
 #if USE_READ_PREDICTION
   if (!fsp->can_write)
@@ -2129,7 +2048,7 @@ int read_file(int fnum,char *data,uint32 pos,int n)
   if (n <= 0)
     return(ret);
 
-  if (seek_file(fnum,pos) != pos)
+  if (seek_file(fsp,pos) != pos)
     {
       DEBUG(3,("Failed to seek to %d\n",pos));
       return(ret);
@@ -2147,9 +2066,8 @@ int read_file(int fnum,char *data,uint32 pos,int n)
 /****************************************************************************
 write to a file
 ****************************************************************************/
-int write_file(int fnum,char *data,int n)
+int write_file(files_struct *fsp,char *data,int n)
 {
-  files_struct *fsp = &Files[fnum];
 
   if (!fsp->can_write) {
     errno = EPERM;
@@ -2318,16 +2236,16 @@ int find_service(char *service)
 /****************************************************************************
   create an error packet from a cached error.
 ****************************************************************************/
-int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
+int cached_error_packet(char *inbuf,char *outbuf,files_struct *fsp,int line)
 {
-  write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
+  write_bmpx_struct *wbmpx = fsp->wbmpx_ptr;
 
   int32 eclass = wbmpx->wr_errclass;
   int32 err = wbmpx->wr_error;
 
   /* We can now delete the auxiliary struct */
   free((char *)wbmpx);
-  Files[fnum].wbmpx_ptr = NULL;
+  fsp->wbmpx_ptr = NULL;
   return error_packet(inbuf,outbuf,eclass,err,line);
 }
 
@@ -2890,7 +2808,6 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
   char *inbuf = NULL;
   char *outbuf = NULL;
   files_struct *fsp = NULL;
-  int fnum;
   time_t start_time;
   BOOL shutdown_server = False;
   connection_struct *saved_conn;
@@ -2906,18 +2823,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
   /* We need to search the file open table for the
      entry containing this dev and inode, and ensure
      we have an oplock on it. */
-  for( fnum = 0; fnum < MAX_FNUMS; fnum++)
-  {
-    if(OPEN_FNUM(fnum))
-    {
-      if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
-         (Files[fnum].open_time.tv_sec == tval->tv_sec) && 
-         (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
-             fsp = &Files[fnum];
-             break;
-      }
-    }
-  }
+  fsp = file_find_dit(dev, inode, tval);
 
   if(fsp == NULL)
   {
@@ -2925,7 +2831,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
     if( DEBUGLVL( 0 ) )
       {
       dbgtext( "oplock_break: cannot find open file with " );
-      dbgtext( "dev = %x, inode = %x (fnum = %d) ", dev, inode, fnum );
+      dbgtext( "dev = %x, inode = %x ", dev, inode);
       dbgtext( "allowing break to succeed.\n" );
       }
     return True;
@@ -2944,8 +2850,8 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
   {
     if( DEBUGLVL( 0 ) )
       {
-      dbgtext( "oplock_break: file %s (fnum = %d, ", fsp->fsp_name, fnum );
-      dbgtext( "dev = %x, inode = %x) has no oplock.\n", dev, inode );
+      dbgtext( "oplock_break: file %s ", fsp->fsp_name );
+      dbgtext( "(dev = %x, inode = %x) has no oplock.\n", dev, inode );
       dbgtext( "Allowing break to succeed regardless.\n" );
       }
     return True;
@@ -2957,8 +2863,8 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
     if( DEBUGLVL( 0 ) )
       {
       dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
-      dbgtext( "file %s (fnum = %d, ", fsp->fsp_name, fnum );
-      dbgtext( "dev = %x, inode = %x)\n", dev, inode );
+      dbgtext( "file %s ", fsp->fsp_name);
+      dbgtext( "(dev = %x, inode = %x)\n", dev, inode );
       }
 
     /* We have to fail the open here as we cannot send another oplock break on
@@ -3000,7 +2906,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
   SSVAL(outbuf,smb_uid,0);
   SSVAL(outbuf,smb_mid,0xFFFF);
   SCVAL(outbuf,smb_vwv0,0xFF);
-  SSVAL(outbuf,smb_vwv2,fnum);
+  SSVAL(outbuf,smb_vwv2,fsp->fnum);
   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
   /* Change this when we have level II oplocks. */
   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
@@ -3029,7 +2935,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
   GetWd(saved_dir);
   unbecome_user();
 
-  while(OPEN_FNUM(fnum) && fsp->granted_oplock)
+  while(OPEN_FSP(fsp) && fsp->granted_oplock)
   {
     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
     {
@@ -3048,7 +2954,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
                      OPLOCK_BREAK_TIMEOUT ) );
 
       DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
-      DEBUGADD( 0, ( "(fnum = %d, dev = %x, inode = %x).\n", fnum, dev, inode));
+      DEBUGADD( 0, ( "(dev = %x, inode = %x).\n", dev, inode));
       shutdown_server = True;
       break;
     }
@@ -3075,7 +2981,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
         dbgtext( "oplock_break: no break received from client " );
         dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
         dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
-        dbgtext( "(fnum = %d, dev = %x, inode = %x).\n", fnum, dev, inode );
+        dbgtext( "(dev = %x, inode = %x).\n", dev, inode );
         }
       shutdown_server = True;
       break;
@@ -3118,7 +3024,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
     exit_server("oplock break failure");
   }
 
-  if(OPEN_FNUM(fnum))
+  if(OPEN_FSP(fsp))
   {
     /* The lockingX reply will have removed the oplock flag 
        from the sharemode. */
@@ -3139,7 +3045,7 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
   if( DEBUGLVL( 3 ) )
     {
     dbgtext( "oplock_break: returning success for " );
-    dbgtext( "fnum = %d, dev = %x, inode = %x.\n", fnum, dev, inode );
+    dbgtext( "dev = %x, inode = %x.\n", dev, inode );
     dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
     }
 
@@ -3791,8 +3697,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
   Used as a last ditch attempt to free a space in the 
   file table when we have run out.
 ****************************************************************************/
-
-static BOOL attempt_close_oplocked_file(files_struct *fsp)
+BOOL attempt_close_oplocked_file(files_struct *fsp)
 {
 
   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
@@ -3810,75 +3715,6 @@ static BOOL attempt_close_oplocked_file(files_struct *fsp)
   return False;
 }
 
-/****************************************************************************
-  find first available file slot
-****************************************************************************/
-int find_free_file(void )
-{
-       int i;
-       static int first_file;
-
-       /* we want to give out file handles differently on each new
-          connection because of a common bug in MS clients where they try to
-          reuse a file descriptor from an earlier smb connection. This code
-          increases the chance that the errant client will get an error rather
-          than causing corruption */
-       if (first_file == 0) {
-               first_file = (getpid() ^ (int)time(NULL)) % MAX_FNUMS;
-               if (first_file == 0) first_file = 1;
-       }
-
-       if (first_file >= MAX_FNUMS)
-               first_file = 1;
-
-       for (i=first_file;i<MAX_FNUMS;i++)
-               if (!Files[i].open && !Files[i].reserved) {
-                       memset(&Files[i], 0, sizeof(Files[i]));
-                       first_file = i+1;
-                       Files[i].reserved = True;
-                       return(i);
-               }
-
-       /* returning a file handle of 0 is a bad idea - so we start at 1 */
-       for (i=1;i<first_file;i++)
-               if (!Files[i].open && !Files[i].reserved) {
-                       memset(&Files[i], 0, sizeof(Files[i]));
-                       first_file = i+1;
-                       Files[i].reserved = True;
-                       return(i);
-               }
-
-        /* 
-         * Before we give up, go through the open files 
-         * and see if there are any files opened with a
-         * batch oplock. If so break the oplock and then
-         * re-use that entry (if it becomes closed).
-         * This may help as NT/95 clients tend to keep
-         * files batch oplocked for quite a long time
-         * after they have finished with them.
-         */
-        for (i=first_file;i<MAX_FNUMS;i++) {
-          if(attempt_close_oplocked_file( &Files[i])) {
-            memset(&Files[i], 0, sizeof(Files[i]));
-            first_file = i+1;
-            Files[i].reserved = True;
-            return(i);
-          }
-        }
-
-        for (i=1;i<MAX_FNUMS;i++) {
-          if(attempt_close_oplocked_file( &Files[i])) {
-            memset(&Files[i], 0, sizeof(Files[i]));
-            first_file = i+1;
-            Files[i].reserved = True;
-            return(i);
-          }
-        }
-
-       DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
-       return(-1);
-}
-
 
 /****************************************************************************
 reply for the core protocol
@@ -4266,23 +4102,6 @@ static int reply_negprot(connection_struct *conn,
 }
 
 
-/****************************************************************************
-close all open files for a connection
-****************************************************************************/
-static void close_open_files(connection_struct *conn)
-{
-  int i;
-  for (i=0;i<MAX_FNUMS;i++)
-    if (Files[i].conn == conn && Files[i].open) {
-      if(Files[i].is_directory)
-        close_directory(i); 
-      else                  
-        close_file(i,False); 
-    }
-}
-
-
-
 /****************************************************************************
 close a cnum
 ****************************************************************************/
@@ -4309,7 +4128,7 @@ void close_cnum(connection_struct *conn, uint16 vuid)
        if (lp_status(SNUM(conn)))
                yield_connection(conn,"STATUS.",MAXSTATUS);
 
-       close_open_files(conn);
+       file_close_conn(conn);
        dptr_closecnum(conn);
 
        /* execute any "postexec = " line */
@@ -4702,7 +4521,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
       }
 
       /* load service specific parameters */
-      if (OPEN_CNUM(conn) && 
+      if (OPEN_CONN(conn) && 
          !become_service(conn,(flags & AS_USER)?True:False)) {
         return(ERROR(ERRSRV,ERRaccess));
       }
@@ -4881,7 +4700,7 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
   smb_last_time = time(NULL);
 
   chain_size = 0;
-  chain_fnum = -1;
+  chain_fsp = NULL;
   reset_chain_pnum();
 
   if (msg_type != 0)
@@ -5135,23 +4954,7 @@ static void init_structs(void )
       string_init(&Connections[i].origpath,"");
     }
 
-  for (i=0;i<MAX_FNUMS;i++)
-    {
-      Files[i].open = False;
-      string_init(&Files[i].fsp_name,"");
-    }
-
-  for (i=0;i<MAX_OPEN_FILES;i++)
-    {
-      file_fd_struct *fd_ptr = &FileFd[i];
-      fd_ptr->ref_count = 0;
-      fd_ptr->dev = (int32)-1;
-      fd_ptr->inode = (int32)-1;
-      fd_ptr->fd = -1;
-      fd_ptr->fd_readonly = -1;
-      fd_ptr->fd_writeonly = -1;
-      fd_ptr->real_open_flags = -1;
-    }
+  file_init();
 
   /* for RPC pipes */
   init_rpc_pipe_hnd();
@@ -5297,25 +5100,6 @@ static void usage(char *pname)
   DEBUG( 1, ( "smbd version %s started.\n", VERSION ) );
   DEBUGADD( 1, ( "Copyright Andrew Tridgell 1992-1997\n" ) );
 
-#ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_NOFILE
-  {
-    struct rlimit rlp;
-    getrlimit(RLIMIT_NOFILE, &rlp);
-    /*
-     * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
-     * extra fd we need to read directories, as well as the log files
-     * and standard handles etc.
-     */
-    rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
-    setrlimit(RLIMIT_NOFILE, &rlp);
-    getrlimit(RLIMIT_NOFILE, &rlp);
-    DEBUG(3,("Maximum number of open files per session is %d\n",(int)rlp.rlim_cur));
-  }
-#endif
-#endif
-
-  
   DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
        (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
 
index 992d8cd61659259c2ab961454f10bfbad832b836..67db3aeb2a5cd0653b7b3e813420e01100293343 100644 (file)
 
 extern int DEBUGLEVEL;
 extern int Protocol;
-extern files_struct Files[];
 extern BOOL case_sensitive;
 extern int Client;
 extern int oplock_sock;
 extern int smb_read_error;
 extern fstring local_machine;
 extern int global_oplock_break;
+extern files_struct *chain_fsp;
 
 /****************************************************************************
   Send the required number of replies back.
@@ -200,7 +200,6 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
   int16 namelen = strlen(pname)+1;
 
   pstring fname;
-  int fnum = -1;
   int unixmode;
   int size=0,fmode=0,mtime=0,rmode;
   int32 inode = 0;
@@ -218,12 +217,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
 
   unix_convert(fname,conn,0,&bad_path);
     
-  fnum = find_free_file();
-  if (fnum < 0)
+  fsp = find_free_file();
+  if (!fsp)
     return(ERROR(ERRSRV,ERRnofids));
 
-  fsp = &Files[fnum];
-
   if (!check_name(fname,conn))
   {
     if((errno == ENOENT) && bad_path)
@@ -231,13 +228,13 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
-    fsp->reserved = False;
+    file_free(fsp);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
   unixmode = unix_mode(conn,open_attr | aARCH);
       
-  open_file_shared(fnum,conn,fname,open_mode,open_ofun,unixmode,
+  open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
                   oplock_request, &rmode,&smb_action);
       
   if (!fsp->open)
@@ -247,12 +244,12 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
-    fsp->reserved = False;
+    file_free(fsp);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
   if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
-    close_file(fnum,False);
+    close_file(fsp,False);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
     
@@ -261,7 +258,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
   mtime = sbuf.st_mtime;
   inode = sbuf.st_ino;
   if (fmode & aDIR) {
-    close_file(fnum,False);
+    close_file(fsp,False);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
 
@@ -271,7 +268,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
     return(ERROR(ERRDOS,ERRnomem));
 
   bzero(params,28);
-  SSVAL(params,0,fnum);
+  SSVAL(params,0,fsp->fnum);
   SSVAL(params,2,fmode);
   put_dos_date2(params,4, mtime);
   SIVAL(params,8, size);
@@ -1212,18 +1209,18 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
   BOOL bad_path = False;
 
   if (tran_call == TRANSACT2_QFILEINFO) {
-    int16 fnum = SVALS(params,0);
+    files_struct *fsp = GETFSP(params,0);
     info_level = SVAL(params,2);
 
-    CHECK_FNUM(fnum,conn);
-    CHECK_ERROR(fnum);
+    CHECK_FSP(fsp,conn);
+    CHECK_ERROR(fsp);
 
-    fname = Files[fnum].fsp_name;
-    if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
-      DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum, strerror(errno)));
+    fname = fsp->fsp_name;
+    if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+      DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
       return(UNIXERROR(ERRDOS,ERRbadfid));
     }
-    pos = lseek(Files[fnum].fd_ptr->fd,0,SEEK_CUR);
+    pos = lseek(fsp->fd_ptr->fd,0,SEEK_CUR);
   } else {
     /* qpathinfo */
     info_level = SVAL(params,0);
@@ -1437,14 +1434,14 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
     return(ERROR(ERRSRV,ERRaccess));
 
   if (tran_call == TRANSACT2_SETFILEINFO) {
-    int16 fnum = SVALS(params,0);
+    files_struct *fsp = GETFSP(params,0);
     info_level = SVAL(params,2);    
 
-    CHECK_FNUM(fnum,conn);
-    CHECK_ERROR(fnum);
+    CHECK_FSP(fsp,conn);
+    CHECK_ERROR(fsp);
 
-    fname = Files[fnum].fsp_name;
-    fd = Files[fnum].fd_ptr->fd;
+    fname = fsp->fsp_name;
+    fd = fsp->fd_ptr->fd;
 
     if(fstat(fd,&st)!=0) {
       DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
index 848f87623eb9e5afac9b02470832eff63f9e9ea7..737700639b1804b1bd68087ceba1a008eb7aead5 100644 (file)
@@ -61,7 +61,6 @@ int            locks_only  = 0;            /* Added by RJS */
 /* we need these because we link to locking*.o */
  void become_root(BOOL save_dir) {}
  void unbecome_root(BOOL restore_dir) {}
-files_struct Files[MAX_OPEN_FILES];
 
 
 /* added by OH */
index 7c7a2ef205b6e1f2c416bf04a0b1ef1dcf88e8ee..3a56c82229821bf0d1171241f8879cd1f37b3237 100644 (file)
@@ -36,7 +36,6 @@ static pstring servicesf = CONFIGFILE;
  void unbecome_root(BOOL restore_dir) {}
 /* We need this because we link to password.o */
 BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd, BOOL override) {return False;}
-files_struct Files[MAX_OPEN_FILES];
 
 static int enum_index(int value, struct enum_list *enumlist)
 {