- added predict.c, moving the routines from util.c
authorAndrew Tridgell <tridge@samba.org>
Fri, 7 Jun 1996 03:34:22 +0000 (03:34 +0000)
committerAndrew Tridgell <tridge@samba.org>
Fri, 7 Jun 1996 03:34:22 +0000 (03:34 +0000)
- added iface_count() and iface_n_ip() routines so its easy to loop
over the local interface list

- made readsize a normal loadparm global

- check for null w in add_domain_entry()

- set the deathtime to time()-1 for doamin entries with servertype==0
This allows servers that are shutting down to be removed

- add the 0x1c name at startup if we are a WINS server. Previously we
added it only if we were a master

- loop over interfaces in add_my_domains(), so people don't have to
have a lmhosts file to get lp_workgroup() on all interfaces

- set add to True for find_workgroupstruct() in nmbsync, and check for
null return

- remove some ugly "errno = EBADF" bits. they just confused things.

12 files changed:
source/include/proto.h
source/lib/interface.c
source/lib/util.c
source/loadparm.h
source/namedb.c
source/nameelect.c
source/nameserv.c
source/namework.c
source/nmbd/nmbd.c
source/nmbsync.c
source/param/loadparm.c
source/smbd/predict.c [new file with mode: 0644]

index 2c7cb8a12690673c515617d8e0ed97c9181e0c71..77c7129b2adcc885325ac6ab85d57c51cc828b26 100644 (file)
@@ -67,6 +67,8 @@ void load_interfaces(void);
 void iface_set_default(char *ip,char *bcast,char *nmask);
 BOOL ismyip(struct in_addr ip);
 BOOL ismybcast(struct in_addr bcast);
+int iface_count(void);
+struct in_addr *iface_n_ip(int n);
 struct in_addr *iface_bcast(struct in_addr ip);
 struct in_addr *iface_nmask(struct in_addr ip);
 struct in_addr *iface_ip(struct in_addr ip);
@@ -197,7 +199,7 @@ void sync_server(enum cmd_type cmd, char *serv_name, char *work_name,
                 int name_type,
                 struct in_addr ip);
 void update_from_reg(char *name, int type, struct in_addr ip);
-void add_my_domains(void);
+void add_my_domains(char *group);
 BOOL same_context(struct dgram_packet *dgram);
 BOOL listening_name(struct work_record *work, struct nmb_name *n);
 void process_logon_packet(struct packet_struct *p,char *buf,int len);
@@ -239,6 +241,9 @@ BOOL server_cryptkey(char *buf);
 BOOL server_validate(char *buf);
 BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
 void pcap_printer_fn(void (*fn)());
+int read_predict(int fd,int offset,char *buf,char **ptr,int num);
+void do_read_prediction();
+void invalidate_read_prediction(int fd);
 void lpq_reset(int snum);
 void print_file(int fnum);
 int get_printqueue(int snum,int cnum,print_queue_struct **queue,
@@ -457,9 +462,6 @@ int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew);
 BOOL send_keepalive(int client);
 int read_data(int fd,char *buffer,int N);
 int write_data(int fd,char *buffer,int N);
-int read_predict(int fd,int offset,char *buf,char **ptr,int num);
-void do_read_prediction();
-void invalidate_read_prediction(int fd);
 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align);
 int read_smb_length(int fd,char *inbuf,int timeout);
 BOOL receive_smb(int fd,char *buffer,int timeout);
index a47ef6e47e78dabbe470d13a2453574d96e225e6..f2a535d80cd4837429aa97cb40d6f00a929bf8ee 100644 (file)
@@ -388,6 +388,33 @@ BOOL ismybcast(struct in_addr bcast)
   return False;
 }
 
