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