Annotation of libwww/Library/src/HTInet.c, revision 2.28

2.1       frystyk     1: /*                                                                    HTInet.c
                      2: **     GENERIC INTERNET UTILITIES
                      3: **
                      4: **     (c) COPYRIGHT MIT 1995.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
2.28    ! kahan       6: **     @(#) $Id: HTInet.c,v 2.27 1999/06/22 22:40:48 frystyk Exp $
2.1       frystyk     7: **
                      8: **     This code is in common between client and server sides.
                      9: **
                     10: **     16 Mar 96  HFN  Spawned off from HTTCP.c
                     11: */
                     12: 
                     13: /* Library include files */
2.19      frystyk    14: #include "wwwsys.h"
2.1       frystyk    15: #include "WWWUtil.h"
                     16: #include "HTParse.h"
                     17: #include "HTAlert.h"
                     18: #include "HTError.h"
                     19: #include "HTNetMan.h"
                     20: #include "HTDNS.h"
                     21: #include "HTInet.h"                                     /* Implemented here */
                     22: 
2.3       frystyk    23: #ifndef DEFAULT_NEWS_HOST
                     24: #define DEFAULT_NEWS_HOST      "news"
                     25: #endif
2.1       frystyk    26: 
2.3       frystyk    27: #ifndef SERVER_FILE
                     28: #define SERVER_FILE            "/usr/local/lib/rn/server"
                     29: #endif
