summaryrefslogtreecommitdiff
path: root/source/namedbserver.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/namedbserver.c')
-rw-r--r--source/namedbserver.c221
1 files changed, 221 insertions, 0 deletions
diff --git a/source/namedbserver.c b/source/namedbserver.c
new file mode 100644
index 00000000000..afb1dc14315
--- /dev/null
+++ b/source/namedbserver.c
@@ -0,0 +1,221 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NBT netbios routines and daemon - version 2
+ Copyright (C) Andrew Tridgell 1994-1996
+
+ 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.
+
+ Revision History:
+
+ 14 jan 96: lkcl@pires.co.uk
+ added multiple workgroup domain master support
+
+ 04 jul 96: lkcl@pires.co.uk
+ created module namedbserver containing server database functions
+
+*/
+
+#include "includes.h"
+#include "smb.h"
+
+extern int ClientNMB;
+extern int ClientDGRAM;
+
+extern int DEBUGLEVEL;
+
+extern pstring myname;
+
+/* this is our domain/workgroup/server database */
+extern struct subnet_record *subnetlist;
+
+extern BOOL updatedlists;
+
+
+/*******************************************************************
+ expire old servers in the serverlist
+ time of -1 indicates everybody dies except those with time of 0
+ remove_all_servers indicates everybody dies.
+ ******************************************************************/
+void remove_old_servers(struct work_record *work, time_t t,
+ BOOL remove_all)
+{
+ struct server_record *s;
+ struct server_record *nexts;
+
+ /* expire old entries in the serverlist */
+ for (s = work->serverlist; s; s = nexts)
+ {
+ if (remove_all || (s->death_time && (t == -1 || s->death_time < t)))
+ {
+ DEBUG(3,("Removing dead server %s\n",s->serv.name));
+ updatedlists = True;
+ nexts = s->next;
+
+ if (s->prev) s->prev->next = s->next;
+ if (s->next) s->next->prev = s->prev;
+
+ if (work->serverlist == s)
+ work->serverlist = s->next;
+
+ free(s);
+ }
+ else
+ {
+ nexts = s->next;
+ }
+ }
+}
+
+
+/***************************************************************************
+ add a server into the list
+ **************************************************************************/
+static void add_server(struct work_record *work,struct server_record *s)
+{
+ struct server_record *s2;
+
+ if (!work->serverlist) {
+ work->serverlist = s;
+ s->prev = NULL;
+ s->next = NULL;
+ return;
+ }
+
+ for (s2 = work->serverlist; s2->next; s2 = s2->next) ;
+
+ s2->next = s;
+ s->next = NULL;
+ s->prev = s2;
+}
+
+
+/****************************************************************************
+ find a server in a server list.
+ **************************************************************************/
+struct server_record *find_server(struct work_record *work, char *name)
+{
+ struct server_record *ret;
+
+ if (!work) return NULL;
+
+ for (ret = work->serverlist; ret; ret = ret->next)
+ {
+ if (strequal(ret->serv.name,name))
+ {
+ return ret;
+ }
+ }
+ return NULL;
+}
+
+
+/****************************************************************************
+ add a server entry
+ ****************************************************************************/
+struct server_record *add_server_entry(struct subnet_record *d,
+ struct work_record *work,
+ char *name,int servertype,
+ int ttl,char *comment,
+ BOOL replace)
+{
+ BOOL newentry=False;
+ struct server_record *s;
+
+ if (name[0] == '*')
+ {
+ return (NULL);
+ }
+
+ s = find_server(work, name);
+
+ if (s && !replace)
+ {
+ DEBUG(4,("Not replacing %s\n",name));
+ return(s);
+ }
+
+ if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment))
+ updatedlists=True;
+
+ if (!s)
+ {
+ newentry = True;
+ s = (struct server_record *)malloc(sizeof(*s));
+
+ if (!s) return(NULL);
+
+ bzero((char *)s,sizeof(*s));
+ }
+
+
+ if (strequal(lp_workgroup(),work->work_group))
+ {
+ if (servertype)
+ servertype |= SV_TYPE_LOCAL_LIST_ONLY;
+ }
+ else
+ {
+ servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
+ }
+
+ /* update the entry */
+ StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
+ StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
+ strupper(s->serv.name);
+ s->serv.type = servertype;
+ s->death_time = servertype ? (ttl?time(NULL)+ttl*3:0) : (time(NULL)-1);
+
+ /* for a domain entry, the comment field refers to the server name */
+
+ if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
+
+ if (newentry)
+ {
+ add_server(work, s);
+
+ DEBUG(3,("Added "));
+ }
+ else
+ {
+ DEBUG(3,("Updated "));
+ }
+
+ DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
+ name,servertype,comment,
+ work->work_group,inet_ntoa(d->bcast_ip)));
+
+ return(s);
+}
+
+
+/*******************************************************************
+ expire old servers in the serverlist
+ ******************************************************************/
+void expire_servers(time_t t)
+{
+ struct subnet_record *d;
+
+ for (d = subnetlist ; d ; d = d->next)
+ {
+ struct work_record *work;
+
+ for (work = d->workgrouplist; work; work = work->next)
+ {
+ remove_old_servers(work, t, False);
+ }
+ }
+}
+