1 /* Generic Communication Code HTTCP.c
2 ** ==========================
4 ** This code is in common between client and server sides.
6 ** 16 Jan 92 Fix strtol() undefined on CMU Mach. - TBL
11 #include "tcp.h" /* Defines SHORT_NAMES if necessary */
13 #define HTInetStatus HTInStat
14 #define HTInetString HTInStri
15 #define HTParseInet HTPaInet
18 /* Module-Wide variables
21 PRIVATE char *hostname=0; /* The name of this host */
27 /* PUBLIC struct sockaddr_in HTHostAddress; */ /* The internet address of the host */
28 /* Valid after call to HTHostName() */
30 /* Encode INET status (as in sys/errno.h) inet_status()
34 ** where gives a description of what caused the error
35 ** global errno gives the error number in the unix way.
38 ** returns a negative status in the unix way.
42 extern int uerrno; /* Deposit of error info (as perr errno.h) */
43 extern int vmserrno; /* Deposit of VMS error info */
44 extern volatile noshare int errno; /* noshare to avoid PSECT conflict */
55 extern char *sys_errlist[]; /* see man perror on cernvax */
63 /* Report Internet Error
64 ** ---------------------
67 PUBLIC int HTInetStatus(char *where)
69 PUBLIC int HTInetStatus(where)
73 CTRACE(tfp, "TCP: Error %d in `errno' after call to %s() failed.\n\t%s\n",
76 "(Error number not translated)"); /* What Is the VM equiv? */
77 #define ER_NO_TRANS_DONE
80 "(Error number not translated)");
81 #define ER_NO_TRANS_DONE
85 #define ER_NO_TRANS_DONE
89 #define ER_NO_TRANS_DONE
92 #ifndef ER_NO_TRANS_DONE
93 errno < sys_nerr ? sys_errlist[errno] : "Unknown error" );
98 CTRACE(tfp, " Unix error number (uerrno) = %ld dec\n", uerrno);
99 CTRACE(tfp, " VMS error (vmserrno) = %lx hex\n", vmserrno);
105 /* Parse a cardinal value parse_cardinal()
106 ** ----------------------
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.
115 ** *pp points to first unread character
116 ** *pstatus points to status updated iff bad
119 PUBLIC unsigned int HTCardinal(int *pstatus,
121 unsigned int max_value)
123 PUBLIC unsigned int HTCardinal(pstatus, pp, max_value)
126 unsigned int max_value;
130 if ( (**pp<'0') || (**pp>'9')) { /* Null string is error */
131 *pstatus = -3; /* No number where one expeceted */
136 while ((**pp>='0') && (**pp<='9')) n = n*10 + *((*pp)++) - '0';
139 *pstatus = -4; /* Cardinal outside range */
147 /* Produce a string for an inernet address
148 ** ---------------------------------------
151 ** returns a pointer to a static string which must be copied if
155 PUBLIC const char * HTInetString(struct sockaddr_in* sin)
157 PUBLIC char * HTInetString(sin)
158 struct sockaddr_in *sin;
161 static char string[16];
162 sprintf(string, "%d.%d.%d.%d",
163 (int)*((unsigned char *)(&sin->sin_addr)+0),
164 (int)*((unsigned char *)(&sin->sin_addr)+1),
165 (int)*((unsigned char *)(&sin->sin_addr)+2),
166 (int)*((unsigned char *)(&sin->sin_addr)+3));
171 /* Parse an internet node address and port
172 ** ---------------------------------------
175 ** str points to a string with a node name or number,
176 ** with optional trailing colon and port number.
177 ** sin points to the binary internet address field.
180 ** *sin is filled in. If no port is specified in str, that
181 ** field is left unchanged in *sin.
184 PUBLIC int HTParseInet(struct sockaddr_in* sin, const char *str)
186 PUBLIC int HTParseInet(sin, str)
187 struct sockaddr_in *sin;
193 struct hostent *phost; /* Pointer to host - See netdb.h */
194 strcpy(host, str); /* Take a copy we can mutilate */
198 /* Parse port number if present
200 if (port=strchr(host, ':')) {
201 *port++ = 0; /* Chop off port */
202 if (port[0]>='0' && port[0]<='9') {
204 sin->sin_port = htons(atol(port));
206 sin->sin_port = htons(strtol(port, (char**)0 , 10));
209 #ifdef SUPPRESS /* 1. crashes!?!. 2. Not recommended */
210 struct servent * serv = getservbyname(port, (char*)0);
211 if (serv) sin->sin_port = serv->s_port;
212 else if (TRACE) printf("TCP: Unknown service %s\n", port);
217 /* Parse host number if present
219 if (*host>='0' && *host<='9') { /* Numeric node address: */
220 sin->sin_addr.s_addr = inet_addr(host); /* See arpa/inet.h */
222 } else { /* Alphanumeric node name: */
223 #ifdef MVS /* Oustanding problem with crsh in MVS gethostbyname */
224 if(TRACE)printf("HTTCP: Calling gethostbyname(%s)\n", host);
226 phost=gethostbyname(host); /* See netdb.h */
228 if(TRACE)printf("HTTCP: gethostbyname() returned %d\n", phost);
232 "HTTPAccess: Can't find internet node name `%s'.\n",host);
233 return -1; /* Fail? */
235 memcpy(&sin->sin_addr, phost->h_addr, phost->h_length);
239 "TCP: Parsed address as port %d, IP address %d.%d.%d.%d\n",
240 (unsigned int)ntohs(sin->sin_port),
241 (int)*((unsigned char *)(&sin->sin_addr)+0),
242 (int)*((unsigned char *)(&sin->sin_addr)+1),
243 (int)*((unsigned char *)(&sin->sin_addr)+2),
244 (int)*((unsigned char *)(&sin->sin_addr)+3));
251 /* Derive the name of the host on which we are
252 ** -------------------------------------------
256 PRIVATE void get_host_details(void)
258 PRIVATE void get_host_details()
261 #ifndef MAXHOSTNAMELEN
262 #define MAXHOSTNAMELEN 64 /* Arbitrary limit */
266 char name[MAXHOSTNAMELEN+1]; /* The name of this host */
267 #ifdef NEED_HOST_ADDRESS /* no -- needs name server! */
268 struct hostent * phost; /* Pointer to host -- See netdb.h */
270 int namelength = sizeof(name);
272 if (hostname) return; /* Already done */
273 gethostname(name, namelength); /* Without domain */
274 CTRACE(tfp, "TCP: Local host name is %s\n", name);
275 StrAllocCopy(hostname, name);
277 #ifdef NEED_HOST_ADDRESS /* no -- needs name server! */
278 phost=gethostbyname(name); /* See netdb.h */
281 "TCP: Can't find my own internet node address for `%s'!!\n",
285 StrAllocCopy(hostname, phost->h_name);
286 memcpy(&HTHostAddress, &phost->h_addr, phost->h_length);
287 if (TRACE) printf(" Name server says that is `%s' = %s\n",
288 hostname, HTInetString(&HTHostAddress));
293 PUBLIC const char * HTHostName(void)
295 PUBLIC char * HTHostName()