Annotation of libwww/Library/src/HTInet.c, revision 2.25
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.25 ! frystyk 6: ** @(#) $Id: HTInet.c,v 2.24 1999/02/03 16:36:46 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: */
2.25 ! frystyk 147: #ifndef WWW_MSWINDOWS
2.1 frystyk 148: #include <signal.h>
2.25 ! frystyk 149: #endif /* WWW_MSWINDOWS */
2.1 frystyk 150: PUBLIC void HTSetSignal (void)
151: {
2.25 ! frystyk 152: #ifndef WWW_MSWINDOWS
2.1 frystyk 153: /* On some systems (SYSV) it is necessary to catch the SIGPIPE signal
154: ** when attemting to connect to a remote host where you normally should
155: ** get `connection refused' back
156: */
157: if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
2.25 ! frystyk 158: HTTRACE(CORE_TRACE, "HTSignal.... Can't catch SIGPIPE\n");
2.1 frystyk 159: } else {
2.25 ! frystyk 160: HTTRACE(CORE_TRACE, "HTSignal.... Ignoring SIGPIPE\n");
2.1 frystyk 161: }
2.25 ! frystyk 162: #endif /* WWW_MSWINDOWS */
2.1 frystyk 163: }
164: #endif /* WWWLIB_SIG */
165:
166: /* ------------------------------------------------------------------------- */
167: /* HOST NAME FUNCTIONS */
168: /* ------------------------------------------------------------------------- */
169:
170: /* Produce a string for an Internet address
171: ** ----------------------------------------
172: **
173: ** On exit,
174: ** returns a pointer to a static string which must be copied if
175: ** it is to be kept.
176: */
177: PUBLIC const char * HTInetString (SockA * sin)
178: {
179: #ifndef DECNET /* Function only used below for a trace message */
180: #if 0
181: /* This dumps core on some Sun systems :-(. The problem is now, that
182: the current implememtation only works for IP-addresses and not in
183: other address spaces. */
184: return inet_ntoa(sin->sin_addr);
185: #endif
186: static char string[16];
187: sprintf(string, "%d.%d.%d.%d",
188: (int)*((unsigned char *)(&sin->sin_addr)+0),
189: (int)*((unsigned char *)(&sin->sin_addr)+1),
190: (int)*((unsigned char *)(&sin->sin_addr)+2),
191: (int)*((unsigned char *)(&sin->sin_addr)+3));
192: return string;
193: #else
194: return "";
195: #endif /* Decnet */
196: }
197:
198: /* Parse a network node address and port
199: ** -------------------------------------
200: ** It is assumed that any portnumber and numeric host address
201: ** is given in decimal notation. Separation character is '.'
2.2 frystyk 202: ** Any port number gets chopped off
2.1 frystyk 203: ** Returns:
204: ** >0 Number of homes
205: ** 0 Wait for persistent socket
206: ** -1 Error
207: */
2.11 frystyk 208: PUBLIC int HTParseInet (HTHost * host, char * hostname, HTRequest * request)
2.1 frystyk 209: {
210: int status = 1;
2.11 frystyk 211: SockA *sin = &host->sock_addr;
2.1 frystyk 212:
213: #ifdef DECNET
214: /* read Decnet node name. @@ Should know about DECnet addresses, but it's
215: probably worth waiting until the Phase transition from IV to V. */
216:
2.11 frystyk 217: sin->sdn_nam.n_len = min(DN_MAXNAML, strlen(hostname)); /* <=6 in phase 4 */
218: strncpy (sin->sdn_nam.n_name, hostname, sin->sdn_nam.n_len + 1);
2.1 frystyk 219:
2.25 ! frystyk 220: HTTRACE(CORE_TRACE, "DECnet: Parsed address as object number %d on host %.6s...\n" _
! 221: sin->sdn_objnum _ hostname);
2.1 frystyk 222: #else /* Internet */
223: {
2.11 frystyk 224: char *strptr = hostname;
2.1 frystyk 225: while (*strptr) {
226: if (*strptr == ':') {
227: *strptr = '\0'; /* Don't want port number in numeric host */
228: break;
229: }
2.18 frystyk 230: if (!isdigit((int) *strptr) && *strptr != '.')
2.1 frystyk 231: break;
232: strptr++;
233: }
234: if (!*strptr) {
235: #ifdef GUSI
2.11 frystyk 236: sin->sin_addr = inet_addr(hostname); /* See netinet/in.h */
2.1 frystyk 237: #else
2.11 frystyk 238: sin->sin_addr.s_addr = inet_addr(hostname); /* See arpa/inet.h */
2.1 frystyk 239: #endif
2.2 frystyk 240: } else {
2.11 frystyk 241: char * port = strchr(hostname, ':'); /* Chop port */
2.2 frystyk 242: if (port) *port = '\0';
2.11 frystyk 243: status = HTGetHostByName(host, hostname, request);
2.2 frystyk 244: }
2.25 ! frystyk 245: #ifdef HTDEBUG
! 246: if (status > 0)
! 247: HTTRACE(CORE_TRACE, "ParseInet... as port %d on %s with %d homes\n" _
! 248: (int) ntohs(sin->sin_port) _ HTInetString(sin) _ status);
! 249: #endif /* HTDEBUG */
2.1 frystyk 250: }
251: #endif /* Internet vs. Decnet */
252: return status;
253: }
254:
255:
2.3 frystyk 256: #if 0
2.1 frystyk 257: /* HTGetDomainName
258: ** Returns the current domain name without the local host name.
259: ** The response is pointing to a static area that might be changed
260: ** using HTSetHostName().
261: **
262: ** Returns NULL on error, "" if domain name is not found
263: */
2.3 frystyk 264: PRIVATE char * HTGetDomainName (void)
2.1 frystyk 265: {
2.3 frystyk 266: char * host = HTGetHostName();
267: char * domain;
2.1 frystyk 268: if (host && *host) {
269: if ((domain = strchr(host, '.')) != NULL)
270: return ++domain;
271: else
272: return "";
273: } else
274: return NULL;
275: }
2.3 frystyk 276: #endif
2.1 frystyk 277:
278: /* HTGetHostName
279: ** Returns the name of this host. It uses the following algoritm:
280: **
281: ** 1) gethostname()
282: ** 2) if the hostname doesn't contain any '.' try to read
283: ** /etc/resolv.conf. If there is no domain line in this file then
284: ** 3) Try getdomainname and do as the man pages say for resolv.conf (sun)
285: ** If there is no domain line in this file, then it is derived
286: ** from the domain name set by the domainname(1) command, usually
287: ** by removing the first component. For example, if the domain-
288: ** name is set to ``foo.podunk.edu'' then the default domain name
289: ** used will be ``pudunk.edu''.
290: **
291: ** This is the same procedure as used by res_init() and sendmail.
292: **
293: ** Return: hostname on success else NULL
294: */
2.3 frystyk 295: PUBLIC char * HTGetHostName (void)
2.1 frystyk 296: {
2.3 frystyk 297: char * hostname = NULL;
2.1 frystyk 298: int fqdn = 0; /* 0=no, 1=host, 2=fqdn */
299: char name[MAXHOSTNAMELEN+1];
300: *(name+MAXHOSTNAMELEN) = '\0';
301:
2.8 frystyk 302: #if defined(HAVE_SYSINFO) && defined(SI_HOSTNAME)
2.1 frystyk 303: if (!fqdn && sysinfo(SI_HOSTNAME, name, MAXHOSTNAMELEN) > 0) {
304: char * dot = strchr(name, '.');
2.25 ! frystyk 305: HTTRACE(CORE_TRACE, "HostName.... sysinfo says `%s\'\n" _ name);
2.1 frystyk 306: StrAllocCopy(hostname, name);
307: fqdn = dot ? 2 : 1;
308: }
309: #endif /* HAVE_SYSINFO */
310:
311: #ifdef HAVE_GETHOSTNAME
312: if (!fqdn && gethostname(name, MAXHOSTNAMELEN) == 0) {
313: char * dot = strchr(name, '.');
2.25 ! frystyk 314: HTTRACE(CORE_TRACE, "HostName.... gethostname says `%s\'\n" _ name);
2.1 frystyk 315: StrAllocCopy(hostname, name);
316: fqdn = dot ? 2 : 1;
317: }
318: #endif /* HAVE_GETHOSTNAME */
319:
320: #ifdef RESOLV_CONF
321: /* Now try the resolver config file */
2.14 frystyk 322: {
323: FILE *fp;
324: if (fqdn==1 && (fp = fopen(RESOLV_CONF, "r")) != NULL) {
325: char buffer[80];
326: *(buffer+79) = '\0';
327: while (fgets(buffer, 79, fp)) {
328: if (!strncasecomp(buffer, "domain", 6) ||
329: !strncasecomp(buffer, "search", 6)) {
330: char *domainstr = buffer+6;
331: char *end;
332: while (*domainstr == ' ' || *domainstr == '\t')
333: domainstr++;
334: end = domainstr;
2.18 frystyk 335: while (*end && !isspace((int) *end))
2.14 frystyk 336: end++;
337: *end = '\0';
338: if (*domainstr) {
339: StrAllocCat(hostname, ".");
340: StrAllocCat(hostname, domainstr);
341: fqdn = 2;
342: break;
343: }
2.1 frystyk 344: }
345: }
2.14 frystyk 346: fclose(fp);
2.1 frystyk 347: }
348: }
349: #endif /* RESOLV_CONF */
350:
351: #ifdef HAVE_GETDOMAINNAME
352: /* If everything else has failed then try getdomainname */
353: if (fqdn==1) {
354: if (getdomainname(name, MAXHOSTNAMELEN)) {
2.25 ! frystyk 355: HTTRACE(CORE_TRACE, "HostName.... Can't get domain name\n");
2.1 frystyk 356: StrAllocCopy(hostname, "");
357: return NULL;
358: }
359:
360: /* If the host name and the first part of the domain name are different
361: then use the former as it is more exact (I guess) */
362: if (strncmp(name, hostname, (int) strlen(hostname))) {
363: char *domain = strchr(name, '.');
364: if (!domain)
365: domain = name;
366: StrAllocCat(hostname, domain);
367: }
368: }
369: #endif /* HAVE_GETDOMAINNAME */
370:
371: if (hostname) {
372: char *strptr = hostname;
373: while (*strptr) {
374: *strptr = TOLOWER(*strptr);
375: strptr++;
376: }
377: if (*(hostname+strlen(hostname)-1) == '.') /* Remove trailing dot */
378: *(hostname+strlen(hostname)-1) = '\0';
2.25 ! frystyk 379: HTTRACE(CORE_TRACE, "HostName.... FQDN is `%s\'\n" _ hostname);
2.1 frystyk 380: }
381: return hostname;
382: }
383:
384: /* HTGetMailAddress
385: **
386: ** Get the mail address of the current user on the current host. The
387: ** domain name used is the one initialized in HTSetHostName or
388: ** HTGetHostName. The login name is determined using (ordered):
389: **
390: ** getlogin
391: ** getpwuid(getuid())
392: **
393: ** The weakness about the last attempt is if the user has multiple
394: ** login names each with the same user ID. If this fails as well then:
395: **
396: ** LOGNAME environment variable
397: ** USER environment variable
398: **
2.3 frystyk 399: ** Returns NULL or string to be freed by caller
2.1 frystyk 400: */
2.3 frystyk 401: PUBLIC char * HTGetMailAddress (void)
2.1 frystyk 402: {
403: #ifdef HT_REENTRANT
2.23 frystyk 404: char name[HT_LOGNAME_MAX]; /* For getlogin_r or getUserName */
2.1 frystyk 405: #endif
406: #ifdef WWW_MSWINDOWS/* what was the plan for this under windows? - EGP */
407: char name[256]; /* For getlogin_r or getUserName */
408: unsigned int bufSize = sizeof(name);
409: #endif
410: #ifdef HAVE_PWD_H
411: struct passwd * pw_info = NULL;
412: #endif
413: char * login = NULL;
414:
415: #ifdef WWW_MSWINDOWS
416: if (!login && GetUserName(name, &bufSize) != TRUE)
2.25 ! frystyk 417: HTTRACE(CORE_TRACE, "MailAddress. GetUsername returns NO\n");
2.1 frystyk 418: #endif /* WWW_MSWINDOWS */
419:
420: #ifdef HAVE_CUSERID
421: if (!login && (login = (char *) cuserid(NULL)) == NULL)
2.25 ! frystyk 422: HTTRACE(CORE_TRACE, "MailAddress. cuserid returns NULL\n");
2.1 frystyk 423: #endif /* HAVE_CUSERID */
424:
425: #ifdef HAVE_GETLOGIN
426: #ifdef HT_REENTRANT
2.23 frystyk 427: if (!login && (login = (char *) getlogin_r(name, HT_LOGNAME_MAX)) == NULL)
2.1 frystyk 428: #else
429: if (!login && (login = (char *) getlogin()) == NULL)
430: #endif /* HT_REENTRANT */
2.25 ! frystyk 431: HTTRACE(CORE_TRACE, "MailAddress. getlogin returns NULL\n");
2.1 frystyk 432: #endif /* HAVE_GETLOGIN */
433:
434: #ifdef HAVE_PWD_H
435: if (!login && (pw_info = getpwuid(getuid())) != NULL)
436: login = pw_info->pw_name;
437: #endif /* HAVE_PWD_H */
438:
439: if (!login && (login = getenv("LOGNAME")) == NULL)
2.25 ! frystyk 440: HTTRACE(CORE_TRACE, "MailAddress. LOGNAME not found\n");
2.1 frystyk 441:
442: if (!login && (login = getenv("USER")) == NULL)
2.25 ! frystyk 443: HTTRACE(CORE_TRACE, "MailAddress. USER not found\n");
2.1 frystyk 444:
445: if (!login) login = HT_DEFAULT_LOGIN;
446:
447: if (login) {
2.3 frystyk 448: char * domain = NULL;
449: char * mailaddress = NULL;
2.1 frystyk 450: StrAllocCopy(mailaddress, login);
451: StrAllocCat(mailaddress, "@");
2.3 frystyk 452: if ((domain = HTGetHostName()) != NULL) {
2.1 frystyk 453: StrAllocCat(mailaddress, domain);
2.3 frystyk 454: HT_FREE(domain);
2.1 frystyk 455: }
456: return mailaddress;
457: }
458: return NULL;
459: }
460:
2.3 frystyk 461: /*
462: ** Except on the NeXT, we pick up the NewsHost name from
463: **
464: ** 1. Environment variable NNTPSERVER
465: ** 2. File SERVER_FILE
466: ** 3. Compilation time macro DEFAULT_NEWS_HOST
467: **
468: ** On the NeXT, we pick up the NewsHost name from, in order:
469: **
470: ** 1. WorldWideWeb default "NewsHost"
471: ** 2. News default "NewsHost"
472: ** 3. Compilation time macro DEFAULT_NEWS_HOST
473: **
474: ** Returns NULL or string to be freed by caller
475: */
476: PUBLIC char * HTGetNewsServer (void)
477: {
478: char * newshost = NULL;
479: char buffer[80];
480:
481: #ifdef NeXTStep
482: if ((newshost = NXGetDefaultValue("WorldWideWeb","NewsHost")) == 0)
483: if ((newshost = NXGetDefaultValue("News","NewsHost")) == 0)
484: newshost = DEFAULT_NEWS_HOST;
485: #else
486: if ((newshost = (char *) getenv("NNTPSERVER")) == NULL) {
487: FILE *fp = fopen(SERVER_FILE, "r");
488: *(buffer+79) = '\0';
489: if (fp) {
490: if (fgets(buffer, 79, fp)) {
491: char *end;
492: newshost = buffer;
493: while (*newshost == ' ' || *newshost == '\t')
494: newshost++;
495: end = newshost;
2.18 frystyk 496: while (*end && !isspace((int) *end))
2.3 frystyk 497: end++;
498: *end = '\0';
499: }
500: fclose(fp);
501: }
502: }
503: #endif /* NestStep */
504:
505: /* Last resort */
506: if (!newshost || !*newshost) newshost = DEFAULT_NEWS_HOST;
507:
508: /* Canonicalize host name */
509: {
510: char * result = NULL;
511: StrAllocCopy(result, newshost);
512: {
513: char * strptr = result;
514: while (*strptr) {
515: *strptr = TOLOWER(*strptr);
516: strptr++;
517: }
518: }
519: return result;
520: }
521: }
2.1 frystyk 522:
2.3 frystyk 523: /* Timezone Offset
524: ** ---------------
525: ** Calculates the offset from GMT in seconds
2.1 frystyk 526: */
2.3 frystyk 527: PUBLIC time_t HTGetTimeZoneOffset (void)
2.1 frystyk 528: {
2.10 frystyk 529: static time_t HTTimeZone = -1; /* Invalid timezone offset */
530: if (HTTimeZone != -1) return HTTimeZone; /* Already done */
2.3 frystyk 531: #ifdef HAVE_TIMEZONE
532: {
533: time_t cur_t = time(NULL);
534: #ifdef HT_REENTRANT
535: struct tm loctime;
536: struct tm *local = (struct tm *) localtime_r(&cur_t, &loctime);
537: #else
538: struct tm *local = localtime(&cur_t);
539: #endif /* HT_REENTRANT */
2.7 frystyk 540: #ifdef HAVE_DAYLIGHT
2.3 frystyk 541: if (daylight && local->tm_isdst>0) { /* daylight time? */
2.7 frystyk 542: #else
543: if (local->tm_isdst>0) { /* daylight time? */
544: #endif /* HAVE_DAYLIGHT */
2.3 frystyk 545: #ifdef HAVE_ALTZONE
546: HTTimeZone = altzone;
547: #else
548: /* Assumes a fixed DST offset of 1 hour, which is probably wrong */
2.22 frystyk 549: #ifdef __CYGWIN__
550: HTTimeZone = _timezone - 3600;
551: #else
2.3 frystyk 552: HTTimeZone = timezone - 3600;
2.22 frystyk 553: #endif
2.3 frystyk 554: #endif /* HAVE_ALTZONE */
555: } else { /* no */
2.22 frystyk 556: #ifdef __CYGWIN__
557: HTTimeZone = _timezone;
558: #else
2.3 frystyk 559: HTTimeZone = timezone;
2.22 frystyk 560: #endif
2.3 frystyk 561: }
562: HTTimeZone = -HTTimeZone;
2.25 ! frystyk 563: HTTRACE(CORE_TRACE, "TimeZone.... GMT + (%02d) hours (including DST)\n" _
2.3 frystyk 564: (int) HTTimeZone/3600);
565: }
566: #else
567: #ifdef HAVE_TM_GMTOFF
568: {
569: time_t cur_t = time(NULL);
570: #ifdef HT_REENTRANT
571: struct tm loctime;
572: localtime_r(&cur_t, &loctime);
573: #else
574: struct tm * local = localtime(&cur_t);
575: #endif /* HT_REENTRANT */
576: HTTimeZone = local->tm_gmtoff;
2.25 ! frystyk 577: HTTRACE(CORE_TRACE, "TimeZone.... GMT + (%02d) hours (including DST)\n" _
2.3 frystyk 578: (int)local->tm_gmtoff / 3600);
579: }
580: #else
2.25 ! frystyk 581: HTTRACE(CORE_TRACE, "TimeZone.... Not defined\n");
2.3 frystyk 582: #endif /* HAVE_TM_GMTOFF */
583: #endif /* HAVE_TIMEZONE */
584: return HTTimeZone;
2.6 frystyk 585: }
586:
587: /*
588: ** Finds a temporary name in in the directory given. If the directory
2.9 frystyk 589: ** is NULL then don't prepend anything.
2.6 frystyk 590: ** If success, the result must be freed by caller, else we return NULL
591: */
2.16 frystyk 592: PUBLIC char * HTGetTmpFileName (const char * abs_dir)
2.6 frystyk 593: {
2.16 frystyk 594: #ifdef HAVE_TEMPNAM
2.21 frystyk 595: #ifdef __CYGWIN__
596: return tempnam(abs_dir, "");
597: #else
2.16 frystyk 598: return tempnam(abs_dir, NULL);
2.21 frystyk 599: #endif /* __CYGWIN__ */
2.16 frystyk 600: #else
601: /*
602: ** This is only approx. as we don't know if this file exists or not.
603: ** Hopefully, tempnam() exists on enough platforms so that this is not
604: ** a problem.
605: */
2.6 frystyk 606: char * result = NULL;
607: char * offset = NULL;
2.16 frystyk 608: if (!(result = (char *) HT_MALLOC((abs_dir ? strlen(abs_dir) : 0) +
609: HT_MAX_TMPNAM + 2)))
2.6 frystyk 610: HT_OUTOFMEM("HTGetTmpFileName");
2.16 frystyk 611:
612: #ifdef WWW_MSWINDOWS
613: if (abs_dir) {
614: #else
2.24 frystyk 615: if (abs_dir && *abs_dir==DIR_SEPARATOR_CHAR) {
2.16 frystyk 616: #endif /* WWW_MSWINDOWS */
617: strcpy(result, abs_dir);
618: offset = result+strlen(result);
2.24 frystyk 619: if (*(offset-1) != DIR_SEPARATOR_CHAR) *offset++ = DIR_SEPARATOR_CHAR;
2.16 frystyk 620:
2.6 frystyk 621: #ifdef HT_REENTRANT
2.16 frystyk 622: tmpnam_r(offset);
2.6 frystyk 623: #else
2.16 frystyk 624: tmpnam(offset);
2.6 frystyk 625: #endif
2.9 frystyk 626:
2.16 frystyk 627: {
2.24 frystyk 628: char * orig = strrchr(offset, DIR_SEPARATOR_CHAR);
2.16 frystyk 629: char * dest = offset;
630: if (orig++) while ((*dest++ = *orig++));
631: }
632: } else {
633: offset = result;
634: #ifdef HT_REENTRANT
635: tmpnam_r(offset);
636: #else
637: tmpnam(offset);
638: #endif
639: offset = result;
2.9 frystyk 640: }
2.6 frystyk 641: return result;
2.16 frystyk 642: #endif /* HAVE_TEMPNAM */
2.11 frystyk 643: }
644:
645: /*
646: ** Copied from X utilities
647: */
2.12 frystyk 648: PUBLIC ms_t HTGetTimeInMillis (void)
2.11 frystyk 649: {
2.13 eric 650: #ifdef WWW_MSWINDOWS
651: return GetTickCount();
652: #else /* WWW_MSWINDOWS */
2.17 frystyk 653: #ifdef HAVE_GETTIMEOFDAY
2.11 frystyk 654: struct timeval tp;
655: gettimeofday(&tp, NULL);
656: return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
2.17 frystyk 657: #else
658: return((ms_t) 0);
659: #endif
2.13 eric 660: #endif /* !WWW_MSWINDOWS */
2.1 frystyk 661: }
Webmaster