2.1       frystyk    30: 
                     31: /* ------------------------------------------------------------------------- */
                     32: 
                     33: /*
                     34: **     Returns the string equivalent to the errno passed in the argument.
                     35: **     We can't use errno directly as we have both errno and socerrno. The
2.20      frystyk    36: **     result is a dynamic string that must be freed by the caller.
2.1       frystyk    37: */
2.20      frystyk    38: PUBLIC char * HTErrnoString (int errornumber)
2.1       frystyk    39: {
2.20      frystyk    40:     char * msg = NULL;
                     41: #ifdef _WINSOCKAPI_
                     42:     if ((msg = (char *) HT_MALLOC(64)) == NULL)
                     43:        HT_OUTOFMEM("HTErrnoString");
                     44:     *msg = '\0';
                     45:     sprintf(msg, "WinSock reported error=%ld", WSAGetLastError());
                     46: #else
2.1       frystyk    47: #ifdef HAVE_STRERROR
2.20      frystyk    48:     StrAllocCopy(msg, strerror(errornumber));
2.1       frystyk    49: #else
                     50: #ifdef HAVE_SYS_ERRLIST
                     51: #ifdef HAVE_SYS_NERR
2.20      frystyk    52:     if (errno < sys_nerr)
                     53:        StrAllocCopy(msg, sys_errlist[errno]);
                     54:     else 
                     55:         StrAllocCopy(msg, "Unknown error");
2.1       frystyk    56: #else
2.20      frystyk    57:     StrAllocCopy(msg, sys_errlist[errno]);
2.1       frystyk    58: #endif /* HAVE_SYS_NERR */
                     59: #else
                     60: #ifdef VMS
2.20      frystyk    61:     if ((msg = (char *) HT_MALLOC(64)) == NULL)
                     62:        HT_OUTOFMEM("HTErrnoString");
                     63:     *msg = '\0';
                     64:     sprintf(msg, "Unix errno=%ld dec, VMS error=%lx hex", errornumber,
2.1       frystyk    65:            vaxc$errno);
                     66: #else
2.20      frystyk    67:     StrAllocCopy(msg, "Error number not translated!");
2.1       frystyk    68: #endif /* _WINSOCKAPI_ */
                     69: #endif /* VMS */
                     70: #endif /* HAVE_SYS_ERRLIST */
                     71: #endif /* HAVE_STRERROR */
2.20      frystyk    72:     return msg;
2.1       frystyk    73: }
                     74: 
                     75: 
                     76: /*     Debug error message
                     77: */
                     78: PUBLIC int HTInetStatus (int errnum, char * where)
                     79: {
                     80: #ifdef VMS
2.25      frystyk    81:     HTTRACE(CORE_TRACE, "System Error Unix = %ld dec\n" _ errno);
                     82:     HTTRACE(CORE_TRACE, "System Error VMS  = %lx hex\n" _ vaxc$errno);
2.1       frystyk    83:     return (-vaxc$errno);
                     84: #else
                     85: #ifdef _WINSOCKAPI_
2.25      frystyk    86:     HTTRACE(CORE_TRACE, "System Error Unix = %ld dec\n" _ errno);
                     87:     HTTRACE(CORE_TRACE, "System Error WinSock error=%lx hex\n" _ 
2.1       frystyk    88:                            WSAGetLastError());
                     89:     return (-errnum);
                     90: #else
2.25      frystyk    91: #ifdef HTDEBUG
                     92:     if (CORE_TRACE) {
2.20      frystyk    93:        char * errmsg = HTErrnoString(errnum);
2.25      frystyk    94:        HTTRACE(CORE_TRACE, "System Error %d after call to %s() failed\n............ %s\n" _
                     95:                errno _ where _ errmsg);
2.20      frystyk    96:        HT_FREE(errmsg);
                     97:     }
2.25      frystyk    98: #endif /* HTDEBUG */
2.1       frystyk    99:     return (-errnum);
                    100: #endif /* _WINSOCKAPI_ */
                    101: #endif /* VMS */
                    102: }
                    103: 
                    104: 
                    105: /*     Parse a cardinal value                                 parse_cardinal()
                    106: **     ----------------------
                    107: **
                    108: ** On entry,
                    109: **     *pp         points to first character to be interpreted, terminated by
                    110: **                 non 0:9 character.
                    111: **     *pstatus    points to status already valid
                    112: **     maxvalue    gives the largest allowable value.
                    113: **
                    114: ** On exit,
                    115: **     *pp         points to first unread character
                    116: **     *pstatus    points to status updated iff bad
                    117: */
                    118: 
                    119: PUBLIC unsigned int HTCardinal (int *          pstatus,
                    120:                                char **         pp,
                    121:                                unsigned int    max_value)
                    122: {
                    123:     unsigned int n=0;
                    124:     if ( (**pp<'0') || (**pp>'9')) {       /* Null string is error */
                    125:        *pstatus = -3;  /* No number where one expeceted */
                    126:        return 0;
                    127:     }
                    128:     while ((**pp>='0') && (**pp<='9')) n = n*10 + *((*pp)++) - '0';
                    129: 
                    130:     if (n>max_value) {
                    131:        *pstatus = -4;  /* Cardinal outside range */
                    132:        return 0;
                    133:     }
                    134: 
                    135:     return n;
                    136: }
                    137: 
                    138: /* ------------------------------------------------------------------------- */
                    139: /*                             SIGNAL HANDLING                              */
                    140: /* ------------------------------------------------------------------------- */
                    141: 
                    142: #ifdef WWWLIB_SIG
                    143: /*                                                                 HTSetSignal
                    144: **  This function sets up signal handlers. This might not be necessary to
                    145: **  call if the application has its own handlers.
                    146: */
                    147: #include <signal.h>
2.26      frystyk   148: 
2.1       frystyk   149: PUBLIC void HTSetSignal (void)
                    150: {
                    151:     /* On some systems (SYSV) it is necessary to catch the SIGPIPE signal
                    152:     ** when attemting to connect to a remote host where you normally should
                    153:     ** get `connection refused' back
                    154:     */
                    155:     if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
2.25      frystyk   156:        HTTRACE(CORE_TRACE, "HTSignal.... Can't catch SIGPIPE\n");
2.1       frystyk   157:     } else {
2.25      frystyk   158:        HTTRACE(CORE_TRACE, "HTSignal.... Ignoring SIGPIPE\n");
2.1       frystyk   159:     }
                    160: }
2.26      frystyk   161: #else /* WWWLIB_SIG */
                    162: 
                    163: PUBLIC void HTSetSignal (void) { }
                    164: 
