Annotation of libwww/Library/src/HTInet.c, revision 2.22
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.22 ! frystyk 6: ** @(#) $Id: HTInet.c,v 2.21 1998/11/30 12:44: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
81: if (PROT_TRACE) HTTrace("System Error Unix = %ld dec\n", errno);
82: if (PROT_TRACE) HTTrace("System Error VMS = %lx hex\n", vaxc$errno);
83: return (-vaxc$errno);
84: #else
85: #ifdef _WINSOCKAPI_
86: if (PROT_TRACE) HTTrace("System Error Unix = %ld dec\n", errno);
87: if (PROT_TRACE) HTTrace("System Error WinSock error=%lx hex\n",
88: WSAGetLastError());
89: return (-errnum);
90: #else
2.20 frystyk 91: if (PROT_TRACE) {
92: char * errmsg = HTErrnoString(errnum);
2.1 frystyk 93: HTTrace("System Error %d after call to %s() failed\n............ %s\n",
2.20 frystyk 94: errno, where, errmsg);
95: HT_FREE(errmsg);
96: }
2.1 frystyk 97: return (-errnum);
98: #endif /* _WINSOCKAPI_ */
99: #endif /* VMS */
100: }
101:
102:
103: /* Parse a cardinal value parse_cardinal()
104: ** ----------------------
105: **
106: ** On entry,
107: ** *pp points to first character to be interpreted, terminated by
108: ** non 0:9 character.
109: ** *pstatus points to status already valid
110: ** maxvalue gives the largest allowable value.
111: **
112: ** On exit,
113: ** *pp points to first unread character
114: ** *pstatus points to status updated iff bad
115: */
116:
117: PUBLIC unsigned int HTCardinal (int * pstatus,
118: char ** pp,
119: unsigned int max_value)
120: {
121: unsigned int n=0;
122: if ( (**pp<'0') || (**pp>'9')) { /* Null string is error */
123: *pstatus = -3; /* No number where one expeceted */
124: return 0;
125: }
126: while ((**pp>='0') && (**pp<='9')) n = n*10 + *((*pp)++) - '0';
127:
128: if (n>max_value) {
129: *pstatus = -4; /* Cardinal outside range */
130: return 0;
131: }
132:
133: return n;
134: }
135:
136: /* ------------------------------------------------------------------------- */
137: /* SIGNAL HANDLING */
138: /* ------------------------------------------------------------------------- */
139:
140: #ifdef WWWLIB_SIG
141: /* HTSetSignal
142: ** This function sets up signal handlers. This might not be necessary to
143: ** call if the application has its own handlers.
144: */
145: #include <signal.h>
146: PUBLIC void HTSetSignal (void)
147: {
148: /* On some systems (SYSV) it is necessary to catch the SIGPIPE signal
149: ** when attemting to connect to a remote host where you normally should
150: ** get `connection refused' back
151: */
152: if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
153: if (PROT_TRACE) HTTrace("HTSignal.... Can't catch SIGPIPE\n");
154: } else {
155: if (PROT_TRACE) HTTrace("HTSignal.... Ignoring SIGPIPE\n");
156: }
157: }
158: #else
159: #ifdef WWW_WIN_DLL
160: PUBLIC void HTSetSignal (void) {}
161: #endif /* WWW_WIN_DLL */
162: #endif /* WWWLIB_SIG */
163:
164: /* ------------------------------------------------------------------------- */
165: /* HOST NAME FUNCTIONS */
166: /* ------------------------------------------------------------------------- */
167:
168: /* Produce a string for an Internet address
169: ** ----------------------------------------
170: **
171: ** On exit,
172: ** returns a pointer to a static string which must be copied if
173: ** it is to be kept.
174: */
175: PUBLIC const char * HTInetString (SockA * sin)
176: {
177: #ifndef DECNET /* Function only used below for a trace message */
178: #if 0
179: /* This dumps core on some Sun systems :-(. The problem is now, that
180: the current implememtation only works for IP-addresses and not in
181: other address spaces. */
182: return inet_ntoa(sin->sin_addr);
183: #endif
184: static char string[16];
185: sprintf(string, "%d.%d.%d.%d",
186: (int)*((unsigned char *)(&sin->sin_addr)+0),
187: (int)*((unsigned char *)(&sin->sin_addr)+1),
188: (int)*((unsigned char *)(&sin->sin_addr)+2),
189: (int)*((unsigned char *)(&sin->sin_addr)+3));
190: return string;
191: #else
192: return "";
193: #endif /* Decnet */
194: }
195:
196: /* Parse a network node address and port
197: ** -------------------------------------
198: ** It is assumed that any portnumber and numeric host address
199: ** is given in decimal notation. Separation character is '.'
2.2 frystyk 200: ** Any port number gets chopped off
2.1 frystyk 201: ** Returns:
202: ** >0 Number of homes
203: ** 0 Wait for persistent socket
204: ** -1 Error
205: */
2.11 frystyk 206: PUBLIC int HTParseInet (HTHost * host, char * hostname, HTRequest * request)
2.1 frystyk 207: {
208: int status = 1;
2.11 frystyk 209: SockA *sin = &host->sock_addr;
2.1 frystyk 210:
211: #ifdef DECNET
212: /* read Decnet node name. @@ Should know about DECnet addresses, but it's
213: probably worth waiting until the Phase transition from IV to V. */
214:
2.11 frystyk 215: sin->sdn_nam.n_len = min(DN_MAXNAML, strlen(hostname)); /* <=6 in phase 4 */
216: strncpy (sin->sdn_nam.n_name, hostname, sin->sdn_nam.n_len + 1);
2.1 frystyk 217:
218: if (PROT_TRACE)
219: HTTrace("DECnet: Parsed address as object number %d on host %.6s...\n",
2.11 frystyk 220: sin->sdn_objnum, hostname);
2.1 frystyk 221: #else /* Internet */
222: {
2.11 frystyk 223: char *strptr = hostname;
2.1 frystyk 224: while (*strptr) {
225: if (*strptr == ':') {
226: *strptr = '\0'; /* Don't want port number in numeric host */
227: break;
228: }
2.18 frystyk 229: if (!isdigit((int) *strptr) && *strptr != '.')
2.1 frystyk 230: break;
231: strptr++;
232: }
233: if (!*strptr) {
234: #ifdef GUSI
2.11 frystyk 235: sin->sin_addr = inet_addr(hostname); /* See netinet/in.h */
2.1 frystyk 236: #else
2.11 frystyk 237: sin->sin_addr.s_addr = inet_addr(hostname); /* See arpa/inet.h */
2.1 frystyk 238: #endif
2.2 frystyk 239: } else {
2.11 frystyk 240: char * port = strchr(hostname, ':'); /* Chop port */
2.2 frystyk 241: if (port) *port = '\0';
2.11 frystyk 242: status = HTGetHostByName(host, hostname, request);
2.2 frystyk 243: }
2.1 frystyk 244: if (PROT_TRACE) {
245: if (status > 0)
246: HTTrace("ParseInet... as port %d on %s with %d homes\n",
247: (int) ntohs(sin->sin_port), HTInetString(sin), status);
248: }
249: }
250: #endif /* Internet vs. Decnet */
251: return status;
252: }
253:
254:
2.3 frystyk 255: #if 0
2.1 frystyk 256: /* HTGetDomainName
257: ** Returns the current domain name without the local host name.
258: ** The response is pointing to a static area that might be changed
259: ** using HTSetHostName().
260: **
261: ** Returns NULL on error, "" if domain name is not found
262: */
2.3 frystyk 263: PRIVATE char * HTGetDomainName (void)
2.1 frystyk 264: {
2.3 frystyk 265: char * host = HTGetHostName();
266: char * domain;
2.1 frystyk 267: if (host && *host) {
268: if ((domain = strchr(host, '.')) != NULL)
269: return ++domain;
270: else
271: return "";
272: } else
273: return NULL;
274: }
2.3 frystyk 275: #endif
2.1 frystyk 276:
277: /* HTGetHostName
278: ** Returns the name of this host. It uses the following algoritm:
279: **
280: ** 1) gethostname()
281: ** 2) if the hostname doesn't contain any '.' try to read
282: ** /etc/resolv.conf. If there is no domain line in this file then
283: ** 3) Try getdomainname and do as the man pages say for resolv.conf (sun)
284: ** If there is no domain line in this file, then it is derived
285: ** from the domain name set by the domainname(1) command, usually
286: ** by removing the first component. For example, if the domain-
287: ** name is set to ``foo.podunk.edu'' then the default domain name
288: ** used will be ``pudunk.edu''.
289: **
290: ** This is the same procedure as used by res_init() and sendmail.
291: **
292: ** Return: hostname on success else NULL
293: */
2.3 frystyk 294: PUBLIC char * HTGetHostName (void)
2.1 frystyk 295: {
2.3 frystyk 296: char * hostname = NULL;
2.1 frystyk 297: int fqdn = 0; /* 0=no, 1=host, 2=fqdn */
298: char name[MAXHOSTNAMELEN+1];
299: *(name+MAXHOSTNAMELEN) = '\0';
300:
2.8 frystyk 301: #if defined(HAVE_SYSINFO) && defined(SI_HOSTNAME)
2.1 frystyk 302: if (!fqdn && sysinfo(SI_HOSTNAME, name, MAXHOSTNAMELEN) > 0) {
303: char * dot = strchr(name, '.');
304: if (PROT_TRACE) HTTrace("HostName.... sysinfo says `%s\'\n", name);
305: StrAllocCopy(hostname, name);
306: fqdn = dot ? 2 : 1;
307: }
308: #endif /* HAVE_SYSINFO */
309:
310: #ifdef HAVE_GETHOSTNAME
311: if (!fqdn && gethostname(name, MAXHOSTNAMELEN) == 0) {
312: char * dot = strchr(name, '.');
313: if (PROT_TRACE) HTTrace("HostName.... gethostname says `%s\'\n", name);
314: StrAllocCopy(hostname, name);
315: fqdn = dot ? 2 : 1;
316: }
317: #endif /* HAVE_GETHOSTNAME */
318:
319: #ifdef RESOLV_CONF
320: /* Now try the resolver config file */
2.14 frystyk 321: {
322: FILE *fp;
323: if (fqdn==1 && (fp = fopen(RESOLV_CONF, "r")) != NULL) {
324: char buffer[80];
325: *(buffer+79) = '\0';
326: while (fgets(buffer, 79, fp)) {
327: if (!strncasecomp(buffer, "domain", 6) ||
328: !strncasecomp(buffer, "search", 6)) {
329: char *domainstr = buffer+6;
330: char *end;
331: while (*domainstr == ' ' || *domainstr == '\t')
332: domainstr++;
333: end = domainstr;
2.18 frystyk 334: while (*end && !isspace((int) *end))
2.14 frystyk 335: end++;
336: *end = '\0';
337: if (*domainstr) {
338: StrAllocCat(hostname, ".");
339: StrAllocCat(hostname, domainstr);
340: fqdn = 2;
341: break;
342: }
2.1 frystyk 343: }
344: }
2.14 frystyk 345: fclose(fp);
2.1 frystyk 346: }
347: }
348: #endif /* RESOLV_CONF */
349:
350: #ifdef HAVE_GETDOMAINNAME
351: /* If everything else has failed then try getdomainname */
352: if (fqdn==1) {
353: if (getdomainname(name, MAXHOSTNAMELEN)) {
354: if (PROT_TRACE)
355: HTTrace("HostName.... Can't get domain name\n");
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';
379: if (PROT_TRACE) HTTrace("HostName.... FQDN is `%s\'\n", hostname);
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
404: char name[LOGNAME_MAX+1]; /* For getlogin_r or getUserName */
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)
417: if (PROT_TRACE) HTTrace("MailAddress. GetUsername returns NO\n");
418: #endif /* WWW_MSWINDOWS */
419:
420: #ifdef HAVE_CUSERID
421: if (!login && (login = (char *) cuserid(NULL)) == NULL)
422: if (PROT_TRACE) HTTrace("MailAddress. cuserid returns NULL\n");
423: #endif /* HAVE_CUSERID */
424:
425: #ifdef HAVE_GETLOGIN
426: #ifdef HT_REENTRANT
427: if (!login && (login = (char *) getlogin_r(name, LOGNAME_MAX)) == NULL)
428: #else
429: if (!login && (login = (char *) getlogin()) == NULL)
430: #endif /* HT_REENTRANT */
431: if (PROT_TRACE) HTTrace("MailAddress. getlogin returns NULL\n");
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)
440: if (PROT_TRACE) HTTrace("MailAddress. LOGNAME not found\n");
441:
442: if (!login && (login = getenv("USER")) == NULL)
443: if (PROT_TRACE) HTTrace("MailAddress. USER not found\n");
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;
563: if (CORE_TRACE)
564: HTTrace("TimeZone.... GMT + (%02d) hours (including DST)\n",
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;
578: if (CORE_TRACE)
579: HTTrace("TimeZone.... GMT + (%02d) hours (including DST)\n",
580: (int)local->tm_gmtoff / 3600);
581: }
582: #else
583: if (CORE_TRACE) HTTrace("TimeZone.... Not defined\n");
584: #endif /* HAVE_TM_GMTOFF */
585: #endif /* HAVE_TIMEZONE */
586: return HTTimeZone;
2.6 frystyk 587: }
588:
589: /*
590: ** Finds a temporary name in in the directory given. If the directory
2.9 frystyk 591: ** is NULL then don't prepend anything.
2.6 frystyk 592: ** If success, the result must be freed by caller, else we return NULL
593: */
2.16 frystyk 594: PUBLIC char * HTGetTmpFileName (const char * abs_dir)
2.6 frystyk 595: {
2.16 frystyk 596: #ifdef HAVE_TEMPNAM
2.21 frystyk 597: #ifdef __CYGWIN__
598: return tempnam(abs_dir, "");
599: #else
2.16 frystyk 600: return tempnam(abs_dir, NULL);
2.21 frystyk 601: #endif /* __CYGWIN__ */
2.16 frystyk 602: #else
603: /*
604: ** This is only approx. as we don't know if this file exists or not.
605: ** Hopefully, tempnam() exists on enough platforms so that this is not
606: ** a problem.
607: */
2.6 frystyk 608: char * result = NULL;
609: char * offset = NULL;
2.16 frystyk 610: if (!(result = (char *) HT_MALLOC((abs_dir ? strlen(abs_dir) : 0) +
611: HT_MAX_TMPNAM + 2)))
2.6 frystyk 612: HT_OUTOFMEM("HTGetTmpFileName");
2.16 frystyk 613:
614: #ifdef WWW_MSWINDOWS
615: if (abs_dir) {
616: #else
617: if (abs_dir && *abs_dir=='/') {
618: #endif /* WWW_MSWINDOWS */
619: strcpy(result, abs_dir);
620: offset = result+strlen(result);
621: if (*(offset-1) != '/') *offset++ = '/';
622:
2.6 frystyk 623: #ifdef HT_REENTRANT
2.16 frystyk 624: tmpnam_r(offset);
2.6 frystyk 625: #else
2.16 frystyk 626: tmpnam(offset);
2.6 frystyk 627: #endif
2.9 frystyk 628:
2.16 frystyk 629: {
2.9 frystyk 630: #ifdef WWW_MSWINDOWS
2.16 frystyk 631: char * orig = strrchr(offset, '\\');
2.9 frystyk 632: #else
2.16 frystyk 633: char * orig = strrchr(offset, '/');
2.9 frystyk 634: #endif /* WWW_MSWINDOWS */
2.16 frystyk 635: char * dest = offset;
636: if (orig++) while ((*dest++ = *orig++));
637: }
638: } else {
639: offset = result;
640: #ifdef HT_REENTRANT
641: tmpnam_r(offset);
642: #else
643: tmpnam(offset);
644: #endif
645: offset = result;
2.9 frystyk 646: }
2.6 frystyk 647: return result;
2.16 frystyk 648: #endif /* HAVE_TEMPNAM */
2.11 frystyk 649: }
650:
651: /*
652: ** Copied from X utilities
653: */
2.12 frystyk 654: PUBLIC ms_t HTGetTimeInMillis (void)
2.11 frystyk 655: {
2.13 eric 656: #ifdef WWW_MSWINDOWS
657: return GetTickCount();
658: #else /* WWW_MSWINDOWS */
2.17 frystyk 659: #ifdef HAVE_GETTIMEOFDAY
2.11 frystyk 660: struct timeval tp;
661: gettimeofday(&tp, NULL);
662: return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
2.17 frystyk 663: #else
664: return((ms_t) 0);
665: #endif
2.13 eric 666: #endif /* !WWW_MSWINDOWS */
2.1 frystyk 667: }
Webmaster