Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* [ ORIGNICK: irc bot -- version X+final+++. ] ******************************
- * irc bot for obtaining names stored in a file, looping until one is found. *
- * supports general irc functions, channel invite/(re)joining, random *
- * nicknames, backgrounding, server list, quit priority, passwd auth, debug *
- * and other misc. functions. *
- * *
- * AUTHOR: *
- * v9/vade79@realhalo.org, realhalo.org. (* model) *
- * Estella/Estella@Mystagic, mystagic.com (ipv6 port) *
- * *
- * COMPILE: *
- * # cc orignick.c -o orignick -lcrypt *
- * method 1(usually), depends on distribution/os. *
- * *
- * # cc orignick.c -o orignick *
- * method 2(secondary), depends distribution/os. *
- * *
- * note: apply the "-DNOCOLOR" argument to your compiler to disable color. *
- * *
- * DISTRIBUTION: *
- * +autostop(snatch->solid model) : stops scanning once met any objective. *
- * +check(snatch->solid model) : extended buffer checking for security. *
- * +fix(snatch->solid model) : appended fixes from the snatch model. *
- * +cchannel(snatch->solid model) : channel correction support. *
- * +noroot(snatch->solid model) : disallowed root to run by default. *
- * +version(snatch->solid model) : display the version and id information. *
- * +nickfix(snatch->solid model) : major non-functional error fixed. (1.9) *
- * +extended(snatch->solid model) : for servers that allow 30 char names. *
- * +buffix(snatch->solid model) : fixes off-by-one buffer sizes. (2.3) *
- * +buffix2(snatch->solid model) : fixes differences in allocations. (2.4) *
- * -permnick(snatch->solid model) : conflicted with new options. *
- * +combine(solid->complete model): combined both features of both models. *
- * +invite(solid->complete model) : re-included for the combined model. *
- * +doquit(complete->iodine model): priority to get nicknames that quit. *
- * +passwd(complete->iodine model): kill passwd option used via privmsg. *
- * +nodisp(complete->iodine model): disable bot showing status. *
- * +envfix(complete->iodine model): fixes possible null sets in env vars. *
- * +global(iodine->global model) : support for more linux distributions. *
- * +buffree(iodine->global model) : released finished buffers, save memory. *
- * +kdelay(iodine->global model) : delay remote kills, prevent regain. *
- * +vhost(iodine->global model) : virtual host support. (3.5) *
- * +delay(iodine->global model) : delay support, to prevent flood. (3.8) *
- * +vhostfix(iodine->global model): fixes reconnection memory wipe. (3.9) *
- * +vreply(iodine->global model) : version response option. *
- * +delayfix(iodine->global model): change in delay method, less waste. *
- * +cvreply(iodine->global model) : won't reply to version until newnick. *
- * -buffix2(iodine->global model) : reverted to old buffer method, for new. *
- * +bsd(global->glob++ model) : support for bsd distributions/os. *
- * +kencrypt(global->glob++ model): kill passwd encryption. *
- * +finished(glob++->final model) : orignick project completed. (NUL) *
- * +finished(final->final+ model) : minor fix from previous version. (NUL) *
- * +done(final+->final++ model) : final changes. (X) *
- * +done(final++->final+++ model) : so i thought, fixed fd volume. (X) *
- * *
- * TUTORIAL: *
- * the names file(-f argument) should contain a list similar to this: *
- * ------------------------------------------------------------------------- *
- * a *
- * b *
- * c *
- * ... *
- * ------------------------------------------------------------------------- *
- * if you are trying to get one letter nicknames, for example. other uses *
- * could be to hold botnet names - to prevent posing. or possibly to hold *
- * an array of nicknames you use. many reasons can apply. *
- * *
- * the server file(-s argument) should contain a list similar to this: *
- * ------------------------------------------------------------------------- *
- * irc.server1.net *
- * irc.server2.net *
- * irc.server3.net *
- * ... *
- * ------------------------------------------------------------------------- *
- * the port is changed via the -p argument, if none is given it reverts to *
- * the default port. *
- * *
- * EXAMPLES: *
- * note: all examples include the same load file("alphabet") and server *
- * file("servers") in the current directory. (-f and -s options, required) *
- * *
- * # ./orignick -f alphabet -s servers -c '#private' -k keyed -n on[a-z] *
- * this example would join #private with the key 'keyed' and use the *
- * nickname "on[a-z]" if not in use. *
- * *
- * # ./orignick -f alphabet -s servers -P 6666 -d *
- * this example would change the irc connection port to 6666 and show the *
- * output of server data. *
- * *
- * # ./orignick -f alphabet -s servers -b -P ~/pid.orignick *
- * this example would background orignick and write the pid to *
- * pid.orignick in the home directory. *
- * *
- * # ./orignick -f alphabet -s servers -K killme *
- * this example would set the kill password to "killme" and could be *
- * killed via "/msg <botnick/channel> killme" remotely. by being killed *
- * it will simply quit the server and reconnect to the next server on the *
- * server list. so, since it can be killed via the channel, don't make it *
- * an easy password. also, if you are not comfortable with having your *
- * password in the command line you can set the environmental variable *
- * "PASSWD"(default) to the password you desire. (use -E or the *
- * environmental variable "EPASSWD" for encrypted passwords, if you don't *
- * know how to encrypt your password use the -M option of orignick) *
- * *
- * # ./orignick -f alphabet -s servers -Z -S 1000000 -L 3000000 -H host.com *
- * this example would disable version replies, set a server delayed *
- * response time for a full second, set a special situation delayed *
- * response time for a full three seconds(both delay times are used to *
- * prevent excess flooding) and use host.com as a virtual host. *
- * *
- * # ./orignick -f alphabet -s servers -V "mIRC32 v5.82 K.Mardam-Bey" *
- * this example would set the version reply to "mIRC32 v5.82 K.Mardam-Bey" *
- * instead of the default orignick reply. (note: will only reply after *
- * the desired nickname(s) has been obtained.) *
- * *
- * final note: if the -e argument is used make sure the server supports 30 *
- * character names. otherwise, display and internal errors will occur. if *
- * you notice excess flooding quits by the bot, apply the -S and/or -L *
- * arguments with a specified time that stops the excess flood quits. *
- * (-S 1000000 and/or -L 3000000 perhaps?) *
- * *
- * COMMENTS: *
- * i'm aware that i didn't write this in the most clean manner, but it is *
- * effective and compact to me. i'm the only person who really needs to *
- * read it anyways. also, there are benefits from having a channel for the *
- * bot to join, it will keep the nicknames you already have via the quit *
- * method. finally, when orignick is placed in the background it will not *
- * exit due to errors that it would during normal foreground processing. *
- * *
- * orignick.c: program source code for orignick. (969l!2992w!36061b) *
- *****************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <pwd.h>
- #include <signal.h>
- #include <netdb.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- /* GENERAL INFORMATION, POSSIBLE CHANGES. */
- #define VERSION "X+final-ipv6+++" /* version information. */
- #define ENV_IRCHOST "IRC_HOST" /* optional virtual host variable. */
- #define ENV_PASSWORD "PASSWD" /* optional passwd variable. */
- #define ENV_EPASSWORD "EPASSWD" /* optional crypted passwd variable. */
- #define ENV_USERNAME "USERNAME" /* optional username variable. */
- #define ENV_REALNAME "REALNAME" /* optional realname variable. */
- #define DEFAULT_INFO "Unknown" /* generic name info if no other. */
- #define DEFAULT_PORT 6667 /* generic irc port to connect to. */
- #define MAX_NAME_LENGTH 9 /* name argument limit. (regular) */
- #define MAX_NAME_LENGTH_EXT 30 /* name argument limit. (extended) */
- #define MAX_ARGS 512 /* name and server array limit. */
- #define MAX_ERRORS 5 /* invalid nicknames before exit. */
- #define KILL_DELAY 5 /* delay after remote kill to rcon. */
- #define BASE_BUFFER 1024 /* shouldn't change this. */
- #define VERSION_FPROT 5 /* delay for version reply. (secs) */
- #define ALLOW_ROOT 0 /* 1=allow root to run, 0=don't. */
- /* #define NOCOLOR */ /* un-comment to disable color. */
- #define _XOPEN_SOURCE /* for the encrypted passwd option. */
- /* PROMPTS OR PRECURSORS TO DISPLAY TEXT. */
- #ifdef NOCOLOR
- #define PMT "[orignick6]: " /* regular. (no color) */
- #define EPMT "[ERROR]: " /* error. (no color) */
- #define DPMT "[debug]: " /* debug. (no color) */
- #endif
- #ifndef NOCOLOR
- #define PMT "\033[1;30m[\033[1;37morignick6\033[1;30m]:\033[0m " /* regular. */
- #define EPMT "\033[1;30m[\033[1;31mERROR\033[1;30m]:\033[0m " /* error. */
- #define DPMT "\033[1;30m[\033[0;36mdebug\033[1;30m]:\033[0m " /* debug. */
- #endif
- /* PROGRAM BEGIN. */
- int port=DEFAULT_PORT;
- int name_length=MAX_NAME_LENGTH;
- int killd=KILL_DELAY;
- int ischannel=0;
- int ispasswd=0;
- int isnick=0;
- int isvhost=0;
- int isversion=1;
- int isbg=0;
- int allowversion=0;
- int nodisplay=0;
- int noquit=0;
- int debug=0;
- int delay=0;
- int delay2=0;
- int tot_n=0;
- int tot_s=0;
- int bg=0;
- char id[]="$Id: orignick.c,v "VERSION" 2001/03/30 23:35:21 EST vade79 Exp $";
- char *names[MAX_ARGS];
- char *servers[MAX_ARGS];
- char *vreply="orignick/v"VERSION": v9@realhalo.org, realhalo.org.";
- char *channel_key="none";
- char *parm;
- char *nickname;
- char *basenickname;
- char *username;
- char *realname;
- char *password;
- char *channel;
- char *vhost;
- void abort_show(){
- fprintf(stderr,"(ctrl-c aborted)\n");
- exit(0);
- }
- void bug_show(){
- printe("orignick failed in memory management, please report this event and ho"
- "w it occured",1);
- }
- void version_fprot(){
- allowversion=0;
- }
- int main(int argc,char **argv){
- int i=0;
- int j=0;
- int isname=0;
- int isserver=0;
- int isun=0;
- int isrn=0;
- int ispid=0;
- char *pid_file;
- char *name_file;
- char *server_file;
- extern char *optarg;
- FILE *pid_f;
- setreuid(getuid(),getuid());
- setregid(getgid(),getgid());
- signal(SIGHUP,SIG_IGN);
- signal(SIGPIPE,SIG_IGN);
- signal(SIGTSTP,SIG_IGN);
- signal(SIGSEGV,bug_show);
- signal(SIGINT,abort_show);
- fprintf(stderr,"(%u) [*] orignick/v%s, written by: vade79/v9[@realhalo.org]."
- "\n\n",getpid(),VERSION);
- if((!getuid()||!getgid())&&!ALLOW_ROOT)
- printe("running orignick as root is disabled",1);
- make_userinfo();
- while((i=getopt(argc,argv,"f:s:p:u:r:c:k:n:S:L:P:dbK:E:M:D:H:V:ZzNev"))!=EOF){
- switch(i){
- case 'f':
- if(!isname){
- isname=1;
- if(!(name_file=(char *)malloc(strlen(optarg)+1)))
- printe("main(): allocating memory",1);
- strcpy(name_file,optarg);
- }
- break;
- case 's':
- if(!isserver){
- isserver=1;
- if(!(server_file=(char *)malloc(strlen(optarg)+1)))
- printe("main(): allocating memory",1);
- strcpy(server_file,optarg);
- }
- break;
- case 'p':
- if(atoi(optarg)>0)
- port=atoi(optarg);
- break;
- case 'u':
- if(!isun){
- if(!(username=(char *)malloc(strlen(optarg)+1)))
- printe("main(): allocating memory",1);
- strcpy(username,optarg);
- isun=1;
- }
- break;
- case 'r':
- if(!isrn){
- if(!(realname=(char *)malloc(strlen(optarg)+1)))
- printe("main(): allocating memory",1);
- strcpy(realname,optarg);
- isrn=1;
- }
- break;
- case 'c':
- ischannel=1;
- if(!(channel=(char *)malloc(strlen(optarg)+2)))
- printe("main(): allocating memory",1);
- strcpy(channel,optarg);
- if(channel[0]!=0x23&&channel[0]!=0x26)
- sprintf(channel,"#%s",optarg);
- strtok(channel,",");
- break;
- case 'k':
- if(!(channel_key=(char *)malloc(strlen(optarg)+1)))
- printe("main(): allocating memory",1);
- strcpy(channel_key,optarg);
- break;
- case 'n':
- isnick=1;
- if(!(nickname=(char *)malloc(strlen(optarg)+1)))
- printe("main(): allocating memory",1);
- strcpy(nickname,optarg);
- if(!(basenickname=(char *)malloc(strlen(nickname)+1)))
- printe("main(): allocating memory",1);
- strcpy(basenickname,nickname);
- break;
- case 'S':
- delay=atoi(optarg);
- break;
- case 'L':
- delay2=atoi(optarg);
- break;
- case 'P':
- ispid=1;
- if(!(pid_file=(char *)malloc(strlen(optarg)+1)))
- printe("main(): allocating memory",1);
- strcpy(pid_file,optarg);
- break;
- case 'd':
- debug=1;
- break;
- case 'b':
- bg=1;
- break;
- case 'K':
- ispasswd=1;
- if(!(password=(char *)malloc(strlen(optarg)+1)))
- printe("main(): allocating memory",1);
- strcpy(password,optarg);
- break;
- case 'E':
- ispasswd=2;
- if(!(password=(char *)malloc(strlen(optarg)+1)))
- printe("main(): allocating memory",1);
- strcpy(password,optarg);
- break;
- case 'M':
- orignick_encrypt(optarg);
- fprintf(stderr,"%sEncrypted password: %s\n",PMT,password);
- exit(0);
- break;
- case 'D':
- if(atoi(optarg)>-1)
- killd=atoi(optarg);
- break;
- case 'H':
- isvhost=1;
- if(!(vhost=(char *)malloc(strlen(optarg)+1)))
- printe("main(): allocating memory",1);
- strcpy(vhost,optarg);
- break;
- case 'V':
- isversion=1;
- if(!(vreply=(char *)malloc(strlen(optarg)+1)))
- printe("main(): allocating memory",1);
- strcpy(vreply,optarg);
- break;
- case 'Z':
- isversion=0;
- break;
- case 'z':
- noquit=1;
- break;
- case 'N':
- nodisplay=1;
- break;
- case 'e':
- name_length=MAX_NAME_LENGTH_EXT;
- break;
- case 'v':
- fprintf(stderr,"Version information: orignick/v%s.\n"
- "Id inormation: %s\n",VERSION,id);
- exit(0);
- break;
- default:
- usage(argv[0]);
- break;
- }
- }
- if(!isvhost)
- if(getenv(ENV_IRCHOST)&&strlen((char *)getenv(ENV_IRCHOST))>0){
- isvhost=1;
- if(!(vhost=(char *)malloc(strlen((char *)getenv(ENV_IRCHOST))+1)))
- printe("main(): allocating memory",1);
- strcpy(vhost,(char *)getenv(ENV_IRCHOST));
- }
- if(!ispasswd){
- if(getenv(ENV_PASSWORD)&&strlen((char *)getenv(ENV_PASSWORD))>0){
- ispasswd=1;
- if(!(password=(char *)malloc(strlen((char *)getenv(ENV_PASSWORD))+1)))
- printe("main(): allocating memory",1);
- strcpy(password,(char *)getenv(ENV_PASSWORD));
- }
- if(getenv(ENV_EPASSWORD)&&strlen((char *)getenv(ENV_EPASSWORD))>0){
- ispasswd=2;
- if(!(password=(char *)malloc(strlen((char *)getenv(ENV_EPASSWORD))+1)))
- printe("main(): allocating memory",1);
- strcpy(password,(char *)getenv(ENV_EPASSWORD));
- }
- }
- if(!isun)
- if(getenv(ENV_USERNAME)&&strlen((char *)getenv(ENV_USERNAME))>0){
- isun=1;
- if(!(username=(char *)malloc(strlen((char *)getenv(ENV_USERNAME))+1)))
- printe("main(): allocating memory",1);
- strcpy(username,(char *)getenv(ENV_USERNAME));
- }
- if(!isrn)
- if(getenv(ENV_REALNAME)&&strlen((char *)getenv(ENV_REALNAME))>0){
- isrn=1;
- if(!(realname=(char *)malloc(strlen((char *)getenv(ENV_REALNAME))+1)))
- printe("main(): allocating memory",1);
- strcpy(realname,(char *)getenv(ENV_REALNAME));
- }
- if(!isserver||!isname)
- usage(argv[0]);
- else{
- fprintf(stderr,"%sHostname is set: %s.\n",PMT,isvhost?vhost:"default");
- fprintf(stderr,"%sServer response delays are set: 1(%dms), 2(%dms).\n",PMT,
- delay,delay2);
- fprintf(stderr,"%sMaximum nickname length is set: %d. (%s)\n",PMT,
- name_length,name_length==MAX_NAME_LENGTH?"default":"extended");
- fprintf(stderr,"%sChannel join is set: %s.\n",PMT,ischannel?channel:"none");
- fprintf(stderr,"%sVersion reply is set: %s.\n",PMT,isversion?"on":"off");
- fprintf(stderr,"%sOn quit grab is set: %s.\n",PMT,noquit?"off":"on");
- fprintf(stderr,"%sKill password is set: %s.\n",PMT,ispasswd?"on":"off");
- if(ispasswd)
- fprintf(stderr,"%sKill delay time is set: %ds. (%s)\n",PMT,killd,
- killd==KILL_DELAY?"default":"extended");
- fprintf(stderr,"%sUsing server file: %s.\n",PMT,server_file);
- make_server_list(server_file);
- if(!tot_s){
- fprintf(stderr,"%sNot enough servers gathered to create an array.\n",PMT);
- exit(1);
- }
- fprintf(stderr,"%sArray server list created: %d server(s).\n",PMT,tot_s--);
- fprintf(stderr,"%sUsing name file: %s.\n",PMT,name_file);
- make_names_list(name_file);
- if(!tot_n){
- fprintf(stderr,"%sNot enough names gathered to create an array.\n",PMT);
- exit(1);
- }
- fprintf(stderr,"%sArray name list created: %d name(s).\n",PMT,tot_n--);
- if(!isnick)
- rand_nickname(name_length);
- if(bg){
- fprintf(stderr,"%sForking into the background.\n",PMT);
- switch(isbg=fork()){
- case -1:
- printe("forking into the background",1);
- break;
- case 0:
- if(ispid){
- pid_f=fopen(pid_file,"w");
- fprintf(pid_f,"%u\n",getpid());
- fclose(pid_f);
- }
- setsid();
- while(1){
- irc_parse(servers[j++],port);
- usleep(250000);
- if(tot_s<j)
- j=0;
- }
- break;
- default:
- fprintf(stderr,"%sBackgrounded to pid: %u.\n",PMT,isbg);
- exit(0);
- break;
- }
- }
- else
- while(1){
- irc_parse(servers[j++],port);
- usleep(250000);
- if(tot_s<j)
- j=0;
- }
- }
- exit(0);
- }
- int valid_name(char *word){
- int i=0;
- for(i=0;i<strlen(word);i++)
- if(word[i]<0x30||word[i]>0x7D)
- return(1);
- return(0);
- }
- int make_names_list(char *path){
- int i=0;
- int j=0;
- char read[(BASE_BUFFER+name_length)];
- FILE *fd;
- if(!(fd=fopen(path,"r")))
- printe("name file doesn't appear to exist or isn't readable",1);
- tot_n=0;
- while(fgets(read,sizeof(read),fd)){
- if(j>=MAX_ARGS)
- printe("too many names to store in memory",1);
- if(read[0]!=0x23){
- for(i=0;i<strlen(read);i++)
- if(read[i]==0x0A)
- read[i]=0x0;
- if(read[0]!=0x0A&&read[0]!=0x0){
- if(j-tot_n>MAX_ERRORS)
- printe("maximum invalid name(s) exceeded",1);
- if(strlen(read)>name_length)
- printe("ignored name in name file due to length restrictions",0);
- else if(valid_name(read))
- printe("ignored name in name file due to invalid character(s)",0);
- else{
- if(!(names[tot_n]=(char *)malloc(name_length)+1))
- printe("make_names_list(): allocating memory",1);
- strcpy(names[tot_n++],read);
- }
- }
- bzero(read,sizeof(read));
- }
- j++;
- }
- fclose(fd);
- return(0);
- }
- int make_server_list(char *path){
- int i=0;
- int j=0;
- char read[(256+2)];
- FILE *fd;
- if(!(fd=fopen(path,"r")))
- printe("server file doesn't appear to exist or isn't readable",1);
- while(fgets(read,sizeof(read),fd)){
- if(j>=MAX_ARGS)
- printe("too many servers to store in memory",1);
- if(read[0]!=0x23){
- for(i=0;i<strlen(read);i++)
- if(read[i]==0x0A)
- read[i]=0x0;
- if(read[0]!=0x0A&&read[0]!=0x0)
- if(strlen(read)>256)
- printe("ignored server due to length restrictions",0);
- else{
- if(!(servers[tot_s]=(char *)malloc(256+1)))
- printe("make_server_list(): allocating memory",1);
- strcpy(servers[tot_s++],read);
- }
- bzero(read,sizeof(read));
- }
- j++;
- }
- fclose(fd);
- return(0);
- }
- int make_userinfo(){
- struct passwd *userinfo;
- if(!(userinfo=getpwuid(getuid())))
- printe("passwd entry doesn't appear to exist",1);
- else{
- if(strlen(userinfo->pw_name)){
- if(!(username=(char *)malloc(strlen((char *)userinfo->pw_name)+1)))
- printe("make_userinfo(): allocating memory",1);
- strcpy(username,(char *)userinfo->pw_name);
- }
- else{
- if(!(username=(char *)malloc(strlen(DEFAULT_INFO)+1)))
- printe("make_userinfo(): allocating memory",1);
- strcpy(username,DEFAULT_INFO);
- }
- if(strlen(userinfo->pw_gecos)){
- if(!(realname=(char *)malloc(strlen((char *)userinfo->pw_gecos)+1)))
- printe("make_userinfo(): allocating memory",1);
- strcpy(realname,(char *)userinfo->pw_gecos);
- }
- else{
- if(!(realname=(char *)malloc(strlen(DEFAULT_INFO)+1)))
- printe("make_userinfo(): allocating memory",1);
- strcpy(realname,DEFAULT_INFO);
- }
- }
- return(0);
- }
- int parameter(char *array,int i){
- int j=0;
- int k=0;
- char buf[(strlen(array)+1)];
- bzero(buf,sizeof(buf));
- if(i<0)
- strcpy(buf,"*");
- else
- for(j=0;j<strlen(array);j++){
- if(array[j]==0x20)
- i--;
- else if(!i)
- buf[k++]=array[j];
- if(array[j]==0x0A||array[j]==0x0)
- j=(strlen(array)+1);
- }
- if(i>0)
- strcpy(buf,"*");
- free(parm);
- if(!(parm=(char *)malloc(strlen(buf)+1)))
- printe("parameter(): allocating memory",1);
- strcpy(parm,buf);
- return(0);
- }
- int orignick_encrypt(char *pwd){
- char chr[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
- char salt[3];
- struct timeval tv;
- srandom(time(0));
- sprintf(salt,"%c%c%c",chr[random()%64],chr[random()%64],0x0);
- if(!(password=(char *)malloc(strlen((char *)crypt(pwd,salt))+1)))
- printe("orignick_encrypt(): allocating memory",1);
- strcpy(password,(char *)crypt(pwd,salt));
- return(0);
- }
- int rand_nickname(int size){
- int i=0;
- int r=0;
- char string[(MAX_NAME_LENGTH_EXT+1)];
- struct timeval tv;
- while(i<=sizeof(string)){
- gettimeofday(&tv,(struct timezone*)0);
- srand(tv.tv_usec);
- if((2.0*rand()/(RAND_MAX+1.0))>1)
- r=(0x41+(int)(26.0*rand()/(RAND_MAX+1.0)));
- else
- r=(0x61+(int)(26.0*rand()/(RAND_MAX+1.0)));
- string[i++]=r;
- }
- if(!(nickname=(char *)malloc(strlen(string)+1)))
- printe("rand_nickname(): allocating memory",1);
- strncpy(nickname,string,size);
- return(0);
- }
- int irc_parse(char *host,int port){
- int err;
- int i=0;
- int j=0;
- int k=0;
- int l=0;
- int m=0;
- int sock=0;
- int serr=0;
- int first_ison=0;
- int start=0;
- int stop=0;
- char *tmpchannel;
- char *tmppassword;
- char active_nickname[BASE_BUFFER];
- char swrite[BASE_BUFFER];
- char sread[BASE_BUFFER];
- char sread_line[BASE_BUFFER];
- struct hostent *he;
- struct sockaddr_in6 irc;
- alarm(0);
- allowversion=0;
- if(!bg)
- fprintf(stderr,"%sAttempting to connect to: %s:%d.\n",PMT,host,port);
- sock=socket(PF_INET6,SOCK_STREAM,0);
- if(sock<0){
- if(!bg)
- printe("socket error",0);
- serr=1;
- }
- bzero(&irc,sizeof(struct sockaddr_in6));
- irc.sin6_family=AF_INET6;
- if(isvhost){
- if (inet_pton(AF_INET6, vhost, &(irc.sin6_addr)) <= 0) {
- if ((he = getipnodebyname(vhost, AF_INET6, AI_DEFAULT, &err)) == NULL) {
- if(!bg&&!serr)
- printe("couldn't resolve the provided host, trying any.",0);
- irc.sin6_addr=in6addr_any;
- }
- else
- memcpy((char *)&irc.sin6_addr,(char *)he->h_addr,he->h_length);
- }
- if(bind(sock,(struct sockaddr*)&irc,sizeof(struct sockaddr_in6))){
- if(!bg&&!serr)
- printe("binding name to socket, trying any.",0);
- bzero(&irc,sizeof(struct sockaddr_in6));
- irc.sin6_len=sizeof(irc);
- irc.sin6_family=AF_INET6;
- irc.sin6_addr=in6addr_any;
- if(bind(sock,(struct sockaddr*)&irc,sizeof(struct sockaddr_in6))){
- if(!bg&&!serr)
- printe("binding any name to socket.",0);
- serr=1;
- }
- }
- }
- bzero(&irc,sizeof(struct sockaddr_in6));
- irc.sin6_len=sizeof(irc);
- irc.sin6_family=AF_INET6;
- irc.sin6_port=htons(port);
- if (inet_pton(AF_INET6, host, &(irc.sin6_addr)) <= 0) {
- if ((he = getipnodebyname(host, AF_INET6, AI_DEFAULT, &err)) == NULL) {
- if(!bg&&!serr)
- printe("couldn't resolve the provided host",0);
- serr=1;
- }
- else
- memcpy((char *)&irc.sin6_addr,(char *)he->h_addr,he->h_length);
- }
- if(connect(sock,(struct sockaddr *)&irc,sizeof(irc))){
- if(!bg&&!serr)
- printe("couldn't connect to the provided host",0);
- serr=1;
- }
- if(!serr){
- if(isnick){
- if(!(nickname=(char *)malloc(strlen(basenickname)+1)))
- printe("main(): allocating memory",1);
- strcpy(nickname,basenickname);
- }
- else
- rand_nickname(name_length);
- strtok(username," ");
- sprintf(swrite,"\nUSER %.128s %.128s %.128s :%.128s\nNICK %.128s\n",username,
- username,username,realname,nickname);
- write(sock,swrite,sizeof(swrite));
- while(1){
- bzero(sread,sizeof(sread));
- bzero(swrite,sizeof(swrite));
- if(!read(sock,sread,sizeof(sread))){
- if(!bg){
- if(first_ison&&!nodisplay)
- fprintf(stderr,"\n");
- fprintf(stderr,"%sSession closed from: %s:%d.\n",PMT,host,port);
- }
- break;
- }
- for(i=0;i<strlen(sread);i++){
- if(sread[i]==0x0A){
- sread_line[j]=0x0;
- parameter(sread_line,0);
- if(!strcmp(parm,"PING")){
- parameter(sread_line,1);
- snprintf(swrite,sizeof(swrite),"\nPONG %s\n",parm);
- write(sock,swrite,sizeof(swrite));
- }
- bzero(active_nickname,sizeof(active_nickname));
- strncpy(active_nickname,sread_line,sizeof(active_nickname));
- strtok(active_nickname,"!");
- for(l=1;l<strlen(active_nickname);l++)
- active_nickname[(l-1)]=active_nickname[l];
- active_nickname[l-1]=0x0;
- parameter(sread_line,1);
- if(!stop){
- if(!strcmp(parm,"303")){
- if(!first_ison){
- first_ison=1;
- if(!bg&&!debug)
- if(nodisplay)
- fprintf(stderr,"%sAttempting to obtain supplied names...\n",PMT);
- else
- fprintf(stderr,"(. = in use, ! = free, % = failed, * = success%s): ",
- ispasswd?", @ = killed":"");
- }
- parameter(sread_line,3);
- if(strlen(parm)==1){
- ondelay(1);
- snprintf(swrite,sizeof(swrite),"\nNICK %s\n",names[(k-1)]);
- write(sock,swrite,sizeof(swrite));
- if(!bg&&!debug&&first_ison&&!nodisplay)
- fprintf(stderr,"!(%s is free)",names[(k-1)]);
- }
- else{
- if(k>tot_n)
- k=0;
- snprintf(swrite,sizeof(swrite),"\nISON %s\n",names[k++]);
- write(sock,swrite,sizeof(swrite));
- if(!bg&&!debug&&first_ison&&!nodisplay)
- fprintf(stderr,".");
- ondelay(0);
- }
- }
- if(!strcmp(parm,"431")||!strcmp(parm,"432")||!strcmp(parm,"433")){
- if(!first_ison){
- rand_nickname(name_length);
- if(!bg)
- fprintf(stderr,"%sFailed setting nickname, trying random. (%s)\n",
- PMT,nickname);
- snprintf(swrite,sizeof(swrite),"\nNICK %s\n",nickname);
- write(sock,swrite,sizeof(swrite));
- }
- if(start){
- if(!bg&&!debug&&first_ison&&!nodisplay)
- fprintf(stderr,"%(set failed)");
- if(k>tot_n)
- k=0;
- snprintf(swrite,sizeof(swrite),"\nISON %s\n",names[k++]);
- write(sock,swrite,sizeof(swrite));
- ondelay(0);
- }
- }
- if(!strcmp(parm,"NICK")){
- if(!strcmp(active_nickname,nickname)){
- parameter(sread_line,2);
- if(!(nickname=(char *)malloc(strlen(parm)+1)))
- printe("irc_parse(): allocating memory",1);
- strcpy(nickname,parm);
- for(m=1;m<strlen(nickname);m++)
- nickname[(m-1)]=nickname[m];
- nickname[(m-1)]=0x0;
- if(!bg&&!debug&&first_ison)
- if(!nodisplay)
- fprintf(stderr,"*(%s set, now idle)",nickname);
- else
- fprintf(stderr,"%sObtained nickname: %s.\n",PMT,nickname);
- stop=1;
- }
- }
- if(!strcmp(parm,"QUIT")&&ischannel&&!noquit){
- for(m=0;m<=tot_n;m++)
- if(!(strcmp(active_nickname,names[m]))){
- ondelay(1);
- snprintf(swrite,sizeof(swrite),"\nNICK %s\n",names[m]);
- write(sock,swrite,sizeof(swrite));
- if(!bg&&!debug&&first_ison&&!nodisplay)
- fprintf(stderr,"!(%s is free, quit in %s)",names[m],channel);
- }
- }
- }
- if(!strcmp(parm,"001")){
- if(!bg)
- fprintf(stderr,"%sConnected successfully to: %s:%d.\n",PMT,host,port);
- parameter(sread_line,2);
- if(!(nickname=(char *)malloc(strlen(parm)+1)))
- printe("irc_parse(): allocating memory",1);
- strcpy(nickname,parm);
- if(!bg)
- fprintf(stderr,"%sConnected with nickname: %s.\n",PMT,nickname);
- if(ischannel){
- snprintf(swrite,sizeof(swrite),"\nJOIN %s :%s\n",channel,channel_key);
- write(sock,swrite,sizeof(swrite));
- }
- if(k>tot_n)
- k=0;
- snprintf(swrite,sizeof(swrite),"\nISON %s\n",names[k++]);
- write(sock,swrite,sizeof(swrite));
- start=1;
- ondelay(0);
- }
- if(!strcmp(parm,"366")){
- parameter(sread_line,3);
- if(!bg&&!first_ison)
- fprintf(stderr,"%sJoined channel: %s.\n",PMT,parm);
- }
- if((!strcmp(parm,"403")||!strcmp(parm,"471")||!strcmp(parm,"472")
- ||!strcmp(parm,"473")||!strcmp(parm,"474")||!strcmp(parm,"475"))&&!bg
- &&!first_ison){
- parameter(sread_line,3);
- fprintf(stderr,"%sFailed joining channel: %s.\n",PMT,parm);
- }
- if(!strcmp(parm,"461")){
- make_userinfo();
- sprintf(swrite,"\nUSER %.128s %.128s %.128s :%.128s\nNICK %.128s\n",
- username,username,username,realname,nickname);
- write(sock,swrite,sizeof(swrite));
- }
- if(!strcmp(parm,"PRIVMSG")){
- parameter(sread_line,3);
- if(isversion&&!allowversion&&stop&&!strcasecmp(":\x01VERSION\x01",parm)){
- snprintf(swrite,sizeof(swrite),"\nNOTICE %s :%cVERSION %s%c\n",
- active_nickname,0x01,vreply,0x01);
- write(sock,swrite,sizeof(swrite));
- allowversion=1;
- signal(SIGALRM,version_fprot);
- alarm(VERSION_FPROT);
- }
- else if(ispasswd){
- if(!(tmppassword=(char *)malloc(strlen(parm)+1)))
- printe("irc_parse(): allocating memory",1);
- strcpy(tmppassword,parm);
- for(m=1;m<strlen(tmppassword);m++)
- tmppassword[(m-1)]=tmppassword[m];
- tmppassword[(m-1)]=0x0;
- if((ispasswd==2&&!strcmp((char *)crypt(tmppassword,password),password))
- ||(ispasswd==1&&!strcmp(tmppassword,password))){
- if(!bg&&!debug&&first_ison&&!nodisplay)
- fprintf(stderr,"@(%s sent kill passwd, killing with %ds delay)",
- active_nickname,killd);
- shutdown(sock,2);
- stop=1;
- sleep(killd);
- }
- free(tmppassword);
- }
- }
- if(!strcmp(parm,"KICK")&&ischannel){
- parameter(sread_line,2);
- if(!strcmp(parm,channel)){
- parameter(sread_line,3);
- if(!strcmp(parm,nickname)){
- snprintf(swrite,sizeof(swrite),"\nJOIN %s :%s\n",channel,channel_key);
- write(sock,swrite,sizeof(swrite));
- }
- }
- }
- if(!strcmp(parm,"INVITE")&&ischannel){
- parameter(sread_line,3);
- if(!(tmpchannel=(char *)malloc(strlen(parm)+1)))
- printe("irc_parse(): allocating memory",1);
- strcpy(tmpchannel,parm);
- for(m=1;m<strlen(tmpchannel);m++)
- tmpchannel[(m-1)]=tmpchannel[m];
- tmpchannel[(m-1)]=0x0;
- if(!strcmp(tmpchannel,channel)){
- snprintf(swrite,sizeof(swrite),"\nJOIN %s :%s\n",channel,channel_key);
- write(sock,swrite,sizeof(swrite));
- }
- free(tmpchannel);
- }
- bzero(swrite,sizeof(swrite));
- parameter(sread_line,1);
- if(!bg&&debug&&strcmp(parm,"421"))
- fprintf(stderr,"%s%s\n",DPMT,sread_line);
- bzero(sread_line,sizeof(sread_line));
- j=0;
- }
- else if(sread[i]!=0x0D)
- sread_line[j++]=sread[i];
- }
- }
- }
- else if(!bg){
- if(first_ison&&!nodisplay)
- fprintf(stderr,"\n");
- fprintf(stderr,"\n%sSession closed from: %s:%d.\n",PMT,host,port);
- }
- if(sock)
- close(sock);
- return(0);
- }
- int printe(char *err,int quit){
- if(isbg<1)
- fprintf(stderr,"%s%s.\n",EPMT,err);
- if(quit)
- exit(1);
- }
- int ondelay(int ext){
- if(ext)
- if(delay2)
- usleep(delay2);
- else
- if(delay)
- usleep(delay);
- return(0);
- }
- int usage(char *prog){
- fprintf(stderr,"Usage: %s <-s file> <-f file> [options...]\n\n"
- " -s <file>%cserver file list. [standard per line format] (required)\n"
- " -f <file>%cname file list. [standard per line format] (required)\n"
- " -p <numeric>%cwill use an alternate ircd port to connect to.\n"
- " -u <argument>%cwill use an alternate user name. [non-passwd entry]\n"
- " -r <argument>%cwill use an alternate real name. [non-passwd entry]\n"
- " -c <argument>%cwill join the provided channel.\n"
- " -k <argument>%cwill apply a key to join the channel. [for the -c option]\n"
- " -n <argument>%cwill use a non-random nickname to start with.\n"
- " -d%c%cwill use debug mode. [show server data]\n"
- " -b%c%cwill place orignick into the background. [with errors ignored]\n"
- " -S <numeric>%cwill delay responding with provided time. [1000000=1s]\n"
- " -L <numeric>%cis like -S, but used for special situations. [3000000=3s]\n"
- " -P <file>%cfile to place the pid of the bg process. [for the -b option]\n"
- " -K <argument>%cwill use a kill passwd to reset the bot via irc.\n"
- " -E <argument>%cis like -K, but uses an encrypted password instead.\n"
- " -M <argument>%cwill encrypt the argument as a password and exit.\n"
- " -D <numeric>%cwill use an alternate remote kill delay time.\n"
- " -H <argument>%cwill use the provided argument as a virtual host.\n"
- " -V <argument>%cwill use the provided argument as a version reply.\n"
- " -Z%c%cwill ignore remote version requests.\n"
- " -z%c%cwill disable on quit nickname grabs. [if in channel]\n"
- " -N%c%cwill disable local status showing on the bot.\n"
- " -e%c%cwill use extended nickname length. [servers with >9 nick limit]\n"
- " -v%c%cwill display version information and exit.\n"
- "\nAuthor: vade79@realhalo.org, realhalo.org. [ihadnihn]\n",prog,0x9,0x9,0x9,
- 0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,
- 0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9);
- exit(0);
- }
Add Comment
Please, Sign In to add comment