~ubuntu-branches/ubuntu/edgy/ncbi-tools6/edgy

« back to all changes in this revision

Viewing changes to connect/ncbi_connutil.c

  • Committer: Bazaar Package Importer
  • Author(s): Barry deFreese
  • Date: 2006-07-19 23:28:07 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20060719232807-et3cdmcjgmnyleyx
Tags: 6.1.20060507-3ubuntu1
Re-merge with Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  $Id: ncbi_connutil.c,v 6.79 2005/11/29 21:32:31 lavr Exp $
 
1
/*  $Id: ncbi_connutil.c,v 6.108 2006/04/21 14:38:12 lavr Exp $
2
2
 * ===========================================================================
3
3
 *
4
4
 *                            PUBLIC DOMAIN NOTICE
37
37
#include <ctype.h>
38
38
#include <errno.h>
39
39
#include <stdlib.h>
40
 
 
41
 
 
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
 
42
#    include <limits.h>
 
43
#  endif
 
44
#  if defined(HAVE_GETPWUID)  ||  defined(HAVE_GETPWUID_R)
 
45
#    include <pwd.h>
 
46
#  endif
 
47
#  include <unistd.h>
 
48
#elif defined(NCBI_OS_MSWIN)
 
49
#  if defined(_MSC_VER)  &&  (_MSC_VER > 1200)
 
50
#    define WIN32_LEAN_AND_MEAN
 
51
#  endif
 
52
#  include <windows.h>
 
53
#endif
 
54
 
 
55
 
 
56
extern const char* ConnNetInfo_GetValue(const char* service, const char* param,
 
57
                                        char* value, size_t value_size,
 
58
                                        const char* def_value)
45
59
{
46
 
    char        key[256];
47
 
    char*       sec;
 
60
    char        buf[256];
48
61
    const char* val;
 
62
    char*       s;
49
63
 
50
 
    if (!param  ||  !value  ||  value_size <= 0)
 
64
    if (!value  ||  value_size <= 0)
51
65
        return 0;
52
66
    *value = '\0';
53
67
 
 
68
    if (!param  ||  !*param)
 
69
        return 0;
 
70
 
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))
58
76
            return 0;
 
77
 
59
78
        /* First, environment search for 'service_CONN_param' */
60
 
        sprintf(key, "%s_" DEF_CONN_REG_SECTION "_%s", service, param);
61
 
        strupr(key);
62
 
        if ((val = getenv(key)) != 0)
 
79
        s = (char*) memcpy(buf, service, slen) + slen;
 
80
        *s++ = '_';
 
81
        memcpy(s, DEF_CONN_REG_SECTION, sizeof(DEF_CONN_REG_SECTION) - 1);
 
82
        s += sizeof(DEF_CONN_REG_SECTION) - 1;
 
83
        *s++ = '_';
 
84
        memcpy(s, param, plen);
 
85
        if ((val = getenv(strupr(buf))) != 0)
63
86
            return strncpy0(value, val, value_size - 1);
 
87
 
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;
67
 
        strupr(key);
68
 
        strcpy(sec, service);
69
 
        strupr(sec);
70
 
        CORE_REG_GET(sec, key, value, value_size, 0);
 
89
        buf[slen++] = '\0';
 
90
        s = buf + slen;
 
91
        CORE_REG_GET(buf, s, value, value_size, 0);
71
92
        if (*value)
72
93
            return value;
73
94
    } else {
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))
76
98
            return 0;
77
 
        sprintf(key, DEF_CONN_REG_SECTION "_%s", param);
78
 
        strupr(key);
 
99
        s = buf;
 
100
        memcpy(s, DEF_CONN_REG_SECTION, sizeof(DEF_CONN_REG_SECTION) - 1);
 
101
        s += sizeof(DEF_CONN_REG_SECTION) - 1;
 
102
        *s++ = '_';
 
103
        memcpy(s, param, plen);
 