2.1       frystyk   165: #endif /* WWWLIB_SIG */
                    166: 
                    167: /* ------------------------------------------------------------------------- */
                    168: /*                          HOST NAME FUNCTIONS                             */
                    169: /* ------------------------------------------------------------------------- */
                    170: 
                    171: /*     Produce a string for an Internet address
                    172: **     ----------------------------------------
                    173: **
                    174: ** On exit,
                    175: **     returns a pointer to a static string which must be copied if
                    176: **             it is to be kept.
                    177: */
                    178: PUBLIC const char * HTInetString (SockA * sin)
                    179: {
                    180: #ifndef DECNET  /* Function only used below for a trace message */
                    181: #if 0
                    182:     /* This dumps core on some Sun systems :-(. The problem is now, that 
                    183:        the current implememtation only works for IP-addresses and not in
                    184:        other address spaces. */
                    185:     return inet_ntoa(sin->sin_addr);
                    186: #endif
                    187:     static char string[16];
                    188:     sprintf(string, "%d.%d.%d.%d",
                    189:            (int)*((unsigned char *)(&sin->sin_addr)+0),
                    190:            (int)*((unsigned char *)(&sin->sin_addr)+1),
                    191:            (int)*((unsigned char *)(&sin->sin_addr)+2),
                    192:            (int)*((unsigned char *)(&sin->sin_addr)+3));
                    193:     return string;
                    194: #else
                    195:     return "";
                    196: #endif /* Decnet */
                    197: }
                    198: 
                    199: /*     Parse a network node address and port
                    200: **     -------------------------------------
                    201: **     It is assumed that any portnumber and numeric host address
                    202: **     is given in decimal notation. Separation character is '.'
2.2       frystyk   203: **     Any port number gets chopped off
2.1       frystyk   204: **      Returns:
                    205: **             >0      Number of homes
                    206: **              0      Wait for persistent socket
                    207: **             -1      Error
                    208: */
2.11      frystyk   209: PUBLIC int HTParseInet (HTHost * host, char * hostname, HTRequest * request)
2.1       frystyk   210: {
                    211:     int status = 1;
2.11      frystyk   212:     SockA *sin = &host->sock_addr;
2.1       frystyk   213: 
                    214: #ifdef DECNET
                    215:     /* read Decnet node name. @@ Should know about DECnet addresses, but it's
                    216:        probably worth waiting until the Phase transition from IV to V. */
                    217: 
2.11      frystyk   218:     sin->sdn_nam.n_len = min(DN_MAXNAML, strlen(hostname));  /* <=6 in phase 4 */
                    219:     strncpy (sin->sdn_nam.n_name, hostname, sin->sdn_nam.n_len + 1);
2.1       frystyk   220: 
2.25      frystyk   221:     HTTRACE(CORE_TRACE, "DECnet: Parsed address as object number %d on host %.6s...\n" _ 
                    222:                sin->sdn_objnum _ hostname);
2.1       frystyk   223: #else /* Internet */
                    224:     {
2.11      frystyk   225:        char *strptr = hostname;
2.1       frystyk   226:        while (*strptr) {
                    227:            if (*strptr == ':') {
                    228:                *strptr = '\0';    /* Don't want port number in numeric host */
                    229:                break;
                    230:            }
2.18      frystyk   231:            if (!isdigit((int) *strptr) && *strptr != '.')
2.1       frystyk   232:                break;
                    233:            strptr++;
                    234:        }
                    235:        if (!*strptr) {
                    236: #ifdef GUSI
2.11      frystyk   237:            sin->sin_addr = inet_addr(hostname);                 /* See netinet/in.h */
2.1       frystyk   238: #else
2.11      frystyk   239:            sin->sin_addr.s_addr = inet_addr(hostname);   /* See arpa/inet.h */
2.1       frystyk   240: #endif
2.2       frystyk   241:        } else {
2.11      frystyk   242:            char * port = strchr(hostname, ':');                        /* Chop port */
2.2       frystyk   243:            if (port) *port = '\0';
2.11      frystyk   244:            status = HTGetHostByName(host, hostname, request);
2.2       frystyk   245:        }
2.25      frystyk   246: #ifdef HTDEBUG
                    247:        if (status > 0)
                    248:            HTTRACE(CORE_TRACE, "ParseInet... as port %d on %s with %d homes\n" _
                    249:                    (int) ntohs(sin->sin_port) _ HTInetString(sin) _ status);
                    250: #endif /* HTDEBUG */
2.1       frystyk   251:     }
                    252: #endif /* Internet vs. Decnet */
                    253:     return status;
                    254: }
                    255: 
                    256: 
