00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "ncbi_ansi_ext.h"
00034 #include "ncbi_server_infop.h"
00035 #include <assert.h>
00036 #include <ctype.h>
00037 #include <math.h>
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040
00041 #define MAX_IP_ADDR_LEN 16
00042
00043
00044
00045
00046
00047
00048
00049
00050 typedef struct {
00051 char* (*Write )(size_t reserve, const USERV_Info* u);
00052 SSERV_Info* (*Read )(const char** str, size_t add);
00053 size_t (*SizeOf)(const USERV_Info *u);
00054 int (*Equal )(const USERV_Info *u1, const USERV_Info *u2);
00055 } SSERV_Info_VTable;
00056
00057
00058
00059
00060 typedef struct {
00061 ESERV_Type type;
00062 const char* tag;
00063 size_t tag_len;
00064 SSERV_Info_VTable vtable;
00065 } SSERV_Attr;
00066
00067
00068 static const char* k_FlagTag[] = {
00069 "Regular",
00070 "Blast"
00071 };
00072
00073
00074
00075
00076 static int s_LocalServerDefault = 0;
00077
00078
00079 int SERV_SetLocalServerDefault(int onoff)
00080 {
00081 int retval = s_LocalServerDefault;
00082 s_LocalServerDefault = onoff ? 1 : 0;
00083 return retval;
00084 }
00085
00086
00087
00088
00089 static const SSERV_Attr* s_GetAttrByType(ESERV_Type type);
00090 static const SSERV_Attr* s_GetAttrByTag(const char* tag);
00091
00092
00093 const char* SERV_TypeStr(ESERV_Type type)
00094 {
00095 const SSERV_Attr* attr = s_GetAttrByType(type);
00096 if (attr)
00097 return attr->tag;
00098 return "";
00099 }
00100
00101
00102 const char* SERV_ReadType(const char* str, ESERV_Type* type)
00103 {
00104 const SSERV_Attr* attr = s_GetAttrByTag(str);
00105 if (!attr)
00106 return 0;
00107 *type = attr->type;
00108 return str + attr->tag_len;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117 char* SERV_WriteInfo(const SSERV_Info* info)
00118 {
00119 char c_t[MAX_CONTENT_TYPE_LEN];
00120 const SSERV_Attr* attr;
00121 size_t reserve;
00122 char* str;
00123
00124 if (!(attr = s_GetAttrByType(info->type)))
00125 return 0;
00126 if (info->type != fSERV_Dns
00127 && MIME_ComposeContentTypeEx(info->mime_t, info->mime_s,
00128 info->mime_e, c_t, sizeof(c_t))) {
00129 char* p;
00130 assert(c_t[strlen(c_t) - 2] == '\r' && c_t[strlen(c_t) - 1] == '\n');
00131 c_t[strlen(c_t) - 2] = 0;
00132 p = strchr(c_t, ' ');
00133 assert(p);
00134 p++;
00135 memmove(c_t, p, strlen(p) + 1);
00136 } else
00137 *c_t = 0;
00138 reserve = attr->tag_len+1 + MAX_IP_ADDR_LEN + 1+5 + 1+10 +
00139 1+9 + 3+strlen(c_t) + 1+5 + 1+5 +
00140 1+7 + 1+14 + 1+5 + 1+12 + 1;
00141
00142 if ((str = attr->vtable.Write(reserve, &info->u)) != 0) {
00143 char* s = str;
00144 size_t n;
00145
00146 memcpy(s, attr->tag, attr->tag_len);
00147 s += attr->tag_len;
00148 *s++ = ' ';
00149 s += SOCK_HostPortToString(info->host, info->port, s, reserve);
00150 if ((n = strlen(str + reserve)) != 0) {
00151 *s++ = ' ';
00152 memmove(s, str + reserve, n + 1);
00153 s = str + strlen(str);
00154 }
00155
00156 assert(info->flag < (int)(sizeof(k_FlagTag)/sizeof(k_FlagTag[0])));
00157 if (k_FlagTag[info->flag] && *k_FlagTag[info->flag])
00158 s += sprintf(s, " %s", k_FlagTag[info->flag]);
00159 s += sprintf(s, " B=%.2f", info->coef);
00160 if (*c_t)
00161 s += sprintf(s, " C=%s", c_t);
00162 s += sprintf(s, " L=%s", info->locl & 0x0F ? "yes" : "no");
00163 if (info->type != fSERV_Dns && (info->locl & 0xF0))
00164 s += sprintf(s, " P=yes");
00165 if (info->host && info->quorum) {
00166 if (info->quorum == (unsigned short)(-1))
00167 s += sprintf(s, " Q=yes");
00168 else
00169 s += sprintf(s, " Q=%hu", info->quorum);
00170 }
00171 s += sprintf(s," R=%.*f", fabs(info->rate) < 0.01 ? 3 : 2, info->rate);
00172 if (!(info->type & fSERV_Http) && info->type != fSERV_Dns)
00173 s += sprintf(s, " S=%s", info->sful ? "yes" : "no");
00174 s += sprintf(s, " T=%lu", (unsigned long)info->time);
00175 }
00176 return str;
00177 }
00178
00179
00180 SSERV_Info* SERV_ReadInfoEx(const char* info_str, const char* name)
00181 {
00182
00183 ESERV_Type type;
00184 const char* str = SERV_ReadType(info_str, &type);
00185 int coef, mime, locl, priv, quorum, rate, sful, time;
00186 unsigned int host;
00187 unsigned short port;
00188 SSERV_Info* info;
00189
00190 if (!str || (*str && !isspace((unsigned char)(*str))))
00191 return 0;
00192
00193 while (*str && isspace((unsigned char)(*str)))
00194 str++;
00195 if (!ispunct((unsigned char)(*str)) || *str == ':') {
00196 if (!(str = SOCK_StringToHostPort(str, &host, &port)))
00197 return 0;
00198 while (*str && isspace((unsigned char)(*str)))
00199 str++;
00200 } else {
00201 host = 0;
00202 port = 0;
00203 }
00204
00205 info = s_GetAttrByType(type)->vtable.Read(&str, name ? strlen(name)+1 : 0);
00206 if (!info)
00207 return 0;
00208 info->host = host;
00209 if (port)
00210 info->port = port;
00211 coef = mime = locl = priv = quorum = rate = sful = time = 0;
00212
00213 while (*str && isspace((unsigned char)(*str)))
00214 str++;
00215 while (*str) {
00216 if (*(str + 1) == '=') {
00217 int n;
00218 double d;
00219 unsigned short h;
00220 unsigned long t;
00221 char s[4];
00222 EMIME_Type mime_t;
00223 EMIME_SubType mime_s;
00224 EMIME_Encoding mime_e;
00225
00226 switch (toupper((unsigned char)(*str++))) {
00227 case 'B':
00228 if (!coef && sscanf(str, "=%lf%n", &d, &n) >= 1) {
00229 if (d < -100.0)
00230 d = -100.0;
00231 else if (d < 0.0)
00232 d = (d < -0.1 ? d : -0.1);
00233 else if (d < 0.01)
00234 d = 0.0;
00235 else if (d > 1000.0)
00236 d = 1000.0;
00237 info->coef = d;
00238 str += n;
00239 coef = 1;
00240 }
00241 break;
00242 case 'C':
00243 if (type == fSERV_Dns)
00244 break;
00245 if (!mime && MIME_ParseContentTypeEx(str + 1, &mime_t,
00246 &mime_s, &mime_e)) {
00247 info->mime_t = mime_t;
00248 info->mime_s = mime_s;
00249 info->mime_e = mime_e;
00250 mime = 1;
00251 while (*str && !isspace((unsigned char)(*str)))
00252 str++;
00253 }
00254 break;
00255 case 'L':
00256 if (!locl && sscanf(str, "=%3s%n", s, &n) >= 1) {
00257 if (strcasecmp(s, "YES") == 0) {
00258 info->locl |= 0x01;
00259 str += n;
00260 locl = 1;
00261 } else if (strcasecmp(s, "NO") == 0) {
00262 info->locl &= ~0x0F;
00263 str += n;
00264 locl = 1;
00265 }
00266 }
00267 break;
00268 case 'P':
00269 if (type == fSERV_Dns)
00270 break;
00271 if (!priv && sscanf(str, "=%3s%n", s, &n) >= 1) {
00272 if (strcasecmp(s, "YES") == 0) {
00273 info->locl |= 0x10;
00274 str += n;
00275 priv = 1;
00276 } else if (strcasecmp(s, "NO") == 0) {
00277 info->locl &= ~0xF0;
00278 str += n;
00279 priv = 1;
00280 }
00281 }
00282 break;
00283 case 'Q':
00284 if (type == fSERV_Firewall || !info->host || quorum)
00285 break;
00286 if (sscanf(str,"=%3s%n",s,&n) >= 1 && strcasecmp(s, "YES")==0){
00287 info->quorum = (unsigned short)(-1);
00288 str += n;
00289 quorum = 1;
00290 } else if (sscanf(str, "=%hu%n", &h, &n) >= 1) {
00291 info->quorum = h;
00292 str += n;
00293 quorum = 1;
00294 }
00295 break;
00296 case 'R':
00297 if (!rate && sscanf(str, "=%lf%n", &d, &n) >= 1) {
00298 if (fabs(d) < 0.001)
00299 d = 0.0;
00300 else if (fabs(d) > 100000.0)
00301 d = d < 0.0 ? -100000.0 : 100000.0;
00302 info->rate = d;
00303 str += n;
00304 rate = 1;
00305 }
00306 break;
00307 case 'S':
00308 if ((type & fSERV_Http) != 0)
00309 break;
00310 if (!sful && sscanf(str, "=%3s%n", s, &n) >= 1) {
00311 if (strcasecmp(s, "YES") == 0) {
00312 if (type == fSERV_Dns)
00313 break;
00314 info->sful = 1;
00315 str += n;
00316 sful = 1;
00317 } else if (strcasecmp(s, "NO") == 0) {
00318 info->sful = 0;
00319 str += n;
00320 sful = 1;
00321 }
00322 }
00323 break;
00324 case 'T':
00325 if (!time && sscanf(str, "=%lu%n", &t, &n) >= 1) {
00326 info->time = (TNCBI_Time) t;
00327 str += n;
00328 time = 1;
00329 }
00330 break;
00331 }
00332 } else {
00333 size_t i;
00334 for (i = 0; i < sizeof(k_FlagTag)/sizeof(k_FlagTag[0]); i++) {
00335 size_t n = strlen(k_FlagTag[i]);
00336 if (strncasecmp(str, k_FlagTag[i], n) == 0) {
00337 info->flag = (ESERV_Flag) i;
00338 str += n;
00339 break;
00340 }
00341 }
00342 }
00343 if (*str && !isspace((unsigned char)(*str)))
00344 break;
00345 while (*str && isspace((unsigned char)(*str)))
00346 str++;
00347 }
00348 if (*str) {
00349 free(info);
00350 info = 0;
00351 } else if (name) {
00352 strcpy((char*) info + SERV_SizeOfInfo(info), name);
00353 if (info->type == fSERV_Dns)
00354 info->u.dns.name = 1;
00355 } else if (info->type == fSERV_Dns) {
00356 info->u.dns.name = 0;
00357 }
00358 return info;
00359 }
00360
00361
00362 SSERV_Info* SERV_ReadInfo(const char* info_str)
00363 {
00364 return SERV_ReadInfoEx(info_str, 0);
00365 }
00366
00367
00368 SSERV_Info* SERV_CopyInfoEx(const SSERV_Info* orig, const char* name)
00369 {
00370 size_t size = SERV_SizeOfInfo(orig);
00371 SSERV_Info* info;
00372 if (!size)
00373 return 0;
00374 if ((info = (SSERV_Info*)malloc(size + (name ? strlen(name)+1 : 0))) != 0){
00375 memcpy(info, orig, size);
00376 memset(&info->reserved, 0, sizeof(info->reserved));
00377 if (name) {
00378 strcpy((char*) info + size, name);
00379 if (orig->type == fSERV_Dns)
00380 info->u.dns.name = 1;
00381 } else if (orig->type == fSERV_Dns)
00382 info->u.dns.name = 0;
00383 }
00384 return info;
00385 }
00386
00387
00388 SSERV_Info* SERV_CopyInfo(const SSERV_Info* orig)
00389 {
00390 return SERV_CopyInfoEx(orig, 0);
00391 }
00392
00393
00394 const char* SERV_NameOfInfo(const SSERV_Info* info)
00395 {
00396 if (!info)
00397 return 0;
00398 return info->type != fSERV_Dns || info->u.dns.name
00399 ? (const char*) info + SERV_SizeOfInfo(info) : "";
00400 }
00401
00402
00403 size_t SERV_SizeOfInfo(const SSERV_Info *info)
00404 {
00405 const SSERV_Attr* attr = info ? s_GetAttrByType(info->type) : 0;
00406 return attr
00407 ? sizeof(*info) - sizeof(info->u) + attr->vtable.SizeOf(&info->u) : 0;
00408 }
00409
00410
00411 int SERV_EqualInfo(const SSERV_Info *i1, const SSERV_Info *i2)
00412 {
00413 const SSERV_Attr* attr;
00414 if (i1->type != i2->type || i1->host != i2->host || i1->port != i2->port)
00415 return 0;
00416 attr = s_GetAttrByType(i1->type);
00417 return attr->vtable.Equal ? attr->vtable.Equal(&i1->u, &i2->u) : 1;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426 static char* s_Ncbid_Write(size_t reserve, const USERV_Info* u)
00427 {
00428 const SSERV_NcbidInfo* info = &u->ncbid;
00429 const char* args = SERV_NCBID_ARGS(info);
00430 char* str = (char*) malloc(reserve + strlen(args) + 3);
00431
00432 if (str) {
00433 sprintf(str + reserve, "%s", *args ? args : "''");
00434 }
00435 return str;
00436 }
00437
00438
00439 static SSERV_Info* s_Ncbid_Read(const char** str, size_t add)
00440 {
00441 SSERV_Info* info;
00442 char *args, *c;
00443
00444 if (!(args = strdup(*str)))
00445 return 0;
00446 for (c = args; *c; c++) {
00447 if (isspace((unsigned char)(*c))) {
00448 *c++ = '\0';
00449 while (*c && isspace((unsigned char)(*c)))
00450 c++;
00451 break;
00452 }
00453 }
00454 if ((info = SERV_CreateNcbidInfoEx(0, 80, args, add)) != 0)
00455 *str += c - args;
00456 free(args);
00457 return info;
00458 }
00459
00460
00461 static size_t s_Ncbid_SizeOf(const USERV_Info* u)
00462 {
00463 return sizeof(u->ncbid) + strlen(SERV_NCBID_ARGS(&u->ncbid))+1;
00464 }
00465
00466
00467 static int s_Ncbid_Equal(const USERV_Info* u1, const USERV_Info* u2)
00468 {
00469 return
00470 strcmp(SERV_NCBID_ARGS(&u1->ncbid), SERV_NCBID_ARGS(&u2->ncbid)) == 0;
00471 }
00472
00473
00474 SSERV_Info* SERV_CreateNcbidInfoEx
00475 (unsigned int host,
00476 unsigned short port,
00477 const char* args,
00478 size_t add)
00479 {
00480 SSERV_Info* info;
00481
00482 add += args ? strlen(args) : 0;
00483 if ((info = (SSERV_Info*) malloc(sizeof(SSERV_Info) + add + 1)) != 0) {
00484 info->type = fSERV_Ncbid;
00485 info->host = host;
00486 info->port = port;
00487 info->sful = 0;
00488 info->locl = s_LocalServerDefault & 0x0F;
00489 info->time = 0;
00490 info->coef = 0.0;
00491 info->rate = 0.0;
00492 info->mime_t = eMIME_T_Undefined;
00493 info->mime_s = eMIME_Undefined;
00494 info->mime_e = eENCOD_None;
00495 info->flag = SERV_DEFAULT_FLAG;
00496 memset(&info->reserved, 0, sizeof(info->reserved));
00497 info->quorum = 0;
00498 info->u.ncbid.args = (TNCBI_Size) sizeof(info->u.ncbid);
00499 if (strcmp(args, "''") == 0)
00500 args = 0;
00501 strcpy(SERV_NCBID_ARGS(&info->u.ncbid), args ? args : "");
00502 }
00503 return info;
00504 }
00505
00506
00507 SSERV_Info* SERV_CreateNcbidInfo
00508 (unsigned int host,
00509 unsigned short port,
00510 const char* args)
00511 {
00512 return SERV_CreateNcbidInfoEx(host, port, args, 0);
00513 }
00514
00515
00516
00517
00518
00519
00520
00521 static char* s_Standalone_Write(size_t reserve, const USERV_Info* u_info)
00522 {
00523 char* str = (char*) malloc(reserve + 1);
00524
00525 if (str)
00526 str[reserve] = '\0';
00527 return str;
00528 }
00529
00530
00531
00532 static SSERV_Info* s_Standalone_Read(const char** str, size_t add)
00533 {
00534 return SERV_CreateStandaloneInfoEx(0, 0, add);
00535 }
00536
00537
00538 static size_t s_Standalone_SizeOf(const USERV_Info* u)
00539 {
00540 return sizeof(u->standalone);
00541 }
00542
00543
00544 SSERV_Info* SERV_CreateStandaloneInfoEx
00545 (unsigned int host,
00546 unsigned short port,
00547 size_t add)
00548 {
00549 SSERV_Info *info = (SSERV_Info*) malloc(sizeof(SSERV_Info) + add);
00550
00551 if (info) {
00552 info->type = fSERV_Standalone;
00553 info->host = host;
00554 info->port = port;
00555 info->sful = 0;
00556 info->locl = s_LocalServerDefault & 0x0F;
00557 info->time = 0;
00558 info->coef = 0.0;
00559 info->rate = 0.0;
00560 info->mime_t = eMIME_T_Undefined;
00561 info->mime_s = eMIME_Undefined;
00562 info->mime_e = eENCOD_None;
00563 info->flag = SERV_DEFAULT_FLAG;
00564 memset(&info->reserved, 0, sizeof(info->reserved));
00565 info->quorum = 0;
00566 memset(&info->u.standalone, 0, sizeof(info->u.standalone));
00567 }
00568 return info;
00569 }
00570
00571
00572 SSERV_Info* SERV_CreateStandaloneInfo(unsigned int host, unsigned short port)
00573 {
00574 return SERV_CreateStandaloneInfoEx(host, port, 0);
00575 }
00576
00577
00578
00579
00580
00581
00582 static char* s_Http_Write(size_t reserve, const USERV_Info* u)
00583 {
00584 const SSERV_HttpInfo* info = &u->http;
00585 const char* path = SERV_HTTP_PATH(info);
00586 const char* args = SERV_HTTP_ARGS(info);
00587 char* str = (char*) malloc(reserve + strlen(path) + strlen(args) + 2);
00588 if (str) {
00589 int n = sprintf(str + reserve, "%s", path);
00590 if (*args)
00591 sprintf(str + reserve + n, "%s%s", &"?"[*args == '#'], args);
00592 }
00593 return str;
00594 }
00595
00596
00597 static SSERV_Info* s_HttpAny_Read(ESERV_Type type,
00598 const char** str,
00599 size_t add)
00600 {
00601 SSERV_Info* info;
00602 char *path, *args, *c;
00603
00604 if (!**str || !(path = strdup(*str)))
00605 return 0;
00606 for (c = path; *c; c++) {
00607 if (isspace((unsigned char)(*c))) {
00608 *c++ = '\0';
00609 while (*c && isspace((unsigned char)(*c)))
00610 c++;
00611 break;
00612 }
00613 }
00614 if ((args = strchr(path, '?')) != 0)
00615 *args++ = '\0';
00616 if ((info = SERV_CreateHttpInfoEx(type, 0, 80, path, args, add)) != 0)
00617 *str += c - path;
00618 free(path);
00619 return info;
00620 }
00621
00622
00623 static SSERV_Info *s_HttpGet_Read(const char** str, size_t add)
00624 {
00625 return s_HttpAny_Read(fSERV_HttpGet, str, add);
00626 }
00627
00628
00629 static SSERV_Info *s_HttpPost_Read(const char** str, size_t add)
00630 {
00631 return s_HttpAny_Read(fSERV_HttpPost, str, add);
00632 }
00633
00634
00635 static SSERV_Info *s_Http_Read(const char** str, size_t add)
00636 {
00637 return s_HttpAny_Read(fSERV_Http, str, add);
00638 }
00639
00640
00641 static size_t s_Http_SizeOf(const USERV_Info* u)
00642 {
00643 return sizeof(u->http) + strlen(SERV_HTTP_PATH(&u->http))+1 +
00644 strlen(SERV_HTTP_ARGS(&u->http))+1;
00645 }
00646
00647
00648 static int s_Http_Equal(const USERV_Info* u1, const USERV_Info* u2)
00649 {
00650 return
00651 strcmp(SERV_HTTP_PATH(&u1->http), SERV_HTTP_PATH(&u2->http)) == 0 &&
00652 strcmp(SERV_HTTP_ARGS(&u1->http), SERV_HTTP_ARGS(&u2->http)) == 0;
00653 }
00654
00655
00656 SSERV_Info* SERV_CreateHttpInfoEx
00657 (ESERV_Type type,
00658 unsigned int host,
00659 unsigned short port,
00660 const char* path,
00661 const char* args,
00662 size_t add)
00663 {
00664 SSERV_Info* info;
00665
00666 if (type & ~fSERV_Http)
00667 return 0;
00668 add += (path ? strlen(path) : 0) + 1 + (args ? strlen(args) : 0);
00669 if ((info = (SSERV_Info*) malloc(sizeof(SSERV_Info) + add + 1)) != 0) {
00670 info->type = type;
00671 info->host = host;
00672 info->port = port;
00673 info->sful = 0;
00674 info->locl = s_LocalServerDefault & 0x0F;
00675 info->time = 0;
00676 info->coef = 0.0;
00677 info->rate = 0.0;
00678 info->mime_t = eMIME_T_Undefined;
00679 info->mime_s = eMIME_Undefined;
00680 info->mime_e = eENCOD_None;
00681 info->flag = SERV_DEFAULT_FLAG;
00682 memset(&info->reserved, 0, sizeof(info->reserved));
00683 info->quorum = 0;
00684 info->u.http.path = (TNCBI_Size) sizeof(info->u.http);
00685 info->u.http.args = (TNCBI_Size) (info->u.http.path +
00686 (path ? strlen(path) : 0) + 1);
00687 strcpy(SERV_HTTP_PATH(&info->u.http), path ? path : "");
00688 strcpy(SERV_HTTP_ARGS(&info->u.http), args ? args : "");
00689 }
00690 return info;
00691 }
00692
00693
00694 SSERV_Info* SERV_CreateHttpInfo
00695 (ESERV_Type type,
00696 unsigned int host,
00697 unsigned short port,
00698 const char* path,
00699 const char* args)
00700 {
00701 return SERV_CreateHttpInfoEx(type, host, port, path, args, 0);
00702 }
00703
00704
00705
00706
00707
00708
00709 static char* s_Firewall_Write(size_t reserve, const USERV_Info* u_info)
00710 {
00711 const char* name = SERV_TypeStr(u_info->firewall.type);
00712 size_t namelen = strlen(name);
00713 char* str = (char*) malloc(reserve + (namelen ? namelen + 1 : 0));
00714
00715 if (str)
00716 strcpy(str + reserve, name);
00717 return str;
00718 }
00719
00720
00721 static SSERV_Info* s_Firewall_Read(const char** str, size_t add)
00722 {
00723 ESERV_Type type;
00724 const char* s;
00725 if (!(s = SERV_ReadType(*str, &type)))
00726 type = (ESERV_Type) 0;
00727 else
00728 *str = s;
00729 return SERV_CreateFirewallInfoEx(0, 0, type, add);
00730 }
00731
00732
00733 static size_t s_Firewall_SizeOf(const USERV_Info* u)
00734 {
00735 return sizeof(u->firewall);
00736 }
00737
00738
00739 static int s_Firewall_Equal(const USERV_Info* u1, const USERV_Info* u2)
00740 {
00741 return u1->firewall.type == u2->firewall.type;
00742 }
00743
00744
00745 SSERV_Info* SERV_CreateFirewallInfoEx(unsigned int host, unsigned short port,
00746 ESERV_Type type, size_t add)
00747 {
00748 SSERV_Info* info = (SSERV_Info*) malloc(sizeof(SSERV_Info) + add);
00749
00750 if (info) {
00751 info->type = fSERV_Firewall;
00752 info->host = host;
00753 info->port = port;
00754 info->sful = 0;
00755 info->locl = s_LocalServerDefault & 0x0F;
00756 info->time = 0;
00757 info->coef = 0.0;
00758 info->rate = 0.0;
00759 info->mime_t = eMIME_T_Undefined;
00760 info->mime_s = eMIME_Undefined;
00761 info->mime_e = eENCOD_None;
00762 info->flag = SERV_DEFAULT_FLAG;
00763 memset(&info->reserved, 0, sizeof(info->reserved));
00764 info->quorum = 0;
00765 info->u.firewall.type = type;
00766 }
00767 return info;
00768 }
00769
00770
00771 SSERV_Info* SERV_CreateFirewallInfo(unsigned int host, unsigned short port,
00772 ESERV_Type type)
00773 {
00774 return SERV_CreateFirewallInfoEx(host, port, type, 0);
00775 }
00776
00777
00778
00779
00780
00781
00782
00783 static char* s_Dns_Write(size_t reserve, const USERV_Info* u_info)
00784 {
00785 char* str = (char*) malloc(reserve + 1);
00786
00787 if (str)
00788 str[reserve] = '\0';
00789 return str;
00790 }
00791
00792
00793
00794 static SSERV_Info* s_Dns_Read(const char** str, size_t add)
00795 {
00796 return SERV_CreateDnsInfoEx(0, add);
00797 }
00798
00799
00800 static size_t s_Dns_SizeOf(const USERV_Info* u)
00801 {
00802 return sizeof(u->dns);
00803 }
00804
00805
00806 SSERV_Info* SERV_CreateDnsInfoEx(unsigned int host, size_t add)
00807 {
00808 SSERV_Info* info = (SSERV_Info*) malloc(sizeof(SSERV_Info) + add);
00809
00810 if (info) {
00811 info->type = fSERV_Dns;
00812 info->host = host;
00813 info->port = 0;
00814 info->sful = 0;
00815 info->locl = s_LocalServerDefault & 0x0F;
00816 info->time = 0;
00817 info->coef = 0.0;
00818 info->rate = 0.0;
00819 info->mime_t = eMIME_T_Undefined;
00820 info->mime_s = eMIME_Undefined;
00821 info->mime_e = eENCOD_None;
00822 info->flag = SERV_DEFAULT_FLAG;
00823 memset(&info->reserved, 0, sizeof(info->reserved));
00824 info->quorum = 0;
00825 memset(&info->u.dns, 0, sizeof(info->u.dns));
00826 }
00827 return info;
00828 }
00829
00830
00831 SSERV_Info* SERV_CreateDnsInfo(unsigned int host)
00832 {
00833 return SERV_CreateDnsInfoEx(host, 0);
00834 }
00835
00836
00837
00838
00839
00840
00841 static const char kNCBID [] = "NCBID";
00842 static const char kSTANDALONE[] = "STANDALONE";
00843 static const char kHTTP_GET [] = "HTTP_GET";
00844 static const char kHTTP_POST [] = "HTTP_POST";
00845 static const char kHTTP [] = "HTTP";
00846 static const char kFIREWALL [] = "FIREWALL";
00847 static const char kDNS [] = "DNS";
00848
00849
00850 static const SSERV_Attr s_SERV_Attr[] = {
00851 { fSERV_Ncbid,
00852 kNCBID, sizeof(kNCBID) - 1,
00853 {s_Ncbid_Write, s_Ncbid_Read,
00854 s_Ncbid_SizeOf, s_Ncbid_Equal} },
00855
00856 { fSERV_Standalone,
00857 kSTANDALONE, sizeof(kSTANDALONE) - 1,
00858 {s_Standalone_Write, s_Standalone_Read,
00859 s_Standalone_SizeOf, 0} },
00860
00861 { fSERV_HttpGet,
00862 kHTTP_GET, sizeof(kHTTP_GET) - 1,
00863 {s_Http_Write, s_HttpGet_Read,
00864 s_Http_SizeOf, s_Http_Equal} },
00865
00866 { fSERV_HttpPost,
00867 kHTTP_POST, sizeof(kHTTP_POST) - 1,
00868 {s_Http_Write, s_HttpPost_Read,
00869 s_Http_SizeOf, s_Http_Equal} },
00870
00871 { fSERV_Http,
00872 kHTTP, sizeof(kHTTP) - 1,
00873 {s_Http_Write, s_Http_Read,
00874 s_Http_SizeOf, s_Http_Equal} },
00875
00876 { fSERV_Firewall,
00877 kFIREWALL, sizeof(kFIREWALL) - 1,
00878 {s_Firewall_Write, s_Firewall_Read,
00879 s_Firewall_SizeOf, s_Firewall_Equal} },
00880
00881 { fSERV_Dns,
00882 kDNS, sizeof(kDNS) - 1,
00883 {s_Dns_Write, s_Dns_Read,
00884 s_Dns_SizeOf, 0} }
00885 };
00886
00887
00888 static const SSERV_Attr* s_GetAttrByType(ESERV_Type type)
00889 {
00890 size_t i;
00891 for (i = 0; i < sizeof(s_SERV_Attr)/sizeof(s_SERV_Attr[0]); i++) {
00892 if (s_SERV_Attr[i].type == type)
00893 return &s_SERV_Attr[i];
00894 }
00895 return 0;
00896 }
00897
00898
00899 static const SSERV_Attr* s_GetAttrByTag(const char* tag)
00900 {
00901 if (tag) {
00902 size_t i;
00903 for (i = 0; i < sizeof(s_SERV_Attr)/sizeof(s_SERV_Attr[0]); i++) {
00904 size_t len = s_SERV_Attr[i].tag_len;
00905 if (strncasecmp(tag, s_SERV_Attr[i].tag, len) == 0
00906 && (!tag[len] || isspace((unsigned char) tag[len])))
00907 return &s_SERV_Attr[i];
00908 }
00909 }
00910 return 0;
00911 }
00912
00913