104
        s = strupr(buf);
79
105
    }
80
106
 
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);
84
110
 
85
111
    /* Last resort: Search for 'param' in default registry section */
86
 
    strcpy(key, param);
87
 
    strupr(key);
88
 
    CORE_REG_GET(DEF_CONN_REG_SECTION, key, value, value_size, def_value);
89
 
 
 
112
    s += sizeof(DEF_CONN_REG_SECTION);
 
113
    CORE_REG_GET(DEF_CONN_REG_SECTION, s, value, value_size, def_value);
90
114
    return value;
91
115
}
92
116
 
100
124
extern SConnNetInfo* ConnNetInfo_Create(const char* service)
101
125
{
102
126
#define REG_VALUE(name, value, def_value) \
103
 
    s_GetValue(service, name, value, sizeof(value), def_value)
 
127
    ConnNetInfo_GetValue(service, name, value, sizeof(value), def_value)
104
128
 
105
129
    SConnNetInfo* info = (SConnNetInfo*) malloc(sizeof(*info) +
106
130
                                                (service  &&  *service
118
142
    if (!SOCK_gethostbyaddr(0, info->client_host, sizeof(info->client_host)))
119
143
        SOCK_gethostname(info->client_host, sizeof(info->client_host));
120
144
 
121
 
    /* Future extentions, clear up for now */
 
145
    /* Future extensions, clear up for now */
122
146
    info->scheme  = eURL_Unspec;
123
147
    info->user[0] = '\0';
124
148
    info->pass[0] = '\0';
185
209
        (strcmp(str, "1") == 0  ||
186
210
         strcasecmp(str, "true") == 0  ||
187
211
         strcasecmp(str, "yes" ) == 0  ||
 
212
         strcasecmp(str, "on"  ) == 0  ||
188
213
         strcasecmp(str, "some") == 0)) {
189
214
        info->debug_printout = eDebugPrintout_Some;
190
215
    } else if (*str  &&
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));
203
229
 
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));
210
237
 
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));
217
245
 
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);
246
274
 
247
275
extern int/*bool*/ ConnNetInfo_AdjustForHttpProxy(SConnNetInfo* info)
248
276
{
249
 
    if (info->http_proxy_adjusted  ||  !*info->http_proxy_host)
 
277
    if (!info  ||  info->http_proxy_adjusted  ||  !*info->http_proxy_host)
250
278
        return 0/*false*/;
251
279
 
252
280
    if (strlen(info->host) + 16 + strlen(info->path) >= sizeof(info->path)) {
559
587
                                         const char*   arg,
560
588
                                         const char*   val)
561
589
{
562
 
    const char* amp = "&";
 
590
    size_t len, used;
563
591
 
564
592
    if (!arg || !*arg)
565
593
        return 1/*success*/;
566
 
    if (!info->args[0])
567
 
        amp = "";
568
 
    if (strlen(info->args) + strlen(amp) + strlen(arg) +
569
 
        (val ? 1 + strlen(val) : 0) >= sizeof(info->args))
 
594
 
 
595
    used = strlen(info->args);
 
596
    len  = strlen(arg);
 
597
    
 
598
    if (used + (used ? 1/*&*/ : 0) + len +
 
599
        (val && *val ? 1/*=*/ + strlen(val) : 0) >= sizeof(info->args)) {
570
600
        return 0/*failure*/;
571
 
    strcat(info->args, amp);
572
 
    strcat(info->args, arg);
573
 
    if (!val || !*val)
574
 
        return 1/*success*/;
575
 
    strcat(info->args, "=");
576
 
    strcat(info->args, val);
 
601
    }
 
602
 
 
603
    if (used)
 
604
        info->args[used++] = '&';
 
605
    strcpy(info->args + used, arg);
 
606
    if (val && *val) {
 
607
        used += len;
 
608
        info->args[used++] = '=';
 
609
        strcpy(info->args + used, val);
 
610
    }
577
611
    return 1/*success*/;
578
612
}
579
613
 
582
616
                                          const char*   arg,
583
617
                                          const char*   val)
