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