/* by hkpco (ChanAm Park) hkpco@korea.com http://hkpco.kr/ irc bot program */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include void pong( int sockfd, char *ping, int sz ); // keep-alive¸¦ À§ÇÑ ÇÔ¼ö int irc_req( int sockfd, char *req, ... ); // request¸¦ º¸³»±â À§ÇÑ ÇÔ¼ö int main( int argc , char **argv ) { pid_t pid; int sockfd, port, status; struct sockaddr_in sock; struct hostent *host_st; char nickname[64] = {0x00,}, channel[64] = {0x00,}; char rcv_data[4096] = {0x00,}, tmp_buf[64+2] = {0x00,}, *strp; if( argc < 5 ) { fprintf( stderr, "%s \n", argv[0] ); return -1; } /******* µ¥¸ó ÇÁ·Î±×·¥À» À§ÇÑ ¼¼ÆÃ *******/ pid = fork(); if( pid < 0 ) { perror( "fork()" ); return -1; } else if( pid != 0 ) { return 0; } else { setsid(); } /******* ¼¼ÆÃ ³¡ *******/ printf( "\n\n\n\n" ); /******* Á¢¼Ó Á¤º¸ ÀúÀå *******/ port = atoi(argv[2]); strncpy( nickname, argv[3], sizeof(nickname) -1 ); strncpy( channel, "#", 1 ); strncat( channel, argv[4], sizeof(channel) -2 ); /******* Á¢¼Ó Á¤º¸ ÀúÀå ³¡ *******/ host_st = gethostbyname(argv[1]); if( host_st == NULL ) { perror( "gethostbyname()" ); return -1; } if( argc > 2 ) port = atoi(argv[2]); sockfd = socket( PF_INET, SOCK_STREAM, 0 ); if( sockfd < 0 ) { perror( "socket()" ); return -1; } bzero( sock.sin_zero, sizeof(sock.sin_zero) ); sock.sin_family = AF_INET; sock.sin_port = htons(port); sock.sin_addr = *((struct in_addr *)host_st->h_addr); if( connect( sockfd, (struct sockaddr *)&sock, sizeof(sock) ) < 0 ) { perror( "connect()" ); return -1; } /******* IRC Ãʱâ Á¢¼Ó *******/ irc_req( sockfd, "NICK", nickname, NULL ); read( sockfd, rcv_data, sizeof(rcv_data) ); printf( "Response:\n%s\n\n", rcv_data ); memset( rcv_data, 0x0, sizeof(rcv_data) ); memset( tmp_buf , 0x0, sizeof(tmp_buf)); snprintf( tmp_buf, sizeof(tmp_buf) -1, ":%s\n", nickname ); irc_req( sockfd, "USER", nickname, ". ." , tmp_buf , NULL ); read( sockfd, rcv_data, sizeof(rcv_data) ); printf( "Response:\n%s\n\n", rcv_data ); if( (strp = strstr( rcv_data, "PING" )) == NULL ) { memset( rcv_data, 0x0, sizeof(rcv_data) ); read( sockfd, rcv_data, sizeof(rcv_data) ); strp = strstr( rcv_data, "PING" ); pong( sockfd, strp, strlen(strp) ); } else { pong( sockfd, strp, strlen(strp) ); } memset( rcv_data, 0x0, sizeof(rcv_data) ); read( sockfd, rcv_data, sizeof(rcv_data) ); printf( "Response:\n%s\n\n", rcv_data ); irc_req( sockfd, "USERHOST", nickname, NULL ); read( sockfd, rcv_data, sizeof(rcv_data) ); printf( "Response:\n%s\n\n", rcv_data ); memset( rcv_data, 0x0, sizeof(rcv_data) ); irc_req( sockfd, "JOIN", channel, NULL ); read( sockfd, rcv_data, sizeof(rcv_data) ); printf( "Response:\n%s\n\n", rcv_data ); memset( rcv_data, 0x0, sizeof(rcv_data) ); irc_req( sockfd, "PRIVMSG", channel, ":bot of hkpco.", NULL ); read( sockfd, rcv_data, sizeof(rcv_data) ); memset( rcv_data, 0x0, sizeof(rcv_data) ); /******* IRC Ãʱâ Á¢¼Ó ³¡ *******/ /******* ¸Þ½ÃÁö ó¸® *******/ while(1) { fd_set fds; int cmd_pps[2]; pid_t cmd_prcs; char cmd_buf[1024] = {0x00,}, buf_snd[2048] = {0x00,};; char buf[1024] = {0x00,}, *p; FD_ZERO(&fds); FD_SET( sockfd, &fds ); if( (select( sockfd +1, &fds, (fd_set *)NULL, (fd_set *)NULL, (struct timeval*)NULL )) < 0 ) { perror( "select()" ); return -1; } if( FD_ISSET( sockfd, &fds ) ) { read( sockfd, buf, sizeof(buf) -1 ); if( (p = strstr( buf, "PING" )) ) { pong( sockfd, p, strlen(p) ); } else if( strstr( buf, "whoareyou?" ) ) { if( pipe(cmd_pps) < 0 ) { perror( "pipe()" ); continue; } // ÀÚ½Ä ÇÁ·Î¼¼½º¿ÍÀÇ Åë½ÅÀ» À§ÇÑ pipe »ý¼º if( (cmd_prcs = fork()) < 0 ) { perror( "fork()" ); continue; } if( cmd_prcs == 0 ) { dup2( cmd_pps[1], 1 ); dup2( cmd_pps[1], 2 ); close(cmd_pps[0]); close(cmd_pps[1]); execl( "/usr/bin/id", "-a", NULL ); // id ¸í·ÉÀÇ °á°ú´Â ÆÄÀÌÇÁ¸¦ ÅëÇÏ¿© Àü¼ÛµÊ return 0; } else { read( cmd_pps[0], cmd_buf, sizeof(cmd_buf) -1 ); // ÆÄÀÌÇÁ¸¦ ÅëÇÏ¿© ÀÚ½Ä ÇÁ·Î¼¼½ºÀÇ id ¸í·É °á°ú¸¦ ¼ö½Å snprintf( buf_snd, sizeof(buf_snd) -1, "PRIVMSG %s :%s\n", channel, cmd_buf ); write( sockfd, buf_snd, strlen(buf_snd) ); close(cmd_pps[0]); close(cmd_pps[1]); } waitpid( cmd_prcs, &status, 0 ); } // irc bot Á¾·á ¸í·É üũ else if( strstr( buf, "!go_away" ) ) { break; } memset( buf, 0x0, sizeof(buf) ); memset( cmd_buf, 0x0, sizeof(cmd_buf) ); memset( buf_snd, 0x0, sizeof(buf_snd) ); } } /******* ¸Þ½ÃÁö ó¸® ³¡ *******/ printf( "\n[-] EXIT\n" ); close(sockfd); return 0; } void pong( int sockfd, char *ping, int sz ) { int cnt; char buffer[4096] = {0x00,}; strncpy( buffer, ping, sz ); memcpy( buffer, "PONG", 4 ); for( cnt = 1 ; cnt < sz ; cnt++ ) { if( buffer[cnt] == '\n' ) break; } write( sockfd, buffer, cnt ); printf( "Request:\n" ); write( 1, buffer, cnt ); printf( "\n\n" ); } int irc_req( int sockfd, char *req, ... ) { va_list v_arg; char buffer[4096] = {0x00,}; char *ptr; strncpy( buffer, req, sizeof(buffer) -1 ); va_start( v_arg, req ); while( (ptr = va_arg( v_arg, char* )) != NULL ) { strncat( buffer, " ", sizeof(buffer) -1 ); strncat( buffer, ptr, sizeof(buffer) -1 ); } strncat( buffer, "\n", sizeof(buffer) -1 ); write( sockfd, buffer, strlen(buffer) ); printf( "Request:\n%s\n\n", buffer ); return 0; }