2.3       frystyk   257: #if 0
2.1       frystyk   258: /*                                                             HTGetDomainName
                    259: **     Returns the current domain name without the local host name.
                    260: **     The response is pointing to a static area that might be changed
                    261: **     using HTSetHostName().
                    262: **
                    263: **     Returns NULL on error, "" if domain name is not found
                    264: */
2.3       frystyk   265: PRIVATE char * HTGetDomainName (void)
2.1       frystyk   266: {
2.3       frystyk   267:     char * host = HTGetHostName();
                    268:     char * domain;
2.1       frystyk   269:     if (host && *host) {
                    270:        if ((domain = strchr(host, '.')) != NULL)
                    271:            return ++domain;
                    272:        else
                    273:            return "";
                    274:     } else
                    275:        return NULL;
                    276: }
2.3       frystyk   277: #endif
2.1       frystyk   278: 
                    279: /*                                                             HTGetHostName
                    280: **     Returns the name of this host. It uses the following algoritm:
                    281: **
                    282: **     1) gethostname()
                    283: **     2) if the hostname doesn't contain any '.' try to read
                    284: **        /etc/resolv.conf. If there is no domain line in this file then
                    285: **     3) Try getdomainname and do as the man pages say for resolv.conf (sun)
                    286: **        If there is no domain line in this file, then it is derived
                    287: **        from the domain name set by the domainname(1) command, usually
                    288: **        by removing the first component. For example, if the domain-
                    289: **        name is set to ``foo.podunk.edu'' then the default domain name
                    290: **        used will be ``pudunk.edu''.
                    291: **
                    292: **     This is the same procedure as used by res_init() and sendmail.
                    293: **
                    294: **     Return: hostname on success else NULL
                    295: */