584
618
{
585
 
    char amp = '&';
586
 
    size_t off;
 
619
    size_t len, off, used;
587
620
 
588
621
    if (!arg || !*arg)
589
622
        return 1/*success*/;
590
 
    if (!info->args[0])
591
 
        amp = '\0';
592
 
    off = strlen(arg) + (val && *val ? 1 + strlen(val) : 0) + (amp ? 1 : 0);
593
 
    if (off + strlen(info->args) >= sizeof(info->args))
 
623
 
 
624
    used = strlen(info->args);
 
625
    len  = strlen(arg);
 
626
    off  = len + (val && *val ? 1/*=*/ + strlen(val) : 0) + (used? 1/*&*/ : 0);
 
627
 
 
628
    if (off + used >= sizeof(info->args))
594
629
        return 0/*failure*/;
595
 
    if (amp)
596
 
        memmove(&info->args[off], info->args, strlen(info->args) + 1);
 
630
 
 
631
    if (used)
 
632
        memmove(info->args + off, info->args, used + 1);
597
633
    strcpy(info->args, arg);
598
634
    if (val && *val) {
599
 
        strcat(info->args, "=");
600
 
        strcat(info->args, val);
 
635
        info->args[len++] = '=';
 
636
        strcpy(info->args + len, val);
601
637
    }
602
 
    if (amp)
603
 
        info->args[off - 1] = amp;
 
638
    if (used)
 
639
        info->args[off - 1] = '&';
604
640
    return 1/*success*/;
605
641
}
606
642
 
618
654
        if (*a == '&')
619
655
            a++;
620
656
        arglen = strcspn(a, "&");
621
 
        if (arglen < argnamelen || strncmp(a, arg, argnamelen) != 0 ||
 
657
        if (arglen < argnamelen || strncasecmp(a, arg, argnamelen) != 0 ||
622
658
            (a[argnamelen] && a[argnamelen] != '=' && a[argnamelen] != '&'))
623
659
            continue;
624
660
        if (a[arglen]) {
634
670
}
635
671
 
636
672
 
 
673
extern void ConnNetInfo_DeleteAllArgs(SConnNetInfo* info,
 
674
                                      const char*   args)
 
675
{
 
676
    char* temp;
 
677
    char* arg;
 
678
    if (!args || !*args || !(temp = strdup(args))) {
 
679
        if (args && *args)
 
680
            *info->args = '\0';
 
681
        return;
 
682
    }
 
683
    arg = temp;
 
684
    while (*arg) {
 
685
        char* end = strchr(arg, '&');
 
686
        if (!end)
 
687
            end = arg + strlen(arg);
 
688
        else
 
689
            *end++ = '\0';
 
690
        ConnNetInfo_DeleteArg(info, arg);
 
691
        arg = end;
 
692
    }
 
693
    free(temp);
 
694
}
 
695
 
 
696
 
637
697
extern int/*bool*/ ConnNetInfo_PreOverrideArg(SConnNetInfo* info,
638
698
                                              const char*   arg,
639
699
                                              const char*   val)
640
700
{
641
701
    if (!arg || !*arg)
642
702
        return 1/*success*/;
643
 
    ConnNetInfo_DeleteArg(info, arg);
 
703
    ConnNetInfo_DeleteAllArgs(info, arg);
644
704
    return ConnNetInfo_PrependArg(info, arg, val);
645
705
}
646
706
 
651
711
{
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);
656
716
}
657
717
 
658
718
 
 
719
static int/*bool*/ s_IsSufficientAddress(const char* addr)
 
