earlybrowserreborn - Blame information for rev 4

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