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