720
{
 
721
    size_t i, len = strlen(addr);
 
722
    int dots = 0, isip = 1;
 
723
    const char* dot = 0;
 
724
 
 
725
    for (i = 0; i < len; i++) {
 
726
        if (addr[i] == '.') {
 
727
            ++dots;
 
728
            if (i  &&  dots <= 3) {
 
729
                if (isip) {
 
730
                    size_t n = (size_t)(&addr[i] - (dot ? dot : addr - 1));
 
731
                    if (n <= 1  ||  n > 4)
 
732
                        isip = 0;
 
733
                }
 
734
            } else
 
735
                isip = 0;
 
736
            dot = &addr[i];
 
737
        } else if (!isdigit((unsigned char) addr[i]))
 
738
            isip = 0;
 
739
    }
 
740
    if (dots < 3)
 
741
        isip = 0;
 
742
    if (dot == &addr[len - 1])
 
743
        --dots;
 
744
    return isip ? 1 : dots < 2 ? 0 : 1;
 
745
}
 
746
 
 
747
 
 
748
static const char* s_ClientAddress(const char* client_host)
 
749
{
 
750
    unsigned int ip;
 
751
    char addr[64];
 
752
    char* s;
 
753
 
 
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))) {
 
758
        return client_host;
 
759
    }
 
760
    sprintf(s, "%s(%s)", client_host, addr);
 
761
    return s;
 
762
}
 
763
 
 
764
 
 
765
extern int/*bool*/ ConnNetInfo_SetupStandardArgs(SConnNetInfo* info)
 
766
{
 
767
    static const char service[]  = "service";
 
768
    static const char address[]  = "address";
 
769
    static const char platform[] = "platform";
 
770
    const char* arch;
 
771
    const char* addr;
 
772
 
 
773
    if (!info)
 
774
        return 0/*failed*/;
 
775
    if (!info->service  ||  !*info->service) {
 
776
        assert(0);
 
777
        return 0/*failed*/;
 
778
    }
 
779
    /* Dispatcher CGI arguments (sacrifice some if they all do not fit) */
 
780
    if (!(arch = CORE_GetPlatform())  ||  !*arch)
 
781
        ConnNetInfo_DeleteArg(info, platform);
 
782
    else
 
783
        ConnNetInfo_PreOverrideArg(info, platform, arch);
 
784
    if (!(addr = s_ClientAddress(info->client_host))  ||  !*addr)
 
785
        ConnNetInfo_DeleteArg(info, address);
 
786
    else
 
787
        ConnNetInfo_PreOverrideArg(info, address, addr);
 
788
    if (addr != info->client_host)
 
789
        free((void*) addr);
 
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))
 
795
                return 0/*failed*/;
 
796
        }
 
797
    }
 
798
    return 1/*succeeded*/;
 
799
}
 
800
 
 
801
 