2.3       frystyk   296: PUBLIC char * HTGetHostName (void)
2.1       frystyk   297: {
2.3       frystyk   298:     char * hostname = NULL;
2.1       frystyk   299:     int fqdn = 0;                                   /* 0=no, 1=host, 2=fqdn */
                    300:     char name[MAXHOSTNAMELEN+1];
                    301:     *(name+MAXHOSTNAMELEN) = '\0';
                    302: 
2.8       frystyk   303: #if defined(HAVE_SYSINFO) && defined(SI_HOSTNAME)
2.1       frystyk   304:     if (!fqdn && sysinfo(SI_HOSTNAME, name, MAXHOSTNAMELEN) > 0) {
                    305:        char * dot = strchr(name, '.');
2.25      frystyk   306:        HTTRACE(CORE_TRACE, "HostName.... sysinfo says `%s\'\n" _ name);
2.1       frystyk   307:        StrAllocCopy(hostname, name);
                    308:        fqdn = dot ? 2 : 1;
                    309:     }
                    310: #endif /* HAVE_SYSINFO */
                    311: 
                    312: #ifdef HAVE_GETHOSTNAME
                    313:     if (!fqdn && gethostname(name, MAXHOSTNAMELEN) == 0) {
                    314:        char * dot = strchr(name, '.');
2.25      frystyk   315:        HTTRACE(CORE_TRACE, "HostName.... gethostname says `%s\'\n" _ name);
2.1       frystyk   316:        StrAllocCopy(hostname, name);
                    317:        fqdn = dot ? 2 : 1;
                    318:     }
                    319: #endif /* HAVE_GETHOSTNAME */
                    320: 
                    321: #ifdef RESOLV_CONF
                    322:     /* Now try the resolver config file */
2.14      frystyk   323:     {
                    324:        FILE *fp;
                    325:        if (fqdn==1 && (fp = fopen(RESOLV_CONF, "r")) != NULL) {
                    326:            char buffer[80];
                    327:            *(buffer+79) = '\0';
                    328:            while (fgets(buffer, 79, fp)) {
                    329:                if (!strncasecomp(buffer, "domain", 6) ||
                    330:                    !strncasecomp(buffer, "search", 6)) {
                    331:                    char *domainstr = buffer+6;
                    332:                    char *end;
                    333:                    while (*domainstr == ' ' || *domainstr == '\t')
                    334:                        domainstr++;
                    335:                    end = domainstr;
2.18      frystyk   336:                    while (*end && !isspace((int) *end))
2.14      frystyk   337:                        end++;
                    338:                    *end = '\0';
                    339:                    if (*domainstr) {
                    340:                        StrAllocCat(hostname, ".");
                    341:                        StrAllocCat(hostname, domainstr);
                    342:                        fqdn = 2;
                    343:                        break;
                    344:                    }
2.1       frystyk   345:                }
                    346:            }
2.14      frystyk   347:            fclose(fp);
2.1       frystyk   348:        }
                    349:     }
                    350: #endif /* RESOLV_CONF */
                    351: 
                    352: #ifdef HAVE_GETDOMAINNAME
                    353:     /* If everything else has failed then try getdomainname */
                    354:     if (fqdn==1) {
                    355:        if (getdomainname(name, MAXHOSTNAMELEN)) {
2.25      frystyk   356:            HTTRACE(CORE_TRACE, "HostName.... Can't get domain name\n");
2.1       frystyk   357:            StrAllocCopy(hostname, "");
                    358:            return NULL;
                    359:        }
                    360: 
                    361:        /* If the host name and the first part of the domain name are different
                    362:           then use the former as it is more exact (I guess) */
                    363:        if (strncmp(name, hostname, (int) strlen(hostname))) {
                    364:            char *domain = strchr(name, '.');
                    365:            if (!domain)
                    366:                domain = name;
                    367:            StrAllocCat(hostname, domain);
                    368:        }
                    369:     }
                    370: #endif /* HAVE_GETDOMAINNAME */
                    371: 
                    372:     if (hostname) {
                    373:        char *strptr = hostname;
                    374:        while (*strptr) {           
                    375:            *strptr = TOLOWER(*strptr);
                    376:            strptr++;
                    377:        }
                    378:        if (*(hostname+strlen(hostname)-1) == '.')    /* Remove trailing dot */
                    379:            *(hostname+strlen(hostname)-1) = '\0';
2.25      frystyk   380:        HTTRACE(CORE_TRACE, "HostName.... FQDN is `%s\'\n" _ hostname);
2.1       frystyk   381:     }
                    382:     return hostname;
                    383: }
                    384: 
                    385: /*                                                            HTGetMailAddress
                    386: **
                    387: **     Get the mail address of the current user on the current host. The
                    388: **     domain name used is the one initialized in HTSetHostName or
                    389: **     HTGetHostName. The login name is determined using (ordered):
                    390: **
                    391: **             getlogin
                    392: **             getpwuid(getuid())
                    393: **
                    394: **     The weakness about the last attempt is if the user has multiple
                    395: **     login names each with the same user ID. If this fails as well then:
                    396: **
                    397: **             LOGNAME environment variable
                    398: **             USER environment variable
                    399: **
2.3       frystyk   400: **     Returns NULL or string to be freed by caller
2.1       frystyk   401: */
2.3       frystyk   402: PUBLIC char * HTGetMailAddress (void)
2.1       frystyk   403: {
                    404: #ifdef HT_REENTRANT
2.23      frystyk   405:   char name[HT_LOGNAME_MAX];    /* For getlogin_r or getUserName */
2.28    ! kahan     406:   int result;
2.1       frystyk   407: #endif
                    408: #ifdef WWW_MSWINDOWS/* what was the plan for this under windows? - EGP */
                    409:   char name[256];    /* For getlogin_r or getUserName */
                    410:   unsigned int bufSize = sizeof(name);
                    411: #endif
                    412: #ifdef HAVE_PWD_H
                    413:     struct passwd * pw_info = NULL;
                    414: #endif
                    415:     char * login = NULL;
                    416: 
                    417: #ifdef WWW_MSWINDOWS
                    418:     if (!login && GetUserName(name, &bufSize) != TRUE)
2.25      frystyk   419:         HTTRACE(CORE_TRACE, "MailAddress. GetUsername returns NO\n");
2.1       frystyk   420: #endif /* WWW_MSWINDOWS */
                    421: 
                    422: #ifdef HAVE_CUSERID
                    423:     if (!login && (login = (char *) cuserid(NULL)) == NULL)
2.25      frystyk   424:         HTTRACE(CORE_TRACE, "MailAddress. cuserid returns NULL\n");
2.1       frystyk   425: #endif /* HAVE_CUSERID */
                    426: 
                    427: #ifdef HAVE_GETLOGIN
2.28    ! kahan     428: #ifdef GETLOGIN_R_RETURNS_POINTER
2.23      frystyk   429:     if (!login && (login = (char *) getlogin_r(name, HT_LOGNAME_MAX)) == NULL)
2.28    ! kahan     430: #elif defined(GETLOGIN_R_RETURNS_INT)
        !           431:     if (!login && (result = getlogin_r(name, HT_LOGNAME_MAX)) == 0)
        !           432:     {
        !           433:        login = &name[0];
        !           434:     }
        !           435:     else
2.1       frystyk   436: #else
                    437:     if (!login && (login = (char *) getlogin()) == NULL)
                    438: #endif /* HT_REENTRANT */
2.25      frystyk   439:        HTTRACE(CORE_TRACE, "MailAddress. getlogin returns NULL\n");
2.1       frystyk   440: #endif /* HAVE_GETLOGIN */
                    441: 
                    442: #ifdef HAVE_PWD_H
                    443:     if (!login && (pw_info = getpwuid(getuid())) != NULL)
                    444:        login = pw_info->pw_name;
                    445: #endif /* HAVE_PWD_H */
                    446: 
                    447:     if (!login && (login = getenv("LOGNAME")) == NULL)
2.25      frystyk   448:        HTTRACE(CORE_TRACE, "MailAddress. LOGNAME not found\n");
2.1       frystyk   449: 
                    450:     if (!login && (login = getenv("USER")) == NULL)
2.25      frystyk   451:        HTTRACE(CORE_TRACE, "MailAddress. USER not found\n");
2.1       frystyk   452: 
                    453:     if (!login) login = HT_DEFAULT_LOGIN;
                    454: 
                    455:     if (login) {
2.3       frystyk   456:        char * domain = NULL;
                    457:        char * mailaddress = NULL;
2.1       frystyk   458:        StrAllocCopy(mailaddress, login);
                    459:        StrAllocCat(mailaddress, "@");
2.3       frystyk   460:        if ((domain = HTGetHostName()) != NULL) {
2.1       frystyk   461:            StrAllocCat(mailaddress, domain);
2.3       frystyk   462:            HT_FREE(domain);
2.1       frystyk   463:        }
                    464:        return mailaddress;
                    465:     }
                    466:     return NULL;
                    467: }
                    468: 
