#include #include #include #include #include #include #include #include #include #include #include #include "kb_server.h" #define PACKET_LENGTH 129 static FILE *fp_packet = NULL; static int packet_fd = -1; static int fd_fifos[2] = {-1, -1}; static int COPY = 1; static int TRUE = 1; static int FALSE = 0; struct packet_cluster_vars { int nlines; char packet_lines[10][NET_LENGTH]; }; typedef struct packet_cluster_vars PCVars; static void send_to_client(int fdc, const char *contest_line, const char *cmd_type); static void send_ccv_data(void); static int set_packet_port(const char *pp, int set_pp); static void read_packet_port(PCVars *pcv); static int write_to_fifo(char *s1); static int int_to_char(int in, char *s1); static void concat(char *s1, const char *s2, int is2, int js2, int nullout_s1); static int kb_index(const char *s1, const char *s2); static void left_blank_unpad(char *s1); int main(void) { int server_sockfd, client_sockfd; socklen_t server_len, client_len; struct sockaddr_in server_address, client_address; int nread, fd, fd_max, fdc; int i, j, irc, cmd, ibl, ibl2, iscon; int iread, nbytes, ispp, lplo; fd_set readfds, testfds; char line_io[NET_LENGTH], line_hold[NET_LENGTH], msg[NET_LENGTH]; char packet_line_out[NET_LENGTH]; char csfd_char[5], pfd_char[5], mtowho[21]; struct hostent *client_info; PCVars pcv; int shutdown=0, upd_client=0; int CLOSE_SP=0, OPEN_SP=1; char packet_port[10]="OFF"; server_sockfd = socket(AF_INET, SOCK_STREAM, 0); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(9734); server_len = sizeof(server_address); if(bind(server_sockfd, (struct sockaddr *)&server_address, server_len)) { perror("kb_server-bind"); close(server_sockfd); exit(1); } listen(server_sockfd, 5); FD_ZERO(&readfds); FD_SET(server_sockfd, &readfds); fd_max = server_sockfd; signal(SIGPIPE, SIG_IGN); while(TRUE) { if(shutdown && !ccv.number_of_clients) { if(strcmp(packet_port, "OFF")) set_packet_port (packet_port, CLOSE_SP); close(server_sockfd); exit(0); } testfds = readfds; if(select(fd_max+1, &testfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0)<1) { perror("kb_server-select"); exit(1); } for(fd=0; fd<=fd_max; fd++) if(FD_ISSET(fd, &testfds)) { if(fd==packet_fd) { read_packet_port (&pcv); for(j=0; jfd_max) fd_max = client_sockfd; client_info = gethostbyaddr((struct in_addr *)&client_address.sin_addr, sizeof(struct in_addr), AF_INET); int_to_char (client_sockfd, csfd_char); ccv.number_of_clients++; shutdown = 1; strcpy(ccv.client_fd[ccv.number_of_clients-1], csfd_char); strcpy(ccv.client_name[ccv.number_of_clients-1], client_info->h_name); strcpy(ccv.client_alias[ccv.number_of_clients-1], *client_info->h_aliases); strcpy(ccv.client_addr_dq[ccv.number_of_clients-1], inet_ntoa (client_address.sin_addr)); strcpy(msg, "Connecting "); strcat(msg, ccv.client_alias[ccv.number_of_clients-1]); strcpy(line_io, "at "); strcat(line_io, ccv.client_addr_dq[ccv.number_of_clients-1]); strcat(line_io, " to fd "); strcat(line_io, ccv.client_fd[ccv.number_of_clients-1]); for(i=0; i1) { upd_client = TRUE; strcpy(msg, ""); send_to_client (client_sockfd, msg, "S"); } } } else { ioctl(fd, FIONREAD, &nread); if(!nread) { close(fd); FD_CLR(fd, &readfds); for(i=0; i-1) { concat(line_hold, line_io, ibl, strlen(line_io)-1, COPY); left_blank_unpad (line_hold); ibl2 = kb_index (line_hold, " "); if(ibl2>-1) { concat(mtowho, line_hold, 0, ibl2-1, COPY); iscon = -1; if(!strcmp(mtowho, "ALL") || !strcmp(mtowho, "all")) iscon = 255; else for(i=0; i-1) { strcpy(msg, "Message from "); for(i=0; i-1) { fdc = atoi(ccv.client_fd[ccv.number_of_clients-1]); strcpy(line_io, "is open on fd "); int_to_char (packet_fd, pfd_char); strcat(line_io, pfd_char); strcpy(msg, pfd_char); send_to_client (fdc, msg, "n"); strcpy(msg, "Packet port"); send_to_client (fdc, line_io, "M"); send_to_client (fdc, msg, "m"); } break; case 'H' : case 'I' : case 'i' : case 'T' : for(i=1; i-1) { concat(packet_port, line_io, ibl+2, strlen(line_io)-2, COPY); } ispp = set_packet_port (packet_port, OPEN_SP); if(ispp) { if(packet_fd>fd_max) fd_max = packet_fd; if(fd_fifos[1]>fd_max) fd_max = fd_fifos[1]; FD_SET(packet_fd, &readfds); strcpy(line_io, "opened on fd "); int_to_char (packet_fd, pfd_char); strcat(line_io, pfd_char); strcpy(msg, pfd_char); } else { strcpy(line_io, "could not be opened!"); strcpy(msg, "-1"); } } else { strcpy(line_io, "is already open on fd "); int_to_char (packet_fd, pfd_char); strcat(line_io, pfd_char); strcat(line_io, "!"); strcpy(msg, pfd_char); } for(i=0; i-1) { for(i=0; i-1) { close(fd_fifos[i]); remove(fifos[i]); fd_fifos[i] = -1; } packet_fd = -1; if(set_pp) { for(i=0; i<2; i++) if(stat(fifos[i], &statbuf)) mkfifo(fifos[i], 0777); strcpy(kline_start, "kermit -z -Y <"); strcat(kline_start, fifos[1]); strcat(kline_start, " >"); strcat(kline_start, fifos[0]); strcat(kline_start, " &"); fd_fifos[0] = open(fifos[0], O_RDONLY|O_NONBLOCK); if(fd_fifos[0]>-1) isys_kermit = system(kline_start); if(!isys_kermit) fd_fifos[1] = open(fifos[1], O_WRONLY); if(fd_fifos[1]>-1) { packet_fd = fd_fifos[0]; spp = TRUE; printf("port %s opened on fds %d and %d\n", pp, fd_fifos[0], fd_fifos[1]); } else printf("cannot open port %s\n", pp); } } else { if(fp_packet) { tcsetattr(packet_fd, TCSADRAIN, &settings_save); fclose(fp_packet); fp_packet = NULL; packet_fd = -1; } if(set_pp) { strcpy(port_name, "/dev/"); strcat(port_name, pp); fp_packet = fopen(port_name, "r+"); if(fp_packet) { packet_fd = fileno(fp_packet); printf("port %s opened on fd %d\n", port_name, packet_fd); tcgetattr(packet_fd, &settings_packet); settings_save = settings_packet; cfsetispeed(&settings_packet, B4800); cfsetospeed(&settings_packet, B4800); settings_packet.c_cflag &= ~CSTOPB; settings_packet.c_lflag &= ~ICANON; settings_packet.c_lflag &= ~ECHO; settings_packet.c_oflag |= OPOST; settings_packet.c_cc[VMIN] = 0; settings_packet.c_cc[VTIME] = 0; tcsetattr(packet_fd, TCSANOW, &settings_packet); spp = TRUE; } else printf("cannot open port %s\n", port_name); } } return spp; } static void read_packet_port(PCVars *pcv) { int i, iread, ibsn, icc, fdc; char packet_line_hold[PACKET_LENGTH]; char line_io[NET_LENGTH], msg[NET_LENGTH]; static int nbytes=0; static char packet_line_in[PACKET_LENGTH]=""; pcv->nlines = 0; while(nbytes-1) { for(i=icc+4; i<=nbytes; i++) packet_line_in[i-2] = packet_line_in[i]; nbytes -= 2; } icc = kb_index (packet_line_in, "\n\r"); if(icc>-1) { packet_line_in[icc] = '\r'; packet_line_in[icc+1] = '\n'; } for(i=0; i-1 && pcv->nlines<9) { if(ibsn>NET_LENGTH-4) { concat(pcv->packet_lines[pcv->nlines], packet_line_in, 0, NET_LENGTH-4, COPY); nbytes -= (NET_LENGTH-3); if(nbytes) { concat(packet_line_hold, packet_line_in, NET_LENGTH-3, nbytes+NET_LENGTH-4, COPY); strcpy(packet_line_in, packet_line_hold); } else strcpy(packet_line_in, ""); } else { concat(pcv->packet_lines[pcv->nlines], packet_line_in, 0, ibsn, COPY); nbytes -= (ibsn+1); if(nbytes) { concat(packet_line_hold, packet_line_in, ibsn+1, nbytes+ibsn, COPY); strcpy(packet_line_in, packet_line_hold); } else strcpy(packet_line_in, ""); } ibsn = kb_index (packet_line_in, "\n"); pcv->nlines++; } if(!strcmp(packet_line_in, "cmd:") || (kb_index (packet_line_in, "Kermit>")>-1) || !strcmp(packet_line_in, "Please enter your call: ")) { strcpy(pcv->packet_lines[pcv->nlines], packet_line_in); pcv->nlines++; nbytes = 0; strcpy(packet_line_in, ""); } else if(!strcmp(packet_line_in, "*** DISCONNECTED") || (kb_index (packet_line_in, "Communications disconnect")>-1)) { strcpy(pcv->packet_lines[pcv->nlines], packet_line_in); pcv->nlines++; nbytes = 0; strcpy(packet_line_in, ""); if(fp_packet) { fputc(3, fp_packet); fflush(fp_packet); } for(i=0; i pow(10, nout)-1) nout++; for(i=nout; i>0; i--) s1[nout-i] = ((in%(int)pow(10, i))/(int)pow(10, i-1))+48; s1[nout] = '\0'; return nout; } static void concat(char *s1, const char *s2, int is2, int js2, int nullout_s1) { int i; if(!nullout_s1) while(*s1) s1++; for(i=is2; i<=js2; i++) { *s1 = *(s2+i); s1++; } *s1 = '\0'; } static int kb_index(const char *s1, const char *s2) { const char *p1, *p2; int i; for(i=0; s1[i]; i++) { p1 = &s1[i]; p2 = s2; while(*p2 && *p2==*p1) { p1++; p2++; } if(!*p2) return i; } return -1; } static void left_blank_unpad(char *s1) { char s1_hold[NET_LENGTH]; int i=0; while(s1[i]==' ') i++; concat(s1_hold, s1, i, strlen(s1)-1, COPY); strcpy(s1, s1_hold); }