/* * Initialize variables. */ void tninit(void) { init_terminal(); init_network(); init_telnet(); init_sys(); }
/* * Initialize variables. */ void tninit() { init_terminal(); init_network(); init_telnet(); init_sys(); #if defined(TN3270) init_3270(); #endif }
/* * Initialize variables. */ void tninit(void) { init_terminal(); init_network(); init_telnet(); init_sys(); #ifdef TN3270 init_3270(); #endif }
CURLcode Curl_telnet(struct connectdata *conn, bool *done) { CURLcode code; struct SessionHandle *data = conn->data; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; #ifdef USE_WINSOCK HMODULE wsock2; WSOCK2_FUNC close_event_func; WSOCK2_FUNC create_event_func; WSOCK2_FUNC event_select_func; WSOCK2_FUNC enum_netevents_func; WSAEVENT event_handle; WSANETWORKEVENTS events; HANDLE stdin_handle; HANDLE objs[2]; DWORD obj_count; DWORD wait_timeout; DWORD waitret; DWORD readfile_read; #else int interval_ms; struct pollfd pfd[2]; #endif ssize_t nread; bool keepon = TRUE; char *buf = data->state.buffer; struct TELNET *tn; *done = TRUE; /* uncontionally */ code = init_telnet(conn); if(code) return code; tn = (struct TELNET *)data->reqdata.proto.telnet; code = check_telnet_options(conn); if(code) return code; #ifdef USE_WINSOCK /* ** This functionality only works with WinSock >= 2.0. So, ** make sure have it. */ code = check_wsock2(data); if (code) return code; /* OK, so we have WinSock 2.0. We need to dynamically */ /* load ws2_32.dll and get the function pointers we need. */ wsock2 = LoadLibrary("WS2_32.DLL"); if (wsock2 == NULL) { failf(data,"failed to load WS2_32.DLL (%d)", ERRNO); return CURLE_FAILED_INIT; } /* Grab a pointer to WSACreateEvent */ create_event_func = GetProcAddress(wsock2,"WSACreateEvent"); if (create_event_func == NULL) { failf(data,"failed to find WSACreateEvent function (%d)", ERRNO); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSACloseEvent */ close_event_func = GetProcAddress(wsock2,"WSACloseEvent"); if (close_event_func == NULL) { failf(data,"failed to find WSACloseEvent function (%d)", ERRNO); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSAEventSelect */ event_select_func = GetProcAddress(wsock2,"WSAEventSelect"); if (event_select_func == NULL) { failf(data,"failed to find WSAEventSelect function (%d)", ERRNO); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSAEnumNetworkEvents */ enum_netevents_func = GetProcAddress(wsock2,"WSAEnumNetworkEvents"); if (enum_netevents_func == NULL) { failf(data,"failed to find WSAEnumNetworkEvents function (%d)", ERRNO); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* We want to wait for both stdin and the socket. Since ** the select() function in winsock only works on sockets ** we have to use the WaitForMultipleObjects() call. */ /* First, create a sockets event object */ event_handle = (WSAEVENT)create_event_func(); if (event_handle == WSA_INVALID_EVENT) { failf(data,"WSACreateEvent failed (%d)", SOCKERRNO); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* The get the Windows file handle for stdin */ stdin_handle = GetStdHandle(STD_INPUT_HANDLE); /* Create the list of objects to wait for */ objs[0] = event_handle; objs[1] = stdin_handle; /* Tell winsock what events we want to listen to */ if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) { close_event_func(event_handle); FreeLibrary(wsock2); return 0; } /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it, else use the old WaitForMultipleObjects() way */ if(GetFileType(stdin_handle) == FILE_TYPE_PIPE) { /* Don't wait for stdin_handle, just wait for event_handle */ obj_count = 1; /* Check stdin_handle per 100 milliseconds */ wait_timeout = 100; } else { obj_count = 2; wait_timeout = INFINITE; } /* Keep on listening and act on events */ while(keepon) { waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout); switch(waitret) { case WAIT_TIMEOUT: { unsigned char outbuf[2]; int out_count = 0; ssize_t bytes_written; char *buffer = buf; while(1) { if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, &readfile_read, NULL)) { keepon = FALSE; break; } nread = readfile_read; if(!nread) break; if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer), &readfile_read, NULL)) { keepon = FALSE; break; } nread = readfile_read; while(nread--) { outbuf[0] = *buffer++; out_count = 1; if(outbuf[0] == CURL_IAC) outbuf[out_count++] = CURL_IAC; Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, out_count, &bytes_written); } } } break; case WAIT_OBJECT_0 + 1: { unsigned char outbuf[2]; int out_count = 0; ssize_t bytes_written; char *buffer = buf; if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer), &readfile_read, NULL)) { keepon = FALSE; break; } nread = readfile_read; while(nread--) { outbuf[0] = *buffer++; out_count = 1; if(outbuf[0] == CURL_IAC) outbuf[out_count++] = CURL_IAC; Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, out_count, &bytes_written); } } break; case WAIT_OBJECT_0: if(enum_netevents_func(sockfd, event_handle, &events) != SOCKET_ERROR) { if(events.lNetworkEvents & FD_READ) { /* This reallu OUGHT to check its return code. */ (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); telrcv(conn, (unsigned char *)buf, nread); fflush(stdout); /* Negotiate if the peer has started negotiating, otherwise don't. We don't want to speak telnet with non-telnet servers, like POP or SMTP. */ if(tn->please_negotiate && !tn->already_negotiated) { negotiate(conn); tn->already_negotiated = 1; } } if(events.lNetworkEvents & FD_CLOSE) { keepon = FALSE; } } break; } } /* We called WSACreateEvent, so call WSACloseEvent */ if (close_event_func(event_handle) == FALSE) { infof(data,"WSACloseEvent failed (%d)", SOCKERRNO); } /* "Forget" pointers into the library we're about to free */ create_event_func = NULL; close_event_func = NULL; event_select_func = NULL; enum_netevents_func = NULL; /* We called LoadLibrary, so call FreeLibrary */ if (!FreeLibrary(wsock2)) infof(data,"FreeLibrary(wsock2) failed (%d)", ERRNO); #else pfd[0].fd = sockfd; pfd[0].events = POLLIN; pfd[1].fd = 0; pfd[1].events = POLLIN; interval_ms = 1 * 1000; while (keepon) { switch (Curl_poll(pfd, 2, interval_ms)) { case -1: /* error, stop reading */ keepon = FALSE; continue; case 0: /* timeout */ break; default: /* read! */ if(pfd[1].revents & POLLIN) { /* read from stdin */ unsigned char outbuf[2]; int out_count = 0; ssize_t bytes_written; char *buffer = buf; nread = read(0, buf, 255); while(nread--) { outbuf[0] = *buffer++; out_count = 1; if(outbuf[0] == CURL_IAC) outbuf[out_count++] = CURL_IAC; Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, out_count, &bytes_written); } } if(pfd[0].revents & POLLIN) { /* This OUGHT to check the return code... */ (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); /* if we receive 0 or less here, the server closed the connection and we bail out from this! */ if (nread <= 0) { keepon = FALSE; break; } telrcv(conn, (unsigned char *)buf, nread); /* Negotiate if the peer has started negotiating, otherwise don't. We don't want to speak telnet with non-telnet servers, like POP or SMTP. */ if(tn->please_negotiate && !tn->already_negotiated) { negotiate(conn); tn->already_negotiated = 1; } } } if(data->set.timeout) { struct timeval now; /* current time */ now = Curl_tvnow(); if(Curl_tvdiff(now, conn->created) >= data->set.timeout) { failf(data, "Time-out"); code = CURLE_OPERATION_TIMEDOUT; keepon = FALSE; } } } #endif /* mark this as "no further transfer wanted" */ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); return code; }
static CURLcode telnet_do(struct connectdata *conn, bool *done) { CURLcode result; struct SessionHandle *data = conn->data; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; #ifdef USE_WINSOCK HMODULE wsock2; WSOCK2_FUNC close_event_func; WSOCK2_FUNC create_event_func; WSOCK2_FUNC event_select_func; WSOCK2_FUNC enum_netevents_func; WSAEVENT event_handle; WSANETWORKEVENTS events; HANDLE stdin_handle; HANDLE objs[2]; DWORD obj_count; DWORD wait_timeout; DWORD waitret; DWORD readfile_read; int err; #else int interval_ms; struct pollfd pfd[2]; int poll_cnt; curl_off_t total_dl = 0; curl_off_t total_ul = 0; #endif ssize_t nread; struct timeval now; bool keepon = TRUE; char *buf = data->state.buffer; struct TELNET *tn; *done = TRUE; /* unconditionally */ result = init_telnet(conn); if(result) return result; tn = (struct TELNET *)data->req.protop; result = check_telnet_options(conn); if(result) return result; #ifdef USE_WINSOCK /* ** This functionality only works with WinSock >= 2.0. So, ** make sure have it. */ result = check_wsock2(data); if(result) return result; /* OK, so we have WinSock 2.0. We need to dynamically */ /* load ws2_32.dll and get the function pointers we need. */ wsock2 = LoadLibrary(TEXT("WS2_32.DLL")); if(wsock2 == NULL) { failf(data, "failed to load WS2_32.DLL (%d)", ERRNO); return CURLE_FAILED_INIT; } /* Grab a pointer to WSACreateEvent */ create_event_func = GetProcAddress(wsock2, "WSACreateEvent"); if(create_event_func == NULL) { failf(data, "failed to find WSACreateEvent function (%d)", ERRNO); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSACloseEvent */ close_event_func = GetProcAddress(wsock2, "WSACloseEvent"); if(close_event_func == NULL) { failf(data, "failed to find WSACloseEvent function (%d)", ERRNO); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSAEventSelect */ event_select_func = GetProcAddress(wsock2, "WSAEventSelect"); if(event_select_func == NULL) { failf(data, "failed to find WSAEventSelect function (%d)", ERRNO); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSAEnumNetworkEvents */ enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents"); if(enum_netevents_func == NULL) { failf(data, "failed to find WSAEnumNetworkEvents function (%d)", ERRNO); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* We want to wait for both stdin and the socket. Since ** the select() function in winsock only works on sockets ** we have to use the WaitForMultipleObjects() call. */ /* First, create a sockets event object */ event_handle = (WSAEVENT)create_event_func(); if(event_handle == WSA_INVALID_EVENT) { failf(data, "WSACreateEvent failed (%d)", SOCKERRNO); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* Tell winsock what events we want to listen to */ if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) { close_event_func(event_handle); FreeLibrary(wsock2); return CURLE_OK; } /* The get the Windows file handle for stdin */ stdin_handle = GetStdHandle(STD_INPUT_HANDLE); /* Create the list of objects to wait for */ objs[0] = event_handle; objs[1] = stdin_handle; /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it, else use the old WaitForMultipleObjects() way */ if(GetFileType(stdin_handle) == FILE_TYPE_PIPE || data->set.is_fread_set) { /* Don't wait for stdin_handle, just wait for event_handle */ obj_count = 1; /* Check stdin_handle per 100 milliseconds */ wait_timeout = 100; } else { obj_count = 2; wait_timeout = 1000; } /* Keep on listening and act on events */ while(keepon) { waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout); switch(waitret) { case WAIT_TIMEOUT: { for(;;) { if(data->set.is_fread_set) { /* read from user-supplied method */ result = (int)data->state.fread_func(buf, 1, BUFSIZE - 1, data->state.in); if(result == CURL_READFUNC_ABORT) { keepon = FALSE; result = CURLE_READ_ERROR; break; } if(result == CURL_READFUNC_PAUSE) break; if(result == 0) /* no bytes */ break; readfile_read = result; /* fall thru with number of bytes read */ } else { /* read from stdin */ if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, &readfile_read, NULL)) { keepon = FALSE; result = CURLE_READ_ERROR; break; } if(!readfile_read) break; if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer), &readfile_read, NULL)) { keepon = FALSE; result = CURLE_READ_ERROR; break; } } result = send_telnet_data(conn, buf, readfile_read); if(result) { keepon = FALSE; break; } } } break; case WAIT_OBJECT_0 + 1: { if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer), &readfile_read, NULL)) { keepon = FALSE; result = CURLE_READ_ERROR; break; } result = send_telnet_data(conn, buf, readfile_read); if(result) { keepon = FALSE; break; } } break; case WAIT_OBJECT_0: events.lNetworkEvents = 0; if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) { if((err = SOCKERRNO) != EINPROGRESS) { infof(data, "WSAEnumNetworkEvents failed (%d)", err); keepon = FALSE; result = CURLE_READ_ERROR; } break; } if(events.lNetworkEvents & FD_READ) { /* read data from network */ result = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); /* read would've blocked. Loop again */ if(result == CURLE_AGAIN) break; /* returned not-zero, this an error */ else if(result) { keepon = FALSE; break; } /* returned zero but actually received 0 or less here, the server closed the connection and we bail out */ else if(nread <= 0) { keepon = FALSE; break; } result = telrcv(conn, (unsigned char *) buf, nread); if(result) { keepon = FALSE; break; } /* Negotiate if the peer has started negotiating, otherwise don't. We don't want to speak telnet with non-telnet servers, like POP or SMTP. */ if(tn->please_negotiate && !tn->already_negotiated) { negotiate(conn); tn->already_negotiated = 1; } } if(events.lNetworkEvents & FD_CLOSE) { keepon = FALSE; } break; } if(data->set.timeout) { now = Curl_tvnow(); if(Curl_tvdiff(now, conn->created) >= data->set.timeout) { failf(data, "Time-out"); result = CURLE_OPERATION_TIMEDOUT; keepon = FALSE; } } } /* We called WSACreateEvent, so call WSACloseEvent */ if(!close_event_func(event_handle)) { infof(data, "WSACloseEvent failed (%d)", SOCKERRNO); } /* "Forget" pointers into the library we're about to free */ create_event_func = NULL; close_event_func = NULL; event_select_func = NULL; enum_netevents_func = NULL; /* We called LoadLibrary, so call FreeLibrary */ if(!FreeLibrary(wsock2)) infof(data, "FreeLibrary(wsock2) failed (%d)", ERRNO); #else pfd[0].fd = sockfd; pfd[0].events = POLLIN; if(data->set.is_fread_set) { poll_cnt = 1; interval_ms = 100; /* poll user-supplied read function */ } else { /* really using fread, so infile is a FILE* */ pfd[1].fd = fileno((FILE *)data->state.in); pfd[1].events = POLLIN; poll_cnt = 2; interval_ms = 1 * 1000; } while(keepon) { switch (Curl_poll(pfd, poll_cnt, interval_ms)) { case -1: /* error, stop reading */ keepon = FALSE; continue; case 0: /* timeout */ pfd[0].revents = 0; pfd[1].revents = 0; /* fall through */ default: /* read! */ if(pfd[0].revents & POLLIN) { /* read data from network */ result = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); /* read would've blocked. Loop again */ if(result == CURLE_AGAIN) break; /* returned not-zero, this an error */ else if(result) { keepon = FALSE; break; } /* returned zero but actually received 0 or less here, the server closed the connection and we bail out */ else if(nread <= 0) { keepon = FALSE; break; } total_dl += nread; Curl_pgrsSetDownloadCounter(data, total_dl); result = telrcv(conn, (unsigned char *)buf, nread); if(result) { keepon = FALSE; break; } /* Negotiate if the peer has started negotiating, otherwise don't. We don't want to speak telnet with non-telnet servers, like POP or SMTP. */ if(tn->please_negotiate && !tn->already_negotiated) { negotiate(conn); tn->already_negotiated = 1; } } nread = 0; if(poll_cnt == 2) { if(pfd[1].revents & POLLIN) { /* read from in file */ nread = read(pfd[1].fd, buf, BUFSIZE - 1); } } else { /* read from user-supplied method */ nread = (int)data->state.fread_func(buf, 1, BUFSIZE - 1, data->state.in); if(nread == CURL_READFUNC_ABORT) { keepon = FALSE; break; } if(nread == CURL_READFUNC_PAUSE) break; } if(nread > 0) { result = send_telnet_data(conn, buf, nread); if(result) { keepon = FALSE; break; } total_ul += nread; Curl_pgrsSetUploadCounter(data, total_ul); } else if(nread < 0) keepon = FALSE; break; } /* poll switch statement */ if(data->set.timeout) { now = Curl_tvnow(); if(Curl_tvdiff(now, conn->created) >= data->set.timeout) { failf(data, "Time-out"); result = CURLE_OPERATION_TIMEDOUT; keepon = FALSE; } } if(Curl_pgrsUpdate(conn)) { result = CURLE_ABORTED_BY_CALLBACK; break; } } #endif /* mark this as "no further transfer wanted" */ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); return result; }
CURLcode Curl_telnet(struct connectdata *conn) { CURLcode code; struct SessionHandle *data = conn->data; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; #if defined(WIN32) || defined(WIN64) HMODULE wsock2; WSOCK2_FUNC close_event_func; WSOCK2_FUNC create_event_func; WSOCK2_FUNC event_select_func; WSOCK2_FUNC enum_netevents_func; WSAEVENT event_handle; WSANETWORKEVENTS events; HANDLE stdin_handle; HANDLE objs[2]; DWORD waitret; DWORD readfile_read; #else fd_set readfd; fd_set keepfd; #endif ssize_t nread; bool keepon = TRUE; char *buf = data->state.buffer; struct TELNET *tn; code = init_telnet(conn); if(code) return code; tn = (struct TELNET *)conn->proto.telnet; code = check_telnet_options(conn); if(code) return code; #if defined(WIN32) || defined(WIN64) /* ** This functionality only works with WinSock >= 2.0. So, ** make sure have it. */ code = check_wsock2(data); if (code) return code; /* OK, so we have WinSock 2.0. We need to dynamically */ /* load ws2_32.dll and get the function pointers we need. */ wsock2 = LoadLibrary("WS2_32.DLL"); if (wsock2 == NULL) { failf(data,"failed to load WS2_32.DLL (%d)",GetLastError()); return CURLE_FAILED_INIT; } /* Grab a pointer to WSACreateEvent */ create_event_func = GetProcAddress(wsock2,"WSACreateEvent"); if (create_event_func == NULL) { failf(data,"failed to find WSACreateEvent function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSACloseEvent */ close_event_func = GetProcAddress(wsock2,"WSACloseEvent"); if (create_event_func == NULL) { failf(data,"failed to find WSACloseEvent function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSAEventSelect */ event_select_func = GetProcAddress(wsock2,"WSAEventSelect"); if (event_select_func == NULL) { failf(data,"failed to find WSAEventSelect function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSAEnumNetworkEvents */ enum_netevents_func = GetProcAddress(wsock2,"WSAEnumNetworkEvents"); if (enum_netevents_func == NULL) { failf(data,"failed to find WSAEnumNetworkEvents function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* We want to wait for both stdin and the socket. Since ** the select() function in winsock only works on sockets ** we have to use the WaitForMultipleObjects() call. */ /* First, create a sockets event object */ event_handle = (WSAEVENT)create_event_func(); if (event_handle == WSA_INVALID_EVENT) { failf(data,"WSACreateEvent failed (%d)",WSAGetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* The get the Windows file handle for stdin */ stdin_handle = GetStdHandle(STD_INPUT_HANDLE); /* Create the list of objects to wait for */ objs[0] = stdin_handle; objs[1] = event_handle; /* Tell winsock what events we want to listen to */ if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) { close_event_func(event_handle); FreeLibrary(wsock2); return 0; } /* Keep on listening and act on events */ while(keepon) { waitret = WaitForMultipleObjects(2, objs, FALSE, INFINITE); switch(waitret - WAIT_OBJECT_0) { case 0: { unsigned char outbuf[2]; int out_count = 0; ssize_t bytes_written; char *buffer = buf; if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer), &readfile_read, NULL)) { keepon = FALSE; break; } nread = readfile_read; while(nread--) { outbuf[0] = *buffer++; out_count = 1; if(outbuf[0] == CURL_IAC) outbuf[out_count++] = CURL_IAC; Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, out_count, &bytes_written); } } break; case 1: if(enum_netevents_func(sockfd, event_handle, &events) != SOCKET_ERROR) { if(events.lNetworkEvents & FD_READ) { /* This reallu OUGHT to check its return code. */ (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); telrcv(conn, (unsigned char *)buf, nread); fflush(stdout); /* Negotiate if the peer has started negotiating, otherwise don't. We don't want to speak telnet with non-telnet servers, like POP or SMTP. */ if(tn->please_negotiate && !tn->already_negotiated) { negotiate(conn); tn->already_negotiated = 1; } } if(events.lNetworkEvents & FD_CLOSE) { keepon = FALSE; } } break; } } /* We called WSACreateEvent, so call WSACloseEvent */ if (close_event_func(event_handle) == FALSE) { infof(data,"WSACloseEvent failed (%d)",WSAGetLastError()); } /* "Forget" pointers into the library we're about to free */ create_event_func = NULL; close_event_func = NULL; event_select_func = NULL; enum_netevents_func = NULL; /* We called LoadLibrary, so call FreeLibrary */ if (!FreeLibrary(wsock2)) infof(data,"FreeLibrary(wsock2) failed (%d)",GetLastError()); #else FD_ZERO (&readfd); /* clear it */ FD_SET (sockfd, &readfd); FD_SET (0, &readfd); keepfd = readfd; while (keepon) { struct timeval interval; readfd = keepfd; /* set this every lap in the loop */ interval.tv_sec = 1; interval.tv_usec = 0; switch (select (sockfd + 1, &readfd, NULL, NULL, &interval)) { case -1: /* error, stop reading */ keepon = FALSE; continue; case 0: /* timeout */ break; default: /* read! */ if(FD_ISSET(0, &readfd)) { /* read from stdin */ unsigned char outbuf[2]; int out_count = 0; ssize_t bytes_written; char *buffer = buf; nread = read(0, buf, 255); while(nread--) { outbuf[0] = *buffer++; out_count = 1; if(outbuf[0] == CURL_IAC) outbuf[out_count++] = CURL_IAC; Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, out_count, &bytes_written); } } if(FD_ISSET(sockfd, &readfd)) { /* This OUGHT to check the return code... */ (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); /* if we receive 0 or less here, the server closed the connection and we bail out from this! */ if (nread <= 0) { keepon = FALSE; break; } telrcv(conn, (unsigned char *)buf, nread); /* Negotiate if the peer has started negotiating, otherwise don't. We don't want to speak telnet with non-telnet servers, like POP or SMTP. */ if(tn->please_negotiate && !tn->already_negotiated) { negotiate(conn); tn->already_negotiated = 1; } } } if(data->set.timeout) { struct timeval now; /* current time */ now = Curl_tvnow(); if(Curl_tvdiff(now, conn->created)/1000 >= data->set.timeout) { failf(data, "Time-out"); code = CURLE_OPERATION_TIMEOUTED; keepon = FALSE; } } } #endif /* mark this as "no further transfer wanted" */ Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); return code; }
int main(int ac,char **av) { struct sockaddr_in peeraddr; int addrlen=sizeof(struct sockaddr_in); char *remote_name=nil; char *remote_port=nil; int c; int s; /* socket to remote*/ struct hostent *hp; struct servent *sp; struct sockaddr_in server; FILE *f; time_t now; char *log_file=nil; char *tmp=nil; syslog(LOG_INFO,"iftelnetd: Starting..."); debug=0; while ((c = getopt(ac,av,"dl:h:p:")) != EOF) switch (c) { case 'd': debug=1; break; case 'l': log_file=strdup(optarg); break; case 'h': remote_name=strdup(optarg); break; case 'p': remote_port=strdup(optarg); break; default: ; syslog(LOG_ERR,"iftelnetd: Wrong number of args!"); syslog(LOG_ERR,"iftelnetd: Usage:"); syslog(LOG_ERR,"iftelnetd: iftelnetd [-h remote_addr] [-p remote_port] [-l logfile] [-d]"); syslog(LOG_ERR,"iftelnetd: Aborting."); if(log_file) free(log_file); if(remote_name) free(remote_name); if(remote_port) free(remote_port); return 1; break; } if(!remote_name) { syslog(LOG_WARNING,"iftelnetd: Remote addr not set. Assuming 'localhost'"); remote_name=strdup("localhost"); } if(!remote_port) { syslog(LOG_WARNING,"iftelnetd: Remote port not set. Assuming 'fido'"); remote_port=strdup("fido"); } if(getpeername(0,(struct sockaddr*)&peeraddr,&addrlen) == 0) { tmp=strdup(inet_ntoa(peeraddr.sin_addr)); syslog(LOG_INFO,"iftelnetd: incoming TCP connection from %s", tmp ? tmp : "Unknown" ); syslog(LOG_INFO,"iftelnetd: Rerouting to %s:%s", remote_name, remote_port); } if(log_file) { now=time(nil); if((f=fopen(log_file,"a"))!=nil) { fprintf(f,"%s\t%s\n", ctime(&now), tmp ? tmp : "Unknown" ); fclose(f); } free(log_file); } if(tmp) free(tmp); if((sp=getservbyname(remote_port,"tcp"))==NULL) { syslog(LOG_ERR,"iftelnetd: Can't find service: %s",remote_port); syslog(LOG_ERR,"iftelnetd: Aborting."); free(remote_name); free(remote_port); return 1; } if((s=socket(AF_INET,SOCK_STREAM,0))==-1) { syslog(LOG_ERR,"iftelnetd: Can't create Internet domain socket"); syslog(LOG_ERR,"iftelnetd: Aborting."); free(remote_name); free(remote_port); return 1; } if((hp=gethostbyname(remote_name))==NULL) { syslog(LOG_ERR,"iftelnetd: %s - Unknown host",remote_name); syslog(LOG_ERR,"iftelnetd: Aborting."); free(remote_name); free(remote_port); return; } memset(&server,0,sizeof(server)); memcpy((char *)&server.sin_addr,hp->h_addr,hp->h_length); server.sin_family=hp->h_addrtype; server.sin_port = sp->s_port; if(connect(s,(struct sockaddr *)&server,sizeof(server)) == -1) { syslog(LOG_ERR, "iftelnetd: Can't connect %s",remote_name); syslog(LOG_ERR, "iftelnetd: Aborting."); free(remote_name); free(remote_port); return; } init_telnet(); write1(VERSION_S "\r\n" ,strlen(VERSION_S)+2); com_gw(s); free(remote_name); free(remote_port); close(s); syslog(LOG_INFO,"iftelnetd: Done."); }