📄 ncbi_service.c
字号:
/* * =========================================================================== * PRODUCTION $Log: ncbi_service.c,v $ * PRODUCTION Revision 1000.3 2004/06/01 18:45:22 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.52 * PRODUCTION * =========================================================================== *//* $Id: ncbi_service.c,v 1000.3 2004/06/01 18:45:22 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Anton Lavrentiev * * File Description: * Top-level API to resolve NCBI service name to the server meta-address. * */#include "ncbi_ansi_ext.h"#include "ncbi_dispd.h"#include "ncbi_lbsmd.h"#include "ncbi_priv.h"#include <ctype.h>#include <stdlib.h>#include <time.h>#define SERV_SERVICE_NAME "SERVICE_NAME"static char* s_ServiceName(const char* service, size_t depth){ char *s, *p; char key[128]; char srv[128]; if (++depth > 8 || !service || !*service || sizeof(DEF_CONN_REG_SECTION) + sizeof(SERV_SERVICE_NAME) + strlen(service) >= sizeof(key)) return 0/*failure*/; s = key; strcpy(s, DEF_CONN_REG_SECTION); s += sizeof(DEF_CONN_REG_SECTION) - 1; *s++ = '_'; strcpy(s, SERV_SERVICE_NAME); s += sizeof(SERV_SERVICE_NAME) - 1; *s++ = '_'; strcpy(s, service); strupr(key); /* Looking for "CONN_SERVICE_NAME_service" in environment */ if (!(p = getenv(key))) { *--s = '\0'; /* Looking for "CONN_SERVICE_NAME" in registry's section [service] */ CORE_REG_GET(service, key, srv, sizeof(srv), 0); if (!*srv) return strdup(service); } else strncpy0(srv, p, sizeof(srv) - 1); /* No cycle detection in service name redefinition */ return s_ServiceName(srv, depth);}char* SERV_ServiceName(const char* service){ return s_ServiceName(service, 0);}SERV_ITER SERV_OpenSimple(const char* service){ SConnNetInfo* net_info = ConnNetInfo_Create(service); SERV_ITER iter = SERV_Open(service, fSERV_Any, 0, net_info); ConnNetInfo_Destroy(net_info); return iter;}static int/*bool*/ s_AddSkipInfo(SERV_ITER iter, SSERV_Info* info){ if (iter->n_skip == iter->n_max_skip) { SSERV_Info** temp; size_t n = iter->n_max_skip + 10; if (iter->skip) temp = (SSERV_Info**) realloc(iter->skip, sizeof(*temp) * n); else temp = (SSERV_Info**) malloc(sizeof(*temp) * n); if (!temp) return 0; iter->skip = temp; iter->n_max_skip = n; } iter->skip[iter->n_skip++] = info; return 1;}static SERV_ITER s_Open(const char* service, TSERV_Type type, unsigned int preferred_host, double preference, const SConnNetInfo* net_info, const SSERV_Info* const skip[], size_t n_skip, SSERV_Info** info, HOST_INFO* host_info, int external){ const char* s = s_ServiceName(service, 0); const SSERV_VTable* op; SERV_ITER iter; if (!s || !*s || !(iter = (SERV_ITER) malloc(sizeof(*iter)))) return 0; iter->service = s; iter->type = type; iter->preferred_host = preferred_host == SERV_LOCALHOST ? SOCK_gethostbyname(0) : preferred_host; iter->preference = 0.01*(preference < 0.0 ? 0.0 : preference > 100.0 ? 100.0 : preference); iter->n_skip = iter->n_max_skip = 0; iter->skip = 0; iter->last = 0; iter->op = 0; iter->data = 0; iter->external = external; if (n_skip) { size_t i; for (i = 0; i < n_skip; i++) { size_t skipinfolen = SERV_SizeOfInfo(skip[i]); SSERV_Info* skipinfo = (SSERV_Info*) malloc(skipinfolen); if (!skipinfo) { SERV_Close(iter); return 0; } memcpy(skipinfo, skip[i], skipinfolen); skipinfo->time = (TNCBI_Time)(-1); if (!s_AddSkipInfo(iter, skipinfo)) { free(skipinfo); SERV_Close(iter); } } } assert(n_skip == iter->n_skip); if (!net_info) { if (!(op = SERV_LBSMD_Open(iter, info, host_info))) { /* LBSMD failed in non-DISPD mapping */ SERV_Close(iter); return 0; } } else { if (net_info->stateless) iter->type |= fSERV_StatelessOnly; if (net_info->firewall) iter->type |= fSERV_Firewall; if ((net_info->lb_disable || !(op = SERV_LBSMD_Open(iter, info, host_info))) && !(op = SERV_DISPD_Open(iter, net_info, info, host_info))) { SERV_Close(iter); return 0; } } assert(op != 0); iter->op = op; return iter;}SERV_ITER SERV_OpenEx(const char* service, TSERV_Type type, unsigned int preferred_host, const SConnNetInfo* net_info, const SSERV_Info* const skip[], size_t n_skip){ return s_Open(service, type, preferred_host, 0.0, net_info, skip, n_skip, 0, 0, 0/*not external*/);}SERV_ITER SERV_OpenP(const char* service, TSERV_Type type, unsigned int preferred_host, double preference, int/*bool*/ external){ return s_Open(service, type, preferred_host, preference, 0, 0, 0, 0, 0, external);}static SSERV_Info* s_GetInfo(const char* service, TSERV_Type type, unsigned int preferred_host, double preference, const SConnNetInfo* net_info, const SSERV_Info* const skip[], size_t n_skip, HOST_INFO* host_info, int/*bool*/ external){ SSERV_Info* info = 0; SERV_ITER iter= s_Open(service, type, preferred_host, preference, net_info, skip, n_skip, &info, host_info, external); if (iter && !info && iter->op && iter->op->GetNextInfo) info = (*iter->op->GetNextInfo)(iter, host_info); SERV_Close(iter); return info;}SSERV_Info* SERV_GetInfoEx(const char* service, TSERV_Type type, unsigned int preferred_host, const SConnNetInfo* net_info, const SSERV_Info* const skip[], size_t n_skip, HOST_INFO* host_info){ return s_GetInfo(service, type, preferred_host, 0.0, net_info, skip, n_skip, host_info, 0/*not external*/);}SSERV_Info* SERV_GetInfoP(const char* service, TSERV_Type type, unsigned int preferred_host, double preference, int/*bool*/ external){ return s_GetInfo(service, type, preferred_host, preference, 0, 0, 0, 0, external);}static void s_SkipSkip(SERV_ITER iter){ if (iter->n_skip) { TNCBI_Time t = (TNCBI_Time) time(0); size_t i = 0; while (i < iter->n_skip) { SSERV_Info* info = iter->skip[i]; if (info->time < t) { if (i < --iter->n_skip) memmove(iter->skip + i, iter->skip + i + 1, sizeof(*iter->skip)*(iter->n_skip - i)); if (info == iter->last) iter->last = 0; free(info); } else i++; } }}const SSERV_Info* SERV_GetNextInfoEx(SERV_ITER iter, HOST_INFO* host_info){ SSERV_Info* info = 0; if (iter && iter->op) { /* First, remove all outdated entries from our skip list */ s_SkipSkip(iter); /* Next, obtain a fresh entry from the actual mapper */ if (iter->op->GetNextInfo && (info = (*iter->op->GetNextInfo)(iter, host_info)) != 0 && !s_AddSkipInfo(iter, info)) { free(info); info = 0; } iter->last = info; } return info;}const char* SERV_MapperName(SERV_ITER iter){ return iter && iter->op ? iter->op->name : 0;}int/*bool*/ SERV_Penalize(SERV_ITER iter, double fine){ if (!iter || !iter->op || !iter->op->Penalize || !iter->last) return 0; return (*iter->op->Penalize)(iter, fine);}char* SERV_GetConfig(void){ return SERV_LBSMD_GetConfig();}void SERV_Reset(SERV_ITER iter){ size_t i; if (!iter) return; for (i = 0; i < iter->n_skip; i++) free(iter->skip[i]); iter->n_skip = 0; iter->last = 0; if (iter->op && iter->op->Reset) (*iter->op->Reset)(iter);}void SERV_Close(SERV_ITER iter){ if (!iter)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -