39
39
#include <stdlib.h>
42
static const char* s_GetValue(const char* service, const char* param,
43
char* value, size_t value_size,
44
const char* def_value)
40
#if defined(NCBI_OS_UNIX)
41
# ifndef NCBI_OS_SOLARIS
44
# if defined(HAVE_GETPWUID) || defined(HAVE_GETPWUID_R)
48
#elif defined(NCBI_OS_MSWIN)
49
# if defined(_MSC_VER) && (_MSC_VER > 1200)
50
# define WIN32_LEAN_AND_MEAN
56
extern const char* ConnNetInfo_GetValue(const char* service, const char* param,
57
char* value, size_t value_size,
58
const char* def_value)
50
if (!param || !value || value_size <= 0)
64
if (!value || value_size <= 0)
68
if (!param || !*param)
54
71
if (service && *service) {
55
72
/* Service-specific inquiry */
56
if (strlen(service) + 1 + sizeof(DEF_CONN_REG_SECTION) +
57
strlen(param) + 1 > sizeof(key))
73
size_t slen = strlen(service);
74
size_t plen = strlen(param) + 1;
75
if (slen + 1 + sizeof(DEF_CONN_REG_SECTION) + plen > sizeof(buf))
59
78
/* First, environment search for 'service_CONN_param' */
60
sprintf(key, "%s_" DEF_CONN_REG_SECTION "_%s", service, param);
62
if ((val = getenv(key)) != 0)
79
s = (char*) memcpy(buf, service, slen) + slen;
81
memcpy(s, DEF_CONN_REG_SECTION, sizeof(DEF_CONN_REG_SECTION) - 1);
82
s += sizeof(DEF_CONN_REG_SECTION) - 1;
84
memcpy(s, param, plen);
85
if ((val = getenv(strupr(buf))) != 0)
63
86
return strncpy0(value, val, value_size - 1);
64
88
/* Next, search for 'CONN_param' in '[service]' registry section */
65
sprintf(key, DEF_CONN_REG_SECTION "_%s", param);
66
sec = key + strlen(key) + 1;
70
CORE_REG_GET(sec, key, value, value_size, 0);
91
CORE_REG_GET(buf, s, value, value_size, 0);
74
95
/* Common case. Form 'CONN_param' */
75
if (sizeof(DEF_CONN_REG_SECTION) + strlen(param) + 1 > sizeof(key))
96
size_t plen = strlen(param) + 1;
97
if (sizeof(DEF_CONN_REG_SECTION) + plen > sizeof(buf))
77
sprintf(key, DEF_CONN_REG_SECTION "_%s", param);
100
memcpy(s, DEF_CONN_REG_SECTION, sizeof(DEF_CONN_REG_SECTION) - 1);
101
s += sizeof(DEF_CONN_REG_SECTION) - 1;
103
memcpy(s, param, plen);
81
107
/* Environment search for 'CONN_param' */
82
if ((val = getenv(key)) != 0)
108
if ((val = getenv(s)) != 0)
83
109
return strncpy0(value, val, value_size - 1);
85
111
/* Last resort: Search for 'param' in default registry section */
88
CORE_REG_GET(DEF_CONN_REG_SECTION, key, value, value_size, def_value);
112
s += sizeof(DEF_CONN_REG_SECTION);
113
CORE_REG_GET(DEF_CONN_REG_SECTION, s, value, value_size, def_value);
199
224
info->stateless = (*str &&
200
225
(strcmp(str, "1") == 0 ||
201
226
strcasecmp(str, "true") == 0 ||
202
strcasecmp(str, "yes" ) == 0));
227
strcasecmp(str, "yes" ) == 0 ||
228
strcasecmp(str, "on" ) == 0));
204
230
/* firewall mode? */
205
231
REG_VALUE(REG_CONN_FIREWALL, str, DEF_CONN_FIREWALL);
206
232
info->firewall = (*str &&
207
233
(strcmp(str, "1") == 0 ||
208
234
strcasecmp(str, "true") == 0 ||
209
strcasecmp(str, "yes" ) == 0));
235
strcasecmp(str, "yes" ) == 0 ||
236
strcasecmp(str, "on" ) == 0));
211
238
/* prohibit the use of local load balancer? */
212
239
REG_VALUE(REG_CONN_LB_DISABLE, str, DEF_CONN_LB_DISABLE);
213
240
info->lb_disable = (*str &&
214
241
(strcmp(str, "1") == 0 ||
215
242
strcasecmp(str, "true") == 0 ||
216
strcasecmp(str, "yes" ) == 0));
243
strcasecmp(str, "yes" ) == 0 ||
244
strcasecmp(str, "on" ) == 0));
218
246
/* user header (with optional '\r\n' added automagically) */
219
247
REG_VALUE(REG_CONN_HTTP_USER_HEADER, str, DEF_CONN_HTTP_USER_HEADER);
652
712
if (!arg || !*arg)
653
713
return 1/*success*/;
654
ConnNetInfo_DeleteArg(info, arg);
714
ConnNetInfo_DeleteAllArgs(info, arg);
655
715
return ConnNetInfo_AppendArg(info, arg, val);
719
static int/*bool*/ s_IsSufficientAddress(const char* addr)
721
size_t i, len = strlen(addr);
722
int dots = 0, isip = 1;
725
for (i = 0; i < len; i++) {
726
if (addr[i] == '.') {
728
if (i && dots <= 3) {
730
size_t n = (size_t)(&addr[i] - (dot ? dot : addr - 1));
737
} else if (!isdigit((unsigned char) addr[i]))
742
if (dot == &addr[len - 1])
744
return isip ? 1 : dots < 2 ? 0 : 1;
748
static const char* s_ClientAddress(const char* client_host)
754
if (!client_host || s_IsSufficientAddress(client_host) ||
755
!(ip = SOCK_gethostbyname(*client_host ? client_host : 0)) ||
756
SOCK_ntoa(ip, addr, sizeof(addr)) != 0 ||
757
!(s = (char*) malloc(strlen(client_host) + strlen(addr) + 3))) {
760
sprintf(s, "%s(%s)", client_host, addr);
765
extern int/*bool*/ ConnNetInfo_SetupStandardArgs(SConnNetInfo* info)
767
static const char service[] = "service";
768
static const char address[] = "address";
769
static const char platform[] = "platform";
775
if (!info->service || !*info->service) {
779
/* Dispatcher CGI arguments (sacrifice some if they all do not fit) */
780
if (!(arch = CORE_GetPlatform()) || !*arch)
781
ConnNetInfo_DeleteArg(info, platform);
783
ConnNetInfo_PreOverrideArg(info, platform, arch);
784
if (!(addr = s_ClientAddress(info->client_host)) || !*addr)
785
ConnNetInfo_DeleteArg(info, address);
787
ConnNetInfo_PreOverrideArg(info, address, addr);
788
if (addr != info->client_host)
790
if (!ConnNetInfo_PreOverrideArg(info, service, info->service)) {
791
ConnNetInfo_DeleteArg(info, platform);
792
if (!ConnNetInfo_PreOverrideArg(info, service, info->service)) {
793
ConnNetInfo_DeleteArg(info, address);
794
if (!ConnNetInfo_PreOverrideArg(info, service, info->service))
798
return 1/*succeeded*/;
659
802
extern SConnNetInfo* ConnNetInfo_Clone(const SConnNetInfo* info)
661
804
SConnNetInfo* x_info;
1633
1778
/****************************************************************************
1634
* Reading and writing [host][:port] addresses
1779
* Reading and writing [host][:port] addresses: Deprecated here, use upcalls.
1638
1782
extern const char* StringToHostPort(const char* str,
1639
1783
unsigned int* host,
1640
1784
unsigned short* port)
1653
for (s = str; *s; s++) {
1654
if (isspace((unsigned char)(*s)) || *s == ':')
1657
if ((alen = (size_t)(s - str)) > sizeof(abuf) - 1)
1660
strncpy0(abuf, str, alen);
1661
if (!(h = SOCK_gethostbyname(abuf)))
1666
if (sscanf(++s, "%hu%n", &p, &n) < 1 ||
1667
(s[n] && !isspace((unsigned char) s[n])))
1668
return alen ? 0 : str;
1786
return SOCK_StringToHostPort(str, host, port);
1679
1789
extern size_t HostPortToString(unsigned int host,
1680
1790
unsigned short port,
1684
char x_buf[16/*sizeof("255.255.255.255")*/ + 8/*:port*/];
1687
if (!buf || !buflen)
1691
else if (SOCK_ntoa(host, x_buf, sizeof(x_buf)) != 0) {
1697
n += sprintf(x_buf + n, ":%hu", port);
1698
assert(n < sizeof(x_buf));
1701
memcpy(buf, x_buf, n);
1794
return SOCK_HostPortToString(host, port, buf, buflen);
1846
/****************************************************************************
1847
* CONNUTIL_GetUsername
1851
extern const char* CONNUTIL_GetUsername(char* buf, size_t bufsize)
1853
#if defined(NCBI_OS_UNIX)
1854
# if !defined(NCBI_OS_SOLARIS) && defined(HAVE_GETLOGIN_R)
1855
# ifndef LOGIN_NAME_MAX
1856
# ifdef _POSIX_LOGIN_NAME_MAX
1857
# define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX
1859
# define LOGIN_NAME_MAX 256
1862
char loginbuf[LOGIN_NAME_MAX + 1];
1865
# if !defined(NCBI_OS_SOLARIS) && defined(HAVE_GETPWUID_R)
1869
#elif defined(NCBI_OS_MSWIN)
1870
char loginbuf[256 + 1];
1871
DWORD loginbufsize = sizeof(loginbuf) - 1;
1875
assert(buf && bufsize);
1877
#ifndef NCBI_OS_UNIX
1879
# ifdef NCBI_OS_MSWIN
1880
if (GetUserName(loginbuf, &loginbufsize)) {
1881
assert(loginbufsize < sizeof(loginbuf));
1882
loginbuf[loginbufsize] = '\0';
1883
strncpy0(buf, loginbuf, bufsize - 1);
1886
if ((login = getenv("USERNAME")) != 0) {
1887
strncpy0(buf, login, bufsize - 1);
1892
#else /*!NCBI_OS_UNIX*/
1894
# if defined(NCBI_OS_SOLARIS) || !defined(HAVE_GETLOGIN_R)
1895
/* NB: getlogin() is MT-safe on Solaris, yet getlogin_r() comes in two
1896
* flavors that differ only in return type, so to make things simpler,
1897
* use plain getlogin() here */
1898
# ifndef NCBI_OS_SOLARIS
1901
if ((login = getlogin()) != 0)
1902
strncpy0(buf, login, bufsize - 1);
1903
# ifndef NCBI_OS_SOLARIS
1909
if (getlogin_r(loginbuf, sizeof(loginbuf) - 1) == 0) {
1910
loginbuf[sizeof(loginbuf) - 1] = '\0';
1911
strncpy0(buf, loginbuf, bufsize - 1);
1916
# if defined(NCBI_OS_SOLARIS) || \
1917
(!defined(HAVE_GETPWUID_R) && defined(HAVE_GETPWUID))
1918
/* NB: getpwuid() is MT-safe on Solaris, so use it here, if available */
1919
# ifndef NCBI_OS_SOLARIS
1922
if ((pw = getpwuid(getuid())) != 0 && pw->pw_name)
1923
strncpy0(buf, pw->pw_name, bufsize - 1);
1924
# ifndef NCBI_OS_SOLARIS
1927
if (pw && pw->pw_name)
1929
# elif defined(HAVE_GETPWUID_R)
1930
# if HAVE_GETPWUID_R == 4
1931
/* obsolete but still existent */
1932
pw = getpwuid_r(getuid(), &pwd, pwdbuf, sizeof(pwdbuf));
1933
# elif HAVE_GETPWUID_R == 5
1934
/* POSIX-conforming */
1935
if (getpwuid_r(getuid(), &pwd, pwdbuf, sizeof(pwdbuf), &pw) != 0)
1938
# error "Unknown value of HAVE_GETPWUID_R, 4 or 5 expected."
1940
if (pw && pw->pw_name) {
1942
strncpy0(buf, pw->pw_name, bufsize - 1);
1945
# endif /*HAVE_GETPWUID_R*/
1947
#endif /*!NCBI_OS_UNIX*/
1950
if (!(login = getenv("USER")) && !(login = getenv("LOGNAME"))) {
1954
strncpy0(buf, login, bufsize - 1);
1960
/****************************************************************************
1961
* Page size granularity
1962
* See also at corelib's ncbi_system.cpp::GetVirtualMemoryPageSize().
1965
size_t CONNUTIL_GetVMPageSize(void)
1967
static size_t ps = 0;
1970
#if defined(NCBI_OS_MSWIN)
1973
ps = (size_t) si.dwAllocationGranularity;
1974
#elif defined(NCBI_OS_UNIX)
1975
# if defined(_SC_PAGESIZE)
1976
# define NCBI_SC_PAGESIZE _SC_PAGESIZE
1977
# elif defined(_SC_PAGE_SIZE)
1978
# define NCBI_SC_PAGESIZE _SC_PAGE_SIZE
1979
# elif defined(NCBI_SC_PAGESIZE)
1980
# undef NCBI_SC_PAGESIZE
1982
# ifndef NCBI_SC_PAGESIZE
1985
long x = sysconf(NCBI_SC_PAGESIZE);
1986
# undef NCBI_SC_PAGESIZE
1989
# ifdef HAVE_GETPAGESIZE
1990
if ((x = getpagesize()) <= 0)
1754
2004
* --------------------------------------------------------------------------
1755
2005
* $Log: ncbi_connutil.c,v $
2006
* Revision 6.108 2006/04/21 14:38:12 lavr
2007
* ConnNetInfo_GetValue() simplified and sped up considerably
2009
* Revision 6.107 2006/04/21 01:37:17 lavr
2010
* SConnNetInfo::lb_disable reinstated along with LB_DISABLE reg/env key
2012
* Revision 6.105 2006/04/20 13:58:32 lavr
2013
* Registry keys for new switching scheme for service mappers;
2014
* Registry keys for LOCAL service mappers;
2015
* ConnNetInfo_GetValue() exported
2017
* Revision 6.104 2006/04/19 02:12:06 lavr
2018
* Call DeleteAllArgs when doing argument overrides
2020
* Revision 6.103 2006/04/19 01:38:48 lavr
2021
* ConnNetInfo_{Append|Prepend}Arg sped-up considerably
2023
* Revision 6.102 2006/04/11 13:51:23 lavr
2024
* URL_Connect(): Relax on parameter checking
2026
* Revision 6.101 2006/03/19 01:40:17 lavr
2027
* Yet another fix for s_IsSufficientAddress()
2029
* Revision 6.100 2006/03/17 16:42:33 lavr
2030
* BUF_StripToPattern(): Avoid type-punned ptr (and keep off GCC warning)
2032
* Revision 6.99 2006/03/16 20:04:02 lavr
2033
* s_IsSufficientAddress(): IP recognition bug fixed
2035
* Revision 6.98 2006/03/07 15:37:19 lavr
2036
* CONNUTIL_GetUsername(): Do not define loginbuf, if it's going to be unused
2038
* Revision 6.97 2006/02/23 17:42:36 lavr
2039
* CONNUTIL_GetVMPageSize(): use sysctl() first (fallback to getpagesize())
2041
* Revision 6.96 2006/02/23 15:23:03 lavr
2042
* +CONNUTIL_GetVMPageSize() [merely copy of what corelib/ncbi_system.cpp has]
2044
* Revision 6.95 2006/02/14 15:50:22 lavr
2045
* Introduce and use CONN_TRACE (via CORE_TRACE) -- NOP in Release mode
2047
* Revision 6.94 2006/02/01 16:24:24 lavr
2048
* CONNUTIL_GetUsername(): '\0'-terminate returned result of getlogin_r()
2050
* Revision 6.93 2006/02/01 00:54:45 ucko
2051
* One more fix to CONNUTIL_GetUsername: favor LOGIN_NAME_MAX over
2052
* _POSIX_LOGIN_NAME_MAX, which tends to be smaller, and may not be
2053
* defined at all on some BSDish systems, and fall back to 256 if neither
2056
* Revision 6.92 2006/01/31 20:38:12 lavr
2057
* CONNUTIL_GetUsername(): Pass pointer to buffer size in GetUserName()
2059
* Revision 6.91 2006/01/31 20:29:24 lavr
2060
* CONNUTIL_GetUsername(): use strncpy0 everywhere
2062
* Revision 6.90 2006/01/31 20:26:46 lavr
2063
* #include <pwd.h> only us getpwuid[_r]() is known to exist
2065
* Revision 6.89 2006/01/31 19:32:55 lavr
2066
* Use GetUserName() as provided by <winbase.h>
2068
* Revision 6.88 2006/01/31 19:24:40 lavr
2069
* CONNUTIL_GetUsername(): Clean ASCII username on MS-Windows
2071
* Revision 6.87 2006/01/31 19:14:28 lavr
2072
* CONNUTIL_GetUsername(): MS-Windows-specific username discovery
2074
* Revision 6.86 2006/01/31 17:22:55 lavr
2075
* CONNUTIL_GetUsername(): Consider USERNAME environment on Windows only
2077
* Revision 6.85 2006/01/31 17:11:53 lavr
2078
* MT-safe (as much as possible) implementation of CONNUTIL_GetUsername()
2080
* Revision 6.84 2006/01/30 18:03:04 lavr
2081
* Fix CONNUTIL_GetUsername() to return "buf" (instead of constant 0)
2083
* Revision 6.83 2006/01/27 17:08:56 lavr
2084
* Spell CONNUTIL_GetUsername() this way
2086
* Revision 6.82 2006/01/27 17:00:52 lavr
2087
* New CONNUTIL_GetUsername(); StringHostToPort() and HostPortToString()
2088
* to remain obsoleted and upcall standardized SOCK_...() replacements
2090
* Revision 6.81 2006/01/11 20:20:05 lavr
2091
* -UTIL_ClientAddress()
2092
* +ConnNetInfo_DeleteAllArgs()
2093
* +ConnNetInfo_SetupStandardArgs()
2095
* Revision 6.80 2006/01/11 16:25:02 lavr
2096
* +UTIL_ClientAddress()
1756
2098
* Revision 6.79 2005/11/29 21:32:31 lavr
1757
2099
* Reserve SConnNetInfo::scheme, user, and pass for future use