Annotation of libwww/Library/src/HTTCP.c, revision 2.12

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

Webmaster