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