Annotation of libwww/Library/src/HTTCP.c, revision 2.12
1.1 timbl 1: /* Generic Communication Code HTTCP.c
2: ** ==========================
3: **
4: ** This code is in common between client and server sides.
5: **
6: ** 16 Jan 92 TBL Fix strtol() undefined on CMU Mach.
7: ** 25 Jun 92 JFG Added DECNET option through TCP socket emulation.
2.7 duns 8: ** 13 Sep 93 MD Added correct return of vmserrorno for HTInetStatus.
9: ** Added decoding of vms error message for MULTINET.
1.1 timbl 10: */
11:
12:
13: #include "HTUtils.h"
14: #include "tcp.h" /* Defines SHORT_NAMES if necessary */
15: #ifdef SHORT_NAMES
16: #define HTInetStatus HTInStat
2.12 ! luotonen 17: #define HTErrnoString HTErrnoS
1.1 timbl 18: #define HTInetString HTInStri
19: #define HTParseInet HTPaInet
20: #endif
21:
2.8 luotonen 22:
2.11 duns 23: /* VMS stuff */
24: #ifdef VMS
25: #ifndef MULTINET
26: #define FD_SETSIZE 32
27: #else /* Multinet */
28: #define FD_SETSIZE 256
29: #endif /* Multinet */
30: #endif /* VMS */
31:
32:
1.1 timbl 33: /* Module-Wide variables
34: */
35:
36: PRIVATE char *hostname=0; /* The name of this host */
37:
38:
39:
40: /* Encode INET status (as in sys/errno.h) inet_status()
41: ** ------------------
42: **
43: ** On entry,
44: ** where gives a description of what caused the error
45: ** global errno gives the error number in the unix way.
46: **
47: ** On return,
48: ** returns a negative status in the unix way.
49: */
50: #ifndef PCNFS
2.7 duns 51: #ifdef VMS
2.10 duns 52: #ifndef __DECC
1.1 timbl 53: extern int uerrno; /* Deposit of error info (as per errno.h) */
2.7 duns 54: extern volatile noshare int socket_errno; /* socket VMS error info
55: (used for translation of vmserrno) */
1.1 timbl 56: extern volatile noshare int vmserrno; /* Deposit of VMS error info */
57: extern volatile noshare int errno; /* noshare to avoid PSECT conflict */
2.10 duns 58: #endif /* not DECC */
2.11 duns 59: #endif /* VMS */
60:
1.1 timbl 61: #ifndef errno
62: extern int errno;
63: #endif /* errno */
64:
65: #ifndef VM
2.7 duns 66: #ifndef VMS
1.1 timbl 67: #ifndef NeXT
68: #ifndef THINK_C
69: extern char *sys_errlist[]; /* see man perror on cernvax */
70: extern int sys_nerr;
71: #endif /* think c */
72: #endif /* NeXT */
2.7 duns 73: #endif /* VMS */
1.1 timbl 74: #endif /* VM */
75:
76: #endif /* PCNFS */
77:
2.12 ! luotonen 78:
! 79: /*
! 80: * Returns the string equivalent of the current errno.
! 81: */
! 82: PUBLIC CONST char * HTErrnoString NOARGS
1.1 timbl 83: {
2.11 duns 84: #ifndef VMS
2.7 duns 85:
1.1 timbl 86: #ifdef VM
2.12 ! luotonen 87: return "(Error number not translated)"; /* What Is the VM equiv? */
1.1 timbl 88: #define ER_NO_TRANS_DONE
89: #endif
2.12 ! luotonen 90:
! 91: #if defined(NeXT) || defined(THINK_C)
! 92: return strerror(errno);
1.1 timbl 93: #define ER_NO_TRANS_DONE
94: #endif
2.12 ! luotonen 95:
! 96: #ifndef ER_NO_TRANS_DONE
! 97: return (errno < sys_nerr ? sys_errlist[errno] : "Unknown error");
1.1 timbl 98: #endif
99:
2.12 ! luotonen 100: #else /* VMS */
! 101:
! 102: static char buf[60];
! 103: sprintf(buf,"Unix errno = %ld dec, VMS error = %lx hex",errno,vaxc$errno);
! 104: return buf;
! 105:
1.1 timbl 106: #endif
2.12 ! luotonen 107: }
! 108:
! 109:
! 110: /* Report Internet Error
! 111: ** ---------------------
! 112: */
! 113: PUBLIC int HTInetStatus ARGS1(char *, where)
! 114: {
! 115: #ifndef VMS
! 116:
! 117: CTRACE(tfp,
! 118: "TCP errno... %d after call to %s() failed.\n............ %s\n",
! 119: errno, where, HTErrnoString());
1.1 timbl 120:
2.11 duns 121: #else /* VMS */
2.12 ! luotonen 122:
2.11 duns 123: CTRACE(tfp, " Unix error number = %ld dec\n", errno);
124: CTRACE(tfp, " VMS error = %lx hex\n", vaxc$errno);
2.12 ! luotonen 125:
2.11 duns 126: #ifdef MULTINET
127: CTRACE(tfp, " Multinet error = %lx hex\n", socket_errno);
128: #endif /* MULTINET */
2.12 ! luotonen 129:
2.11 duns 130: #endif /* VMS */
2.7 duns 131:
132: #ifdef VMS
2.11 duns 133: /* errno happen to be zero if vaxc$errno <> 0 */
134: return -vaxc$errno;
2.7 duns 135: #else
1.1 timbl 136: return -errno;
2.7 duns 137: #endif
1.1 timbl 138: }
139:
140:
141: /* Parse a cardinal value parse_cardinal()
142: ** ----------------------
143: **
144: ** On entry,
145: ** *pp points to first character to be interpreted, terminated by
146: ** non 0:9 character.
147: ** *pstatus points to status already valid
148: ** maxvalue gives the largest allowable value.
149: **
150: ** On exit,
151: ** *pp points to first unread character
152: ** *pstatus points to status updated iff bad
153: */
154:
155: PUBLIC unsigned int HTCardinal ARGS3
156: (int *, pstatus,
157: char **, pp,
158: unsigned int, max_value)
159: {
160: int n;
161: if ( (**pp<'0') || (**pp>'9')) { /* Null string is error */
162: *pstatus = -3; /* No number where one expeceted */
163: return 0;
164: }
165:
166: n=0;
167: while ((**pp>='0') && (**pp<='9')) n = n*10 + *((*pp)++) - '0';
168:
169: if (n>max_value) {
170: *pstatus = -4; /* Cardinal outside range */
171: return 0;
172: }
173:
174: return n;
175: }
176:
177:
178: #ifndef DECNET /* Function only used below for a trace message */
179:
180: /* Produce a string for an Internet address
181: ** ----------------------------------------
182: **
183: ** On exit,
184: ** returns a pointer to a static string which must be copied if
185: ** it is to be kept.
186: */
187:
188: PUBLIC CONST char * HTInetString ARGS1(SockA*,sin)
189: {
190: static char string[16];
191: sprintf(string, "%d.%d.%d.%d",
192: (int)*((unsigned char *)(&sin->sin_addr)+0),
193: (int)*((unsigned char *)(&sin->sin_addr)+1),
194: (int)*((unsigned char *)(&sin->sin_addr)+2),
195: (int)*((unsigned char *)(&sin->sin_addr)+3));
196: return string;
197: }
198: #endif /* Decnet */
199:
200:
201: /* Parse a network node address and port
202: ** -------------------------------------
203: **
204: ** On entry,
205: ** str points to a string with a node name or number,
206: ** with optional trailing colon and port number.
207: ** sin points to the binary internet or decnet address field.
208: **
209: ** On exit,
210: ** *sin is filled in. If no port is specified in str, that
211: ** field is left unchanged in *sin.
212: */
213: PUBLIC int HTParseInet ARGS2(SockA *,sin, CONST char *,str)
214: {
215: char *port;
216: char host[256];
217: struct hostent *phost; /* Pointer to host - See netdb.h */
218: strcpy(host, str); /* Take a copy we can mutilate */
219:
220:
221:
222: /* Parse port number if present
223: */
2.8 luotonen 224: if ((port=strchr(host, ':'))) {
1.1 timbl 225: *port++ = 0; /* Chop off port */
226: if (port[0]>='0' && port[0]<='9') {
227:
228: #ifdef unix
229: sin->sin_port = htons(atol(port));
230: #else /* VMS */
231: #ifdef DECNET
232: sin->sdn_objnum = (unsigned char) (strtol(port, (char**)0 , 10));
233: #else
234: sin->sin_port = htons(strtol(port, (char**)0 , 10));
235: #endif /* Decnet */
236: #endif /* Unix vs. VMS */
237:
238: } else {
239:
240: #ifdef SUPPRESS /* 1. crashes!?!. 2. Not recommended */
241: struct servent * serv = getservbyname(port, (char*)0);
242: if (serv) sin->sin_port = serv->s_port;
2.9 luotonen 243: else if (TRACE) fprintf(stderr, "TCP......... Unknown service %s\n", port);
1.1 timbl 244: #endif
245: }
246: }
247:
248: #ifdef DECNET
249: /* read Decnet node name. @@ Should know about DECnet addresses, but it's
250: probably worth waiting until the Phase transition from IV to V. */
251:
252: sin->sdn_nam.n_len = min(DN_MAXNAML, strlen(host)); /* <=6 in phase 4 */
253: strncpy (sin->sdn_nam.n_name, host, sin->sdn_nam.n_len + 1);
254:
255: if (TRACE) fprintf(stderr,
256: "DECnet: Parsed address as object number %d on host %.6s...\n",
257: sin->sdn_objnum, host);
258:
259: #else /* parse Internet host */
260:
261: /* Parse host number if present.
262: */
263: if (*host>='0' && *host<='9') { /* Numeric node address: */
264: sin->sin_addr.s_addr = inet_addr(host); /* See arpa/inet.h */
265:
266: } else { /* Alphanumeric node name: */
267: #ifdef MVS /* Oustanding problem with crash in MVS gethostbyname */
2.6 timbl 268: if(TRACE)fprintf(stderr, "HTTCP: Calling gethostbyname(%s)\n", host);
1.1 timbl 269: #endif
270: phost=gethostbyname(host); /* See netdb.h */
271: #ifdef MVS
2.6 timbl 272: if(TRACE)fprintf(stderr, "HTTCP: gethostbyname() returned %d\n", phost);
1.1 timbl 273: #endif
274: if (!phost) {
275: if (TRACE) fprintf(stderr,
276: "HTTPAccess: Can't find internet node name `%s'.\n",host);
277: return -1; /* Fail? */
278: }
279: memcpy(&sin->sin_addr, phost->h_addr, phost->h_length);
280: }
281:
282: if (TRACE) fprintf(stderr,
2.9 luotonen 283: "TCP......... Parsed address as port %d, IP address %d.%d.%d.%d\n",
2.5 timbl 284: (int)ntohs(sin->sin_port),
1.1 timbl 285: (int)*((unsigned char *)(&sin->sin_addr)+0),
286: (int)*((unsigned char *)(&sin->sin_addr)+1),
287: (int)*((unsigned char *)(&sin->sin_addr)+2),
288: (int)*((unsigned char *)(&sin->sin_addr)+3));
289:
290: #endif /* Internet vs. Decnet */
291:
292: return 0; /* OK */
293: }
294:
295:
2.8 luotonen 296: /*
297: ** Get host name of the machine on the other end of a socket.
298: */
299: PUBLIC char * HTGetHostName ARGS1(int, soc)
300: {
301: struct sockaddr addr;
302: int len = sizeof(struct sockaddr);
303: struct in_addr *iaddr;
304: struct hostent * phost; /* Pointer to host -- See netdb.h */
305: char *name = NULL;
306:
307: #ifdef DECNET /* Decnet ain't got no damn name server 8#OO */
308: return NULL;
309: #else
310: if (getpeername(soc, &addr, &len) < 0)
311: return NULL;
312:
313: iaddr = &(((struct sockaddr_in *)&addr)->sin_addr);
314: phost=gethostbyaddr((char*)iaddr,
315: sizeof(struct in_addr),
316: AF_INET);
317: if (!phost) {
318: if (TRACE) fprintf(stderr,
2.9 luotonen 319: "TCP......... Can't find internet node name for peer!!\n");
2.8 luotonen 320: return NULL;
321: }
322: StrAllocCopy(name, phost->h_name);
2.9 luotonen 323: if (TRACE) fprintf(stderr, "TCP......... Peer name is `%s'\n", name);
2.8 luotonen 324:
325: return name;
326:
327: #endif /* not DECNET */
328: }
329:
330:
1.1 timbl 331: /* Derive the name of the host on which we are
332: ** -------------------------------------------
333: **
334: */
2.8 luotonen 335: PRIVATE void get_host_details NOARGS
1.1 timbl 336:
337: #ifndef MAXHOSTNAMELEN
338: #define MAXHOSTNAMELEN 64 /* Arbitrary limit */
339: #endif
340:
341: {
342: char name[MAXHOSTNAMELEN+1]; /* The name of this host */
343: struct hostent * phost; /* Pointer to host -- See netdb.h */
344: int namelength = sizeof(name);
345:
346: if (hostname) return; /* Already done */
347: gethostname(name, namelength); /* Without domain */
2.9 luotonen 348: CTRACE(tfp, "TCP......... Local host name is %s\n", name);
1.1 timbl 349: StrAllocCopy(hostname, name);
350:
351: #ifndef DECNET /* Decnet ain't got no damn name server 8#OO */
352: phost=gethostbyname(name); /* See netdb.h */
353: if (!phost) {
354: if (TRACE) fprintf(stderr,
2.9 luotonen 355: "TCP......... Can't find my own internet node address for `%s'!!\n",
1.1 timbl 356: name);
357: return; /* Fail! */
358: }
359: StrAllocCopy(hostname, phost->h_name);
2.9 luotonen 360: CTRACE(tfp, "TCP......... Full local host name is %s\n", hostname);
2.8 luotonen 361:
362: #ifdef NEED_HOST_ADDRESS /* no -- needs name server! */
1.1 timbl 363: memcpy(&HTHostAddress, &phost->h_addr, phost->h_length);
364: if (TRACE) fprintf(stderr, " Name server says that I am `%s' = %s\n",
365: hostname, HTInetString(&HTHostAddress));
2.8 luotonen 366: #endif /* NEED_HOST_ADDRESS */
1.1 timbl 367:
368: #endif /* not Decnet */
369: }
370:
2.12 ! luotonen 371:
! 372: PUBLIC CONST char * HTHostName NOARGS
1.1 timbl 373: {
374: get_host_details();
375: return hostname;
376: }
377:
Webmaster