sorted out various timer delay bugs: nameannounce.c nameserv.c
[samba.git] / source / namedbserver.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines and daemon - version 2
5    Copyright (C) Andrew Tridgell 1994-1996
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21    Revision History:
22
23    14 jan 96: lkcl@pires.co.uk
24    added multiple workgroup domain master support
25
26    04 jul 96: lkcl@pires.co.uk
27    created module namedbserver containing server database functions
28
29 */
30
31 #include "includes.h"
32 #include "smb.h"
33
34 extern int ClientNMB;
35 extern int ClientDGRAM;
36
37 extern int DEBUGLEVEL;
38
39 extern pstring myname;
40
41 /* this is our domain/workgroup/server database */
42 extern struct subnet_record *subnetlist;
43
44 extern BOOL updatedlists;
45
46
47 /*******************************************************************
48   expire old servers in the serverlist
49   time of -1 indicates everybody dies except those with time of 0
50   remove_all_servers indicates everybody dies.
51   ******************************************************************/
52 void remove_old_servers(struct work_record *work, time_t t,
53                                         BOOL remove_all)
54 {
55   struct server_record *s;
56   struct server_record *nexts;
57   
58   /* expire old entries in the serverlist */
59   for (s = work->serverlist; s; s = nexts)
60     {
61       if (remove_all || (s->death_time && (t == -1 || s->death_time < t)))
62         {
63           DEBUG(3,("Removing dead server %s\n",s->serv.name));
64           updatedlists = True;
65           nexts = s->next;
66           
67           if (s->prev) s->prev->next = s->next;
68           if (s->next) s->next->prev = s->prev;
69           
70           if (work->serverlist == s) 
71             work->serverlist = s->next; 
72
73           free(s);
74         }
75       else
76         {
77           nexts = s->next;
78         }
79     }
80 }
81
82
83 /***************************************************************************
84   add a server into the list
85   **************************************************************************/
86 static void add_server(struct work_record *work,struct server_record *s)
87 {
88   struct server_record *s2;
89
90   if (!work->serverlist) {
91     work->serverlist = s;
92     s->prev = NULL;
93     s->next = NULL;
94     return;
95   }
96
97   for (s2 = work->serverlist; s2->next; s2 = s2->next) ;
98
99   s2->next = s;
100   s->next = NULL;
101   s->prev = s2;
102 }
103
104
105 /****************************************************************************
106   add a server entry
107   ****************************************************************************/
108 struct server_record *add_server_entry(struct subnet_record *d, 
109                                        struct work_record *work,
110                                        char *name,int servertype, 
111                                        int ttl,char *comment,
112                                        BOOL replace)
113 {
114   BOOL newentry=False;
115   struct server_record *s;
116   
117   if (name[0] == '*')
118     {
119       return (NULL);
120     }
121   
122   for (s = work->serverlist; s; s = s->next)
123     {
124       if (strequal(name,s->serv.name)) break;
125     }
126   
127   if (s && !replace)
128     {
129       DEBUG(4,("Not replacing %s\n",name));
130       return(s);
131     }
132   
133   if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment))
134     updatedlists=True;
135
136   if (!s)
137     {
138       newentry = True;
139       s = (struct server_record *)malloc(sizeof(*s));
140       
141       if (!s) return(NULL);
142       
143       bzero((char *)s,sizeof(*s));
144     }
145   
146   
147   if (d->my_interface && strequal(lp_workgroup(),work->work_group))
148     {
149           if (servertype)
150         servertype |= SV_TYPE_LOCAL_LIST_ONLY;
151     }
152   else
153     {
154       servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
155     }
156   
157   /* update the entry */
158   StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
159   StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
160   strupper(s->serv.name);
161   s->serv.type  = servertype;
162   s->death_time = servertype ? (ttl?time(NULL)+ttl*3:0) : (time(NULL)-1);
163   
164   /* for a domain entry, the comment field refers to the server name */
165   
166   if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
167   
168   if (newentry)
169     {
170       add_server(work, s);
171       
172       DEBUG(3,("Added "));
173     }
174   else
175     {
176       DEBUG(3,("Updated "));
177     }
178   
179   DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
180            name,servertype,comment,
181            work->work_group,inet_ntoa(d->bcast_ip)));
182   
183   return(s);
184 }
185
186
187 /*******************************************************************
188   expire old servers in the serverlist
189   ******************************************************************/
190 void expire_servers(time_t t)
191 {
192   struct subnet_record *d;
193   
194   for (d = subnetlist ; d ; d = d->next)
195     {
196       struct work_record *work;
197       
198       for (work = d->workgrouplist; work; work = work->next)
199         {
200           remove_old_servers(work, t, False);
201         }
202     }
203 }
204