28
28
* File Description:
29
29
* Top-level API to resolve NCBI service name to the server meta-address.
31
* --------------------------------------------------------------------------
32
* $Log: ncbi_service.c,v $
33
* Revision 6.32 2001/11/09 20:03:14 lavr
34
* Minor fix to remove a trailing space in client version tag
36
* Revision 6.31 2001/10/01 19:52:38 lavr
37
* Call update directly; do not remove time from server specs in SERV_Print()
39
* Revision 6.30 2001/09/29 19:33:04 lavr
40
* BUGFIX: SERV_Update() requires VT bound (was not the case in constructor)
42
* Revision 6.29 2001/09/28 22:03:12 vakatov
43
* Included missing <connect/ncbi_ansi_ext.h>
45
* Revision 6.28 2001/09/28 20:50:16 lavr
46
* SERV_Update() modified to capture Used-Server-Info tags;
47
* Update VT method changed - now called on per-line basis;
48
* Few bugfixes related to keeping last info correct
50
* Revision 6.27 2001/09/24 20:28:48 lavr
51
* +SERV_Reset(); SERV_Close() changed to utilize SERV_Reset()
53
* Revision 6.26 2001/09/10 21:19:48 lavr
54
* SERV_Print(): Client version tag added
55
* SERV_OpenEx(): Firewall type handling
57
* Revision 6.25 2001/08/20 21:58:19 lavr
58
* Parameter change for clarity: info -> net_info if type is SConnNetInfo
60
* Revision 6.24 2001/06/25 15:35:54 lavr
61
* Added function: SERV_GetNextInfoEx
63
* Revision 6.23 2001/06/20 17:27:49 kans
64
* include <time.h> for Mac compiler
66
* Revision 6.22 2001/06/19 19:12:01 lavr
67
* Type change: size_t -> TNCBI_Size; time_t -> TNCBI_Time
69
* Revision 6.21 2001/05/24 21:28:12 lavr
70
* Timeout for skip servers increased to 1 year period
72
* Revision 6.20 2001/05/17 15:02:51 lavr
75
* Revision 6.19 2001/04/24 21:37:26 lavr
76
* New code for: SERV_MapperName() and SERV_Penalize().
78
* Revision 6.18 2001/03/21 21:23:30 lavr
79
* Explicit type conversion size_t -> unsigned in printf
81
* Revision 6.17 2001/03/20 22:03:32 lavr
82
* BUGFIX in SERV_Print (miscalculation of buflen for accepted server types)
84
* Revision 6.16 2001/03/06 23:55:25 lavr
85
* SOCK_gethostaddr -> SOCK_gethostbyname
87
* Revision 6.15 2001/03/05 23:10:29 lavr
88
* SERV_WriteInfo takes only one argument now
90
* Revision 6.14 2001/03/02 20:09:51 lavr
91
* Support added for SERV_LOCALHOST as preferred_host.
93
* Revision 6.13 2001/03/01 00:31:23 lavr
94
* SERV_OpenSimple now builds SConnNetInfo to use both LBSMD and DISPD.CGI
96
* Revision 6.12 2001/02/09 17:33:06 lavr
97
* Modified: fSERV_StatelessOnly overrides info->stateless
99
* Revision 6.11 2001/01/25 17:05:32 lavr
100
* Bugfix in SERV_OpenEx: op was not inited to 0
102
* Revision 6.10 2001/01/08 23:47:29 lavr
103
* (unsigned char) conversion in isspace
105
* Revision 6.9 2001/01/08 22:38:34 lavr
106
* Numerous patches to code after debugging
108
* Revision 6.8 2000/12/29 18:01:27 lavr
109
* SERV_Print introduced; pool of skipped services now follows
110
* expiration times of services and is updated on that basis.
112
* Revision 6.7 2000/12/06 22:20:30 lavr
113
* Skip info list is not maintained forever; instead the entries get
114
* deleted in accordance with their expiration period
116
* Revision 6.6 2000/10/20 17:19:04 lavr
117
* SConnNetInfo made 'const' as a parameter to 'SERV_Open*'
118
* 'SERV_Update' added as a private interface
120
* Revision 6.5 2000/10/05 22:36:21 lavr
121
* Additional parameters in call to DISPD mapper
123
* Revision 6.4 2000/05/31 23:12:23 lavr
124
* First try to assemble things together to get working service mapper
126
* Revision 6.3 2000/05/22 16:53:11 lavr
127
* Rename service_info -> server_info everywhere (including
128
* file names) as the latter name is more relevant
130
* Revision 6.2 2000/05/12 21:42:59 lavr
131
* Cleaned up for the C++ compilation, etc.
133
* Revision 6.1 2000/05/12 18:50:20 lavr
134
* First working revision
136
* ==========================================================================
139
#include "ncbi_servicep.h"
140
#include "ncbi_servicep_lbsmd.h"
141
#include "ncbi_servicep_dispd.h"
142
#include <connect/ncbi_ansi_ext.h>
33
#include "ncbi_ansi_ext.h"
34
#include "ncbi_dispd.h"
35
#include "ncbi_lbsmd.h"
36
#include "ncbi_priv.h"
144
37
#include <ctype.h>
145
38
#include <stdlib.h>
41
#define SERV_SERVICE_NAME "SERVICE_NAME"
44
static char* s_ServiceName(const char* service, size_t depth)
50
if (++depth > 8 || !service || !*service ||
51
sizeof(DEF_CONN_REG_SECTION) + sizeof(SERV_SERVICE_NAME) +
52
strlen(service) >= sizeof(key))
55
strcpy(s, DEF_CONN_REG_SECTION);
56
s += sizeof(DEF_CONN_REG_SECTION) - 1;
58
strcpy(s, SERV_SERVICE_NAME);
59
s += sizeof(SERV_SERVICE_NAME) - 1;
63
/* Looking for "CONN_SERVICE_NAME_service" in environment */
64
if (!(p = getenv(key))) {
66
/* Looking for "CONN_SERVICE_NAME" in registry's section [service] */
67
CORE_REG_GET(service, key, srv, sizeof(srv), 0);
69
return strdup(service);
71
strncpy0(srv, p, sizeof(srv) - 1);
73
/* No cycle detection in service name redefinition */
74
return s_ServiceName(srv, depth);
78
char* SERV_ServiceName(const char* service)
80
return s_ServiceName(service, 0);
150
84
SERV_ITER SERV_OpenSimple(const char* service)
172
123
iter->skip = temp;
173
124
iter->n_max_skip = n;
176
126
iter->skip[iter->n_skip++] = info;
181
SERV_ITER SERV_OpenEx(const char* service,
182
TSERV_Type type, unsigned int preferred_host,
183
const SConnNetInfo* net_info,
184
const SSERV_Info* const skip[], size_t n_skip)
131
static SERV_ITER s_Open(const char* service, TSERV_Type types,
132
unsigned int preferred_host, double preference,
133
const SConnNetInfo* net_info,
134
const SSERV_Info* const skip[], size_t n_skip,
135
SSERV_Info** info, HOST_INFO* host_info, int external)
137
const char* s = s_ServiceName(service, 0);
186
138
const SSERV_VTable* op;
191
if (!service || !*service ||
192
!(iter = (SERV_ITER) malloc(sizeof(*iter) + strlen(service)+1)))
141
if (!s || !*s || !(iter = (SERV_ITER) malloc(sizeof(*iter))))
195
iter->service = (char*) iter + sizeof(*iter);
196
strcpy((char*) iter->service, service);
198
iter->preferred_host =
199
preferred_host == SERV_LOCALHOST
146
iter->preferred_host = preferred_host == SERV_LOCALHOST
200
147
? SOCK_gethostbyname(0) : preferred_host;
201
iter->n_skip = iter->n_max_skip = 0;
148
iter->preference = 0.01*(preference < 0.0 ? 0.0 :
149
preference > 100.0 ? 100.0 : preference);
150
iter->n_skip = iter->n_max_skip = 0;
155
iter->external = external;
207
t = (TNCBI_Time) time(0);
208
for (i = 0; i < n_skip; i++) {
209
size_t infolen = SERV_SizeOfInfo(skip[i]);
210
SSERV_Info* info = (SSERV_Info*) malloc(infolen);
215
memcpy(info, skip[i], infolen);
216
info->time = t + 3600/*hour*/*24/*day*/*365/*year - long enough :-) */;
217
if (!s_AddSkipInfo(iter, info)) {
159
for (i = 0; i < n_skip; i++) {
160
size_t skipinfolen = SERV_SizeOfInfo(skip[i]);
161
SSERV_Info* skipinfo = (SSERV_Info*) malloc(skipinfolen);
166
memcpy(skipinfo, skip[i], skipinfolen);
167
skipinfo->time = (TNCBI_Time)(-1);
168
if (!s_AddSkipInfo(iter, skipinfo)) {
222
174
assert(n_skip == iter->n_skip);
225
if (!(op = SERV_LBSMD_Open(iter))) {
177
if (!(op = SERV_LBSMD_Open(iter, info, host_info))) {
226
178
/* LBSMD failed in non-DISPD mapping */
227
179
SERV_Close(iter);
231
183
if (net_info->stateless)
232
iter->type |= fSERV_StatelessOnly;
184
iter->types |= fSERV_StatelessOnly;
233
185
if (net_info->firewall)
234
iter->type |= fSERV_Firewall;
235
if ((net_info->lb_disable || !(op = SERV_LBSMD_Open(iter))) &&
236
!(op = SERV_DISPD_Open(iter, net_info))) {
186
iter->types |= fSERV_Firewall;
187
if ((net_info->lb_disable ||
188
!(op = SERV_LBSMD_Open(iter, info, host_info))) &&
189
!(op = SERV_DISPD_Open(iter, net_info, info, host_info))) {
237
190
SERV_Close(iter);
201
SERV_ITER SERV_OpenEx(const char* service,
202
TSERV_Type types, unsigned int preferred_host,
203
const SConnNetInfo* net_info,
204
const SSERV_Info* const skip[], size_t n_skip)
206
return s_Open(service, types, preferred_host, 0.0,
207
net_info, skip, n_skip, 0, 0, 0/*not external*/);
211
SERV_ITER SERV_OpenP(const char* service, TSERV_Type types,
212
unsigned int preferred_host, double preference,
213
int/*bool*/ external)
215
return s_Open(service, types, preferred_host, preference,
216
0, 0, 0, 0, 0, external);
220
static SSERV_Info* s_GetInfo(const char* service, TSERV_Type types,
221
unsigned int preferred_host, double preference,
222
const SConnNetInfo* net_info,
223
const SSERV_Info* const skip[], size_t n_skip,
224
HOST_INFO* host_info, int/*bool*/ external)
226
SSERV_Info* info = 0;
227
SERV_ITER iter= s_Open(service, types, preferred_host, preference,
228
net_info, skip, n_skip, &info, host_info, external);
229
if (iter && !info && iter->op && iter->op->GetNextInfo)
230
info = (*iter->op->GetNextInfo)(iter, host_info);
236
SSERV_Info* SERV_GetInfoEx(const char* service, TSERV_Type types,
237
unsigned int preferred_host,
238
const SConnNetInfo* net_info,
239
const SSERV_Info* const skip[], size_t n_skip,
240
HOST_INFO* host_info)
242
return s_GetInfo(service, types, preferred_host, 0.0,
243
net_info, skip, n_skip, host_info, 0/*not external*/);
247
SSERV_Info* SERV_GetInfoP(const char* service, TSERV_Type types,
248
unsigned int preferred_host, double preference,
249
int/*bool*/ external)
251
return s_GetInfo(service, types, preferred_host, preference,
252
0, 0, 0, 0, external);
248
256
static void s_SkipSkip(SERV_ITER iter)
250
TNCBI_Time t = (TNCBI_Time) time(0);
259
TNCBI_Time t = (TNCBI_Time) time(0);
254
while (i < iter->n_skip) {
255
SSERV_Info* info = iter->skip[i];
256
if (info->time < t) {
257
if (i < --iter->n_skip)
258
memmove(iter->skip + i, iter->skip + i + 1,
259
sizeof(*iter->skip)*(iter->n_skip - i));
260
if (info == iter->last)
262
while (n < iter->n_skip) {
263
SSERV_Info* temp = iter->skip[n];
264
if (temp->time < t) {
265
if (n < --iter->n_skip) {
266
memmove(iter->skip + n, iter->skip + n + 1,
267
sizeof(*iter->skip)*(iter->n_skip - n));
269
if (iter->last == temp)
269
const SSERV_Info* SERV_GetNextInfoEx(SERV_ITER iter, char** env)
279
const SSERV_Info* SERV_GetNextInfoEx(SERV_ITER iter, HOST_INFO* host_info)
271
281
SSERV_Info* info = 0;
376
char* SERV_Print(SERV_ITER iter)
391
char* SERV_PrintEx(SERV_ITER iter, const SConnNetInfo* referrer)
378
static const char revision[] = "$Revision: 6.32 $";
379
static const char client_version[] = "Client-Version:";
393
static const char referrer_header[] = "Referer: "/*standard misspelling*/;
394
static const char client_revision[] = "Client-Revision: %hu.%hu\r\n";
380
395
static const char accepted_types[] = "Accepted-Server-Types:";
381
TSERV_Type type = (TSERV_Type) (iter->type & ~fSERV_StatelessOnly);
382
396
char buffer[128], *str;
383
398
size_t buflen, i;
387
401
/* Put client version number */
388
buflen = sizeof(client_version) - 1;
389
memcpy(buffer, client_version, buflen);
390
for (i = 0; revision[i]; i++)
391
if (isspace((unsigned char) revision[i]))
393
while (revision[i] && buflen + 2 < sizeof(buffer)) {
394
if (revision[i] == '$') {
395
if (isspace((unsigned char) revision[i - 1]))
399
buffer[buflen++] = revision[i++];
401
strcpy(&buffer[buflen], "\r\n");
402
assert(strlen(buffer) == buflen + 2 && buflen + 2 < sizeof(buffer));
403
if (!BUF_Write(&buf, buffer, buflen + 2)) {
402
buflen = sprintf(buffer, client_revision,
403
SERV_CLIENT_REVISION_MAJOR, SERV_CLIENT_REVISION_MINOR);
404
assert(buflen < sizeof(buffer));
405
if (!BUF_Write(&buf, buffer, buflen)) {
404
406
BUF_Destroy(buf);
407
/* Form accepted server types */
408
buflen = sizeof(accepted_types) - 1;
409
memcpy(buffer, accepted_types, buflen);
410
for (t = 1; t; t <<= 1) {
412
const char* name = SERV_TypeStr((ESERV_Type) t);
413
size_t namelen = strlen(name);
414
if (!namelen || buflen + 1 + namelen + 2 >= sizeof(buffer))
416
buffer[buflen++] = ' ';
417
strcpy(&buffer[buflen], name);
421
if (buffer[buflen - 1] != ':') {
422
strcpy(&buffer[buflen], "\r\n");
423
assert(strlen(buffer) == buflen + 2 && buflen + 2 < sizeof(buffer));
424
if (!BUF_Write(&buf, buffer, buflen + 2)) {
410
int/*bool*/ refer = referrer && iter->op && iter->op->name;
411
if (refer && strcasecmp(iter->op->name, "DISPD") == 0) {
412
const char* host = referrer->host;
413
const char* path = referrer->path;
414
const char* args = referrer->args;
415
const char* service = iter->service;
417
if (referrer->port && referrer->port != DEF_CONN_PORT)
418
sprintf(port, ":%hu", referrer->port);
421
if (!BUF_Write(&buf, referrer_header, sizeof(referrer_header)-1) ||
422
!BUF_Write(&buf, "http://", 7) ||
423
!BUF_Write(&buf, host, strlen(host)) ||
424
!BUF_Write(&buf, port, strlen(port)) ||
425
!BUF_Write(&buf, path, strlen(path)) ||
426
!BUF_Write(&buf, "?service=", 9) ||
427
!BUF_Write(&buf, service, strlen(service)) ||
428
(args[0] && (!BUF_Write(&buf, "&", 1) ||
429
!BUF_Write(&buf, args, strlen(args)))) ||
430
!BUF_Write(&buf, "\r\n", 2)) {
434
} else if (refer && strcasecmp(iter->op->name, "LBSMD") == 0) {
435
const char* host = referrer->client_host;
436
const char* service = iter->service;
437
if (!BUF_Write(&buf, referrer_header, sizeof(referrer_header)-1) ||
438
!BUF_Write(&buf, "lbsm://", 7) ||
439
!BUF_Write(&buf, host, strlen(host)) ||
440
!BUF_Write(&buf, "/dispatch?service=", 18) ||
441
!BUF_Write(&buf, service, strlen(service)) ||
442
!BUF_Write(&buf, "\r\n", 2)) {
447
/* Form accepted server types */
448
buflen = sizeof(accepted_types) - 1;
449
memcpy(buffer, accepted_types, buflen);
450
types = (TSERV_Type) (iter->types & ~fSERV_StatelessOnly);
451
for (t = 1; t; t <<= 1) {
453
const char* name = SERV_TypeStr((ESERV_Type) t);
454
size_t namelen = strlen(name);
455
if (!namelen || buflen + 1 + namelen + 2 >= sizeof(buffer))
457
buffer[buflen++] = ' ';
458
strcpy(&buffer[buflen], name);
462
if (buffer[buflen - 1] != ':') {
463
strcpy(&buffer[buflen], "\r\n");
464
assert(strlen(buffer) == buflen+2 && buflen+2 < sizeof(buffer));
465
if (!BUF_Write(&buf, buffer, buflen + 2)) {
470
/* Drop any outdated skip entries */
472
/* Put all the rest into rejection list */
473
for (i = 0; i < iter->n_skip; i++) {
474
if (!(str = SERV_WriteInfo(iter->skip[i])))
476
buflen = sprintf(buffer, "Skip-Info-%u: ", (unsigned) i + 1);
477
assert(buflen < sizeof(buffer)-1);
478
if (!BUF_Write(&buf, buffer, buflen) ||
479
!BUF_Write(&buf, str, strlen(str)) ||
480
!BUF_Write(&buf, "\r\n", 2)) {
486
if (i < iter->n_skip) {
425
487
BUF_Destroy(buf);
429
/* Drop any outdated skip entries */
431
/* Put all the rest into rejection list */
432
for (i = 0; i < iter->n_skip; i++) {
433
if (!(str = SERV_WriteInfo(iter->skip[i])))
435
buflen = sprintf(buffer, "Skip-Info-%u: ", (unsigned) i + 1);
436
assert(buflen < sizeof(buffer)-1);
437
if (!BUF_Write(&buf, buffer, buflen) ||
438
!BUF_Write(&buf, str, strlen(str)) ||
439
!BUF_Write(&buf, "\r\n", 2)) {
491
/* Ok then, we have filled the entire header, <CR><LF> terminated */
492
if ((buflen = BUF_Size(buf)) != 0) {
493
if ((str = (char*) malloc(buflen + 1)) != 0) {
494
if (BUF_Read(buf, str, buflen) != buflen) {
445
if (i >= iter->n_skip) {
446
/* Ok then, we have filled the entire header, <CR><LF> terminated */
447
if ((buflen = BUF_Size(buf)) != 0) {
448
if ((str = (char*) malloc(buflen + 1)) != 0) {
449
if (BUF_Read(buf, str, buflen) != buflen) {
459
502
BUF_Destroy(buf);
510
char* SERV_Print(SERV_ITER iter)
512
return SERV_PrintEx(iter, 0);
517
* Note parameters' ranges here:
521
* Hence, the formula below always yields a value in the range [0.0 .. 1.0].
523
double SERV_Preference(double pref, double gap, unsigned int n)
525
assert(0.0 <= pref && pref <= 1.0);
526
assert(0.0 < gap && gap <= 1.0);
530
else if (gap >= 0.75*(1.0/(double) n))
538
* --------------------------------------------------------------------------
539
* $Log: ncbi_service.c,v $
540
* Revision 6.55 2004/08/19 15:48:35 lavr
541
* SERV_ITER::type renamed into SERV_ITER::types to reflect its bitmask nature
543
* Revision 6.54 2004/07/01 16:28:19 lavr
544
* +SERV_PrintEx(): "Referer:" tag impelemented
546
* Revision 6.53 2004/06/14 16:37:09 lavr
547
* Allow no more than one firewall server info in the skip list
549
* Revision 6.52 2004/05/17 18:19:43 lavr
550
* Mark skip infos with maximal time instead of calculating 1 year from now
552
* Revision 6.51 2004/03/23 02:28:21 lavr
553
* Limit service name resolution recursion by 8
555
* Revision 6.50 2004/01/30 14:37:26 lavr
556
* Client revision made independent of CVS revisions
558
* Revision 6.49 2003/09/02 21:17:15 lavr
559
* Clean up included headers
561
* Revision 6.48 2003/06/26 15:20:46 lavr
562
* Additional parameter "external" in implementation of generic methods
564
* Revision 6.47 2003/06/09 19:53:01 lavr
567
* Revision 6.46 2003/04/30 17:00:47 lavr
568
* Name collision resolved
570
* Revision 6.45 2003/02/28 14:49:04 lavr
571
* SERV_Preference(): redeclare last argument 'unsigned'
573
* Revision 6.44 2003/02/13 22:04:16 lavr
574
* Document SERV_Preference() domain, change last argument, tweak formula
576
* Revision 6.43 2003/01/31 21:19:30 lavr
577
* +SERV_GetInfoP(), preference measure for preferred host, SERV_Preference()
579
* Revision 6.42 2002/11/12 05:53:01 lavr
580
* Fit a long line within 80 chars
582
* Revision 6.41 2002/10/28 20:16:00 lavr
583
* Take advantage of host info API
585
* Revision 6.40 2002/10/28 15:43:49 lavr
586
* Use "ncbi_ansi_ext.h" privately and use strncpy0()
588
* Revision 6.39 2002/10/11 19:48:10 lavr
590
* const dropped in return value of SERV_ServiceName()
592
* Revision 6.38 2002/09/04 15:11:41 lavr
595
* Revision 6.37 2002/05/06 19:16:50 lavr
596
* +#include <stdio.h>, +SERV_ServiceName() - translation of service name
598
* Revision 6.36 2002/04/15 20:07:09 lavr
599
* Use size_t for iterating over skip_info's
601
* Revision 6.35 2002/04/13 06:35:11 lavr
602
* Fast track routine SERV_GetInfoEx(), many syscalls optimizations
604
* Revision 6.34 2002/03/22 19:51:28 lavr
605
* Do not explicitly include <assert.h>: included from ncbi_core.h
607
* Revision 6.33 2002/03/11 21:59:32 lavr
608
* 'Client version' changed into 'Client revision'
610
* Revision 6.32 2001/11/09 20:03:14 lavr
611
* Minor fix to remove a trailing space in client version tag
613
* Revision 6.31 2001/10/01 19:52:38 lavr
614
* Call update directly; do not remove time from server specs in SERV_Print()
616
* Revision 6.30 2001/09/29 19:33:04 lavr
617
* BUGFIX: SERV_Update() requires VT bound (was not the case in constructor)
619
* Revision 6.29 2001/09/28 22:03:12 vakatov
620
* Included missing <connect/ncbi_ansi_ext.h>
622
* Revision 6.28 2001/09/28 20:50:16 lavr
623
* SERV_Update() modified to capture Used-Server-Info tags;
624
* Update VT method changed - now called on per-line basis;
625
* Few bugfixes related to keeping last info correct
627
* Revision 6.27 2001/09/24 20:28:48 lavr
628
* +SERV_Reset(); SERV_Close() changed to utilize SERV_Reset()
630
* Revision 6.26 2001/09/10 21:19:48 lavr
631
* SERV_Print(): Client version tag added
632
* SERV_OpenEx(): Firewall type handling
634
* Revision 6.25 2001/08/20 21:58:19 lavr
635
* Parameter change for clarity: info -> net_info if type is SConnNetInfo
637
* Revision 6.24 2001/06/25 15:35:54 lavr
638
* Added function: SERV_GetNextInfoEx
640
* Revision 6.23 2001/06/20 17:27:49 kans
641
* include <time.h> for Mac compiler
643
* Revision 6.22 2001/06/19 19:12:01 lavr
644
* Type change: size_t -> TNCBI_Size; time_t -> TNCBI_Time
646
* Revision 6.21 2001/05/24 21:28:12 lavr
647
* Timeout for skip servers increased to 1 year period
649
* Revision 6.20 2001/05/17 15:02:51 lavr
652
* Revision 6.19 2001/04/24 21:37:26 lavr
653
* New code for: SERV_MapperName() and SERV_Penalize().
655
* Revision 6.18 2001/03/21 21:23:30 lavr
656
* Explicit type conversion size_t -> unsigned in printf
658
* Revision 6.17 2001/03/20 22:03:32 lavr
659
* BUGFIX in SERV_Print (miscalculation of buflen for accepted server types)
661
* Revision 6.16 2001/03/06 23:55:25 lavr
662
* SOCK_gethostaddr -> SOCK_gethostbyname
664
* Revision 6.15 2001/03/05 23:10:29 lavr
665
* SERV_WriteInfo takes only one argument now
667
* Revision 6.14 2001/03/02 20:09:51 lavr
668
* Support added for SERV_LOCALHOST as preferred_host.
670
* Revision 6.13 2001/03/01 00:31:23 lavr
671
* SERV_OpenSimple now builds SConnNetInfo to use both LBSMD and DISPD.CGI
673
* Revision 6.12 2001/02/09 17:33:06 lavr
674
* Modified: fSERV_StatelessOnly overrides info->stateless
676
* Revision 6.11 2001/01/25 17:05:32 lavr
677
* Bugfix in SERV_OpenEx: op was not inited to 0
679
* Revision 6.10 2001/01/08 23:47:29 lavr
680
* (unsigned char) conversion in isspace
682
* Revision 6.9 2001/01/08 22:38:34 lavr
683
* Numerous patches to code after debugging
685
* Revision 6.8 2000/12/29 18:01:27 lavr
686
* SERV_Print introduced; pool of skipped services now follows
687
* expiration times of services and is updated on that basis.
689
* Revision 6.7 2000/12/06 22:20:30 lavr
690
* Skip info list is not maintained forever; instead the entries get
691
* deleted in accordance with their expiration period
693
* Revision 6.6 2000/10/20 17:19:04 lavr
694
* SConnNetInfo made 'const' as a parameter to 'SERV_Open*'
695
* 'SERV_Update' added as a private interface
697
* Revision 6.5 2000/10/05 22:36:21 lavr
698
* Additional parameters in call to DISPD mapper
700
* Revision 6.4 2000/05/31 23:12:23 lavr
701
* First try to assemble things together to get working service mapper
703
* Revision 6.3 2000/05/22 16:53:11 lavr
704
* Rename service_info -> server_info everywhere (including
705
* file names) as the latter name is more relevant
707
* Revision 6.2 2000/05/12 21:42:59 lavr
708
* Cleaned up for the C++ compilation, etc.
710
* Revision 6.1 2000/05/12 18:50:20 lavr
711
* First working revision
713
* ==========================================================================