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

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

Webmaster