summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h10
-rw-r--r--source3/lib/interface.c27
-rw-r--r--source3/lib/util.c134
-rw-r--r--source3/loadparm.h1
-rw-r--r--source3/namedb.c8
-rw-r--r--source3/nameelect.c3
-rw-r--r--source3/nameserv.c5
-rw-r--r--source3/namework.c23
-rw-r--r--source3/nmbd/nmbd.c4
-rw-r--r--source3/nmbsync.c8
-rw-r--r--source3/param/loadparm.c6
-rw-r--r--source3/smbd/predict.c146
12 files changed, 220 insertions, 155 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 2c7cb8a126..77c7129b2a 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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);
diff --git a/source3/lib/interface.c b/source3/lib/interface.c
index a47ef6e47e..f2a535d80c 100644
--- a/source3/lib/interface.c
+++ b/source3/lib/interface.c
@@ -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;
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 6cc9a7e172..cfe8ea05b0 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -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);
diff --git a/source3/loadparm.h b/source3/loadparm.h
index 0e39537c9e..780ed633ca 100644
--- a/source3/loadparm.h
+++ b/source3/loadparm.h
@@ -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);
diff --git a/source3/namedb.c b/source3/namedb.c
index 2e942587be..2868d54ac4 100644
--- a/source3/namedb.c
+++ b/source3/namedb.c
@@ -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 */
diff --git a/source3/nameelect.c b/source3/nameelect.c
index a78c8483c5..765791b80f 100644
--- a/source3/nameelect.c
+++ b/source3/nameelect.c
@@ -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);
}
diff --git a/source3/nameserv.c b/source3/nameserv.c
index ba61dd3417..69be6b0131 100644
--- a/source3/nameserv.c
+++ b/source3/nameserv.c
@@ -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);
+ }
}
/*******************************************************************
diff --git a/source3/namework.c b/source3/namework.c
index cbf65a955f..5e61ecefb4 100644
--- a/source3/namework.c
+++ b/source3/namework.c
@@ -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! */
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index b93ac2d580..cd2ebb0521 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -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"));
diff --git a/source3/nmbsync.c b/source3/nmbsync.c
index e86e8d53eb..c9e0dfc462 100644
--- a/source3/nmbsync.c
+++ b/source3/nmbsync.c
@@ -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);
}
}
}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 876385ab18..fcd70b4b75 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -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/source3/smbd/predict.c b/source3/smbd/predict.c
new file mode 100644
index 0000000000..8df381b367
--- /dev/null
+++ b/source3/smbd/predict.c
@@ -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;
+}
+