+/****************************************************************************
+  how many interfaces do we have
+  **************************************************************************/
+int iface_count(void)
+{
+  int ret = 0;
+  struct interface *i;
+
+  for (i=interfaces;i;i=i->next)
+    ret++;
+  return ret;
+}
+
+/****************************************************************************
+  return IP of the Nth interface
+  **************************************************************************/
+struct in_addr *iface_n_ip(int n)
+{
+  struct interface *i;
+  
+  for (i=interfaces;i && n;i=i->next)
+    n--;
+
+  if (i) return &i->ip;
+  return NULL;
+}
+
 static struct interface *iface_find(struct in_addr ip)
 {
   struct interface *i;
index 6cc9a7e1722ca1b9088cd893492d40f7ae1017fe..cfe8ea05b09f6f8dae8875d9a00f41aaafcbee76 100644 (file)
@@ -56,10 +56,6 @@ int trans_num = 0;
 */
 int case_default = CASE_LOWER;
 
-
-/* size of reads during a direct file to file transfer */
-int ReadSize = 16*1024;
-
 pstring debugf = "/tmp/log.samba";
 int syslog_level;
 
@@ -1951,7 +1947,6 @@ int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL
       
       /* Check if error */
       if(selrtn == -1) {
-       errno = EBADF;
        return -1;
       }
       
@@ -1974,7 +1969,6 @@ int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL
        /* force a particular error number for
           portability */
        DEBUG(5,("read gave error %s\n",strerror(errno)));
-       errno = EBADF;
        return -1;
       }
       
@@ -2068,10 +2062,6 @@ int read_data(int fd,char *buffer,int N)
     {
       ret = read(fd,buffer + total,N - total);
 
-      /* this is for portability */
-      if (ret < 0)
-       errno = EBADF;
-
       if (ret <= 0)
        return total;
       total += ret;
@@ -2101,142 +2091,28 @@ int write_data(int fd,char *buffer,int N)
 }
 
 
