#include #include #include #include #include #include #include #include #include #include static int ConnectOutTimed; /* Copyright (C) 1992,2000 Bisqwit (http://iki.fi/bisqwit/) * No warranty. You are free to modify this source, and to * distribute modified sources, as long as you keep the * existing copyright messages intact and as long as you * remember to add your own copyright markings. */ #define configured 0 /* Set this to 1 to mark that you have modified these. */ #define NICK_TO_KEEP "DontSteal" #define RESPONSIBLE_NICK "Coolguy" #define USERNAME "coolguy" /* account name */ #define REALNAME "John Michael Doe" #define INITIAL_CHANNELS "#usa" #define IRC_SERVER "irc.webbernet.net" #define IRC_PORT 6667 #define LOCALHOST "localhost" #define PROGRAM_NAME "Nickkeeper v1.1" #define SOURCE_URL "http://iki.fi/bisqwit/src/nickkeeper.c" #define RECONNECT_DELAY 11 #define CONNECTION_TIMEOUT 60 #if !configured #error Nickkeeper needs to be configured first! Edit the sourcecode. #endif /**** You don't need to make any modifications below this. ****/ static void SubConnectOut(int signum) { signum = ConnectOutTimed++; } int ConnectOut(const char *Server, int Port, unsigned time) { struct hostent *HostName; struct sockaddr_in SocketName; int plug, p; if((plug = socket(AF_INET,SOCK_STREAM,0)) < 0 || !(HostName = gethostbyname(Server)))return -1; SocketName.sin_family = AF_INET; SocketName.sin_port = htons(Port); memcpy(&SocketName.sin_addr, HostName->h_addr, HostName->h_length); signal(SIGABRT, SubConnectOut); if((p = fork()) < 0)return -1; ConnectOutTimed = 0; /* This timeout implementation doesn't eat tons of * CPU time looping and doesn't clobber queued alarms. * It, however, resets the SIGABRT signal handler. */ if(!p) { usleep(time); kill(getppid(),SIGABRT); _exit(EXIT_SUCCESS); } for(;;) { if((connect(plug,(struct sockaddr *)&SocketName,sizeof(SocketName))) < 0) { /* If ConnectOutTimed>0, then errno can contain whatever. */ if(errno == EINTR && !ConnectOutTimed)continue; if(ConnectOutTimed)errno = ETIMEDOUT; close(plug); plug = -1; } else { signal(SIGPIPE, SIG_IGN); } kill(p, SIGKILL); signal(SIGABRT, SIG_DFL); waitpid(p, NULL, 0); return plug; } } int main(void) { FILE *fp; int sock; Restart: sock = ConnectOut(IRC_SERVER, IRC_PORT, CONNECTION_TIMEOUT); if(sock < 0) { RestartSleep: sleep(RECONNECT_DELAY); goto Restart; } fp = fdopen(sock, "wb+"); if(!fp) { RestartClose: close(sock); goto RestartSleep; } fprintf(fp, "USER "USERNAME" "LOCALHOST" "IRC_SERVER" :"REALNAME"\n" "NICK "NICK_TO_KEEP"\n" "AWAY :This is "PROGRAM_NAME" - contact "RESPONSIBLE_NICK".\n" "JOIN "INITIAL_CHANNELS"\n"); for(;;) { char Buf[600], *s; if(!fgets(Buf, 599, fp)) { fclose(fp); goto RestartClose; } printf("Got %s", Buf); if(!strncmp(Buf, "PING :", 6)) fprintf(fp, "PONG nickkeeper\n"); s = strstr(Buf, "PRIVMSG"); if(s && strstr(Buf, "VERSION") > s) { *strchr(Buf, '!') = 0; printf("Replying version to '%s'\n", Buf+1); fprintf(fp, "NOTICE %s :VERSION %s\n", Buf+1, PROGRAM_NAME" - authorized by "NICK_TO_KEEP". " "This client does not have a human user, contact " RESPONSIBLE_NICK" instead. " "Sourcecode of nickkeeper is at "SOURCE_URL); } if(s && strstr(Buf, "CLIENTINFO") > s) { *strchr(Buf, '!') = 0; printf("Replying version to '%s'\n", Buf+1); fprintf(fp, "NOTICE %s :CLIENTINFO VERSION CLIENTINFO :%s\n", Buf+1, PROGRAM_NAME" - copyright (C) 1992,2000 Bisqwit (http://iki.fi/bisqwit/)"); } } return 0; }