JHT ===> Added comment about internationaliasation and deleted dates.
[ira/wip.git] / source3 / 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-1997
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 extern fstring myworkgroup;
41
42 /* this is our domain/workgroup/server database */
43 extern struct subnet_record *subnetlist;
44
45 extern BOOL updatedlists;
46
47
48 /*******************************************************************
49   expire old servers in the serverlist
50   time of -1 indicates everybody dies except those with time of 0
51   remove_all_servers indicates everybody dies.
52   ******************************************************************/
53 void remove_old_servers(struct work_record *work, time_t t,
54                                         BOOL remove_all)
55 {
56   struct server_record *s;
57   struct server_record *nexts;
58   
59   /* expire old entries in the serverlist */
60   for (s = work->serverlist; s; s = nexts)
61     {
62       if (remove_all || (s->death_time && (t == -1 || s->death_time < t)))
63         {
64           DEBUG(3,("Removing dead server %s\n",s->serv.name));
65           updatedlists = True;
66           nexts = s->next;
67           
68           if (s->prev) s->prev->next = s->next;
69           if (s->next) s->next->prev = s->prev;
70           
71           if (work->serverlist == s) 
72             work->serverlist = s->next; 
73
74           free(s);
75         }
76       else
77         {
78           nexts = s->next;
79         }
80     }
81 }
82
83
84 /***************************************************************************
85   add a server into the list
86   **************************************************************************/
87 static void add_server(struct work_record *work,struct server_record *s)
88 {
89   struct server_record *s2;
90
91   if (!work->serverlist) {
92     work->serverlist = s;
93     s->prev = NULL;
94     s->next = NULL;
95     return;
96   }
97
98   for (s2 = work->serverlist; s2->next; s2 = s2->next) ;
99
100   s2->next = s;
101   s->next = NULL;
102   s->prev = s2;
103 }
104
105
106 /****************************************************************************
107   find a server in a server list.
108   **************************************************************************/
109 struct server_record *find_server(struct work_record *work, char *name)
110 {
111         struct server_record *ret;
112   
113         if (!work) return NULL;
114
115         for (ret = work->serverlist; ret; ret = ret->next)
116         {
117                 if (strequal(ret->serv.name,name))
118                 {
119                         return ret;
120                 }
121         }
122     return NULL;
123 }
124
125
126 /****************************************************************************
127   add a server entry
128   ****************************************************************************/
129 struct server_record *add_server_entry(struct subnet_record *d, 
130                                        struct work_record *work,
131                                        char *name,int servertype, 
132                                        int ttl,char *comment,
133                                        BOOL replace)
134 {
135   BOOL newentry=False;
136   struct server_record *s;
137   
138   if (name[0] == '*')
139   {
140       return (NULL);
141   }
142   
143   s = find_server(work, name);
144
145   if (s && !replace)
146   {
147     DEBUG(4,("Not replacing %s\n",name));
148     return(s);
149   }
150   
151   if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment))
152     updatedlists=True;
153
154   if (!s)
155   {
156     newentry = True;
157     s = (struct server_record *)malloc(sizeof(*s));
158       
159     if (!s) return(NULL);
160       
161     bzero((char *)s,sizeof(*s));
162   }
163   
164   
165   /* update the entry */
166   StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
167   StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
168   strupper(s->serv.name);
169   s->serv.type  = servertype;
170   s->death_time = servertype ? (ttl?time(NULL)+ttl*3:0) : (time(NULL)-1);
171   
172   /* for a domain entry, the comment field refers to the server name */
173   
174   if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
175   
176   if (newentry)
177     {
178       add_server(work, s);
179       
180       DEBUG(3,("Added "));
181     }
182   else
183     {
184       DEBUG(3,("Updated "));
185     }
186   
187   DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
188            name,servertype,comment,
189            work->work_group,inet_ntoa(d->bcast_ip)));
190   
191   return(s);
192 }
193
194
195 /*******************************************************************
196   expire old servers in the serverlist
197   ******************************************************************/
198 void expire_servers(time_t t)
199 {
200   struct subnet_record *d;
201   
202   for (d = FIRST_SUBNET; d ; d = NEXT_SUBNET_INCLUDING_WINS(d))
203     {
204       struct work_record *work;
205       
206       for (work = d->workgrouplist; work; work = work->next)
207         {
208           remove_old_servers(work, t, False);
209         }
210     }
211 }
212