-/* variables used by the read prediction module */
-int rp_fd = -1;
-int rp_offset = 0;
-int rp_length = 0;
-int rp_alloced = 0;
-int rp_predict_fd = -1;
-int rp_predict_offset = 0;
-int rp_predict_length = 0;
-int rp_timeout = 5;
-time_t rp_time = 0;
-char *rp_buffer = NULL;
-BOOL predict_skip=False;
-time_t smb_last_time=(time_t)0;
-
-/****************************************************************************
-handle read prediction on a file
-****************************************************************************/
-int read_predict(int fd,int offset,char *buf,char **ptr,int num)
-{
-  int ret = 0;
-  int possible = rp_length - (offset - rp_offset);
-
-  possible = MIN(possible,num);
-
-  /* give data if possible */
-  if (fd == rp_fd && 
-      offset >= rp_offset && 
-      possible>0 &&
-      smb_last_time-rp_time < rp_timeout)
-    {
-      ret = possible;
-      if (buf)
-       memcpy(buf,rp_buffer + (offset-rp_offset),possible);
-      else
-       *ptr = rp_buffer + (offset-rp_offset);
-      DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
-    }
-
-  if (ret == num) {
-    predict_skip = True;
-  } else {
-    predict_skip = False;
-
-    /* prepare the next prediction */
-    rp_predict_fd = fd;
-    rp_predict_offset = offset + num;
-    rp_predict_length = num;
-  }
-
-  if (ret < 0) ret = 0;
-
-  return(ret);
-}
-
-/****************************************************************************
-pre-read some data
-****************************************************************************/
-void do_read_prediction()
-{
-  if (predict_skip) return;
-
-  if (rp_predict_fd == -1) 
-    return;
-
-  rp_fd = rp_predict_fd;
-  rp_offset = rp_predict_offset;
-  rp_length = 0;
-
-  rp_predict_fd = -1;
-
-  rp_predict_length = MIN(rp_predict_length,2*ReadSize);
-  rp_predict_length = MAX(rp_predict_length,1024);
-  rp_offset = (rp_offset/1024)*1024;
-  rp_predict_length = (rp_predict_length/1024)*1024;
-
-  if (rp_predict_length > rp_alloced)
-    {
-      rp_buffer = Realloc(rp_buffer,rp_predict_length);
-      rp_alloced = rp_predict_length;
-      if (!rp_buffer)
-       {
-         DEBUG(0,("can't allocate read-prediction buffer\n"));
-         rp_predict_fd = -1;
-         rp_fd = -1;
-         rp_alloced = 0;
-         return;
-       }
-    }
-
-  if (lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
-    rp_fd = -1;
-    rp_predict_fd = -1;
-    return;
-  }
-
-  rp_length = read(rp_fd,rp_buffer,rp_predict_length);
-  rp_time = time(NULL);
-  if (rp_length < 0)
-    rp_length = 0;
-}
-
-/****************************************************************************
-invalidate read-prediction on a fd
-****************************************************************************/
-void invalidate_read_prediction(int fd)
-{
- if (rp_fd == fd) 
-   rp_fd = -1;
- if (rp_predict_fd == fd)
-   rp_predict_fd = -1;
-}
-
-
 /****************************************************************************
 transfer some data between two fd's
 ****************************************************************************/
 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
 {
   static char *buf=NULL;  
+  static int size=0;
   char *buf1,*abuf;
-  static int size = 0;
   int total = 0;
 
   DEBUG(4,("transfer_file %d  (head=%d) called\n",n,headlen));
 
-  if ((size < ReadSize) && buf) {
-    free(buf);
-    buf = NULL;
+  if (size == 0) {
+    size = lp_readsize();
+    size = MAX(size,1024);
   }
 
-  size = MAX(ReadSize,1024);
-
   while (!buf && size>0) {
     buf = (char *)Realloc(buf,size+8);
     if (!buf) size /= 2;
   }
+
   if (!buf) {
     DEBUG(0,("Can't allocate transfer buffer!\n"));
     exit(1);
index 0e39537c9e56d4ce52481a062b23cd473ce01730..780ed633cadd2cca6e141f41055ba079459b7195 100644 (file)
@@ -93,6 +93,7 @@ extern int  lp_maxdisksize(void);
 extern int  lp_lpqcachetime(void);
 extern int  lp_syslog(void);
 extern int  lp_deadtime(void);
+extern int  lp_readsize(void);
 extern int  lp_debuglevel(void);
 extern int  lp_maxprotocol(void);
 extern int  lp_maxpacket(void);
index 2e942587be8081517b11099b888c3ad2687812db..2868d54ac4f53e3aa9624a7581aa8670492cf0e1 100644 (file)
@@ -460,6 +460,8 @@ struct domain_record *add_domain_entry(struct in_addr source_ip,
     {
       struct work_record *w = find_workgroupstruct(d, name, add);
       
+      if (!w) return NULL;
+
       /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
         or register with WINS server, if it's our workgroup */
       if (strequal(lp_workgroup(), name))
@@ -586,7 +588,8 @@ struct server_record *add_server_entry(struct domain_record *d,
   if (ismybcast(d->bcast_ip) &&
       strequal(lp_workgroup(),work->work_group))
     {
-      servertype |= SV_TYPE_LOCAL_LIST_ONLY;
+      if (servertype)
+       servertype |= SV_TYPE_LOCAL_LIST_ONLY;
     }
   else
     {
@@ -599,6 +602,9 @@ struct server_record *add_server_entry(struct domain_record *d,
   strupper(s->serv.name);
   s->serv.type  = servertype;
   s->death_time = ttl?time(NULL)+ttl*3:0;
+
+  if (servertype == 0)
+    s->death_time = time(NULL)-1;
   
   /* for a domain entry, the comment field refers to the server name */
   
index a78c8483c5d4440e70bdae524e2d70e25d3e43e4..765791b80f28c9948517001e8e443422c70219db 100644 (file)
@@ -178,8 +178,6 @@ static void become_master(struct domain_record *d, struct work_record *work)
       
       /* add domain master and domain member names or register with WINS */
       add_name_entry(work->work_group,0x1b,NB_ACTIVE         );
-      add_name_entry(work->work_group,0x1c,NB_ACTIVE|NB_GROUP);
-      
       work->ServerType |= SV_TYPE_DOMAIN_MASTER;
       
       if (lp_domain_logons())
@@ -215,7 +213,6 @@ void become_nonmaster(struct domain_record *d, struct work_record *work)
   work->ElectionCriterion &= ~0x4;
   
   remove_name_entry(work->work_group,0x1b);
-  remove_name_entry(work->work_group,0x1c);
   remove_name_entry(work->work_group,0x1d);
   remove_name_entry(MSBROWSE        ,0x01);
 }
index ba61dd34173d9b11aee34ed4864d99ae69c576a3..69be6b0131dd69b0a170348387b017327dbeb052 100644 (file)
@@ -267,6 +267,11 @@ void add_my_names(void)
   add_netbios_entry("*",0x0,NB_ACTIVE,0,SELF,ip,False);
   add_netbios_entry("__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False);
   add_netbios_entry("__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False);
+
+  if (lp_wins_support()) {
+    /* the 0x1c name gets added by any WINS server it seems */
+    add_name_entry(my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);      
+  }
 }
 
 /*******************************************************************
index cbf65a955fc8abdab57fd24c3b0eea90d20a5800..5e61ecefb448b9626e198cc104938219a49a98c8 100644 (file)
@@ -270,16 +270,19 @@ void update_from_reg(char *name, int type, struct in_addr ip)
 /****************************************************************************
   add the default workgroup into my domain
   **************************************************************************/
-void add_my_domains(void)
+void add_my_domains(char *group)
 {
-  /* add or find domain on our local subnet, in the default workgroup */
-  
-  if (*lp_workgroup() != '*')
-    {
-      add_domain_entry(*iface_bcast(ipzero),
-                      *iface_nmask(ipzero),
-                      lp_workgroup(), True);
-    }
+  int n,i;
+  struct in_addr *ip;
+
+  if (*group == '*') return;
+
+  n = iface_count();
+  for (i=0;i<n;i++) {
+    ip = iface_n_ip(i);
+    if (!ip) return;
+    add_domain_entry(*iface_bcast(*ip),*iface_nmask(*ip),lp_workgroup(),True);
+  }
 }
 
 
@@ -728,7 +731,7 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
          struct work_record *work;
          for (work=d->workgrouplist;work;work=remove_workgroup(d,work));
        }
-      add_my_domains();
+      add_my_domains(lp_workgroup());
     }
   
   /* stop browsing altogether. i don't think this is a good idea! */
index b93ac2d580b417ee153604d1577962e8a010d3ee..cd2ebb0521fbdab085d4256d7de0d4941aa7e14a 100644 (file)
@@ -492,7 +492,7 @@ static void usage(char *pname)
     return(-1);        
 
   if (*group)
-    add_domain_entry(*iface_bcast(ipzero),*iface_nmask(ipzero),group, True);
+    add_my_domains(group);
 
   if (!is_daemon && !is_a_socket(0)) {
     DEBUG(0,("standard input is not a socket, assuming -D option\n"));
@@ -519,7 +519,7 @@ static void usage(char *pname)
   string_sub(ServerComment,"%h",myhostname);
 
   add_my_names();
-  add_my_domains();
+  add_my_domains(lp_workgroup());
 
   DEBUG(3,("Checked names\n"));
   
index e86e8d53eb71c38e1d6c6f47a5717add168c558f..c9e0dfc4628f07a1e6268d19b2ba614357e1fa98 100644 (file)
@@ -103,7 +103,6 @@ static BOOL add_info(struct domain_record *d, struct work_record *work, int serv
              uint32 stype = IVAL(p,18);
              int comment_offset = IVAL(p,22) & 0xFFFF;
              char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
-             
              struct work_record *w = work;
              
              DEBUG(4, ("\t%-16.16s     %08x    %s\n", sname, stype, cmnt));
@@ -111,16 +110,17 @@ static BOOL add_info(struct domain_record *d, struct work_record *work, int serv
              if (stype & SV_TYPE_DOMAIN_ENUM)
                {
                  /* creates workgroup on remote subnet */
-                 if ((w = find_workgroupstruct(d,sname, False)))
+                 if ((w = find_workgroupstruct(d,sname, True)))
                    {
                      if (ismybcast(d->bcast_ip))
                        {
                          announce_request(w, d->bcast_ip);
                        }
                    }
-               }
+               }             
              
-             add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
+             if (w)
+               add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
            }
        }
     }
index 876385ab18b277067091485981a874662da12311..fcd70b4b75e812afd392f5241616f82c0bb81c30 100644 (file)
@@ -56,7 +56,6 @@
 BOOL bLoaded = False;
 
 extern int DEBUGLEVEL;
-extern int ReadSize;
 extern pstring user_socket_options;
 
 #ifndef GLOBAL_NAME
@@ -149,6 +148,7 @@ typedef struct
   int syslog;
   int os_level;
   int max_ttl;
+  int ReadSize;
   BOOL bWINSsupport;
   BOOL bWINSproxy;
   BOOL bPreferredMaster;
@@ -409,7 +409,7 @@ struct parm_struct
   {"keepalive",        P_INTEGER, P_GLOBAL, &keepalive,                 NULL},
   {"deadtime",         P_INTEGER, P_GLOBAL, &Globals.deadtime,          NULL},
   {"time offset",      P_INTEGER, P_GLOBAL, &extra_time_offset,         NULL},
-  {"read size",        P_INTEGER, P_GLOBAL, &ReadSize,                  NULL},
+  {"read size",        P_INTEGER, P_GLOBAL, &Globals.ReadSize,          NULL},
 #ifdef KANJI
   {"coding system",    P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system},
 #endif /* KANJI */
@@ -582,6 +582,7 @@ static void init_globals(void)
   Globals.bBrowseList = True;
   Globals.bWINSsupport = True;
   Globals.bWINSproxy = False;
+  Globals.ReadSize = 16*1024;
 
 #ifdef KANJI
   coding_system = interpret_coding_system (KANJI, SJIS_CODE);
@@ -735,6 +736,7 @@ FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
+FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
diff --git a/source/smbd/predict.c b/source/smbd/predict.c
new file mode 100644 (file)
index 0000000..8df381b
--- /dev/null
@@ -0,0 +1,146 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   file read prediction routines
+   Copyright (C) Andrew Tridgell 1992-1995
+   
+   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"
+#include "loadparm.h"
+
+extern int DEBUGLEVEL;
+
+
+/* variables used by the read prediction module */
+static int rp_fd = -1;
+static int rp_offset = 0;
+static int rp_length = 0;
+static int rp_alloced = 0;
+static int rp_predict_fd = -1;
+static int rp_predict_offset = 0;
+static int rp_predict_length = 0;
+static int rp_timeout = 5;
+static time_t rp_time = 0;
+static char *rp_buffer = NULL;
+static BOOL predict_skip=False;
+time_t smb_last_time=(time_t)0;
+
+/****************************************************************************
+handle read prediction on a file
+****************************************************************************/
+int read_predict(int fd,int offset,char *buf,char **ptr,int num)
+{
+  int ret = 0;
+  int possible = rp_length - (offset - rp_offset);
+
+  possible = MIN(possible,num);
+
+  /* give data if possible */
+  if (fd == rp_fd && 
+      offset >= rp_offset && 
+      possible>0 &&
+      smb_last_time-rp_time < rp_timeout)
+    {
+      ret = possible;
+      if (buf)
+       memcpy(buf,rp_buffer + (offset-rp_offset),possible);
+      else
+       *ptr = rp_buffer + (offset-rp_offset);
+      DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
+    }
+
+  if (ret == num) {
+    predict_skip = True;
+  } else {
+    predict_skip = False;
+
+    /* prepare the next prediction */
+    rp_predict_fd = fd;
+    rp_predict_offset = offset + num;
+    rp_predict_length = num;
+  }
+
+  if (ret < 0) ret = 0;
+
+  return(ret);
+}
+
+/****************************************************************************
+pre-read some data
+****************************************************************************/
+void do_read_prediction()
+{
+  static int readsize = 0;
+
+  if (predict_skip) return;
+
+  if (rp_predict_fd == -1) 
+    return;
+
+  rp_fd = rp_predict_fd;
+  rp_offset = rp_predict_offset;
+  rp_length = 0;
+
+  rp_predict_fd = -1;
+
+  if (readsize == 0) {
+    readsize = lp_readsize();
+    readsize = MAX(readsize,1024);
+  }
+
+  rp_predict_length = MIN(rp_predict_length,2*readsize);
+  rp_predict_length = MAX(rp_predict_length,1024);
+  rp_offset = (rp_offset/1024)*1024;
+  rp_predict_length = (rp_predict_length/1024)*1024;
+
+  if (rp_predict_length > rp_alloced)
+    {
+      rp_buffer = Realloc(rp_buffer,rp_predict_length);
+      rp_alloced = rp_predict_length;
+      if (!rp_buffer)
+       {
+         DEBUG(0,("can't allocate read-prediction buffer\n"));
+         rp_predict_fd = -1;
+         rp_fd = -1;
+         rp_alloced = 0;
+         return;
+       }
+    }
+
+  if (lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
+    rp_fd = -1;
+    rp_predict_fd = -1;
+    return;
+  }
+
+  rp_length = read(rp_fd,rp_buffer,rp_predict_length);
+  rp_time = time(NULL);
+  if (rp_length < 0)
+    rp_length = 0;
+}
+
+/****************************************************************************
+invalidate read-prediction on a fd
+****************************************************************************/
+void invalidate_read_prediction(int fd)
+{
+ if (rp_fd == fd) 
+   rp_fd = -1;
+ if (rp_predict_fd == fd)
+   rp_predict_fd = -1;
+}
+