📄 ckcnet.c
字号:
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 */#ifdef TCPSOCKET 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);#ifndef NOLISTEN if (name[0] == '*') return(tcpsrv_open(name, lcl, nett, 0));#endif /* NOLISTEN */ 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 TGVORWIN debug(F101,"netopen can't get service","",socket_errno);#else debug(F101,"netopen can't get service","",errno);#endif /* TGVORWIN */ errno = 0; /* rather than mislead */ return(-1); }#ifdef RLOGCODE if (service && !strcmp("login",p) && service->s_port != htons(513)) { fprintf(stderr, " Warning: login service on port %d instead of port 513\n", ntohs(service->s_port)); fprintf(stderr, " Edit SERVICES file if RLOGIN fails to connect.\n"); debug(F101,"tcpsrv_open login on port","",ntohs(service->s_port)); }#endif /* RLOGCODE */ /* Set up socket structure and get host address */ bzero((char *)&saddr, sizeof(saddr)); debug(F100,"netopen bzero ok","",0); if (#ifdef NT /* we found that Win95 tries to call the DNS */ /* when a numeric IP Address is specified. */ /* and of course the lookup fails resulting */ /* in a long delay. So we test for the IP */ /* numeric value before calling gethostbyname */ /* but only in Win32 so as not to */ /* alter current code that works properly */ /* everywhere else. */ inet_addr(namecopy) == INADDR_NONE &&#endif /* NT */ (host = gethostbyname(namecopy)) != NULL) { debug(F100,"netopen gethostbyname != NULL","",0);#ifdef OS2 strncpy(name,host->h_name,80); strncat(name,":",80-strlen(name)); strncat(name,p,80-strlen(name));#endif /* OS2 */ saddr.sin_family = host->h_addrtype;#ifdef HADDRLIST#ifdef h_addr /* This is for trying multiple IP addresses - see <netdb.h> */ if (!(host->h_addr_list)) return(-1); bcopy(host->h_addr_list[0], (caddr_t)&saddr.sin_addr, host->h_length);#else bcopy(host->h_addr, (caddr_t)&saddr.sin_addr, host->h_length);#endif /* h_addr */#else /* HADDRLIST */ bcopy(host->h_addr, (caddr_t)&saddr.sin_addr, host->h_length);#endif /* HADDRLIST */#ifndef EXCELAN debug(F111,"BCOPY","host->h_addr",host->h_addr);#endif /* EXCELAN */ debug(F111,"BCOPY"," (caddr_t)&saddr.sin_addr", (caddr_t)&saddr.sin_addr); debug(F111,"BCOPY","host->h_length",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 */ debug(F100,"netopen gethostbyname == NULL: INADDRX","",0); ina = inet_addr(namecopy); uu = *(unsigned long *)&ina;#else /* Not INADDRX *//* inet_addr() is unsigned long */ unsigned long uu; debug(F100,"netopen gethostbyname == NULL: Not INADDRX","",0); uu = inet_addr(namecopy);#endif /* INADDRX */ debug(F101,"netopen uu","",uu); 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 TGVORWIN debug(F101,"netopen can't get address","",socket_errno);#else debug(F101,"netopen can't get address","",errno);#endif /* TGVORWIN */ errno = 0; /* Rather than mislead */ return(-1); } } /* Get a file descriptor for the connection. */ saddr.sin_port = service->s_port; sprintf(ipaddr,"%s", (char *)inet_ntoa(saddr.sin_addr)); debug(F110,"netopen trying",ipaddr,0); if (!quiet && *ipaddr) printf(" Trying %s...\n", ipaddr); /* Loop to try additional IP addresses, if any. */ do {#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 /* EXCELAN */#ifdef NT#ifdef COMMENT /* Must make sure that all sockets are opened in Non-overlapped mode since we use the standard C RTL functions to read and write data. But it doesn't seem to work as planned. */ { int optionValue = SO_SYNCHRONOUS_NONALERT; if (setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *) &optionValue, sizeof(optionValue)) != NO_ERROR) return(-1); }#endif /* COMMENT */#endif /* NT */ if ((ttyfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)#endif /* EXCELAN */ {#ifdef EXCELAN experror("TCP socket error");#else#ifdef TGVORWIN#ifdef OLD_TWG errno = socket_errno;#endif /* OLD_TWG */ socket_perror("TCP socket error"); debug(F101,"netopen socket error","",socket_errno);#else perror("TCP socket error"); debug(F101,"netopen socket error","",errno);#endif /* TGVORWIN */#endif /* EXCELAN */ return (-1); } errno = 0;#ifdef RLOGCODE /* Not part of the RLOGIN RFC, but the BSD implementation */ /* requires that the client port be a priviliged port (<1024) */ /* on a Unix system this would require SuperUser permissions */ /* thereby saying that the root of the Unix system has given */ /* permission for this connection to be created */ if (service->s_port == htons((unsigned short)RLOGIN_PORT)) { struct sockaddr_in sin; static unsigned short lport = 1024; /* max reserved port */ int s_errno; lport--; /* Make sure we do not reuse a port */ if (lport == 512) lport = 1023; sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; while (1) { sin.sin_port = htons(lport); if (bind(ttyfd, (struct sockaddr *)&sin, sizeof(sin)) >= 0) break;#ifdef OS2 s_errno = socket_errno; if (s_errno && /* OS2 bind fails with 0, if already in use */#ifdef NT s_errno != WSAEADDRINUSE#else s_errno != SOCEADDRINUSE && s_errno != (SOCEADDRINUSE - SOCBASEERR)#endif /* NT */ )#else /* OS2 */#ifdef TGVORWIN if (socket_errno != EADDRINUSE)#else if (errno != EADDRINUSE)#endif /* TGVORWIN */#endif /* OS2 */ { printf("\nBind failed with errno %d for port %d.\n",#ifdef OS2 s_errno#else#ifdef TGVORWIN socket_errno#else errno#endif /* TGVORWIN */#endif /* OS2 */ , lport );#ifdef OS2 debug(F101,"rlogin bind failed","",s_errno);#else#ifdef TGVORWIN debug(F101,"rlogin bind failed","",socket_errno);#ifdef OLD_TWG errno = socket_errno;#endif /* OLD_TWG */ socket_perror("rlogin bind");#else debug(F101,"rlogin bind failed","",errno); perror("rlogin bind");#endif /* TGVORWIN */#endif /* OS2 */ netclos(); return -1; } lport--; if (lport == 512 /* lowest reserved port to use */ ) { printf("\nNo reserved ports available.\n"); netclos(); return -1; } } debug(F101,"rlogin lport","",lport); ttnproto = NP_RLOGIN; }#endif /* RLOGCODE *//* Now connect to the socket on the other end. */#ifdef EXCELAN if (connect(ttyfd, &saddr) < 0)#else#ifdef NT WSASafeToCancel = 1;#endif /* NT */ if (connect(ttyfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)#endif /* EXCELAN */ {#ifdef NT WSASafeToCancel = 0;#endif /* NT */#ifdef OS2 i = socket_errno;#else /* OS2 */#ifdef TGVORWIN i = socket_errno;#else i = errno; /* Save error code */#endif /* TGVORWIN */#endif /* OS2 */#ifdef RLOGCODE if (#ifdef OS2 i && /* OS2 bind fails with 0, if already in use */#ifdef NT i == WSAEADDRINUSE#else (i == SOCEADDRINUSE || i == (SOCEADDRINUSE - SOCBASEERR))#endif /* NT */#else /* OS2 */#ifdef TGVORWIN socket_errno == EADDRINUSE#else errno == EADDRINUSE#endif /* TGVORWIN */#endif /* OS2 */ && ttnproto == NP_RLOGIN) {#ifdef TCPIPLIB socket_close(ttyfd); /* Close it. */#else close(ttyfd);#endif /* TCPIPLIB */ continue; /* Try a different lport */ }#endif /* RLOGCODE */#ifdef HADDRLIST#ifdef h_addr if (host && host->h_addr_list && host->h_addr_list[1]) { perror(""); host->h_addr_list++; bcopy(host->h_addr_list[0], (caddr_t)&saddr.sin_addr, host->h_length); sprintf(ipaddr,"%s", (char *)inet_ntoa(saddr.sin_addr)); debug(F110,"netopen h_addr_list",ipaddr,0); if (!quiet && *ipaddr) printf(" Trying %s...\n", ipaddr);#ifdef TCPIPLIB socket_close(ttyfd); /* Close it. */#else close(ttyfd);#endif /* TCPIPLIB */ continue; }#endif /* h_addr */#endif /* HADDRLIST */ netclos(); ttyfd = -1; ttnproto = NP_NONE; errno = i; /* And report this error */#ifdef EXCELAN if (errno) experror("netopen connect");#else#ifdef TGVORWIN debug(F101,"netopen connect error","",socket_errno); /* if (errno) socket_perror("netopen connect"); */#ifdef OLD_TWG errno = socket_errno;#endif /* OLD_TWG */ socket_perror("netopen connect");#else /* TGVORWIN */ debug(F101,"netopen connect errno","",errno);#ifdef DEC_TCPIP perror("netopen connect");#endif /* DEC_TCPIP */#ifdef CMU_TCPIP perror("netopen connect");#endif /* CMU_TCPIP */#endif /* TGVORWIN */#endif /* EXCELAN */ return(-1); }#ifdef NT WSASafeToCancel = 0;#endif /* NT */ isconnect = 1; } while (!isconnect);#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.*//* Note from Jeff Altman: 12/13/95 In implementing rlogin protocol I have come to the conclusion that it is a really bad idea to read out-of-band data inline. At least Windows and OS/2 does not handle this well. And if you need to know that data is out-of-band, then it becomes absolutely pointless. Therefore, at least on OS2 and Windows (NT) I have changed the value of on to 0, so that out-of-band data stays out-of-band. 12/18/95 Actually, OOB data should be read inline when possible. Especially with protocols that don't care about the Urgent flag. This is true with Telnet. With Rlogin, you need to be able to catch OOB data. However, the best way to do this is to set a signal handler on SIGURG. This isn't possible on OS/2 and Windows. But it is in UNIX. We will also need OOB data for FTP so better create a general mechanism. The reason for making OOB data be inline is that the standard ttinc/ttoc calls can be used for reading that data on UNIX systems. If we didn't have the OOBINLINE option set then we would have to use recv(,MSG_OOB) to read it.*/#ifdef RLOGCODE#ifdef TCPIPLIB if (ttnproto == NP_RLOGIN || ttnproto == NP_FTP) on = 0;#else /* TCPIPLIB */ if (ttnproto == NP_RLOGIN) { debug(F100,"Installing rlogoobh on SIGURG","",0); signal(SIGURG, rlogoobh); } else #ifdef FTPCODE if (ttnproto == NP_FTP) { signal(SIGURG, ftpoobh); } else#endif /* FTPCODE */ { signal(SIGURG, SIG_DFL); }#endif /* TCPIPLIB */#endif /* RLOGCODE */#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 MOTSV88R4 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#ifdef OSK setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,(char *) &on, sizeof on);#else#ifdef OS2 { int rc; rc = setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE, (char *) &on, sizeof on ); debug(F111,"setsockopt SO_OOBINLINE",on ? "on" : "off" ,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -