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