2.3       frystyk   469: /*
                    470: **     Except on the NeXT, we pick up the NewsHost name from
                    471: **
                    472: **     1.      Environment variable NNTPSERVER
                    473: **     2.      File SERVER_FILE
                    474: **     3.      Compilation time macro DEFAULT_NEWS_HOST
                    475: **
                    476: **     On the NeXT, we pick up the NewsHost name from, in order:
                    477: **
                    478: **     1.      WorldWideWeb default "NewsHost"
                    479: **     2.      News default "NewsHost"
                    480: **     3.      Compilation time macro DEFAULT_NEWS_HOST
                    481: **
                    482: **     Returns NULL or string to be freed by caller
                    483: */
                    484: PUBLIC char * HTGetNewsServer (void)
                    485: {
                    486:     char * newshost = NULL;
                    487:     char buffer[80];
                    488: 
                    489: #ifdef NeXTStep
                    490:     if ((newshost = NXGetDefaultValue("WorldWideWeb","NewsHost")) == 0)
                    491:        if ((newshost = NXGetDefaultValue("News","NewsHost")) == 0)
                    492:            newshost = DEFAULT_NEWS_HOST;
                    493: #else
                    494:     if ((newshost = (char *) getenv("NNTPSERVER")) == NULL) {
                    495:        FILE *fp = fopen(SERVER_FILE, "r");
                    496:        *(buffer+79) = '\0';
                    497:        if (fp) {
                    498:            if (fgets(buffer, 79, fp)) {
                    499:                char *end;
                    500:                newshost = buffer;
                    501:                while (*newshost == ' ' || *newshost == '\t')
                    502:                    newshost++;
                    503:                end = newshost;
2.18      frystyk   504:                while (*end && !isspace((int) *end))
2.3       frystyk   505:                    end++;
                    506:                *end = '\0';
                    507:            }
                    508:            fclose(fp);
                    509:        }
                    510:     }
                    511: #endif /* NestStep */
                    512: 
                    513:     /* Last resort */
                    514:     if (!newshost || !*newshost) newshost = DEFAULT_NEWS_HOST;
                    515: 
                    516:     /* Canonicalize host name */
                    517:     {
                    518:        char * result = NULL;
                    519:        StrAllocCopy(result, newshost);
                    520:        {
                    521:            char * strptr = result;
                    522:            while (*strptr) {
                    523:                *strptr = TOLOWER(*strptr);
                    524:                strptr++;
                    525:            }
                    526:        }
                    527:        return result;
                    528:     }
                    529: }
