src/connect/ncbi_server_info.c

Go to the documentation of this file.
00001 /* $Id: ncbi_server_info.c 174751 2009-10-30 15:07:12Z lavr $
00002  * ===========================================================================
00003  *
00004  *                            PUBLIC DOMAIN NOTICE
00005  *               National Center for Biotechnology Information
00006  *
00007  *  This software/database is a "United States Government Work" under the
00008  *  terms of the United States Copyright Act.  It was written as part of
00009  *  the author's official duties as a United States Government employee and
00010  *  thus cannot be copyrighted.  This software/database is freely available
00011  *  to the public for use. The National Library of Medicine and the U.S.
00012  *  Government have not placed any restriction on its use or reproduction.
00013  *
00014  *  Although all reasonable efforts have been taken to ensure the accuracy
00015  *  and reliability of the software and data, the NLM and the U.S.
00016  *  Government do not and cannot warrant the performance or results that
00017  *  may be obtained by using this software or data. The NLM and the U.S.
00018  *  Government disclaim all warranties, express or implied, including
00019  *  warranties of performance, merchantability or fitness for any particular
00020  *  purpose.
00021  *
00022  *  Please cite the author in any work or product based on this material.
00023  *
00024  * ===========================================================================
00025  *
00026  * Author:  Anton Lavrentiev, Denis Vakatov
00027  *
00028  * File Description:
00029  *   NCBI server meta-address info
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 /* sizeof("255.255.255.255") */
00042 
00043 
00044 /*****************************************************************************
00045  *  Attributes for the different server types::  Interface
00046  */
00047 
00048 /* Table of virtual functions
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/*bool*/ (*Equal )(const USERV_Info *u1, const USERV_Info *u2);
00055 } SSERV_Info_VTable;
00056 
00057 
00058 /* Attributes
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",  /* fSERV_Regular */
00070     "Blast"     /* fSERV_Blast   */
00071 };
00072 
00073 
00074 /* Any server is not local by default.
00075  */
00076 static int/*bool*/ s_LocalServerDefault = 0/*false*/;
00077 
00078 
00079 int/*bool*/ SERV_SetLocalServerDefault(int/*bool*/ onoff)
00080 {
00081     int/*bool*/ retval = s_LocalServerDefault;
00082     s_LocalServerDefault = onoff ? 1/*true*/ : 0/*false*/;
00083     return retval;
00084 }
00085 
00086 
00087 /* Attributes' lookup (by either type or tag)
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  *  Generic methods based on the server info's virtual functions
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/*port*/ + 1+10/*flag*/ +
00139         1+9/*coef*/ + 3+strlen(c_t)/*cont.type*/ + 1+5/*locl*/ + 1+5/*priv*/ +
00140         1+7/*quorum*/ + 1+14/*rate*/ + 1+5/*sful*/ + 1+12/*time*/ + 1/*EOL*/;
00141     /* write server-specific info */
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     /* detect server type */
00183     ESERV_Type     type;
00184     const char*    str = SERV_ReadType(info_str, &type);
00185     int/*bool*/    coef, mime, locl, priv, quorum, rate, sful, time;
00186     unsigned int   host;                /* network byte order       */
00187     unsigned short port;                /* host (native) byte order */
00188     SSERV_Info*    info;
00189 
00190     if (!str || (*str && !isspace((unsigned char)(*str))))
00191         return 0;
00192     /* NB: "str" guarantees there is non-NULL attr */
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     /* read server-specific info according to the detected type */
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;/*unassigned*/
00212     /* continue reading server info: optional parts: ... */
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/*true in low nibble*/;
00259                         str += n;
00260                         locl = 1;
00261                     } else if (strcasecmp(s, "NO") == 0) {
00262                         info->locl &= ~0x0F/*false in low nibble*/;
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;/*true in high nibble*/
00274                         str += n;
00275                         priv = 1;
00276                     } else if (strcasecmp(s, "NO") == 0) {
00277                         info->locl &= ~0xF0;/*false in high nibble*/
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; /*check only here for compatibility*/
00314                         info->sful = 1/*true */;
00315                         str += n;
00316                         sful = 1;
00317                     } else if (strcasecmp(s, "NO") == 0) {
00318                         info->sful = 0/* false */;
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/*true*/;
00355     } else if (info->type == fSERV_Dns) {
00356         info->u.dns.name = 0/*false*/;
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/*true*/;
00381         } else if (orig->type == fSERV_Dns)
00382             info->u.dns.name = 0/*false*/;
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/*bool*/ 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/*==i2->type*/);
00417     return attr->vtable.Equal ? attr->vtable.Equal(&i1->u, &i2->u) : 1;
00418 }
00419 
00420 
00421 
00422 /*****************************************************************************
00423  *  NCBID::   constructor and virtual functions
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/*bool*/ 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) /* special case */
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  *  STANDALONE::   constructor and virtual functions
00518  */
00519 
00520 /*ARGSUSED*/
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 /*ARGSUSED*/
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  *  HTTP::   constructor and virtual functions
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/*bool*/ 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  *  FIREWALL::   constructor and virtual functions
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/*fSERV_Any*/;
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/*bool*/ 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  *  DNS::   constructor and virtual functions
00780  */
00781 
00782 /*ARGSUSED*/
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 /*ARGSUSED*/
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  *  Attributes for the different server types::  Implementation
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 

Generated on Wed Dec 9 04:13:56 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Wed Dec 09 08:17:55 2009 by modify_doxy.py rev. 173732