// Emacs style mode select -*- C++ -*- //--------------------------------------------------------------------------- // // $Id: tcpcomm.c,v 1.2 2003/04/05 22:55:11 fraggle Exp $ // // Copyright(C) 1984-2000 David L. Clark // Copyright(C) 2001-2003 Simon Howard // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your // option) any later version. This program is distributed in the hope that // it will be useful, but WITHOUT ANY WARRANTY; without even the implied // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU General Public License for more details. You should have // received a copy of the GNU General Public License along with this // program; if not, write to the Free Software Foundation, Inc., 59 Temple // Place - Suite 330, Boston, MA 02111-1307, USA. // //--------------------------------------------------------------------------- // // TCP/IP Communications // //--------------------------------------------------------------------------- #include "sw.h" #include "swtitle.h" #include "tcpcomm.h" #include "timer.h" #ifdef TCPIP #include #include #include #include #include #include #include #include #include #include #include #define PORT 3847 static int server_sock = -1; static int tcp_sock = -1; #endif /* #ifdef TCPIP */ // connect to a host void commconnect(char *host) { #ifdef TCPIP struct hostent *hent; struct sockaddr_in in; char *realhost; int port = PORT; // sdh 17/11/2001: check for host:port, use a different // port from the default { char *p = strchr(host, ':'); if (p) { realhost = malloc(p-host + 2); strncpy(realhost, host, p-host); realhost[p-host] = '\0'; port = atoi(p+1); } else { realhost = host; } } // resolve name hent = gethostbyname(realhost); if (realhost != host) free(realhost); if (!hent) { fprintf(stderr, "commconnect: cant resolve '%s': %s\n", host, strerror(errno)); exit(-1); } // create socket tcp_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (tcp_sock < -1) { fprintf(stderr, "commconnect: cant create socket: %s\n", strerror(errno)); exit(-1); } // connect in.sin_family = AF_INET; in.sin_addr.s_addr = ((struct in_addr *) hent->h_addr)->s_addr; in.sin_port = htons(port); if (connect(tcp_sock, (struct sockaddr *) &in, sizeof(in)) < 0) { fprintf(stderr, "commconnect: cant connect to '%s': %s\n", host, strerror(errno)); exit(-1); } // non blocking socket fcntl(tcp_sock, F_SETFL, O_NONBLOCK); fprintf(stderr, "commconnect: connected to '%s'!\n", host); #endif /* #ifdef TCPIP */ } // open a socket and listen until a connection is established void commlisten() { #ifdef TCPIP struct sockaddr_in in; int in_size; // create socket server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (server_sock < 0) { fprintf(stderr, "commlisten: could not create socket: %s\n", strerror(errno)); exit(-1); } // bind to port memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; in.sin_addr.s_addr = INADDR_ANY; in.sin_port = htons(PORT); if (bind(server_sock, (struct sockaddr *) &in, sizeof(in)) < 0) { fprintf(stderr, "commlisten: cant bind to port %i: %s\n", PORT, strerror(errno)); exit(-1); } atexit(commterm); // listen for connections if (listen(server_sock, 1)) { fprintf(stderr, "commlisten: cant listen on port %i: %s\n", PORT, strerror(errno)); exit(-1); } fprintf(stderr, "commlisten: listening for connection on port %i\n", PORT); fcntl(server_sock, F_SETFL, O_NONBLOCK); // listen for connection for (;;) { if (ctlbreak()) { fprintf(stderr, "commlisten: user aborted connect\n"); exit(-1); } in_size = sizeof(in); tcp_sock = accept(server_sock, (struct sockaddr *) &in, &in_size); if (tcp_sock >= 0) { break; } if (errno == EWOULDBLOCK) { Timer_Sleep(100); } else { fprintf(stderr, "commlisten: error accepting connection: %s\n", strerror(errno)); exit(-1); } } // non blocking socket fcntl(tcp_sock, F_SETFL, O_NONBLOCK); fprintf(stderr, "commlisten: accepted connection from %s\n", inet_ntoa(in.sin_addr)); #endif /* #ifdef TCPIP */ } // read a byte from socket int commin() { #ifdef TCPIP unsigned char c; int bytes; // lost connection if (tcp_sock < 0) return -1; // read bytes = read(tcp_sock, &c, 1); if (bytes < 1) { if (errno != EWOULDBLOCK) { fprintf(stderr, "commin: %s reading from socket\n", strerror(errno)); close(tcp_sock); tcp_sock = -1; } return -1; } return c; #else return 0; #endif /* #ifdef TCPIP */ } // send a byte void commout(unsigned char i) { #ifdef TCPIP if (tcp_sock < 0) return; if (!write(tcp_sock, &i, 1)) { fprintf(stderr, "commout: %s writing to socket\n", strerror(errno)); } #endif /* #ifdef TCPIP */ } // disconnect void commterm() { #ifdef TCPIP if (tcp_sock > 0) { close(tcp_sock); tcp_sock = -1; } if (server_sock > 0) { close(server_sock); server_sock = -1; } #endif /* #ifdef TCPIP */ } //--------------------------------------------------------------------------- // // $Log: tcpcomm.c,v $ // Revision 1.2 2003/04/05 22:55:11 fraggle // Remove the FOREVER macro and some unused stuff from std.h // // Revision 1.1.1.1 2003/02/14 19:03:23 fraggle // Initial Sourceforge CVS import // // // sdh 14/2/2003: change license header to GPL // sdh 17/11/2001: ability to specify a different port from default // sdh 16/11/2001: TCPIP #define to disable TCP/IP support // sdh 21/10/2001: added cvs tags // //---------------------------------------------------------------------------