Annotation of libwww/Library/src/HTInet.c, revision 2.26
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.26 ! frystyk 6: ** @(#) $Id: HTInet.c,v 2.25 1999/02/22 22:10:11 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.1 frystyk 406: #endif
407: #ifdef WWW_MSWINDOWS/* what was the plan for this under windows? - EGP */
408: char name[256]; /* For getlogin_r or getUserName */
409: unsigned int bufSize = sizeof(name);
410: #endif
411: #ifdef HAVE_PWD_H
412: struct passwd * pw_info = NULL;
413: #endif
414: char * login = NULL;
415:
416: #ifdef WWW_MSWINDOWS
417: if (!login && GetUserName(name, &bufSize) != TRUE)
2.25 frystyk 418: HTTRACE(CORE_TRACE, "MailAddress. GetUsername returns NO\n");
2.1 frystyk 419: #endif /* WWW_MSWINDOWS */
420:
421: #ifdef HAVE_CUSERID
422: if (!login && (login = (char *) cuserid(NULL)) == NULL)
2.25 frystyk 423: HTTRACE(CORE_TRACE, "MailAddress. cuserid returns NULL\n");
2.1 frystyk 424: #endif /* HAVE_CUSERID */
425:
426: #ifdef HAVE_GETLOGIN
427: #ifdef HT_REENTRANT
2.23 frystyk 428: if (!login && (login = (char *) getlogin_r(name, HT_LOGNAME_MAX)) == NULL)
2.1 frystyk 429: #else
430: if (!login && (login = (char *) getlogin()) == NULL)
431: #endif /* HT_REENTRANT */
2.25 frystyk 432: HTTRACE(CORE_TRACE, "MailAddress. getlogin returns NULL\n");
2.1 frystyk 433: #endif /* HAVE_GETLOGIN */
434:
435: #ifdef HAVE_PWD_H
436: if (!login && (pw_info = getpwuid(getuid())) != NULL)
437: login = pw_info->pw_name;
438: #endif /* HAVE_PWD_H */
439:
440: if (!login && (login = getenv("LOGNAME")) == NULL)
2.25 frystyk 441: HTTRACE(CORE_TRACE, "MailAddress. LOGNAME not found\n");
2.1 frystyk 442:
443: if (!login && (login = getenv("USER")) == NULL)
2.25 frystyk 444: HTTRACE(CORE_TRACE, "MailAddress. USER not found\n");
2.1 frystyk 445:
446: if (!login) login = HT_DEFAULT_LOGIN;
447:
448: if (login) {
2.3 frystyk 449: char * domain = NULL;
450: char * mailaddress = NULL;
2.1 frystyk 451: StrAllocCopy(mailaddress, login);
452: StrAllocCat(mailaddress, "@");
2.3 frystyk 453: if ((domain = HTGetHostName()) != NULL) {
2.1 frystyk 454: StrAllocCat(mailaddress, domain);
2.3 frystyk 455: HT_FREE(domain);
2.1 frystyk 456: }
457: return mailaddress;
458: }
459: return NULL;
460: }
461:
2.3 frystyk 462: /*
463: ** Except on the NeXT, we pick up the NewsHost name from
464: **
465: ** 1. Environment variable NNTPSERVER
466: ** 2. File SERVER_FILE
467: ** 3. Compilation time macro DEFAULT_NEWS_HOST
468: **
469: ** On the NeXT, we pick up the NewsHost name from, in order:
470: **
471: ** 1. WorldWideWeb default "NewsHost"
472: ** 2. News default "NewsHost"
473: ** 3. Compilation time macro DEFAULT_NEWS_HOST
474: **
475: ** Returns NULL or string to be freed by caller
476: */
477: PUBLIC char * HTGetNewsServer (void)
478: {
479: char * newshost = NULL;
480: char buffer[80];
481:
482: #ifdef NeXTStep
483: if ((newshost = NXGetDefaultValue("WorldWideWeb","NewsHost")) == 0)
484: if ((newshost = NXGetDefaultValue("News","NewsHost")) == 0)
485: newshost = DEFAULT_NEWS_HOST;
486: #else
487: if ((newshost = (char *) getenv("NNTPSERVER")) == NULL) {
488: FILE *fp = fopen(SERVER_FILE, "r");
489: *(buffer+79) = '\0';
490: if (fp) {
491: if (fgets(buffer, 79, fp)) {
492: char *end;
493: newshost = buffer;
494: while (*newshost == ' ' || *newshost == '\t')
495: newshost++;
496: end = newshost;
2.18 frystyk 497: while (*end && !isspace((int) *end))
2.3 frystyk 498: end++;
499: *end = '\0';
500: }
501: fclose(fp);
502: }
503: }
504: #endif /* NestStep */
505:
506: /* Last resort */
507: if (!newshost || !*newshost) newshost = DEFAULT_NEWS_HOST;
508:
509: /* Canonicalize host name */
510: {
511: char * result = NULL;
512: StrAllocCopy(result, newshost);
513: {
514: char * strptr = result;
515: while (*strptr) {
516: *strptr = TOLOWER(*strptr);
517: strptr++;
518: }
519: }
520: return result;
521: }
522: }
2.1 frystyk 523:
2.3 frystyk 524: /* Timezone Offset
525: ** ---------------
526: ** Calculates the offset from GMT in seconds
2.1 frystyk 527: */
2.3 frystyk 528: PUBLIC time_t HTGetTimeZoneOffset (void)
2.1 frystyk 529: {
2.10 frystyk 530: static time_t HTTimeZone = -1; /* Invalid timezone offset */
531: if (HTTimeZone != -1) return HTTimeZone; /* Already done */
2.3 frystyk 532: #ifdef HAVE_TIMEZONE
533: {
534: time_t cur_t = time(NULL);
535: #ifdef HT_REENTRANT
536: struct tm loctime;
537: struct tm *local = (struct tm *) localtime_r(&cur_t, &loctime);
538: #else
539: struct tm *local = localtime(&cur_t);
540: #endif /* HT_REENTRANT */
2.7 frystyk 541: #ifdef HAVE_DAYLIGHT
2.3 frystyk 542: if (daylight && local->tm_isdst>0) { /* daylight time? */
2.7 frystyk 543: #else
544: if (local->tm_isdst>0) { /* daylight time? */
545: #endif /* HAVE_DAYLIGHT */
2.3 frystyk 546: #ifdef HAVE_ALTZONE
547: HTTimeZone = altzone;
548: #else
549: /* Assumes a fixed DST offset of 1 hour, which is probably wrong */
2.22 frystyk 550: #ifdef __CYGWIN__
551: HTTimeZone = _timezone - 3600;
552: #else
2.3 frystyk 553: HTTimeZone = timezone - 3600;
2.22 frystyk 554: #endif
2.3 frystyk 555: #endif /* HAVE_ALTZONE */
556: } else { /* no */
2.22 frystyk 557: #ifdef __CYGWIN__
558: HTTimeZone = _timezone;
559: #else
2.3 frystyk 560: HTTimeZone = timezone;
2.22 frystyk 561: #endif
2.3 frystyk 562: }
563: HTTimeZone = -HTTimeZone;
2.25 frystyk 564: HTTRACE(CORE_TRACE, "TimeZone.... GMT + (%02d) hours (including DST)\n" _
2.3 frystyk 565: (int) HTTimeZone/3600);
566: }
567: #else
568: #ifdef HAVE_TM_GMTOFF
569: {
570: time_t cur_t = time(NULL);
571: #ifdef HT_REENTRANT
572: struct tm loctime;
573: localtime_r(&cur_t, &loctime);
574: #else
575: struct tm * local = localtime(&cur_t);
576: #endif /* HT_REENTRANT */
577: HTTimeZone = local->tm_gmtoff;
2.25 frystyk 578: HTTRACE(CORE_TRACE, "TimeZone.... GMT + (%02d) hours (including DST)\n" _
2.3 frystyk 579: (int)local->tm_gmtoff / 3600);
580: }
581: #else
2.25 frystyk 582: HTTRACE(CORE_TRACE, "TimeZone.... Not defined\n");
2.3 frystyk 583: #endif /* HAVE_TM_GMTOFF */
584: #endif /* HAVE_TIMEZONE */
585: return HTTimeZone;
2.6 frystyk 586: }
587:
588: /*
589: ** Finds a temporary name in in the directory given. If the directory
2.9 frystyk 590: ** is NULL then don't prepend anything.
2.6 frystyk 591: ** If success, the result must be freed by caller, else we return NULL
592: */
2.16 frystyk 593: PUBLIC char * HTGetTmpFileName (const char * abs_dir)
2.6 frystyk 594: {
2.16 frystyk 595: #ifdef HAVE_TEMPNAM
2.21 frystyk 596: #ifdef __CYGWIN__
597: return tempnam(abs_dir, "");
598: #else
2.16 frystyk 599: return tempnam(abs_dir, NULL);
2.21 frystyk 600: #endif /* __CYGWIN__ */
2.16 frystyk 601: #else
602: /*
603: ** This is only approx. as we don't know if this file exists or not.
604: ** Hopefully, tempnam() exists on enough platforms so that this is not
605: ** a problem.
606: */
2.6 frystyk 607: char * result = NULL;
608: char * offset = NULL;
2.16 frystyk 609: if (!(result = (char *) HT_MALLOC((abs_dir ? strlen(abs_dir) : 0) +
610: HT_MAX_TMPNAM + 2)))
2.6 frystyk 611: HT_OUTOFMEM("HTGetTmpFileName");
2.16 frystyk 612:
613: #ifdef WWW_MSWINDOWS
614: if (abs_dir) {
615: #else
2.24 frystyk 616: if (abs_dir && *abs_dir==DIR_SEPARATOR_CHAR) {
2.16 frystyk 617: #endif /* WWW_MSWINDOWS */
618: strcpy(result, abs_dir);
619: offset = result+strlen(result);
2.24 frystyk 620: if (*(offset-1) != DIR_SEPARATOR_CHAR) *offset++ = DIR_SEPARATOR_CHAR;
2.16 frystyk 621:
2.6 frystyk 622: #ifdef HT_REENTRANT
2.16 frystyk 623: tmpnam_r(offset);
2.6 frystyk 624: #else
2.16 frystyk 625: tmpnam(offset);
2.6 frystyk 626: #endif
2.9 frystyk 627:
2.16 frystyk 628: {
2.24 frystyk 629: char * orig = strrchr(offset, DIR_SEPARATOR_CHAR);
2.16 frystyk 630: char * dest = offset;
631: if (orig++) while ((*dest++ = *orig++));
632: }
633: } else {
634: offset = result;
635: #ifdef HT_REENTRANT
636: tmpnam_r(offset);
637: #else
638: tmpnam(offset);
639: #endif
640: offset = result;
2.9 frystyk 641: }
2.6 frystyk 642: return result;
2.16 frystyk 643: #endif /* HAVE_TEMPNAM */
2.11 frystyk 644: }
645:
646: /*
647: ** Copied from X utilities
648: */
2.12 frystyk 649: PUBLIC ms_t HTGetTimeInMillis (void)
2.11 frystyk 650: {
2.13 eric 651: #ifdef WWW_MSWINDOWS
652: return GetTickCount();
653: #else /* WWW_MSWINDOWS */
2.17 frystyk 654: #ifdef HAVE_GETTIMEOFDAY
2.11 frystyk 655: struct timeval tp;
656: gettimeofday(&tp, NULL);
657: return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
2.17 frystyk 658: #else
659: return((ms_t) 0);
660: #endif
2.13 eric 661: #endif /* !WWW_MSWINDOWS */
2.1 frystyk 662: }
Webmaster