2.1       frystyk   530: 
2.3       frystyk   531: /*     Timezone Offset
                    532: **     ---------------
                    533: **     Calculates the offset from GMT in seconds
2.1       frystyk   534: */
2.3       frystyk   535: PUBLIC time_t HTGetTimeZoneOffset (void)
2.1       frystyk   536: {
2.10      frystyk   537:     static time_t HTTimeZone = -1;               /* Invalid timezone offset */
                    538:     if (HTTimeZone != -1) return HTTimeZone;                /* Already done */
2.3       frystyk   539: #ifdef HAVE_TIMEZONE
                    540:     {
                    541:        time_t cur_t = time(NULL);
                    542: #ifdef HT_REENTRANT
                    543:        struct tm loctime;
                    544:        struct tm *local = (struct tm *) localtime_r(&cur_t, &loctime);
                    545: #else
                    546:        struct tm *local = localtime(&cur_t);
                    547: #endif /* HT_REENTRANT */
2.7       frystyk   548: #ifdef HAVE_DAYLIGHT
2.3       frystyk   549:        if (daylight && local->tm_isdst>0) {               /* daylight time? */
2.7       frystyk   550: #else
                    551:        if (local->tm_isdst>0) {                           /* daylight time? */
                    552: #endif /* HAVE_DAYLIGHT */
2.3       frystyk   553: #ifdef HAVE_ALTZONE
                    554:            HTTimeZone = altzone;
                    555: #else
                    556:            /* Assumes a fixed DST offset of 1 hour, which is probably wrong */
2.22      frystyk   557: #ifdef __CYGWIN__
                    558:            HTTimeZone = _timezone - 3600;
                    559: #else
2.3       frystyk   560:            HTTimeZone = timezone - 3600;
2.22      frystyk   561: #endif
2.3       frystyk   562: #endif /* HAVE_ALTZONE */
                    563:        } else {                                                       /* no */
2.22      frystyk   564: #ifdef __CYGWIN__
                    565:            HTTimeZone = _timezone;
                    566: #else
2.3       frystyk   567:            HTTimeZone = timezone;
2.22      frystyk   568: #endif
2.3       frystyk   569:        }
                    570:        HTTimeZone = -HTTimeZone;
2.25      frystyk   571:        HTTRACE(CORE_TRACE, "TimeZone.... GMT + (%02d) hours (including DST)\n" _ 
2.3       frystyk   572:                    (int) HTTimeZone/3600);
                    573:     }
                    574: #else
                    575: #ifdef HAVE_TM_GMTOFF
                    576:     {
                    577:        time_t cur_t = time(NULL);
                    578: #ifdef HT_REENTRANT
                    579:        struct tm loctime;
                    580:        localtime_r(&cur_t, &loctime);
                    581: #else
                    582:        struct tm * local = localtime(&cur_t);
                    583: #endif /* HT_REENTRANT */
                    584:        HTTimeZone = local->tm_gmtoff;
2.25      frystyk   585:        HTTRACE(CORE_TRACE, "TimeZone.... GMT + (%02d) hours (including DST)\n" _ 
2.3       frystyk   586:                    (int)local->tm_gmtoff / 3600);
                    587:     }
                    588: #else
2.25      frystyk   589:     HTTRACE(CORE_TRACE, "TimeZone.... Not defined\n");
2.3       frystyk   590: #endif /* HAVE_TM_GMTOFF */
                    591: #endif /* HAVE_TIMEZONE */
                    592:     return HTTimeZone;
2.6       frystyk   593: }
                    594: 
                    595: /*
                    596: **     Finds a temporary name in in the directory given. If the directory
2.9       frystyk   597: **     is NULL then don't prepend anything.
2.6       frystyk   598: **     If success, the result must be freed by caller, else we return NULL
                    599: */
2.16      frystyk   600: PUBLIC char * HTGetTmpFileName (const char * abs_dir)
2.6       frystyk   601: {
2.27      frystyk   602:     char * result = NULL;
2.16      frystyk   603: #ifdef HAVE_TEMPNAM
2.27      frystyk   604:     static char * envtmpdir = NULL;
                    605:     size_t len = 0;
                    606:     if (abs_dir && *abs_dir) {
                    607:       char * tmpdir = getenv("TMPDIR");
                    608:       if (tmpdir)
                    609:           len = strlen(tmpdir);
                    610:       if (len) {
                    611:           if (!(envtmpdir = (char *) HT_REALLOC(envtmpdir, len + 8)))
                    612:               HT_OUTOFMEM("HTGetTmpFileName");
                    613:           strcpy(envtmpdir, "TMPDIR=");
                    614:           strcpy(envtmpdir + 7, tmpdir);
                    615:           putenv("TMPDIR=");
                    616:       }
                    617:     }
2.21      frystyk   618: #ifdef __CYGWIN__
2.27      frystyk   619:     result = tempnam(abs_dir, "");
2.21      frystyk   620: #else
2.27      frystyk   621:     result = tempnam(abs_dir, NULL);
2.21      frystyk   622: #endif /* __CYGWIN__ */
2.27      frystyk   623:     if (len)
                    624:       putenv(envtmpdir);
2.16      frystyk   625: #else
                    626:     /*
                    627:     **  This is only approx. as we don't know if this file exists or not.
                    628:     **  Hopefully, tempnam() exists on enough platforms so that this is not
                    629:     **  a problem.
                    630:     */
2.6       frystyk   631:     char * offset = NULL;
2.16      frystyk   632:     if (!(result = (char *) HT_MALLOC((abs_dir ? strlen(abs_dir) : 0) +
                    633:                                      HT_MAX_TMPNAM + 2)))
2.6       frystyk   634:        HT_OUTOFMEM("HTGetTmpFileName");
2.16      frystyk   635: 
                    636: #ifdef WWW_MSWINDOWS
                    637:     if (abs_dir) {
                    638: #else
2.24      frystyk   639:     if (abs_dir && *abs_dir==DIR_SEPARATOR_CHAR) {
2.16      frystyk   640: #endif /* WWW_MSWINDOWS */
                    641:        strcpy(result, abs_dir);
                    642:        offset = result+strlen(result);
2.24      frystyk   643:        if (*(offset-1) != DIR_SEPARATOR_CHAR) *offset++ = DIR_SEPARATOR_CHAR;
2.16      frystyk   644: 
2.6       frystyk   645: #ifdef HT_REENTRANT
2.16      frystyk   646:        tmpnam_r(offset);
2.6       frystyk   647: #else
2.16      frystyk   648:        tmpnam(offset);
2.6       frystyk   649: #endif
2.9       frystyk   650: 
2.16      frystyk   651:        {
2.24      frystyk   652:            char * orig = strrchr(offset, DIR_SEPARATOR_CHAR);
2.16      frystyk   653:            char * dest = offset;
                    654:            if (orig++) while ((*dest++ = *orig++));
                    655:        }
                    656:     } else {
                    657:        offset = result;
                    658: #ifdef HT_REENTRANT
                    659:        tmpnam_r(offset);
                    660: #else
                    661:        tmpnam(offset);
                    662: #endif
                    663:        offset = result;
2.9       frystyk   664:     }
2.27      frystyk   665: #endif /* HAVE_TEMPNAM */
2.6       frystyk   666:     return result;
2.11      frystyk   667: }
                    668: 
                    669: /*
                    670: **  Copied from X utilities
                    671: */
2.12      frystyk   672: PUBLIC ms_t HTGetTimeInMillis (void)
2.11      frystyk   673: {
2.13      eric      674: #ifdef WWW_MSWINDOWS
                    675:     return GetTickCount();
                    676: #else /* WWW_MSWINDOWS */
2.17      frystyk   677: #ifdef HAVE_GETTIMEOFDAY
2.11      frystyk   678:     struct timeval tp;
                    679:     gettimeofday(&tp, NULL);
                    680:     return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
2.17      frystyk   681: #else
                    682:     return((ms_t) 0);
                    683: #endif
2.13      eric      684: #endif /* !WWW_MSWINDOWS */
2.1       frystyk   685: }

Webmaster