/* msgcmds.c -- handles: all commands entered via /MSG dprintf'ized, 4feb96 */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include "eggdrop.h" #include "users.h" #include "chan.h" #include "proto.h" /* let unknown users greet us and become known */ int learn_users=0; /* new server? */ char newserver[121]; /* new server port? */ int newserverport=0; /* new server password? */ char newserverpass[121]; /* refuse access to non-masters who don't have 'x' flag? */ int require_x=0; /* enable the info subsystem? */ int use_info=1; /* person to send a note to for new users */ char notify_new[121]=""; /* default user flags for people who say 'hello' */ int default_flags=0; extern int serv; extern char botname[]; extern int use_info; extern char origbotname[]; extern char helpdir[]; extern int make_userfile; extern char notefile[]; extern int dcc_total; extern struct dcc_t dcc[]; extern struct userrec *userlist; extern struct chanset_t *chanset; int msg_hello(n,nick,h,p) char *n,*nick,*h,*p; { char host[161],s[161],s1[161]; char *p1; int common=0,atr; if ((!learn_users) && (!make_userfile)) return 0; if (strcasecmp(nick,botname)==0) return 1; atr=get_attr_handle(n); if ((n[0]=='*') && (!(atr & USER_COMMON))) { if (is_user(nick)) { showtext(nick,"badhost",0,0); return 1; } sprintf(s,"%s!%s",nick,h); if (match_ban(s)) { hprintf(serv,"NOTICE %s :You're banned, goober.\n",nick); return 1; } if (strlen(nick)>9) { /* crazy dalnet */ hprintf(serv,"NOTICE %s :Your nick is too long to add right now.\n", nick); return 1; } if (atr & USER_COMMON) { maskhost(s,host); strcpy(s,host); sprintf(host,"%s!%s",nick,&s[2]); userlist=adduser(userlist,nick,host,"-",default_flags); putlog(LOG_MISC,"*","Introduced to %s (%s) -- common site",nick,host); common=1; } else { maskhost(s,host); if (make_userfile) userlist=adduser(userlist,nick,host,"-",default_flags| USER_MASTER|USER_OWNER); else userlist=adduser(userlist,nick,host,"-",default_flags); putlog(LOG_MISC,"*","Introduced to %s (%s)",nick,host); } hprintf(serv,"NOTICE %s :Hi %s! I'm %s, an eggdrop bot.\n",nick, nick,botname); hprintf(serv,"NOTICE %s :I'll recognize you by hostmask '%s'%s\n", nick,host," from now on."); if (common) { hprintf(serv,"NOTICE %s :Since you come from a common irc site, %s", nick,"this means you should\n"); hprintf(serv,"NOTICE %s : always use this nickname when talking %s", nick,"to me.\n"); } set_handle_laston(nick,time(NULL)); if (make_userfile) { #ifdef OWNER hprintf(serv,"NOTICE %s :YOU ARE THE MASTER/OWNER ON THIS BOT NOW\n", nick); #else hprintf(serv,"NOTICE %s :YOU ARE THE MASTER ON THIS BOT NOW\n", nick); #endif showtext(nick,"newbot",0,0); putlog(LOG_MISC,"*","Bot installation complete, first master is %s", nick); make_userfile=0; write_userfile(); add_note(nick,origbotname,"Welcome to eggdrop! :)",-1,0); } else showtext(nick,"intro",0,0); if (notify_new[0]) { sprintf(s,"Introduced to %s from %s",nick,host); strcpy(s1,notify_new); while (s1[0]) { p1=strchr(s1,','); if (p1!=NULL) { *p1=0; p1++; rmspace(p1); } rmspace(s1); add_note(s1,origbotname,s,-1,0); if (p1==NULL) s1[0]=0; else strcpy(s1,p1); } } } else mprintf(serv,"NOTICE %s :Hi, %s.\n",nick,n); return 1; } int msg_pass(hand,nick,host,par) char *hand,*nick,*host,*par; { char old[512],new[512]; if (strcasecmp(nick,botname)==0) return 1; if (strcmp(hand,"*")==0) return 1; if (get_attr_handle(hand) & USER_COMMON) return 1; split(old,par); if (!par[0]) { mprintf(serv,"NOTICE %s :You %s a password set.\n",nick, pass_match_by_handle("-",hand)?"don't have":"have"); putlog(LOG_CMDS,"*","(%s!%s) !%s! PASS?",nick,host,hand); return 1; } if ((!pass_match_by_handle("-",hand)) && (!old[0])) { mprintf(serv,"NOTICE %s :You already have a password set.\n",nick); return 1; } if (!old[0]) { putlog(LOG_CMDS,"*","(%s!%s) !%s! PASS...",nick,host,hand); nsplit(new,par); if (strlen(new)>9) new[9]=0; if (strlen(new)<4) { mprintf(serv,"NOTICE %s :Please use at least 4 characters.\n",nick); return 0; } change_pass_by_handle(hand,new); mprintf(serv,"NOTICE %s :Password set to '%s'\n",nick,new); return 1; } if (!pass_match_by_handle(old,hand)) { mprintf(serv,"NOTICE %s :Incorrect password.\n",nick); return 1; } nsplit(new,par); putlog(LOG_CMDS,"*","(%s!%s) !%s! PASS...",nick,host,hand); if (strlen(new)>9) new[9]=0; if (strlen(new)<4) { mprintf(serv,"NOTICE %s :Please use at least 4 characters.\n",nick); return 0; } change_pass_by_handle(hand,new); mprintf(serv,"NOTICE %s :Password changed to '%s'.\n",nick,new); return 1; } int msg_ident(hand,nick,host,par) char *hand,*nick,*host,*par; { char s[121],s1[121],pass[512],who[NICKLEN]; if (strcasecmp(nick,botname)==0) return 1; if (get_attr_handle(hand) & USER_COMMON) { mprintf(serv,"NOTICE %s :You're at a common site; you can't ident.\n", nick); return 1; } nsplit(pass,par); if (!is_user(nick)) { if (strcmp(hand,"*")!=0) { mprintf(serv,"NOTICE %s :You're not %s, you're %s.\n",nick,nick,hand); return 1; } if ((!par[0]) || (!is_user(par))) return 1; /* dunno you */ } strncpy(who,par,NICKLEN); who[NICKLEN-1]=0; if (!par[0]) strcpy(who,nick); if (pass_match_by_handle("-",who)) { mprintf(serv,"NOTICE %s :You have no password set.\n",nick); return 1; } if (!pass_match_by_handle(pass,who)) { mprintf(serv,"NOTICE %s :Access denied.\n",nick); return 1; } if (strcasecmp(hand,who)==0) { mprintf(serv,"NOTICE %s :I recognize you there.\n",nick); return 1; } if (strcmp(hand,"*")!=0) { mprintf(serv,"NOTICE %s :You're not %s, you're %s.\n",nick,who,hand); return 1; } putlog(LOG_CMDS,"*","(%s!%s) !%s! IDENT %s",nick,host,hand,who); sprintf(s,"%s!%s",nick,host); maskhost(s,s1); mprintf(serv,"NOTICE %s :Added hostmask: %s\n",nick,s1); addhost_by_handle(who,s1); recheck_ops(nick,who); return 1; } int msg_email(hand,nick,host,par) char *hand,*nick,*host,*par; { char s[161]; if (strcasecmp(nick,botname)==0) return 1; if (strcasecmp(hand,"*")==0) return 0; if (get_attr_handle(hand) & USER_COMMON) return 1; if (par[0]) { get_handle_email(hand,s); if (strcasecmp(par,"none")==0) { putlog(LOG_CMDS,"*","(%s!%s) !%s! EMAIL NONE",nick,host,hand); par[0]=0; set_handle_email(userlist,hand,par); mprintf(serv,"NOTICE %s :Removed your email address.\n",nick); } else { putlog(LOG_CMDS,"*","(%s!%s) !%s! EMAIL...",nick,host,hand); set_handle_email(userlist,hand,par); mprintf(serv,"NOTICE %s :Now: %s\n",nick,par); } return 1; } putlog(LOG_CMDS,"*","(%s!%s) !%s! EMAIL?",nick,host,hand); get_handle_email(hand,s); if (s[0]) { mprintf(serv,"NOTICE %s :Currently: %s\n",nick,s); mprintf(serv,"NOTICE %s :To remove it: /msg %s email none\n",nick,botname); } else mprintf(serv,"NOTICE %s :You have no email address set.\n",nick); return 1; } int msg_info(hand,nick,host,par) char *hand,*nick,*host,*par; { char s[121]; if (strcasecmp(nick,botname)==0) return 1; if (!use_info) return 1; if (strcasecmp(hand,"*")==0) return 0; if (get_attr_handle(hand) & USER_COMMON) return 1; if (par[0]) { get_handle_info(hand,s); if (s[0]=='@') mprintf(serv,"NOTICE %s :Your info line is locked.\n",nick); else if (strcasecmp(par,"none")==0) { putlog(LOG_CMDS,"*","(%s!%s) !%s! INFO NONE",nick,host,hand); par[0]=0; set_handle_info(userlist,hand,par); mprintf(serv,"NOTICE %s :Removed your info line.\n",nick); } else { putlog(LOG_CMDS,"*","(%s!%s) !%s! INFO...",nick,host,hand); if (par[0]=='@') strcpy(par,&par[1]); set_handle_info(userlist,hand,par); mprintf(serv,"NOTICE %s :Now: %s\n",nick,par); } return 1; } putlog(LOG_CMDS,"*","(%s!%s) !%s! INFO?",nick,host,hand); get_handle_info(hand,s); if (s[0]) { mprintf(serv,"NOTICE %s :Currently: %s\n",nick,s); mprintf(serv,"NOTICE %s :To remove it: /msg %s info none\n",nick,botname); } else mprintf(serv,"NOTICE %s :You have no info set.\n",nick); return 1; } int msg_who(hand,nick,host,par) char *hand,*nick,*host,*par; { struct chanset_t *chan; if (strcasecmp(nick,botname)==0) return 1; if (strcasecmp(hand,"*")==0) return 0; if (!use_info) return 1; if (!par[0]) { mprintf(serv,"NOTICE %s :Usage: /msg %s who \n",nick, origbotname); return 0; } chan=findchan(par); if (chan==NULL) { mprintf(serv,"NOTICE %s :I don't monitor that channel.\n",nick); return 0; } if ((channel_hidden(chan)) && (!hand_on_chan(chan,hand)) && (!(get_attr_handle(hand)&(USER_OP|USER_FRIEND|USER_MASTER)))) { mprintf(serv,"NOTICE %s :Channel is currently hidden.\n",nick); return 1; } putlog(LOG_CMDS,"*","(%s!%s) !%s! WHO",nick,host,hand); show_all_info(chan->name,nick); return 1; } int msg_whois(hand,nick,host,opar) char *hand,*nick,*host,*opar; { time_t tt; char s[161],s1[81],par[NICKLEN]; int atr,ok; struct chanset_t *chan; if (strcasecmp(nick,botname)==0) return 1; if (strcasecmp(hand,"*")==0) return 0; strncpy(par,opar,NICKLEN); par[NICKLEN-1]=0; putlog(LOG_CMDS,"*","(%s!%s) !%s! WHOIS %s",nick,host,hand,par); if (!is_user(par)) { /* no such handle -- maybe it's a nickname of someone on a chan? */ ok=0; chan=chanset; while ((chan!=NULL) && (!ok)) { if (ischanmember(chan->name,par)) { sprintf(s,"%s!",par); getchanhost(chan->name,par,&s[strlen(s)]); get_handle_by_host(par,s); ok=1; if (par[0]=='*') ok=0; else hprintf(serv,"NOTICE %s :[%s] aka '%s':\n",nick,opar,par); } chan=chan->next; } if (!ok) { hprintf(serv,"NOTICE %s :[%s] No user record.\n",nick,opar); return 1; } } atr=get_attr_handle(par); get_handle_info(par,s); get_handle_laston(par,&tt); if (s[0]=='@') strcpy(s,&s[1]); if ((s[0]) && (!(atr&USER_BOT))) hprintf(serv,"NOTICE %s :[%s] %s\n",nick,par,s); get_handle_email(par,s); if (s[0]) hprintf(serv,"NOTICE %s :[%s] email: %s\n",nick,par,s); ok=0; chan=chanset; while (chan!=NULL) { if (hand_on_chan(chan,par)) { sprintf(s1,"NOTICE %s :[%s] On %s now.",nick,par,chan->name); ok=1; } chan=chan->next; } if ((!ok) && (tt)) { strcpy(s,ctime(&tt)); strcpy(s,&s[4]); s[12]=0; sprintf(s1,"NOTICE %s :[%s] Last seen %s",nick,par,s); } else if (!ok) sprintf(s1,"NOTICE %s :[%s] No user record.",nick,par); if (atr & USER_OP) strcat(s1," (is an op)"); if (atr & USER_BOT) strcat(s1," (is a bot)"); if (atr & USER_MASTER) strcat(s1," (is a master)"); hprintf(serv,"%s\n",s1); return 1; } int msg_help(hand,nick,host,par) char *hand,*nick,*host,*par; { int atr; char s[121],*p; if (strcasecmp(nick,botname)==0) return 1; sprintf(s,"%s!%s",nick,host); atr=get_attr_host(s); if (strcasecmp(hand,"*")==0) { #ifndef QUIET_REJECTION hprintf(serv,"NOTICE %s :I don't know you; please introduce yourself first.\n", nick); hprintf(serv,"NOTICE %s :/MSG %s hello\n",nick,botname); #endif return 0; } if (helpdir[0]) { if (!par[0]) showhelp(nick,"help",atr&USER_OP,atr&USER_MASTER); else { for (p=par; *p!=0; p++) if ((*p>='A') && (*p<='Z')) *p+=('a'-'A'); showhelp(nick,par,atr&USER_OP,atr&USER_MASTER); } } else hprintf(serv,"NOTICE %s :No help.\n",nick); return 1; } /* i guess just op them on every channel they're on */ int msg_op(hand,nick,host,par) char *hand,*nick,*host,*par; { struct chanset_t *chan; if (strcasecmp(nick,botname)==0) return 1; if (pass_match_by_handle(par,hand)) { chan=chanset; while (chan!=NULL) { if ((hand_on_chan(chan,hand)) && (!member_op(chan->name,nick))) add_mode(chan,'+','o',nick); chan=chan->next; } putlog(LOG_CMDS,"*","(%s!%s) !%s! OP",nick,host,hand); return 1; } putlog(LOG_CMDS,"*","(%s!%s) !%s! failed OP",nick,host,hand); return 1; } int msg_invite(hand,nick,host,par) char *hand,*nick,*host,*par; { char pass[512]; if (strcasecmp(nick,botname)==0) return 1; if (strcmp(hand,"*")==0) return 0; nsplit(pass,par); if (pass_match_by_handle(pass,hand)) { if (findchan(par)==NULL) { mprintf(serv,"NOTICE %s :Usage: /MSG %s invite \n", nick,origbotname); return 1; } if (!active_channel(par)) { mprintf(serv,"NOTICE %s :I'm not on %s right now.\n",nick,par); return 1; } mprintf(serv,"INVITE %s %s\n",nick,par); putlog(LOG_CMDS,"*","(%s!%s) !%s! INVITE %s",nick,host,hand,par); return 1; } putlog(LOG_CMDS,"*","(%s!%s) !%s! failed INVITE %s",nick,host,hand,par); return 1; } int msg_status(hand,nick,host,par) char *hand,*nick,*host,*par; { if (strcasecmp(nick,botname)==0) return 1; putlog(LOG_CMDS,"*","(%s!%s) !%s! STATUS",nick,host,hand); tell_chan_info(nick); return 1; } int msg_memory(hand,nick,host,par) char *hand,*nick,*host,*par; { if (strcasecmp(nick,botname)==0) return 1; putlog(LOG_CMDS,"*","(%s!%s) !%s! MEMORY",nick,host,hand); tell_mem_status(nick); return 1; } int msg_die(hand,nick,host,par) char *hand,*nick,*host,*par; { char s[121]; if (strcasecmp(nick,botname)==0) return 1; if (pass_match_by_handle(par,hand)) { putlog(LOG_CMDS,"*","(%s!%s) !%s! DIE",nick,host,hand); tprintf(serv,"NOTICE %s :Daisy, Daisssyyy, give meee yourr ansssweerrrrrr dooooooooo....\n",nick); chatout("*** BOT SHUTDOWN (authorized by %s)\n",hand); tandout("chat %s BOT SHUTDOWN (authorized by %s)\n",origbotname,hand); tandout("bye\n"); tprintf(serv,"QUIT :%s\n",nick); write_userfile(); sleep(1); /* give the server time to understand */ sprintf(s,"DEAD BY REQUEST OF %s!%s",nick,host); fatal(s,0); } putlog(LOG_CMDS,"*","(%s!%s) !%s! failed DIE",nick,host,hand); return 1; } int msg_rehash(hand,nick,host,par) char *hand,*nick,*host,*par; { if (strcasecmp(nick,botname)==0) return 1; if (pass_match_by_handle(par,hand)) { putlog(LOG_CMDS,"*","(%s!%s) !%s! REHASH",nick,host,hand); mprintf(serv,"NOTICE %s :Rehashing...\n",nick); rehash(); return 1; } putlog(LOG_CMDS,"*","(%s!%s) !%s! failed REHASH",nick,host,hand); return 1; } int msg_reset(hand,nick,host,par) char *hand,*nick,*host,*par; { struct chanset_t *chan; if (strcasecmp(nick,botname)==0) return 1; if (par[0]) { chan=findchan(par); if (chan==NULL) { mprintf(serv,"NOTICE %s :I don't monitor channel %s\n",nick,par); return 0; } putlog(LOG_CMDS,"*","(%s!%s) !%s! RESET %s",nick,host,hand,par); mprintf(serv,"NOTICE %s :Resetting channel info on %s...\n",nick,par); reset_chan_info(chan); return 1; } putlog(LOG_CMDS,"*","(%s!%s) !%s! RESET ALL",nick,host,hand); mprintf(serv,"NOTICE %s :Resetting channel info for all channels...\n", nick); chan=chanset; while (chan!=NULL) { reset_chan_info(chan); chan=chan->next; } return 1; } int msg_go(hand,nick,host,par) char *hand,*nick,*host,*par; { struct chanset_t *chan; int ok=0; if (strcasecmp(nick,botname)==0) return 1; if (!(get_attr_handle(hand) & USER_OP)) { putlog(LOG_CMDS,"*","(%s!%s) !%s! failed GO (not op)",nick,host, hand); return 1; } if (par[0]) { /* specific GO */ chan=findchan(par); if (chan==NULL) return 0; if (!me_op(chan)) { tprintf(serv,"PART %s\n",chan->name); putlog(LOG_CMDS,chan->name,"(%s!%s) !%s! GO %s",nick,host,hand,par); return 1; } putlog(LOG_CMDS,chan->name,"(%s!%s) !%s! failed GO %s (i'm chop)",nick, host,hand,par); return 1; } chan=chanset; while (chan!=NULL) { if (ischanmember(chan->name,nick)) { if (!me_op(chan)) { tprintf(serv,"PART %s\n",chan->name); ok=1; } } chan=chan->next; } if (ok) { putlog(LOG_CMDS,"*","(%s!%s) !%s! GO",nick,host,hand); return 1; } putlog(LOG_CMDS,"*","(%s!%s) !%s! failed GO (i'm chop)",nick,host,hand); return 1; } int msg_jump(hand,nick,host,par) char *hand,*nick,*host,*par; { char s[512],port[512]; if (strcasecmp(nick,botname)==0) return 1; nsplit(s,par); /* password */ if (pass_match_by_handle(s,hand)) { if (par[0]) { nsplit(s,par); nsplit(port,par); if (!port[0]) strcpy(port,"6667"); putlog(LOG_CMDS,"*","(%s!%s) !%s! JUMP %s %s %s",nick,host,hand,s,port, par); strcpy(newserver,s); newserverport=atoi(port); strcpy(newserverpass,par); } else putlog(LOG_CMDS,"*","(%s!%s) !%s! JUMP",nick,host,hand); tprintf(serv,"NOTICE %s :Jumping servers...\n",nick); tprintf(serv,"QUIT :changing servers\n"); killsock(serv); serv=(-1); } else putlog(LOG_CMDS,"*","(%s!%s) !%s! failed JUMP",nick,host,hand); return 1; } /* notes */ int msg_notes(hand,nick,host,par) char *hand,*nick,*host,*par; { char pwd[121],fcn[121]; if (strcasecmp(nick,botname)==0) return 1; if (hand[0]=='*') return 0; if (!par[0]) { hprintf(serv,"NOTICE %s :Usage: NOTES [pass] INDEX\n",nick); hprintf(serv,"NOTICE %s : NOTES [pass] TO \n",nick); hprintf(serv,"NOTICE %s : NOTES [pass] READ <# or ALL>\n",nick); hprintf(serv,"NOTICE %s : NOTES [pass] ERASE <# or ALL>\n",nick); return 1; } if (!pass_match_by_handle("-",hand)) { /* they have a password set */ nsplit(pwd,par); if (!pass_match_by_handle(pwd,hand)) return 0; } nsplit(fcn,par); if (strcasecmp(fcn,"INDEX")==0) notes_read(hand,nick,-1,-1); else if (strcasecmp(fcn,"READ")==0) { if (strcasecmp(par,"ALL")==0) notes_read(hand,nick,0,-1); else notes_read(hand,nick,atoi(par),-1); } else if (strcasecmp(fcn,"ERASE")==0) { if (strcasecmp(par,"ALL")==0) notes_del(hand,nick,0,-1); else notes_del(hand,nick,atoi(par),-1); } else if (strcasecmp(fcn,"TO")==0) { char to[514]; int i; FILE *f; nsplit(to,par); if (!par[0]) { hprintf(serv,"NOTICE %s :Usage: NOTES [pass] TO \n", nick); return 0; } if (!is_user(to)) { hprintf(serv,"NOTICE %s :I don't know anyone by that name.\n",nick); return 1; } for (i=0; iaway!=NULL) aok=0; if (dcc[i].type==DCC_FILES) if (dcc[i].u.file->chat->away!=NULL) aok=0; if (aok) { dprintf(i,"\007Outside note [%s]: %s\n",hand,par); hprintf(serv,"NOTICE %s :Note delivered.\n",nick); return 1; } } } if (notefile[0]==0) { hprintf(serv,"NOTICE %s :Notes are not supported on this bot.\n", nick); return 1; } f=fopen(notefile,"a"); if (f==NULL) f=fopen(notefile,"w"); if (f==NULL) { hprintf(serv,"NOTICE %s :Can't create notefile. Sorry.\n",nick); putlog(LOG_MISC,"*","* Notefile unreachable!"); return 1; } fprintf(f,"%s %s %lu %s\n",to,hand,time(NULL),par); fclose(f); hprintf(serv,"NOTICE %s :Note delivered.\n",nick); return 1; } else hprintf(serv,"NOTICE %s :NOTES function must be one of INDEX, %s\n", nick,"READ, ERASE, TO"); putlog(LOG_CMDS,"*","(%s!%s) !%s! NOTES %s %s",nick,host,hand,fcn, par[0]?"...":""); return 1; }