659
802
extern SConnNetInfo* ConnNetInfo_Clone(const SConnNetInfo* info)
660
803
{
661
804
    SConnNetInfo* x_info;
797
940
    char        buffer[80];
798
941
    size_t      headersize;
799
942
    const char* x_args = 0;
 
943
    size_t      user_hdr_len = user_hdr  &&  *user_hdr ? strlen(user_hdr) : 0;
800
944
    const char* x_req_r; /* "POST "/"GET " */
801
945
 
802
946
    /* check the args */
803
 
    if (!host  ||  !*host  ||  !port  ||  !path  ||  !*path  ||
804
 
        (user_hdr  &&  *user_hdr  &&  user_hdr[strlen(user_hdr)-1] != '\n')) {
 
947
    if (!host  ||  !*host  ||  !port  ||
 
948
        (user_hdr  &&  *user_hdr  &&  user_hdr[user_hdr_len - 1] != '\n')) {
805
949
        CORE_LOG(eLOG_Error, "[URL_Connect]  Bad arguments");
806
950
        assert(0);
807
951
        return 0/*error*/;
853
997
    if (/* {POST|GET} <path>?<args> HTTP/1.0\r\n */
854
998
        !BUF_Write(&buf, x_req_r, strlen(x_req_r))            ||
855
999
        !BUF_Write(&buf, path,    strlen(path))               ||
856
 
        (x_args
 
1000
        (x_args  &&  *x_args
857
1001
         &&  (!BUF_Write(&buf, X_REQ_Q, sizeof(X_REQ_Q) - 1)  ||
858
1002
              !BUF_Write(&buf, x_args,  strlen(x_args))))     ||
859
1003
        !BUF_Write(&buf,       X_REQ_E, sizeof(X_REQ_E) - 1)  ||
864
1008
        !BUF_Write(&buf, "\r\n", 2)                           ||
865
1009
 
866
1010
        /* <user_header> */
867
 
        (user_hdr
868
 
         &&  !BUF_Write(&buf, user_hdr, strlen(user_hdr)))    ||
 
1011
        (user_hdr  &&  *user_hdr
 
1012
         &&  !BUF_Write(&buf, user_hdr, user_hdr_len))        ||
869
1013
 
870
1014
        /* Content-Length: <content_length>\r\n\r\n */
871
1015
        (req_method != eReqMethod_Get
1095
1239
 size_t*   n_read,
1096
1240
 EIO_Event what)
1097
1241
{
 
1242
    BUF b;
1098
1243
    switch (what) {
1099
1244
    case eIO_Read:
1100
1245
        *n_read = BUF_Read((BUF) stream, buf, size);
1101
1246
        return *n_read ? eIO_Success : eIO_Closed;
1102
1247
    case eIO_Write:
1103
1248
        assert(stream);
1104
 
        return BUF_PushBack((BUF*) &stream, buf, size)
1105
 
            ? eIO_Success : eIO_Unknown;
 
1249
        b = (BUF) stream;
 
1250
        return BUF_PushBack(&b, buf, size) ? eIO_Success : eIO_Unknown;
1106
1251
    default:
1107
1252
        break;
1108
1253
    }
1631
1776
 
1632
1777
 
1633
1778
/****************************************************************************
1634
 
 * Reading and writing [host][:port] addresses
 
1779
 * Reading and writing [host][:port] addresses:  Deprecated here, use upcalls.
1635
1780
 */
1636
1781
 
1637
 
 
1638
1782
extern const char* StringToHostPort(const char*     str,
1639
1783
                                    unsigned int*   host,
1640
1784
                                    unsigned short* port)
1641
1785
{
1642
 
    unsigned short p;
1643
 
    unsigned int h;
1644
 
    char abuf[256];
1645
 
    const char* s;
1646
 
    size_t alen;
1647
 
    int n = 0;
1648
 
 
1649
 
    if (host)
1650
 
        *host = 0;
1651
 
    if (port)
1652
 
        *port = 0;
1653
 
    for (s = str; *s; s++) {
1654
 
        if (isspace((unsigned char)(*s)) || *s == ':')
1655
 
            break;
1656
 
    }
1657
 
    if ((alen = (size_t)(s - str)) > sizeof(abuf) - 1)
1658
 
        return str;
1659
 
    if (alen) {
1660
 
        strncpy0(abuf, str, alen);
1661
 
        if (!(h = SOCK_gethostbyname(abuf)))
1662
 
            return str;
1663
 
    } else
1664
 
        h = 0;
1665
 
    if (*s == ':') {
1666
 
        if (sscanf(++s, "%hu%n", &p, &n) < 1 ||
1667
 
            (s[n] && !isspace((unsigned char) s[n])))
1668
 
            return alen ? 0 : str;
1669
 
    } else
1670
 
        p = 0;
1671
 
    if (host)
1672
 
        *host = h;
1673
 
    if (port)
1674
 
        *port = p;
1675
 
    return s + n;
 
1786
    return SOCK_StringToHostPort(str, host, port);
1676
1787
}
1677
1788
 
1678
 
 
1679
1789
extern size_t HostPortToString(unsigned int   host,
1680
1790
                               unsigned short port,
1681
1791
                               char*          buf,
1682
1792
                               size_t         buflen)
1683
1793
{
1684
 
    char   x_buf[16/*sizeof("255.255.255.255")*/ + 8/*:port*/];
1685
 
    size_t n;
1686
 
 
1687
 
    if (!buf || !buflen)
1688
 
        return 0;
1689
 
    if (!host)
1690
 
        *x_buf = 0;
1691
 
    else if (SOCK_ntoa(host, x_buf, sizeof(x_buf)) != 0) {
1692
 
        *buf = 0;
1693
 
        return 0;
1694
 
    }
1695
 
    n = strlen(x_buf);
1696
 
    if (port || !host)
1697
 
        n += sprintf(x_buf + n, ":%hu", port);
1698
 
    assert(n < sizeof(x_buf));
1699
 
    if (n >= buflen)
1700
 
        n = buflen - 1;
1701
 
    memcpy(buf, x_buf, n);
1702
 
    buf[n] = 0;
1703
 
    return n;
 
1794
    return SOCK_HostPortToString(host, port, buf, buflen);
1704
1795
}
1705
1796
 
1706
1797
 
1735
1826
}
1736
1827
 
1737
1828
 
1738
 
unsigned int CRC32_Update(unsigned int checksum, const void *ptr, size_t count)
 
1829
extern unsigned int CRC32_Update(unsigned int checksum,
 
1830
                                 const void *ptr, size_t count)
1739
1831
{
1740
1832
    const unsigned char* str = (const unsigned char*) ptr;
1741
1833
    size_t j;
1750
1842
}
1751
1843
 
1752
1844
 
 
1845
 
 
1846
/****************************************************************************
 
1847
 * CONNUTIL_GetUsername
 
1848
 */
 
1849
 
 
1850
 
 
1851
extern const char* CONNUTIL_GetUsername(char* buf, size_t bufsize)
 
1852
{
 
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
 
1858
#      else
 
1859
#        define LOGIN_NAME_MAX 256
 
1860
#      endif
 
1861
#    endif
 
1862
    char loginbuf[LOGIN_NAME_MAX + 1];
 
1863
#  endif
 
1864
    struct passwd* pw;
 
1865
#  if !defined(NCBI_OS_SOLARIS)  &&  defined(HAVE_GETPWUID_R)
 
1866
    struct passwd pwd;
 
1867
    char pwdbuf[256];
 
1868
#  endif
 
1869
#elif defined(NCBI_OS_MSWIN)
 
1870
    char  loginbuf[256 + 1];
 
1871
    DWORD loginbufsize = sizeof(loginbuf) - 1;
 
1872
#endif
 
1873
    const char* login;
 
1874
 
 
1875
    assert(buf  &&  bufsize);
 
1876
 
 
1877
#ifndef NCBI_OS_UNIX
 
1878
 
 
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);
 
1884
        return buf;
 
1885
    }
 
1886
    if ((login = getenv("USERNAME")) != 0) {
 
1887
        strncpy0(buf, login, bufsize - 1);
 
1888
        return buf;
 
1889
    }
 
1890
#  endif
 
1891
 
 
1892
#else /*!NCBI_OS_UNIX*/
 
1893
 
 
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
 
1899
    CORE_LOCK_WRITE;
 
1900
#    endif
 
1901
    if ((login = getlogin()) != 0)
 
1902
        strncpy0(buf, login, bufsize - 1);
 
1903
#    ifndef NCBI_OS_SOLARIS
 
1904
    CORE_UNLOCK;
 
1905
#    endif
 
1906
    if (login)
 
1907
        return buf;
 
1908
#  else
 
1909
    if (getlogin_r(loginbuf, sizeof(loginbuf) - 1) == 0) {
 
1910
        loginbuf[sizeof(loginbuf) - 1] = '\0';
 
1911
        strncpy0(buf, loginbuf, bufsize - 1);
 
1912
        return buf;
 
1913
    }
 
1914
#  endif
 
1915
 
 
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
 
1920
    CORE_LOCK_WRITE;
 
1921
#  endif
 
1922
    if ((pw = getpwuid(getuid())) != 0  &&  pw->pw_name)
 
1923
        strncpy0(buf, pw->pw_name, bufsize - 1);
 
1924
#  ifndef NCBI_OS_SOLARIS
 
1925
    CORE_UNLOCK;
 
1926
#  endif
 
1927
    if (pw  &&  pw->pw_name)
 
1928
        return buf;
 
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)
 
1936
        pw = 0;
 
1937
#    else
 
1938
#      error "Unknown value of HAVE_GETPWUID_R, 4 or 5 expected."
 
1939
#    endif
 
1940
    if (pw  &&  pw->pw_name) {
 
1941
        assert(pw == &pwd);
 
1942
        strncpy0(buf, pw->pw_name, bufsize - 1);
 
1943
        return buf;
 
1944
    }
 
1945
#  endif /*HAVE_GETPWUID_R*/
 
1946
 
 
1947
#endif /*!NCBI_OS_UNIX*/
 
1948
 
 
1949
    /* last resort */
 
1950
    if (!(login = getenv("USER"))  &&  !(login = getenv("LOGNAME"))) {
 
1951
        buf[0] = '\0';
 
1952
        return 0;
 
1953
    }
 
1954
    strncpy0(buf, login, bufsize - 1);
 
1955
    return buf;
 
1956
}
 
1957
 
 
1958
 
 
1959
 
 
1960
/****************************************************************************
 
1961
 * Page size granularity
 
1962
 * See also at corelib's ncbi_system.cpp::GetVirtualMemoryPageSize().
 
1963
 */
 
1964
 
 
1965
size_t CONNUTIL_GetVMPageSize(void)
 
1966
{
 
1967
    static size_t ps = 0;
 
1968
 
 
1969
    if (!ps) {
 
1970
#if defined(NCBI_OS_MSWIN)
 
1971
        SYSTEM_INFO si;
 
1972
        GetSystemInfo(&si); 
 
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
 
1981
#  endif
 
1982
#  ifndef   NCBI_SC_PAGESIZE
 
1983
        long x = 0;
 
1984
#  else
 
1985
        long x = sysconf(NCBI_SC_PAGESIZE);
 
1986
#    undef  NCBI_SC_PAGESIZE
 
1987
#  endif
 
1988
        if (x <= 0) {
 
1989
#  ifdef HAVE_GETPAGESIZE
 
1990
            if ((x = getpagesize()) <= 0)
 
1991
                return 0;
 
1992
#  else
 
1993
            return 0;
 
1994
#  endif
 
1995
        }
 
1996
        ps = (size_t) x;
 
1997
#endif /*OS_TYPE*/
 
1998
    }
 
1999
    return ps;
 
2000
}
 
2001
 
 
2002
 
1753
2003
/*
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
 
2008
 *
 
2009
 * Revision 6.107  2006/04/21 01:37:17  lavr
 
2010
 * SConnNetInfo::lb_disable reinstated along with LB_DISABLE reg/env key
 
2011
 *
 
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
 
2016
 *
 
2017
 * Revision 6.104  2006/04/19 02:12:06  lavr
 
2018
 * Call DeleteAllArgs when doing argument overrides
 
2019
 *
 
2020
 * Revision 6.103  2006/04/19 01:38:48  lavr
 
2021
 * ConnNetInfo_{Append|Prepend}Arg sped-up considerably
 
2022
 *
 
2023
 * Revision 6.102  2006/04/11 13:51:23  lavr
 
2024
 * URL_Connect():  Relax on parameter checking
 
2025
 *
 
2026
 * Revision 6.101  2006/03/19 01:40:17  lavr
 
2027
 * Yet another fix for s_IsSufficientAddress()
 
2028
 *
 
2029
 * Revision 6.100  2006/03/17 16:42:33  lavr
 
2030
 * BUF_StripToPattern(): Avoid type-punned ptr (and keep off GCC warning)
 
2031
 *
 
2032
 * Revision 6.99  2006/03/16 20:04:02  lavr
 
2033
 * s_IsSufficientAddress():  IP recognition bug fixed
 
2034
 *
 
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
 
2037
 *
 
2038
 * Revision 6.97  2006/02/23 17:42:36  lavr
 
2039
 * CONNUTIL_GetVMPageSize(): use sysctl() first (fallback to getpagesize())
 
2040
 *
 
2041
 * Revision 6.96  2006/02/23 15:23:03  lavr
 
2042
 * +CONNUTIL_GetVMPageSize() [merely copy of what corelib/ncbi_system.cpp has]
 
2043
 *
 
2044
 * Revision 6.95  2006/02/14 15:50:22  lavr
 
2045
 * Introduce and use CONN_TRACE (via CORE_TRACE) -- NOP in Release mode
 
2046
 *
 
2047
 * Revision 6.94  2006/02/01 16:24:24  lavr
 
2048
 * CONNUTIL_GetUsername(): '\0'-terminate returned result of getlogin_r()
 
2049
 *
 
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
 
2054
 * is defined.
 
2055
 *
 
2056
 * Revision 6.92  2006/01/31 20:38:12  lavr
 
2057
 * CONNUTIL_GetUsername():  Pass pointer to buffer size in GetUserName()
 
2058
 *
 
2059
 * Revision 6.91  2006/01/31 20:29:24  lavr
 
2060
 * CONNUTIL_GetUsername():  use strncpy0 everywhere
 
2061
 *
 
2062
 * Revision 6.90  2006/01/31 20:26:46  lavr
 
2063
 * #include <pwd.h> only us getpwuid[_r]() is known to exist
 
2064
 *
 
2065
 * Revision 6.89  2006/01/31 19:32:55  lavr
 
2066
 * Use GetUserName() as provided by <winbase.h>
 
2067
 *
 
2068
 * Revision 6.88  2006/01/31 19:24:40  lavr
 
2069
 * CONNUTIL_GetUsername():  Clean ASCII username on MS-Windows
 
2070
 *
 
2071
 * Revision 6.87  2006/01/31 19:14:28  lavr
 
2072
 * CONNUTIL_GetUsername():  MS-Windows-specific username discovery
 
2073
 *
 
2074
 * Revision 6.86  2006/01/31 17:22:55  lavr
 
2075
 * CONNUTIL_GetUsername(): Consider USERNAME environment on Windows only
 
2076
 *
 
2077
 * Revision 6.85  2006/01/31 17:11:53  lavr
 
2078
 * MT-safe (as much as possible) implementation of CONNUTIL_GetUsername()
 
2079
 *
 
2080
 * Revision 6.84  2006/01/30 18:03:04  lavr
 
2081
 * Fix CONNUTIL_GetUsername() to return "buf" (instead of constant 0)
 
2082
 *
 
2083
 * Revision 6.83  2006/01/27 17:08:56  lavr
 
2084
 * Spell CONNUTIL_GetUsername() this way
 
2085
 *
 
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
 
2089
 *
 
2090
 * Revision 6.81  2006/01/11 20:20:05  lavr
 
2091
 * -UTIL_ClientAddress()
 
2092
 * +ConnNetInfo_DeleteAllArgs()
 
2093
 * +ConnNetInfo_SetupStandardArgs()
 
2094
 *
 
2095
 * Revision 6.80  2006/01/11 16:25:02  lavr
 
2096
 * +UTIL_ClientAddress()
 
2097
 *
1756
2098
 * Revision 6.79  2005/11/29 21:32:31  lavr
1757
2099
 * Reserve SConnNetInfo::scheme, user, and pass for future use
1758
2100
 *