📄 ckcnet.c
字号:
perror("netopen"); x25diag(); } (VOID) close (ttyfd); ttyfd = -1; errno = i; return (-1); } /* Get X.25 link identification used for the connection */ if (ioctl(ttyfd,X25_GET_LINK,&linkid) < 0) { perror ("Getting X.25 link id"); return (-1); } /* Get X.25 logical channel number used for the connection */ if (ioctl(ttyfd,X25_RD_LCGN,&lcn) < 0) { perror ("Getting X.25 lcn"); return (-1); } /* Get SunLink X.25 version */ if (ioctl(ttyfd,X25_VERSION,&x25ver) < 0) { perror ("Getting SunLink X.25 version"); return (-1); } ttnet = nett; /* Sunlink X.25 network */ ttnproto = NP_X3; /* PAD X.3, X.28, X.29 protocol */ if (*lcl < 0) *lcl = 1; /* Local mode */ return(0); } else /* Note that SUNX25 support can coexist with TCP/IP support. */#endif /* SUNX25 *//* Add support for other networks here.*/ if (nett != NET_TCPB) return(-1); /* BSD socket support */ netclos(); /* Close any previous connection. */ strncpy(namecopy, name, NAMECPYL); /* Copy the hostname. */ ttnproto = NP_NONE; /* No protocol selected yet. */ debug(F110,"netopen namecopy",namecopy,0); p = namecopy; /* Was a service requested? */ while (*p != '\0' && *p != ':') p++; /* Look for colon */ if (*p == ':') { /* Have a colon */ *p++ = '\0'; /* Get service name or number */ } else { /* Otherwise use telnet */ p = "telnet"; } debug(F110,"netopen service requested",p,0); if (isdigit(*p)) { /* Use socket number without lookup */ service = &servrec; service->s_port = htons((unsigned short)atoi(p)); } else { /* Otherwise lookup the service name */ service = getservbyname(p, "tcp"); } if (!service) { fprintf(stderr, "Cannot find port for service %s\n", p);#ifdef MULTINET debug(F101,"netopen can't get service","",socket_errno);#else debug(F101,"netopen can't get service","",errno);#endif /* MULTINET */ errno = 0; /* rather than mislead */ return(-1); } /* Set up socket structure and get host address */ bzero((char *)&saddr, sizeof(saddr)); if ((host = gethostbyname(namecopy)) != NULL) { saddr.sin_family = host->h_addrtype; bcopy(host->h_addr, (caddr_t)&saddr.sin_addr, host->h_length); } else {#ifdef INADDRX/* inet_addr() is of type struct in_addr */ struct in_addr ina; unsigned long uu;#ifdef datageneral extern struct in_addr inet_addr();#endif /* datageneral */ ina = inet_addr(namecopy); uu = *(unsigned long *)&ina;#else /* Not INADDRX *//* inet_addr() is unsigned long */ unsigned long uu; uu = inet_addr(namecopy);#endif /* INADDRX */ if ((saddr.sin_addr.s_addr = uu) != ((unsigned long)-1)) saddr.sin_family = AF_INET; else { fprintf(stderr, "Can't get address for %s\n", namecopy);#ifdef MULTINET debug(F101,"netopen can't get address","",socket_errno);#else debug(F101,"netopen can't get address","",errno);#endif /* MULTINET */ errno = 0; /* rather than mislead */ return(-1); } } /* Get a file descriptor for the connection. */ saddr.sin_port = service->s_port; sprintf(ipaddr,"%s", inet_ntoa(saddr.sin_addr)); if (!quiet && *ipaddr) printf(" Trying %s...\n", ipaddr);#ifdef EXCELAN send_socket.sin_family = AF_INET; send_socket.sin_addr.s_addr = 0; send_socket.sin_port = 0; if ((ttyfd = socket(SOCK_STREAM, (struct sockproto *)0, &send_socket, SO_REUSEADDR)) < 0)#else if ((ttyfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)#endif /* EXCELAN */ {#ifdef EXCELAN experror("TCP socket error");#else#ifdef MULTINET socket_perror("TCP socket error"); debug(F101,"netopen socket error","",socket_errno);#else perror("TCP socket error"); debug(F101,"netopen socket error","",errno);#endif /* MULTINET */#endif /* EXCELAN */ return (-1); } errno = 0; /* Now connect to the socket on the other end. */#ifdef EXCELAN if (connect(ttyfd, &saddr) < 0)#else if (connect(ttyfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)#endif /* EXCELAN */ { i = errno; /* save error code */ close(ttyfd); ttyfd = -1; errno = i; /* and report this error */#ifdef EXCELAN if (errno) experror("netopen connect");#else#ifdef MULTINET debug(F101,"netopen connect error","",socket_errno); if (errno) socket_perror("netopen connect");#else debug(F101,"netopen connect errno","",errno);#ifdef WINTCP perror("netopen connect");#endif /* WINTCP */#ifdef DEC_TCPIP perror("netopen connect");#endif /* DEC_TCPIP */#endif /* MULTINET */#endif /* EXCELAN */ return(-1); }#ifdef SO_OOBINLINE/* The symbol SO_OOBINLINE is not known to Ultrix 2.0. It means "leave out of band data inline". The normal value is 0x0100, but don't try this on systems where the symbol is undefined.*/#ifdef datageneral setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);#else#ifdef BSD43 setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);#else#ifdef OSF1 setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);#else#ifdef POSIX setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);#else#ifdef SOLARIS/* Maybe this applies to all SVR4 versions, but the other (else) way has been compiling and working fine on all the others, so best not to change it.*/ setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);#else setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof on);#endif /* SOLARIS */#endif /* POSIX */#endif /* BSD43 */#endif /* OSF1 */#endif /* datageneral */#endif /* SO_OOBINLINE */ /* See if the service is TELNET. */ if ((x = ntohs((unsigned short)service->s_port)) == TELNET_PORT) ttnproto = NP_TELNET; /* Yes, set global flag. */ debug(F101,"netopen service","",x); ttnet = nett; /* TCP/IP (sockets) network */ tn_init = 0; /* Telnet protocol not init'd yet */ if (*lcl < 0) *lcl = 1; /* Local mode. */ return(0); /* Done. */}/* N E T C L O S -- Close current network connection. */intnetclos() { int x = 0; if (ttyfd < 0) /* Was open? */ return(0); /* Wasn't. */ if (ttyfd > -1) /* Was. */#ifdef VMSTCPIP x = socket_close(ttyfd); /* Close it. */#else x = close(ttyfd);#endif /* VMSTCPIP */ ttyfd = -1; /* Mark it as closed. */ tn_init = 0; /* Remember about telnet protocol... */ *ipaddr = '\0'; /* Zero the IP address string */ return(x);}/* N E T T C H K -- Check if network up, and how many bytes can be read *//* Returns number of bytes waiting, or -1 if connection has been dropped.*/int /* Check how many bytes are ready */nettchk() { /* for reading from network */#ifdef VMSTCPIP unsigned int count; int x, y; char c; debug(F101,"nettchk entry ttibn","",ttibn); debug(F101,"nettchk entry ttibp","",ttibp); socket_errno = 0;/* Note: this socket_ioctl() call does NOT return an error if the connection has been broken. (At least not in Multinet.)*/ if (socket_ioctl(ttyfd,FIONREAD,&count) < 0) { debug(F101,"nettchk socket_ioctl error","",socket_errno); if (ttibn < 1) return(-1); else return(ttibn); } debug(F101,"nettchk count","",count);#ifndef DEC_TCPIP/* Let's see if we can skip this for UCX, since it seems to cause trouble.*/ if (count == 0) {/* Here we need to tell the difference between a 0 count on an active connection, and a 0 count because the remote end of the socket broke the connection. There is no mechanism in TGV MultiNet (or WIN/TCP?) to query the status of the connection, so we have to do a read. -1 means there was no data available (socket_errno == EWOULDBLOCK), 0 means the connection is down. But if, by chance, we actually get a character, we have to put it where it won't be lost.*/ y = 1; /* Turn on nonblocking reads */ debug(F101,"nettchk before FIONBIO","",x); x = socket_ioctl(ttyfd,FIONBIO,&y); debug(F101,"nettchk FIONBIO","",x); x = socket_read(ttyfd,&c,1); /* Returns -1 if no data */ debug(F101,"nettchk socket_read","",x); y = 0; /* Turn them back off */ socket_ioctl(ttyfd,FIONBIO,&y); if (x == 0) return(-1); /* Connection is broken. */ if (x == 1) { /* Oops, actually got a byte? */ debug(F101,"nettchk socket_read char","",c); debug(F101,"nettchk ttibp","",ttibp); debug(F101,"nettchk ttibn","",ttibn);/* So put the byte we got into the buffer at the current position. Increment the buffer count, but DON'T increment the buffer pointer.*/ ttibuf[ttibp+ttibn] = c; ttibn++;#ifdef DEBUG ttibuf[ttibp+ttibn] = '\0'; debug(F111,"nettchk ttibn",ttibuf,ttibn);#endif /* DEBUG */ } }#endif /* DEC_TCPIP */ debug(F101,"nettchk returns","",count+ttibn); return(count + ttibn);#else /* Not VMSTCPIP *//* UNIX just uses ttchk(), in which the ioctl() calls on the file descriptor seem to work OK.*/ return(0);#endif /* VMSTCPIP *//* But what about X.25?*/}/* N E T I N C -- Input character from network */int netinc(timo) int timo; {#ifdef VMSTCPIP int x; unsigned char c; /* The locals. */ if (ttibn > 0) { /* Something in internal buffer? */ debug(F100,"netinc char in buf","",0); /* Yes. */ x = 0; /* Success. */ } else { /* Else must read from network. */ x = -1; /* Assume failure. */#ifdef DEBUG debug(F101,"netinc goes to net, timo","",timo); ttibuf[ttibp+1] = '\0'; debug(F111,"netinc ttibuf",ttibuf,ttibp);#endif /* DEBUG */ if (timo <= 0) { /* Untimed case. */ while (1) { /* Wait forever if necessary. */ if (ttbufr() < 0) /* Refill buffer. */ break; /* Error, fail. */ if (ttibn > 0) { /* Success. */ x = 0; break; } } } else { /* Timed case... */ saval = signal(SIGALRM,ttimoff); /* Enable timer interrupt */ alarm(timo); /* for requested interval. */ if (setjmp(njbuf)) { /* Timer went off? */ x = -1; /* Yes, fail. */ } else { while (1) { if (ttbufr() < 0) /* Keep trying to refill it. */ break; /* Till we get an error. */ if (ttibn > 0) { /* Or we get a character. */ x = 0; break; } } } ttimoff(); /* Timer off. */ } } if (x < 0) { /* Return -1 if we failed. */ debug(F100,"netinc timed out","",0); return(-1); } else { /* Otherwise */ ttibn--; /* Return what we got. */ c = ttibuf[ttibp++]; debug(F101,"netinc returning","",c); return((c & 0xff)); }#else /* Not MULTINET or WINTCP */ return(-1);#endif /* VMSTCPIP */}/* N E T T O L -- Output a string of bytes to the network *//* Call with s = pointer to string, n = length. Returns number of bytes actually written on success, or -1 on i/o error, -2 if called improperly.*/intnettol(s,n) char *s; int n; {#ifdef VMSTCPIP int count; if (ttnet == NET_TCPB) { if ((count = socket_write(ttyfd,s,n)) < 1) { debug(F101,"nettol socket_write error","",socket_errno); return(-1); } debug(F111,"nettol socket_write",s,count); return(count); } else return(-2);#else debug(F100,"nettol VMSTCPIP not defined","",0); return(-2);#endif /* VMSTCPIP */}/* N E T T O C -- Output character to network *//* Call with character to be transmitted. Returns 0 if transmission was successful, or -1 upon i/o error, or -2 if called improperly.*/int #ifdef CK_ANSICnettoc(char c)#elsenettoc(c) char c;#endif /* CK_ANSIC *//* nettoc */ {#ifdef VMSTCPIP unsigned char cc; cc = c; if (ttnet == NET_TCPB) { debug(F101,"nettoc cc","",cc); if (socket_write(ttyfd,&cc,1) < 1) { debug(F101,"nettoc socket_write error","",socket_errno); return(-1); } debug(F101,"nettoc socket_write","", cc); return(0); } else return(-2);#else return(-2);#endif /* MULTINET */}/* N E T F L U I -- Flush network input buffer */intnetflui() { int n;#ifdef VMSTCPIP ttibuf[ttibp+1] = '\0'; debug(F111,"netflui 1",ttibuf,ttibn); ttibn = ttibp = 0; /* Flush internal buffer *FIRST* */ if ((n = nettchk()) > 0) { /* Now see what's waiting on the net */ if (n > TTIBUFL) n = TTIBUFL; /* and sponge it up */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -