/** /* $Id: io.c,v 1.1 1998/02/13 08:56:07 falcon Exp $ /* ICB1IO.C icb protcol 1 i/o functions */ /**/ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "show.h" int cur_socket; int gotsigpipe; int carrier; long timer[2]; char stuff[4][255]; char *bigbuf; extern int server_wrap; extern void scrub_free ( void*, int ); extern char *nibble ( char*, int ); extern int idletrack; void got_sigpipe ( signum ) int signum; { gotsigpipe = signum; } void catch_sig() { signal ( SIGPIPE, got_sigpipe ); } int client_socket ( d0, d1, d2, d3, pnum ) unsigned char d0, d1, d2, d3; unsigned short pnum; { int i, s; struct sockaddr_in sin; carrier = 0; if((s=socket(AF_INET, SOCK_STREAM, 0))==-1) { perror("clientsocket: socket() error "); return ( -1 ); } memset ( &sin, 0, sizeof(sin) ); ((unsigned char*)(&sin.sin_addr.s_addr))[0] = d0; ((unsigned char*)(&sin.sin_addr.s_addr))[1] = d1; ((unsigned char*)(&sin.sin_addr.s_addr))[2] = d2; ((unsigned char*)(&sin.sin_addr.s_addr))[3] = d3; sin.sin_family = AF_INET; sin.sin_port = htons ( pnum ); if( connect ( s, (struct sockaddr*) &sin, sizeof(sin) ) == -1 ) { perror("client_socket: connect() error "); return ( -1 ); } catch_sig(); carrier = 1; return ( s ); } int clientsocket ( dest, pnum ) char *dest; unsigned short pnum; { int i, s; struct sockaddr_in sin; unsigned long foo; struct hostent *zeeaddrezz; carrier = 0; if((s=socket(AF_INET, SOCK_STREAM, 0))==-1) { perror("clientsocket: socket() error "); return ( -1 ); } memset ( &sin, 0, sizeof(sin) ); zeeaddrezz = gethostbyname ( dest ); if ( zeeaddrezz == NULL ) { perror("clientsocket: gethostbyname() error"); return ( -1 ); } ((unsigned char*)(&sin.sin_addr.s_addr))[0] = ((unsigned char*)(zeeaddrezz->h_addr))[0], ((unsigned char*)(&sin.sin_addr.s_addr))[1] = ((unsigned char*)(zeeaddrezz->h_addr))[1], ((unsigned char*)(&sin.sin_addr.s_addr))[2] = ((unsigned char*)(zeeaddrezz->h_addr))[2], ((unsigned char*)(&sin.sin_addr.s_addr))[3] = ((unsigned char*)(zeeaddrezz->h_addr))[3], sin.sin_family = AF_INET; sin.sin_port = htons ( pnum ); if( connect ( s, (struct sockaddr*) &sin, sizeof(sin) ) == -1 ) { perror("clientsocket: connect() error "); return ( -1 ); } catch_sig(); carrier = 1; return ( s ); } int checkfd ( fd ) int fd; { int one = 1; fd_set hand; struct timeval foo; int result; FD_ZERO ( &hand ); FD_SET ( fd, &hand ); foo.tv_sec = 0; foo.tv_usec = 0; result = select ( 8, &hand, NULL, NULL, &foo ); if ( result < 0 ) carrier = 0; return ( FD_ISSET ( fd, &hand ) ); } void split ( buf, iter ) unsigned char *buf; int iter; { int i,n,k; n = 0; for ( i = 0; i < iter; i++ ) { k = 0; while ( buf[n] > 1 ) { stuff[i][k] = buf[n]; k++; n++; } /* end of while */ stuff[i][k] = 0; n++; } /* end of for */ k = 0; while ( buf[n] ) { stuff[i][k] = buf[n]; k++; n++; } /* end of while */ stuff[i][k] = 0; } /* end of function split() */ void readpacket ( fd, kind ) int fd; char *kind; { unsigned char len; char buf[256]; int i,j,k; int result; len = 0; i = 0; if ( !carrier ) return; read ( fd, &len, 1 ); while ( i < len ) { result = read ( fd, buf+i, ((int)len)-i ); if ( result < 1 ) { carrier = 0; return; } i += result; } buf[len] = 0; stuff[0][0] = 0; stuff[1][0] = 0; stuff[2][0] = 0; stuff[3][0] = 0; *kind = buf[0]; switch ( buf[0] ) { case 'a' : break; /* login verification */ case 'b' : split ( buf+1, 1 ); break; /* public message */ case 'c' : split ( buf+1, 1 ); break; /* private message */ case 'g' : break; /* exit. now. or incur the server's wrath! */ case 'j' : break; /* protocol check. */ case 'd' : split ( buf+1, 1 ); break; /* status message */ case 'f' : split ( buf+1, 1 ); break; /* announcement message */ case 'i' : split ( buf+1, 1 ); break; /* command message */ default : k = strlen(buf+1); for (j=0;j 240 ) { begin = 0; end = 239; while ( !quit ) { while ( ( end > (begin+1) ) && ( msg[end] != ' ' ) ) end--; for ( i = begin; i < end; i++ ) buf[i-begin] = msg[i]; buf[i-begin] = 0; writepub ( fd, buf ); if ( ( k - end ) < 241 ) { quit = 1; for ( i = end; i < k; i++ ) buf[i-end] = msg[i]; buf[i-end] = 0; writepub ( fd, buf ); if ( bigbuf != NULL ) { scrub_free ( bigbuf, strlen(bigbuf) ); bigbuf = NULL; } } else { begin = end; end = begin + 239; } /* end of if..else */ } /* end of while */ return; } /* end of if */ if ( !msg[0] ) return; sprintf ( buf, " b%s%c", msg, 0 ); foo = strlen ( buf ); lfo = strlen ( buf ); buf[0] = foo; write ( fd, buf, foo + 1); idletrack = time(NULL); } void writecmd ( fd, what, who, msg ) int fd; char *what, *who, *msg; { unsigned char shuttle[256]; unsigned char foo; extern int debug; shuttle[0] = 0; sprintf ( shuttle, " h%s%c", what, 1 ); if ( who != NULL ) strcat ( shuttle, who ); if ( msg != NULL ) { if ( who != NULL ) strcat ( shuttle, " " ); strcat ( shuttle, msg ); } foo = strlen ( shuttle ); if(debug) oprint ("writecmd: '%s'", shuttle ); shuttle[0] = foo; write ( fd, shuttle, foo + 1 ); idletrack = time(NULL); } void gotogroup ( fd, which ) int fd; char *which; { writecmd ( fd, "g", NULL, which ); } void settopic ( fd, what ) int fd; char *what; { writecmd ( fd, "topic", NULL, what ); } void passmod ( fd, who ) int fd; char *who; { writecmd ( fd, "pass", who, NULL ); } void writepriv ( fd, who, msg ) int fd; char *who; char *msg; { unsigned char buf[256]; int i, j, k, kw, quit; int n, index, nindex; unsigned char **bufs; unsigned char *scmd; unsigned char *susr; extern int debug; if(debug) { oprint ("writepriv: msg is %X\n", (long) msg ); oprint ("writepriv: bigbuf is %X\n", (long) bigbuf ); } if ( who == NULL ) return; if ( msg == NULL ) return; kw = strlen ( who ); if ( kw < 1 ) return; insert_tabhis ( who ); /* inserting name to tab history table */ k = strlen ( msg ); if ( k < 1 ) return; if ( k + kw > 240 ) { /* argh! too big for packet, gotta split it up */ if ( server_wrap ) { /* need to prepend server command to the message */ scmd = nibble ( msg, 0 ); susr = nibble ( msg, 1 ); } else { scmd = NULL; susr = NULL; } n = 0; /* number of packets to transmit == #/discrete /m's */ index = 0; /* incremented to the end of the next packet */ quit = 0; while (!quit) { int mag; nindex = index; /* nindex is the beginning of the new packet */ buf[0] = 0; if ( n ) if ( scmd != NULL ) { /* if this the second or later packets, prepend server command */ strcat ( buf, scmd ); strcat ( buf, " " ); } if ( n ) if ( susr != NULL ) { /* if this the second or later packets, prepend dest nick */ strcat ( buf, susr ); strcat ( buf, " " ); } n++; mag = strlen ( buf ); i = mag; /* finding the end of this packet, copying into buf as we go */ while ( ( nindex - index + mag < 240 ) && ( nindex < k ) ) { buf[i] = msg[nindex]; i++; nindex++; } /* if we ran right up to the 240 char limit, wordwrap. */ /* this is icky code -- basically trying to find the */ /* first whitespace within 5 chars of the endpoint. */ if ( nindex - index + mag >= 240 ) for ( j = 0; ( j < 10 ) && ( i > 0 ) && ( buf[i] != ' ' ) && ( nindex - 10 > index ); j++, i--, nindex-- ); buf[i+1] = 0; index = nindex + 1; if ( index >= k ) quit = 1; writecmd ( fd, "m", who, buf ); /* send this packet */ for (j=0;j<256;j++) buf[j] = 0; /* paranoia is your friend */ } /* end of while */ if ( scmd != NULL ) scrub_free(scmd,strlen(scmd)); if ( susr != NULL ) scrub_free(susr,strlen(susr)); return; } /* end of if */ /* fall-through case: no packet splits */ writecmd ( fd, "m", who, msg ); } void writemail(fd,who,msg) int fd; char *who; char *msg; { unsigned char buf[256]; int begin, end, i, k, kw, quit; quit = 0; kw = strlen ( who ); k = strlen ( msg ) + kw; if ( k > 240 - kw ) { begin = 0; end = 239 - kw; while ( !quit ) { while ( ( end > (begin+1) ) && ( msg[end] != ' ' ) ) end--; for ( i = begin; i < end; i++ ) buf[i-begin] = msg[i]; buf[i-begin] = 0; writemail ( fd, who, buf ); if ( ( k - end ) < 241 - kw ) { if ( ( k - end ) < 1 ) return; quit = 1; for ( i = end; i < k; i++ ) buf[i-end] = msg[i]; buf[i-end] = 0; writemail ( fd, who, buf ); if ( bigbuf != NULL ) { scrub_free ( bigbuf, strlen(bigbuf) ); bigbuf = NULL; } } else { begin = end; end = begin + 239 - kw; } /* end of if..else */ } /* end of while */ return; } /* end of if */ writecmd(fd,"write",who,msg); } void login ( fd, name, nick, group, cmd, pass ) int fd; char *name, *nick, *group, *cmd, *pass; { unsigned char buf[256]; unsigned char foo; if ( strlen ( name ) + strlen ( nick ) + strlen ( group ) + strlen ( cmd ) + strlen ( pass ) > 247 ) return; sprintf ( buf, " a%s%c%s%c%s%c%s%c%s%c", name, 1, nick, 1, group, 1, cmd, 1, pass, 0 ); foo = strlen ( buf ); buf[0] = foo; write ( fd, buf, foo + 1 ); idletrack = time(NULL); }