Annotation of libwww/Library/src/HTTCP.c, revision 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