#include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SSL #include #include #include #include #include #include #endif #include "sbuf.h" #include "struct.h" #include "send.h" #include "ctcp.h" #define MAXMOTDLINE 512 extern int mytoi(char *buf); extern void bnckill (int reason); extern int bewmstick (void); //RM extern int sockprint(int fd,const char *format,...); extern int logprint(confetti *jr,const char *format,...); extern int send_queued(struct lsock *cptr); extern int passwordokay (char *s, char *pass); int irc_connect(struct cliententry *cptr, char *server, u_short port, char *pass, int ctype, int cflags); extern int thestat(char *buf,int len, struct cliententry *cptr); extern struct cliententry *getclient(struct cliententry *cptr, int nfd); extern void add_access (confetti *, accesslist *); extern int wipeclient(struct cliententry *cptr); extern confetti *jack; extern int chanlist(char *buf,int len, struct cliententry *client); extern struct cliententry *headclient; extern void *pmalloc(size_t size); extern int mytoi(char *buf); extern unsigned char touppertab[]; extern unsigned char tolowertab[]; unsigned char motdb[MAXMOTDLINE]; char *helplist[] = { "COMMANDS are /quote: ex.) /quote conn bnc.irc.net 6667", "MAIN ", " Identifies you as a supervisor, enabling admin commands", "VIP [new virtual host]", " /quote VIP alone will list current vhosts in the config file", "IDENT ", " If your shell has identwd installed, bnc will take advantage of its features, changing your ident", "KEEPALIVE", " returns you to bnc if a shell closes you (EXPERIMENTAL)", "CONN [port] [pass]", " Connects you to a real irc server", "VDF", " Switches your vhost back to the config default", "VN", " Switches your vhost to the shells default", NULL }; char *helplista[] = { "-----ADMIN *ONLY* COMMANDS----", "BWHO", " Lists all clients using BNC", "BKILL ", " Closes one of the clients with that specified FD", "DIE", " Shuts down BNC", "BDIE", " alternative shutdown", "ADDHOST
", " Adds an allow for an IP to use your BNC", "LISTHOST", " Lists allowed IP hosts", NULL }; int cmd_quit(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_nick(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_pass(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_user(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_help(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_main(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_conn(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_ident(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_vn(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_vdf(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_vip(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_who(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_die(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_bdie(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_bkill(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_addhost(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_listhost(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_keepalive(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_rawecho(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_bmsg(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_prefixrawecho(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_dock(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_resume(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_resumealive(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_dumpll(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_bypass(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int cmd_privmsg(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int srv_nick(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int srv_tellnick(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int srv_join(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int srv_kick(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int srv_part(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int srv_quit(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int srv_ping(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int srv_endmotd(struct cliententry *cptr, char *prefix, int pargc, char **pargv); int srv_privmsg(struct cliententry *cptr, char *prefix, int pargc, char **pargv); cmdstruct serverbnccmds[] = { { "NICK", srv_nick, FLAGCONNECTED, FLAGNONE }, { "PING", srv_ping, FLAGCONNECTED | FLAGDOCKED, FLAGNONE }, { "004", srv_tellnick, FLAGCONNECTED, FLAGNONE }, { "JOIN", srv_join, FLAGCONNECTED, FLAGNONE }, { "KICK", srv_kick, FLAGCONNECTED, FLAGNONE }, { "PART", srv_part, FLAGCONNECTED, FLAGNONE }, { "QUIT", srv_quit, FLAGCONNECTED, FLAGNONE }, { "376", srv_endmotd, FLAGCONNECTED, FLAGNONE }, { "PRIVMSG", srv_privmsg, FLAGCONNECTED, FLAGNONE }, {NULL, NULL, 0,0} }; cmdstruct clientbnccmds[] = { { "QUIT", cmd_quit, FLAGNONE, FLAGCONNECTED }, { "PASS", cmd_pass, FLAGNONE, FLAGCONNECTED | FLAGPASS }, { "NICK", cmd_nick, FLAGNONE, FLAGCONNECTED }, { "USER", cmd_user, FLAGNONE, FLAGCONNECTED }, { "HELP", cmd_help, FLAGPASS, FLAGCONNECTED }, { "BNCHELP", cmd_help, FLAGPASS, FLAGNONE }, { "MAIN", cmd_main, FLAGNONE, FLAGNONE }, { "CONN", cmd_conn, FLAGBASED, FLAGNONE }, { "IDENT", cmd_ident, FLAGPASS, FLAGNONE }, { "VN", cmd_vn, FLAGPASS, FLAGNONE }, { "VDF", cmd_vdf, FLAGPASS, FLAGNONE }, { "VIP", cmd_vip, FLAGPASS, FLAGNONE }, { "BWHO", cmd_who, FLAGSUPER, FLAGNONE }, { "DIE", cmd_die, FLAGSUPER, FLAGNONE }, { "BDIE", cmd_bdie, FLAGSUPER, FLAGNONE }, { "BKILL", cmd_bkill, FLAGSUPER, FLAGNONE }, { "ADDHOST", cmd_addhost, FLAGSUPER, FLAGNONE }, { "LISTHOST", cmd_listhost, FLAGSUPER, FLAGNONE }, { "KEEPALIVE", cmd_keepalive, FLAGPASS, FLAGNONE }, { "RAWECHO", cmd_rawecho, FLAGPASS, FLAGNONE }, { "BMSG", cmd_bmsg, FLAGPASS, FLAGNONE }, { "PRE", cmd_prefixrawecho , FLAGPASS | FLAGBASED, FLAGNONE }, { "DOCK", cmd_dock, FLAGCONNECTED, FLAGNONE }, { "DETACH", cmd_dock, FLAGCONNECTED, FLAGNONE }, { "RESUME", cmd_resume, FLAGPASS, FLAGCONNECTED }, { "RESUME", cmd_resumealive, FLAGPASS, FLAGNONE }, { "DUMPLL", cmd_dumpll, FLAGNONE, FLAGNONE }, { "BYPASS", cmd_bypass, FLAGCONNECTED, FLAGNONE }, { "PRIVMSG", cmd_privmsg, FLAGCONNECTED, FLAGNONE }, { NULL, NULL, 0, 0 } }; int remnl (char *buf, int size) { int p; for (p = 0; p < size; p++) { if (buf[p] == '\0') { return p; } if((buf[p] == '\n') || (buf[p] == '\r')) { buf[p] = '\0'; return p; } } return p; } int irc_strcasecmp(const char *s1, const char *s2) { int x; if(s1 == NULL) { return 1; } if(s2 == NULL) { return 1; } for(;*s1 && *s2; s1++, s2++) { x = touppertab[(unsigned char)*s1] - touppertab[(unsigned char)*s2]; if(x) { return x; } } /* should not need toupper or anything, since they both should be 0 */ if(*s1 == *s2) { return 0; } return 1; } int wipechans(struct cliententry *cptr) { struct chanentry *ochan; struct chanentry *chanlist; chanlist=cptr->headchan; while(chanlist) { ochan=chanlist; chanlist=chanlist->next; free(ochan); } cptr->headchan=NULL; return 0; } struct chanentry *findchan(struct chanentry *chanlist, char *chan) { while(chanlist) { if(!irc_strcasecmp(chanlist->chan,chan)) { return chanlist; } chanlist=chanlist->next; } return NULL; } int wipechan(struct cliententry *cptr, char *chan) { struct chanentry *chanlist; if(cptr == NULL) { return 1; } chanlist=findchan(cptr->headchan,chan); if(chanlist == NULL) { return 1; } if(chanlist->prev) { chanlist->prev->next = chanlist->next; } else { cptr->headchan=chanlist->next; } if(chanlist->next) { chanlist->next->prev=chanlist->prev; } free(chanlist); return 0; } int ismenuh(char *prefix, char *nick) { char *src; if(prefix == NULL) return 0; for(src = prefix; *src && *src != '!'; ++src); return ((strncasecmp(nick, prefix, src - prefix) == 0) && (nick[src - prefix] == 0)); } void list_docks(struct cliententry *cptr) { struct cliententry *dptr; for(dptr = headclient; dptr; dptr=dptr->next) { if(dptr->flags & FLAGDOCKED) break; } if(dptr == NULL) return; tprintf(&cptr->loc, "NOTICE AUTH :You have docked sessions to resume type /quote resume \n"); do { tprintf(&cptr->loc, "NOTICE AUTH :Docked session %i\n", dptr->srv.fd); while( (dptr=dptr->next) && !(dptr->flags & FLAGDOCKED) ); } while(dptr); tprintf(&cptr->loc, "NOTICE AUTH :End of dock list\n"); } int handlepclient (struct cliententry *cptr, int fromwho, int pargc, char **pargv, char *prefix) { int p,f,r,w; FILE *motdf; cmdstruct *bnccmds; f=0; p=0; w=1; if(fromwho == CLIENT) { bnccmds=clientbnccmds; } else { bnccmds=serverbnccmds; } while(bnccmds[p].name != NULL) { if(!strcasecmp(pargv[0],bnccmds[p].name)) { /* lets check flags */ if( (bnccmds[p].flags_on & cptr->flags) == bnccmds[p].flags_on) { if( (bnccmds[p].flags_off & ~cptr->flags) == bnccmds[p].flags_off) { w=0; f=bnccmds[p].func(cptr, prefix, pargc, pargv); break; } } } p++; } if(f > 0) { return f; } if( (cptr->flags & ( FLAGNICK | FLAGUSER | FLAGPASS)) != ( FLAGNICK | FLAGUSER | FLAGPASS) ) { return w; } if( !( cptr->flags & FLAGBASED )) { cptr->flags |= FLAGBASED; if (cptr->flags & FLAGAUTOCONN) { /* handle the autoconn stuff, disabled for now */ if (cptr->susepass) { r=irc_connect(cptr, cptr->autoconn, cptr->sport, cptr->autopass, 0, 0); } else { r=irc_connect(cptr, cptr->autoconn, cptr->sport, NULL, 0, 0); } #if 0 if(r > 1) { return r; } #endif return w; } tprintf(&cptr->loc, "NOTICE AUTH :Welcome to BNC " VERSION ", the irc proxy\n"); if( (cptr->flags & FLAGSUPER) == 0) { motdf = fopen (jack->motdf, "r"); if(motdf != NULL) { while (!feof (motdf)) { memset(motdb,0,MAXMOTDLINE); fgets (motdb,MAXMOTDLINE, motdf); motdb[MAXMOTDLINE]='\0'; p=remnl (motdb,MAXMOTDLINE); motdb[MAXMOTDLINE]='\0'; if(p > 0) { tprintf(&cptr->loc, "NOTICE AUTH :-*- %s\n", motdb); } } fclose (motdf); } } tprintf(&cptr->loc, "NOTICE AUTH :Level two, lets connect to something real now\n"); tprintf(&cptr->loc, "NOTICE AUTH :type /quote conn [-s] [port] [pass] to connect\n"); list_docks(cptr); tprintf(&cptr->loc, "NOTICE AUTH :type /quote help for basic list of commands and usage\n"); } return w; } int srv_ping(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { // int r; if(pargc < 2) { return 0; } tprintf(&cptr->srv, "PONG :%s\n", pargv[1] ); return 0; /* we don't wanna forward anything when docked */ } int srv_part(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { int m; if(pargc < 2) { return FORWARDCMD; } m=ismenuh(prefix,cptr->nick); if(!m) /* its not me, so forget it */ { return FORWARDCMD; } wipechan(cptr,pargv[1]); return FORWARDCMD; } int srv_kick(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if(pargc < 3) { return FORWARDCMD; } if(!strncasecmp(cptr->nick, pargv[2] ,NICKLEN)) { wipechan(cptr, pargv[1]); } return FORWARDCMD; } int srv_endmotd(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { // int r; struct chanentry *chanlist; if(cptr->docked == 1) /* ok resuming is almost done */ { cptr->docked = 0; chanlist=cptr->headchan; while(chanlist) { tprintf(&cptr->loc, ":%s!%s@%s JOIN %s\n",cptr->nick, cptr->uname, cptr->fromip, chanlist->chan ); tprintf(&cptr->srv, "NAMES %s\n",chanlist->chan ); chanlist=chanlist->next; } } return FORWARDCMD; } char *nuh_pgetnick(char *userhost) { char *src; char *nick; for(src = userhost; *src && !(*src == '!' || *src == ' '); ++src); if(src <= userhost) return NULL; nick = pmalloc((src - userhost) + 1); memcpy(nick, userhost, src - userhost); nick[src - userhost] = 0; return nick; } void process_join(struct cliententry *cptr, char *userhost, char *channame) { int len; struct chanentry *channel; channel = findchan(cptr->headchan, channame); if( ismenuh(userhost, cptr->nick) == 0 ) { char *nick; /* user is not me */ nick = nuh_pgetnick(userhost); if(nick == NULL) { /* failed to parse the name */ return; } // printf("NICK %s\n", nick); free(nick); return; } /* user is me */ if(channel != NULL) { /* already known, nothing to do but ignore */ return; } len = strlen(channame); channel = pmalloc(sizeof(struct chanentry) + len + 1); memcpy(channel->chan, channame, len); channel->chan[len] = 0; channel->prev=0; channel->next=cptr->headchan; if(cptr->headchan) cptr->headchan->prev=channel; cptr->headchan=channel; } void process_quit(struct cliententry *cptr, char *userhost) { return; } int srv_quit(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if(prefix == NULL) return FORWARDCMD; process_quit(cptr, prefix); return FORWARDCMD; } int srv_join(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if(pargc < 2 || prefix == NULL) return FORWARDCMD; process_join(cptr, prefix, pargv[1]); return FORWARDCMD; } int srv_nick(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if(pargc < 2) { return 0; } if(prefix == NULL) return 0; if(ismenuh(prefix, cptr->nick)) { strncpy( cptr->nick, pargv[1], NICKLEN); cptr->nick[NICKLEN]='\0'; } return FORWARDCMD; } int srv_tellnick(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if(pargc < 2) { return 0; } strncpy(cptr->nick,pargv[1],NICKLEN); cptr->nick[NICKLEN]='\0'; if(prefix != NULL) { strncpy(cptr->sid,prefix,HOSTLEN); cptr->sid[HOSTLEN]='\0'; } return FORWARDCMD; } int srv_privmsg(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { char *msg; #if 0 int i; printf("pargc %i\n", pargc); for(i = 0; i < pargc; i++) { // printf("(%i) %s\n", i, pargv[i]); printf("(%i) ",i); msg = pargv[i]; putchar('\''); for(;*msg; msg++) { if(*msg >= ' ' && *msg <= '~') putchar(*msg); else if(*msg == '\\') printf("\\"); else if(*msg == '\r') printf("\\r"); else if(*msg == '\n') printf("\\n"); else if(*msg == '\b') printf("\\b"); else printf("\\%3.3o", *msg); } putchar('\''); putchar('\n'); } #endif if(pargc < 3) return FORWARDCMD; msg = pargv[2]; if(*msg != '\001') return FORWARDCMD; return ct_handle(cptr, prefix, pargv[1], msg, SERVER); } int cmd_privmsg(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { char *msg; if(pargc < 3) return FORWARDCMD; msg = pargv[2]; if(*msg != '\001') return FORWARDCMD; return ct_handle(cptr, prefix, pargv[1], msg, CLIENT); } int cmd_resumealive(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { cptr->flags &= ~FLAGDOCKED; return 0; } int cmd_resume(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { int sfd; struct cliententry *client; if(pargc < 3) { tprintf(&cptr->loc, "NOTICE %s :Syntax, /quote resume dock_fd pass\n",cptr->nick); return 0; } sfd=mytoi(pargv[1]); client = getclient(headclient, sfd); if(client == NULL || !(client->flags & FLAGDOCKED)) { tprintf(&cptr->loc, "NOTICE %s :Docked fd not found\n",cptr->nick); return 0; } if(!strncasecmp(client->autopass,pargv[2],PASSLEN)) { tprintf(&client->loc, "NOTICE %s :-*- Resuming session\n",cptr->nick); if( strncasecmp(client->nick, cptr->nick, NICKLEN) ) { tprintf(&client->loc, ":%s@%s!%s NICK :%s\n",cptr->nick,cptr->uname,cptr->fromip, client->nick); } tprintf(&client->loc, ":%s 001 %s :Welcome to a resumed bnc session\n", client->sid, client->nick); tprintf(&client->loc, ":%s 002 %s :your host is %s, running an irc server\n", client->sid, client->nick, client->sid); tprintf(&client->loc, ":%s 003 %s :%s runs docked bnc\n", client->sid, client->nick, client->sid); tprintf(&client->loc, ":%s 004 %s %s 234123 _____ ______\n", client->sid, client->nick, client->sid); tprintf(&client->srv, "LUSERS\nMOTD\n"); client->docked=1; client->loc.fd=cptr->loc.fd; client->flags &= ~FLAGDOCKED; cptr->loc.fd=-1; cptr->srv.fd=-1; return KILLCURRENTUSER; } else tprintf(&cptr->loc, "NOTICE %s :incorrect resume pass\n",cptr->nick); return 0; } int cmd_dock(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if(pargc < 2) { tprintf(&cptr->loc, "NOTICE %s :/quote DOCK pass\n",cptr->nick); return 0; } tprintf(&cptr->loc, "NOTICE %s :To resume, /quote resume %i %s\n",cptr->nick,cptr->srv.fd,pargv[1]); strncpy(cptr->autopass, pargv[1], PASSLEN); cptr->autopass[PASSLEN]='\0'; cptr->flags |= FLAGDOCKED; if(!(cptr->flags & FLAGKEEPALIVE)) { send_queued(&cptr->loc); close(cptr->loc.fd); cptr->loc.fd=DOCKEDFD; } return 0; } int cmd_quit(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { return KILLCURRENTUSER; } int cmd_dumpll(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { struct cliententry *client_ptr; client_ptr = headclient; tprintf(&cptr->loc, "NOTICE AUTH :Dumping Links.\n"); while (client_ptr != NULL) { tprintf(&cptr->loc, "NOTICE AUTH :%p<= %p => %p :(%i,%i)\n", client_ptr->prev, client_ptr, client_ptr->next, client_ptr->loc.fd, client_ptr->srv.fd); client_ptr = client_ptr->next; } tprintf(&cptr->loc, "NOTICE AUTH :End of Linked list.\n"); return 0; } int cmd_rawecho(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if(pargc < 2) { return 0; } tprintf(&cptr->loc, "%s\n",pargv[1]); return 0; } int cmd_prefixrawecho(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if(pargc < 2) return 0; if(prefix == NULL) tprintf(&cptr->loc, ":%s!%s@%s %s\n", cptr->nick, cptr->uname, cptr->fromip, pargv[1]); else tprintf(&cptr->loc, ":%s %s\n", prefix, pargv[1]); return 0; } int cmd_bypass(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if(pargc < 2) { return 0; } tprintf(&cptr->srv, "%s\n",pargv[1]); return 0; } int cmd_nick(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if(pargc < 2) { return 0; } strncpy (cptr->nick, pargv[1], NICKLEN); cptr->nick[NICKLEN]=0; cptr->flags |= FLAGNICK; if( (cptr->flags & FLAGPASS) == 0) { tprintf(&cptr->loc, "NOTICE AUTH :You need to say /quote PASS \n"); } return 0; } int cmd_pass(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { int p; int iswhite; int sargc; char *sargv[4]; if (pargc < 2) { return 0; } p = 0; sargc=1; sargv[0]=pargv[1]; iswhite=0; for(p=0; pargv[1][p] ; p++) { if(sargc > 3) { iswhite=0; /* just be mean */ } if(iswhite) { if( pargv[1][p] != ':' ) { iswhite=0; sargv[sargc++]=&pargv[1][p]; } } else { if( pargv[1][p] == ':' ) { iswhite=1; pargv[1][p]='\0'; } } } /* printf("Pass line gave %i args\n",sargc); for(p=0;pdpass)) { cptr->flags |= FLAGPASS; if(sargc > 1) { cptr->flags |= FLAGAUTOCONN; strncpy (cptr->autoconn, sargv[1], HOSTLEN); cptr->autoconn[HOSTLEN]='\0'; cptr->sport=jack->cport; if(sargc > 2) /* contains port */ { cptr->sport=mytoi(sargv[2]); } if(sargc > 3) /* contains server pass */ { strncpy (cptr->autopass, sargv[3], PASSLEN); cptr->autopass[PASSLEN]='\0'; cptr->susepass=1; } } return 0; } cptr->pfails++; if (cptr->pfails > 2) { return KILLCURRENTUSER; } logprint(jack, "Failed pass from %s password %s\n", cptr->fromip, sargv[0]); if( cptr->flags & FLAGNICK ) { tprintf(&cptr->loc, "NOTICE AUTH :Failed Pass!!\n"); } return 0; } int cmd_user(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if (pargc < 5) { return 0; } strncpy (cptr->realname, pargv[4], REALLEN); cptr->realname[REALLEN]='\0'; strncpy (cptr->uname, pargv[1], USERLEN); cptr->uname[USERLEN]='\0'; cptr->flags |= FLAGUSER; return 0; } int cmd_help(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { int p; for (p = 0; helplist[p] != NULL; p++) { tprintf(&cptr->loc, "NOTICE AUTH :*** %s\n", helplist[p]); } if(cptr->flags & FLAGSUPER) { for (p = 0; helplista[p] != NULL; p++) { tprintf(&cptr->loc, "NOTICE AUTH :*** %s\n", helplista[p]); } } tprintf(&cptr->loc, "NOTICE AUTH :*** For a detailed explanation of commands, consult the file README,\n"); return 0; } int cmd_main(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if (pargc < 2) { return 0; } if (passwordokay (pargv[1], jack->spass)) { cptr->flags |= FLAGSUPER; cptr->flags |= FLAGPASS; tprintf(&cptr->loc, "NOTICE AUTH :Welcome Supervisor!!\n"); return 0; } logprint(jack, "Failed MAIN from %s\n", cptr->fromip); tprintf(&cptr->loc, "NOTICE AUTH :Failed Main!!\n"); return 0; } int cmd_conn(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { int cport; // int res; int ctype; int cflags; char *host; char *port; char *pass; char *src; int p; ctype = 0; cflags = 0; host = port = pass = NULL; for(p = 1; p < pargc; p++) { src = pargv[p]; if(*src == '-') { src++; if(*src == '6') ctype = 1; #ifdef HAVE_SSL if(*src == 's') cflags |= USE_SSL; #endif continue; } if(host == NULL) host = src; else if(port == NULL) port = src; else if(pass == NULL) pass = src; } if (host == NULL) return 0; cport = port != NULL ? mytoi(port) : jack->cport; irc_connect(cptr, host, cport, pass, ctype, cflags); return 0; } int cmd_ident(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if (pargc < 2) { tprintf(&cptr->loc, "NOTICE AUTH :current ident is %s\n", cptr->uname); return 0; } tprintf(&cptr->loc, "NOTICE AUTH :changing ident from %s to %s\n", cptr->uname, pargv[1]); strncpy (cptr->uname, pargv[1], USERLEN); cptr->uname[USERLEN]='\0'; return 0; } int cmd_vn(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { tprintf(&cptr->loc, "NOTICE AUTH :Nulling out Vhost to system internal default\n"); memset (cptr->vhost, '\0',HOSTLEN); return 0; } int cmd_vdf(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if (strlen (jack->vhostdefault) < 1) tprintf(&cptr->loc, "NOTICE AUTH :Switching Vhost back to default\n"); else tprintf(&cptr->loc, "NOTICE AUTH :Switching Vhost back to default (%s)\n", jack->vhostdefault); strncpy (cptr->vhost, jack->vhostdefault, HOSTLEN); cptr->vhost[HOSTLEN]='\0'; return 0; } char *vhostbyid(unsigned long id) { unsigned long idx; struct vhostentry *vhost_ptr; for(idx = 1, vhost_ptr=jack->vhostlist; vhost_ptr; vhost_ptr = vhost_ptr->next, ++idx) { if(idx == id) return vhost_ptr->vhost; } return NULL; } int cmd_vip(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { int f; struct vhostentry *vhost_ptr; char *vhost; unsigned long vhostid; char *pos; if(pargc < 2) { if (strlen (cptr->vhost) != 0) tprintf(&cptr->loc, "NOTICE AUTH :Current Vhost: %s\n", cptr->vhost); else tprintf(&cptr->loc, "NOTICE AUTH :Current Vhost: -SYSTEM DEFAULT-\n"); tprintf(&cptr->loc, "NOTICE AUTH :Listing Vhosts\n"); if (strlen (jack->vhostdefault) < 1) tprintf(&cptr->loc, "NOTICE AUTH : (0) system default\n"); else tprintf(&cptr->loc, "NOTICE AUTH : (0) default (%s)\n", jack->vhostdefault); for(f = 1, vhost_ptr=jack->vhostlist; vhost_ptr; vhost_ptr = vhost_ptr->next, f++) tprintf(&cptr->loc, "NOTICE AUTH : (%i) %s\n", f, vhost_ptr->vhost); tprintf(&cptr->loc, "NOTICE AUTH :End of Vhost list\n"); return 0; } vhost = pargv[1]; vhostid = strtoul(vhost, &pos, 10); if(pos <= vhost || *pos || (vhostid == ULONG_MAX && errno == ERANGE)) { strncpy (cptr->vhost, vhost, HOSTLEN); cptr->vhost[HOSTLEN]='\0'; tprintf(&cptr->loc, "NOTICE AUTH :Set vhost to %s\n", cptr->vhost); return 0; } if(vhostid == 0) { if (strlen (jack->vhostdefault) < 1) tprintf(&cptr->loc, "NOTICE AUTH :Switching Vhost back to default\n"); else tprintf(&cptr->loc, "NOTICE AUTH :Switching Vhost back to default (%s)\n", jack->vhostdefault); strncpy (cptr->vhost, jack->vhostdefault, HOSTLEN); cptr->vhost[HOSTLEN]='\0'; return 0; } vhost = vhostbyid(vhostid); if(vhost == NULL) { tprintf(&cptr->loc, "NOTICE AUTH :No matching vhost for specified ID\n"); return 0; } strncpy (cptr->vhost, vhost, HOSTLEN); cptr->vhost[HOSTLEN]='\0'; tprintf(&cptr->loc, "NOTICE AUTH :Set vhost to %s\n", cptr->vhost); return 0; } int cmd_who(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { int nchans; char chans[128+1]; struct cliententry *client_ptr; char st[11]; client_ptr = headclient; tprintf(&cptr->loc, "NOTICE AUTH :Listing users.\n"); while (client_ptr != NULL) { thestat(st,11, client_ptr); if( client_ptr->flags & FLAGCONNECTED ) { nchans=chanlist(chans,128,client_ptr); if( client_ptr->flags & FLAGDOCKED ) tprintf(&cptr->loc, "NOTICE AUTH :(DOCKED FD %i Status: %s)[%s@%s] on server (%s) %s\n", client_ptr->srv.fd, st, client_ptr->nick, client_ptr->fromip, client_ptr->sid, client_ptr->onserver); else { if( client_ptr->flags & FLAGCONNECTING) tprintf(&cptr->loc, "NOTICE AUTH :(FD %i Status: %s)[%s@%s] connecting to server (%s) %s\n", client_ptr->loc.fd, st, client_ptr->nick, client_ptr->fromip, client_ptr->sid, client_ptr->onserver); else tprintf(&cptr->loc, "NOTICE AUTH :(FD %i Status: %s)[%s@%s] on server (%s) %s\n", client_ptr->loc.fd, st, client_ptr->nick, client_ptr->fromip, client_ptr->sid, client_ptr->onserver); } if(nchans) tprintf(&cptr->loc, "NOTICE AUTH :CHANLIST: %s\n", chans ); } else tprintf(&cptr->loc, "NOTICE AUTH :(FD %i Status: %s)[%s@%s] \n", client_ptr->loc.fd, st, client_ptr->nick, client_ptr->fromip); client_ptr = client_ptr->next; } tprintf(&cptr->loc, "NOTICE AUTH :End of user list.\n"); return 0; } int cmd_bdie(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { tprintf(&cptr->loc, "NOTICE AUTH :Shutting it down....\n"); logprint(jack,"Shutdown called by %s@%s\n",cptr->nick,cptr->fromip); bnckill(FATALITY); return 0; } int cmd_die(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { tprintf(&cptr->loc, "NOTICE AUTH :Shutting it down....\n"); logprint(jack,"Shutdown called by %s@%s\n",cptr->nick,cptr->fromip); bewmstick (); return 0; } int cmd_bmsg(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { int p; struct cliententry *client_ptr; if (pargc < 3) { return 0; } p = mytoi (pargv[1]); if(p < 1) { tprintf(&cptr->loc, "NOTICE AUTH :invalid bmsg arguments\n"); return 0; } client_ptr = getclient(headclient,p); if( client_ptr == NULL) { tprintf(&cptr->loc, "NOTICE AUTH :No such FD %i\n", p); return 0; } tprintf(&client_ptr->loc, "NOTICE AUTH :%i BMSG %s\n",cptr->loc.fd,pargv[2]); return 0; } int cmd_bkill(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { int p; struct cliententry *client_ptr; if (pargc < 2) { return 0; } p = mytoi (pargv[1]); if(p < 1) { tprintf(&cptr->loc, "NOTICE AUTH :invalid bkill argument\n"); return 0; } client_ptr = getclient(headclient,p); if( client_ptr == NULL) { tprintf(&cptr->loc, "NOTICE AUTH :No such FD %i\n", p); return 0; } if(p == cptr->loc.fd) { tprintf(&cptr->loc, "NOTICE AUTH :Suicide is painful\n"); return KILLCURRENTUSER; } tprintf(&cptr->loc, "NOTICE AUTH :Killed %i\n", p); logprint(jack, "BKILL to %s@%s\n", client_ptr->nick, client_ptr->fromip); if(client_ptr->prev == NULL) headclient=client_ptr->next; else client_ptr->prev->next=client_ptr->next; wipeclient(client_ptr); return 0; } int cmd_addhost(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { accesslist *na; if (pargc < 3) { return 0; } if (mytoi (pargv[1]) > 2) { return 0; } na = pmalloc (sizeof (accesslist)); na->type = mytoi (pargv[1]); strncpy (na->addr, pargv[2], HOSTLEN); na->addr[HOSTLEN]='\0'; na->next = NULL; add_access (jack, na); logprint(jack, "ADDHOST %s\n", pargv[2]); return 0; } int cmd_listhost(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { accesslist *na; int i; for (na = jack->alist, i = 1; na; na = na->next, i++) { tprintf(&cptr->loc, "NOTICE AUTH :#%i: (t:%i) %s\r\n", i, (int) na->type, na->addr); } return 0; } int cmd_keepalive(struct cliententry *cptr, char *prefix, int pargc, char **pargv) { if( !(cptr->flags & FLAGKEEPALIVE )) { cptr->flags |= FLAGKEEPALIVE; tprintf(&cptr->loc, "NOTICE AUTH :Enabling KeepAlive\n"); } else { cptr->flags &= ~FLAGKEEPALIVE; tprintf(&cptr->loc, "NOTICE AUTH :Disabling KeepAlive\n"); } return 0; }