/* Jul 96 Russian Mail Port Redirector Stanislav Sinyagin Thanks to Sergey Smirnov and Maksim Moshkow Acts as intermediate gateway between Windows mail client (such as Netscape Mail) and UNIX daemons "sendmail" and "pop3d" It is designed to be placed in inetd.conf to serve to two services. Example inetd.conf entries: smtpwin stream tcp nowait nobody /usr/local/sbin/rusmailport \ rusmailport localhost smtp pop3win stream tcp nowait nobody /usr/local/sbin/rusmailport \ rusmailport localhost pop3 After that, at your Netscape Mail, point SMTP and POP3 servers to host:port at hich you assigned the above services. Compilation: gcc -O2 rusmailport.c -lnsl -lsocket -o rusmailport Usage: rusmailport host {smtp|pop3} Getting it: http://www.isf.ru/~stas/koi8 */ #include #include #include #include #include #include #include #include #include #include #include #include #define BUFLEN 1024 #define USAGE "Usage: rusmailport host {smtp|pop3}\n" int parentPid = 0, sendingPid = 0, recvingPid = 0; extern int win2koi[256]; extern int koi2win[256]; int tcpConnect( char *host_name, char *port_name ); char *argv0; void sigHandler(int sig) { kill( sendingPid, SIGKILL ); kill( recvingPid, SIGKILL ); exit( 0 ); } void childSigHandler(int sig) { exit(1); } int main( int argc, char *argv[] ) { int fd, bread; unsigned char netbuf[ BUFLEN ]; int timeout = 6000; char *host, *port; /* Our end is 1251. Network end is koi8. */ int *tableRecv = koi2win; int *tableSend = win2koi; int i; if( argc != 3 ) { fprintf( stderr, "%s\n", USAGE ); exit( 1 ); } argv0 = argv[0]; host = argv[1]; port = argv[2]; parentPid = getpid(); signal( SIGTERM, sigHandler ); signal( SIGHUP, sigHandler ); signal( SIGQUIT, sigHandler ); signal( SIGINT, sigHandler ); signal( SIGALRM, sigHandler ); if( (fd=tcpConnect( host, port )) == -1 ) { perror( "Can't connect. Exiting" ); exit(-1); } if( (recvingPid = fork()) == 0 ) { /* I am a child. I will read from the network and write to stdout */ signal( SIGALRM, childSigHandler ); while( 1 ) { alarm( timeout ); if( ( bread = read( fd, netbuf, BUFLEN ) ) <= 0 ) exit(0); /* translate the message */ for( i = 0; i < bread; i++ ) { netbuf[i] = tableRecv[ netbuf[i] ]; } if( write( 1, netbuf, bread ) <= 0 ) exit(1); alarm( 0 ); } } if( (sendingPid = fork()) == 0 ) { /* I am another child . I will read from stdin and write to the network */ signal( SIGALRM, childSigHandler ); while( 1 ) { alarm( timeout ); if( (bread = read( 0, netbuf, BUFLEN )) <= 0 ) exit(0); /* translate the message */ for( i = 0; i < bread; i++ ) { netbuf[i] = tableSend[ netbuf[i] ]; } if( write( fd, netbuf, bread ) <=0 ) exit(1); alarm( 0 ); } } /* Now wait for both children */ wait( NULL ); /* One of the children finished. Another must finish near time. */ alarm( 5 ); wait( NULL ); return 0; } int tcpConnect( char *host_name, char *port_name ) { int fd; struct sockaddr_in port; struct hostent *h; struct servent *serv; port.sin_family = AF_INET; if( *host_name>='0' && *host_name<='9' ) { port.sin_addr.s_addr = inet_addr( host_name ); } else { h = gethostbyname( host_name ); if( !h ) { printf( "%s: %s: unknown host\n", argv0, host_name ); return -1; } port.sin_addr = *((struct in_addr *) h->h_addr); } if( *port_name>='0' && *port_name<='9' ) port.sin_port = htons( atoi( port_name ) ); else { serv = getservbyname( port_name,(char*)0 ); if( serv ) port.sin_port = serv->s_port; else { printf( "%s: %s: unknown service\n", argv0, port_name ); return -1; } } fd = socket( AF_INET, SOCK_STREAM, 0 ); if( fd < 0 ) return -1; if( connect( fd, (struct sockaddr *) &port, sizeof port ) < 0 ) { printf( "%s: Host is not responding: %s:%s\n", argv0, host_name, port_name ); return -1; } return fd; } int win2koi[256] = { 0, 1, 2, 3, 4, 5, 6, 7 , 8, 9, 10, 11, 12, 13, 14, 15 , 16, 17, 18, 19, 20, 21, 22, 23 , 24, 25, 26, 27, 28, 29, 30, 31 , 32, 33, 34, 35, 36, 37, 38, 39 , 40, 41, 42, 43, 44, 45, 46, 47 , 48, 49, 50, 51, 52, 53, 54, 55 , 56, 57, 58, 59, 60, 61, 62, 63 , 64, 65, 66, 67, 68, 69, 70, 71 , 72, 73, 74, 75, 76, 77, 78, 79 , 80, 81, 82, 83, 84, 85, 86, 87 , 88, 89, 90, 91, 92, 93, 94, 95 , 96, 97, 98, 99, 100, 101, 102, 103 , 104, 105, 106, 107, 108, 109, 110, 111 , 112, 113, 114, 115, 116, 117, 118, 119 , 120, 121, 122, 123, 124, 125, 126, 127 , 128, 129, 130, 131, 132, 133, 134, 135 , 136, 137, 138, 139, 140, 141, 142, 143 , 144, 145, 146, 147, 148, 149, 150, 151 , 152, 153, 154, 155, 156, 157, 158, 159 , 154, 161, 162, 163, 164, 165, 166, 167 , 179, 191, 170, 171, 172, 173, 174, 175 , 156, 177, 178, 179, 180, 181, 182, 158 , 163, 185, 186, 187, 188, 189, 190, 191 , 225, 226, 247, 231, 228, 229, 246, 250 , 233, 234, 235, 236, 237, 238, 239, 240 , 242, 243, 244, 245, 230, 232, 227, 254 , 251, 253, 255, 249, 248, 252, 224, 241 , 193, 194, 215, 199, 196, 197, 214, 218 , 201, 202, 203, 204, 205, 206, 207, 208 , 210, 211, 212, 213, 198, 200, 195, 222 , 219, 221, 223, 217, 216, 220, 192, 209 }; int koi2win[256] = { 0, 1, 2, 3, 4, 5, 6, 7 , 8, 9, 10, 11, 12, 13, 14, 15 , 16, 17, 18, 19, 20, 21, 22, 23 , 24, 25, 26, 27, 28, 29, 30, 31 , 32, 33, 34, 35, 36, 37, 38, 39 , 40, 41, 42, 43, 44, 45, 46, 47 , 48, 49, 50, 51, 52, 53, 54, 55 , 56, 57, 58, 59, 60, 61, 62, 63 , 64, 65, 66, 67, 68, 69, 70, 71 , 72, 73, 74, 75, 76, 77, 78, 79 , 80, 81, 82, 83, 84, 85, 86, 87 , 88, 89, 90, 91, 92, 93, 94, 95 , 96, 97, 98, 99, 100, 101, 102, 103 , 104, 105, 106, 107, 108, 109, 110, 111 , 112, 113, 114, 115, 116, 117, 118, 119 , 120, 121, 122, 123, 124, 125, 126, 127 , 128, 129, 130, 131, 132, 133, 134, 135 , 136, 137, 138, 139, 140, 141, 142, 143 , 144, 145, 146, 147, 148, 149, 150, 151 , 152, 153, 160, 155, 176, 157, 183, 159 , 160, 161, 162, 184, 164, 165, 166, 167 , 168, 169, 170, 171, 172, 173, 174, 175 , 176, 177, 178, 168, 180, 181, 182, 183 , 184, 185, 186, 187, 188, 189, 190, 169 , 254, 224, 225, 246, 228, 229, 244, 227 , 245, 232, 233, 234, 235, 236, 237, 238 , 239, 255, 240, 241, 242, 243, 230, 226 , 252, 251, 231, 248, 253, 249, 247, 250 , 222, 192, 193, 214, 196, 197, 212, 195 , 213, 200, 201, 202, 203, 204, 205, 206 , 207, 223, 208, 209, 210, 211, 198, 194 , 220, 219, 199, 216, 221, 217, 215, 218 };