-CSDIRS=database
+CSDIRS=database chancmds usercmds authcmds
.PHONY: all dirs clean
-all: chanserv.so chanserv_chancmds.so chanserv_usercmds.so chanserv_protect.so chanserv_auth.so chanserv_grep.so \
- chanserv_chansearch.so dirs
+all: chanserv.so chanserv_protect.so chanserv_grep.so chanserv_chansearch.so dirs
dirs:
for i in $(CSDIRS) ; do $(MAKE) -C $$i all ; done
chanservdump.o chanservschedule.o
ld -shared -Bdynamic ${LIBPGSQL} -o $@ $^
-chanserv_chancmds.so: chancmds.o
- ld -shared -Bdynamic -o $@ $^
-
-chanserv_usercmds.so: usercmds.o
- ld -shared -Bdynamic -o $@ $^
-
chanserv_protect.so: chanserv_protect.o
ld -shared -Bdynamic -o $@ $^
-chanserv_auth.so: authcmds.o authlib.o
- ld -shared -Bdynamic -o $@ $^
-
chanserv_grep.so: chanservgrep.o
ld -shared -Bdynamic ${LIBPCRE} -o $@ $^
+++ /dev/null
-#include "chanserv.h"
-#include "authlib.h"
-#include "../lib/irc_string.h"
-
-#include <stdio.h>
-#include <string.h>
-
-int csa_dohello(void *source, int cargc, char **cargv);
-int csa_doauth(void *source, int cargc, char **cargv);
-int csa_doreqpw(void *source, int cargc, char **cargv);
-int csa_doreqmasterpw(void *source, int cargc, char **cargv);
-int csa_donewpw(void *source, int cargc, char **cargv);
-int csa_doemail(void *source, int cargc, char **cargv);
-int csa_dosetpw(void *source, int cargc, char **cargv);
-int csa_dosetmail(void *source, int cargc, char **cargv);
-int csa_dosetmasterpw(void *source, int cargc, char **cargv);
-
-void _init() {
- csa_initregex();
- chanservaddcommand("hello", QCMD_NOTAUTHED, 2, csa_dohello, "Creates a new user account.");
- chanservaddcommand("auth", QCMD_ALIAS | QCMD_SECURE | QCMD_NOTAUTHED, 2, csa_doauth, "Authenticates you on the bot.");
- chanservaddcommand("login", QCMD_SECURE | QCMD_NOTAUTHED, 2, csa_doauth, "Authenticates you on the bot.");
- chanservaddcommand("newpass", QCMD_AUTHED, 3, csa_donewpw, "Change your password.");
- chanservaddcommand("email", QCMD_AUTHED, 3, csa_doemail, "Change your email address.");
- chanservaddcommand("requestpassword", QCMD_NOTAUTHED, 2, csa_doreqpw, "Requests the current password by email.");
- chanservaddcommand("requestmasterpassword", QCMD_AUTHED, 1, csa_doreqmasterpw, "Requests a new master password by email.");
- chanservaddcommand("setpassword", QCMD_OPER, 2, csa_dosetpw, "Set a new password.");
- chanservaddcommand("setemail", QCMD_OPER, 2, csa_dosetmail, "Set the email address.");
- chanservaddcommand("setmasterpassword", QCMD_OPER, 2, csa_dosetmasterpw, "Set the master password.");
-// chanservaddcommand("getpassword", QCMD_DEV, 2, csa_dogetpw, "Get the password.");
-// chanservaddcommand("getmasterpassword", QCMD_DEV, 2, csa_dogetmasterpw, "Get the master password.");
-}
-
-void _fini() {
- csa_freeregex();
- chanservremovecommand("hello", csa_dohello);
- chanservremovecommand("auth", csa_doauth);
- chanservremovecommand("login", csa_doauth);
- chanservremovecommand("requestpassword", csa_doreqpw);
- chanservremovecommand("requestmasterpassword", csa_doreqmasterpw);
- chanservremovecommand("newpass", csa_donewpw);
- chanservremovecommand("email", csa_doemail);
- chanservremovecommand("setpassword", csa_dosetpw);
- chanservremovecommand("setemail", csa_dosetmail);
- chanservremovecommand("setmasterpassword", csa_dosetmasterpw);
-}
-
-/*
- * check if account is "throttled"
- */
-int csa_checkthrottled(nick *sender, reguser *rup, char *s)
-{
- time_t now;
- long d;
- float t;
-
- now=time(NULL);
- d=MAX_RESEND_TIME+rup->lastemailchange-now;
-
- if (d>MAX_RESEND_TIME)
- d=MAX_RESEND_TIME;
-
- if (d>0L) {
- t = ((float) d) / ((float) 3600);
- chanservstdmessage(sender, QM_MAILTHROTTLED, t);
- cs_log(sender,"%s FAIL username %s, new request throttled for %.1f hours",s,rup->username,t);
- return 1;
- }
- return 0;
-}
-
-/*
- * /msg Q HELLO <email address> <email address>
- */
-int csa_dohello(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup;
- char userhost[USERLEN+HOSTLEN+2];
-
- if (getreguserfromnick(sender))
- return CMD_ERROR;
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "hello");
- return CMD_ERROR;
- }
-
- if (findreguserbynick(sender->nick)) {
- chanservstdmessage(sender, QM_AUTHNAMEINUSE, sender->nick);
- return CMD_ERROR;
- }
-
- if (strcmp(cargv[0],cargv[1])) {
- chanservstdmessage(sender, QM_EMAILDONTMATCH);
- cs_log(sender,"HELLO FAIL username %s email don't match (%s vs %s)",sender->nick,cargv[0],cargv[1]);
- return CMD_ERROR;
- }
-
- if (csa_checkeboy(sender, cargv[0]))
- return CMD_ERROR;
-
- rup=getreguser();
- rup->status=0;
- rup->ID=++lastuserID;
- strncpy(rup->username,sender->nick,NICKLEN); rup->username[NICKLEN]='\0';
- rup->created=time(NULL);
- rup->lastauth=time(NULL);
- rup->lastemailchange=time(NULL);
- rup->flags=QUFLAG_NOTICE;
- rup->languageid=0;
- rup->suspendby=0;
- rup->suspendexp=0;
- rup->password[0]='\0';
- rup->masterpass[0]='\0';
- rup->email=getsstring(cargv[0],EMAILLEN);
- rup->info=NULL;
- sprintf(userhost,"%s@%s",sender->ident,sender->host->name->content);
- rup->lastuserhost=getsstring(userhost,USERLEN+HOSTLEN+1);
- rup->suspendreason=NULL;
- rup->comment=NULL;
- rup->knownon=NULL;
- rup->checkshd=NULL;
- rup->stealcount=0;
- rup->fakeuser=NULL;
- rup->nicks=NULL;
- addregusertohash(rup);
- csa_createrandompw(rup->password, PASSLEN);
- csa_createrandompw(rup->masterpass, PASSLEN);
- chanservstdmessage(sender, QM_NEWACCOUNT, rup->username,rup->email->content);
- cs_log(sender,"HELLO OK created auth %s (%s)",rup->username,rup->email->content);
- csdb_createuser(rup);
- csdb_createmail(rup, QMAIL_NEWACCOUNT);
-
- return CMD_OK;
-}
-
-/*
- * /msg Q AUTH <account> <password>
- */
-int csa_doauth(void *source, int cargc, char **cargv) {
- reguser *rup;
- activeuser* aup;
- nick *sender=source;
- nicklist *nl = NULL;
- char userhost[USERLEN+HOSTLEN+2];
- int ucount=0;
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "auth");
- return CMD_ERROR;
- }
-
- if (!(aup = getactiveuserfromnick(sender)))
- return CMD_ERROR;
-
- aup->authattempts++;
- if (aup->authattempts > MAXAUTHATTEMPT) {
- if ((aup->authattempts % 100) == 0)
- chanservwallmessage("Warning: User %s!%s@%s attempted to auth %d times. Last attempt: AUTH %s %s",
- nl->np->nick, nl->np->ident, nl->np->host->name->content, cargv[0], cargv[1]);
- chanservstdmessage(sender, QM_AUTHFAIL);
- cs_log(sender,"AUTH FAIL too many auth attempts (last attempt: AUTH %s %s)",cargv[0], cargv[1]);
- return CMD_ERROR;
- }
-
- if (!(rup=findreguserbynick(cargv[0]))) {
- chanservstdmessage(sender, QM_AUTHFAIL);
- cs_log(sender,"AUTH FAIL bad username %s",cargv[0]);
- return CMD_ERROR;
- }
-
- if (!checkpassword(rup, cargv[1])) {
- chanservstdmessage(sender, QM_AUTHFAIL);
- cs_log(sender,"AUTH FAIL username %s bad password %s",rup->username,cargv[1]);
- return CMD_ERROR;
- }
-
- rup->lastauth=time(NULL);
- sprintf(userhost,"%s@%s",sender->ident,sender->host->name->content);
- if (rup->lastuserhost)
- freesstring(rup->lastuserhost);
- rup->lastuserhost=getsstring(userhost,USERLEN+HOSTLEN+1);
-
- if (UHasSuspension(rup) && rup->suspendexp && (time(0) >= rup->suspendexp)) {
- /* suspension has expired, remove it */
- rup->flags&=(~(QUFLAG_SUSPENDED|QUFLAG_GLINE|QUFLAG_DELAYEDGLINE));
- rup->suspendby=0;
- rup->suspendexp=0;
- freesstring(rup->suspendreason);
- rup->suspendreason=0;
- }
-
- if (UIsNeedAuth(rup))
- rup->flags&=~(QUFLAG_NEEDAUTH);
- csdb_updateuser(rup);
-
- if (UIsDelayedGline(rup)) {
- /* delayed-gline - schedule the user's squelching */
- deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
- scheduleoneshot(time(NULL)+rand()%900, &chanservdgline, (void*)rup);
- }
- else if (UIsGline(rup)) {
- /* instant-gline - lets be lazy and set a schedule expiring now :) */
- deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
- scheduleoneshot(time(NULL), &chanservdgline, (void*)rup);
- }
- else if (UIsSuspended(rup)) {
- /* plain suspend */
- chanservstdmessage(sender, QM_AUTHSUSPENDED);
- chanservstdmessage(sender, QM_REASON, rup->suspendreason->content);
- if (rup->suspendexp) {
- struct tm* tmp;
- char buf[200];
-
- tmp=gmtime(&(rup->suspendexp));
- strftime(buf, 15, "%d/%m/%y %H:%M", tmp);
- chanservstdmessage(sender, QM_EXPIRES, buf);
- }
- return CMD_ERROR;
- }
-
- if (!UHasHelperPriv(rup) && !UIsNoAuthLimit(rup)) {
- for (nl=rup->nicks; nl; nl=nl->next)
- ucount++;
-
- if (ucount >= MAXAUTHCOUNT) {
- chanservstdmessage(sender, QM_TOOMANYAUTHS);
- return CMD_ERROR;
- }
- }
-
- chanservstdmessage(sender, QM_AUTHOK, rup->username);
- cs_log(sender,"AUTH OK username %s", rup->username);
- localusersetaccount(sender, rup->username);
-
- return CMD_OK;
-}
-
-/*
- * /msg Q REQUESTPASSWORD <account> <email>
- */
-int csa_doreqpw(void *source, int cargc, char **cargv) {
- reguser *rup;
- nick *sender=source;
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "requestpassword");
- return CMD_ERROR;
- }
-
- if (!(rup=findreguser(sender, cargv[0])))
- return CMD_ERROR;
-
- if (ircd_strcmp(cargv[1],rup->email->content)) {
- chanservstdmessage(sender, QM_BADEMAIL, rup->username);
- cs_log(sender,"REQUESTPASSWORD FAIL wrong email, username %s email %s",rup->username,cargv[1]);
- return CMD_ERROR;
- }
-
- if (csa_checkthrottled(sender, rup, "REQUESTPASSWORD"))
- return CMD_ERROR;
-
- rup->lastemailchange=time(NULL);
- csdb_updateuser(rup);
- csdb_createmail(rup, QMAIL_REQPW);
- chanservstdmessage(sender, QM_MAILQUEUED, rup->username);
- cs_log(sender,"REQUESTPASSWORD OK username %s email %s", rup->username,rup->email->content);
-
- return CMD_OK;
-}
-
-/*
- * /msg Q NEWPASS <master password> <new password> <new password>
- */
-int csa_donewpw(void *source, int cargc, char **cargv) {
- reguser *rup;
- nick *sender=source;
-
- if (cargc<3) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "newpass");
- return CMD_ERROR;
- }
-
- if (!(rup=getreguserfromnick(sender)))
- return CMD_ERROR;
-
- if (!checkmasterpassword(rup, cargv[0])) {
- chanservstdmessage(sender, QM_AUTHFAIL);
- cs_log(sender,"NEWPASS FAIL username %s bad masterpassword %s",rup->username,cargv[0]);
- return CMD_ERROR;
- }
-
- if (strcmp(cargv[1],cargv[2])) {
- chanservstdmessage(sender, QM_PWDONTMATCH); /* Sorry, passwords do not match */
- cs_log(sender,"NEWPASS FAIL username %s new passwords don't match (%s vs %s)",rup->username,cargv[1],cargv[2]);
- return CMD_ERROR;
- }
-
- if (strlen(cargv[1]) < 6) {
- chanservstdmessage(sender, QM_PWTOSHORT); /* new password to short */
- cs_log(sender,"NEWPASS FAIL username %s password to short %s (%d characters)",rup->username,cargv[1],strlen(cargv[1]));
- return CMD_ERROR;
- }
-
- setpassword(rup, cargv[1]);
- rup->lastauth=time(NULL);
- chanservstdmessage(sender, QM_PWCHANGED);
- cs_log(sender,"NEWPASS OK username %s", rup->username);
- csdb_updateuser(rup);
- csdb_createmail(rup, QMAIL_NEWPW);
-
- return CMD_OK;
-}
-
-/*
- * /msg Q REQUESTMASTERPASSWORD
- */
-int csa_doreqmasterpw(void *source, int cargc, char **cargv) {
- reguser *rup;
- nick *sender=source;
-
- if (!(rup=getreguserfromnick(sender)))
- return CMD_ERROR;
-
- if (csa_checkthrottled(sender, rup, "REQUESTMASTERPASSWORD"))
- return CMD_ERROR;
-
- csa_createrandompw(rup->masterpass, PASSLEN);
- chanservstdmessage(sender, QM_MASTERPWCHANGED);
- cs_log(sender,"REQUESTMASTERPASSWORD OK username %s",rup->username);
- csdb_updateuser(rup);
- csdb_createmail(rup, QMAIL_NEWMASTERPW);
-
- return CMD_OK;
-}
-
-/*
- * /msg Q EMAIL <master password> <email address> <email address>
- */
-int csa_doemail(void *source, int cargc, char **cargv) {
- reguser *rup;
- nick *sender=source;
-
- if (cargc<3) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "email");
- return CMD_ERROR;
- }
-
- if (!(rup=getreguserfromnick(sender)))
- return CMD_ERROR;
-
- if (!checkmasterpassword(rup, cargv[0])) {
- chanservstdmessage(sender, QM_AUTHFAIL);
- cs_log(sender,"EMAIL FAIL username %s bad masterpass %s",rup->username,cargv[0]);
- return CMD_ERROR;
- }
-
- if (strcmp(cargv[1],cargv[2])) {
- chanservstdmessage(sender, QM_EMAILDONTMATCH);
- cs_log(sender,"EMAIL FAIL username %s email don't match (%s vs %s)",rup->username,cargv[1],cargv[2]);
- return CMD_ERROR;
- }
-
- if (csa_checkeboy(sender, cargv[1]))
- return CMD_ERROR;
-
-// rup2->ID = rup->ID;
-// rup2->email=getsstring(rup->email->content,EMAILLEN); /* save previous email addy */
-
- csdb_createmail(rup, QMAIL_NEWEMAIL);
- freesstring(rup->email);
- rup->email=getsstring(cargv[1],EMAILLEN);
- rup->lastemailchange=time(NULL);
- chanservstdmessage(sender, QM_EMAILCHANGED, cargv[1]);
- cs_log(sender,"EMAIL OK username %s",rup->username);
- csdb_updateuser(rup);
-
- return CMD_OK;
-}
-
-/*
- * /msg Q SETPASSWORD <account> <new password>
- */
-int csa_dosetpw(void *source, int cargc, char **cargv) {
- reguser *rup;
- nick *sender=source;
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "setpassword");
- return CMD_ERROR;
- }
-
- if (!(rup=findreguser(sender, cargv[0])))
- return CMD_ERROR;
-
- strncpy(rup->password,cargv[1],PASSLEN);
- rup->password[PASSLEN]='\0';
- chanservstdmessage(sender, QM_PWCHANGED);
- cs_log(sender,"SETPASSWORD OK username %s",rup->username);
- csdb_updateuser(rup);
-
- return CMD_OK;
-}
-
-/*
- * /msg Q SETEMAIL <account> <email address>
- */
-int csa_dosetmail(void *source, int cargc, char **cargv) {
- reguser *rup;
- nick *sender=source;
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "setemail");
- return CMD_ERROR;
- }
-
- if (!(rup=findreguser(sender, cargv[0])))
- return CMD_ERROR;
-
- if (csa_checkeboy(sender, cargv[1]))
- return CMD_ERROR;
-
- freesstring(rup->email);
- rup->email=getsstring(cargv[1],EMAILLEN);
- rup->lastemailchange=time(NULL);
- chanservstdmessage(sender, QM_EMAILCHANGED, cargv[1]);
- cs_log(sender,"SETEMAIL OK username %s <%s>",rup->username,rup->email->content);
- csdb_updateuser(rup);
-
- return CMD_OK;
-}
-
-/*
- * /msg Q SETMASTERPASSWORD <account>
- */
-int csa_dosetmasterpw(void *source, int cargc, char **cargv) {
- reguser *rup;
- nick *sender=source;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "setmasterpassword");
- return CMD_ERROR;
- }
-
- if (!(rup=findreguser(sender, cargv[0])))
- return CMD_ERROR;
-
- csa_createrandompw(rup->masterpass, PASSLEN);
- chanservstdmessage(sender, QM_MASTERPWCHANGED);
- cs_log(sender,"SETMASTERPASSWORD OK username %s",rup->username);
- csdb_updateuser(rup);
-
- return CMD_OK;
-}
--- /dev/null
+# Automatically generated Makefile, do not edit.
+
+.PHONY: all Makefile
+all: Makefile chanserv_authcmds.so
+
+Makefile:
+ ../mkcommandlist.pl chanserv_authcmds.so
+
+chanserv_authcmds.so: auth.o email.o hello.o login.o newpass.o requestmasterpassword.o requestpassword.o setemail.o setmasterpassword.o setpassword.o commandlist.o
+ ld -shared -Bdynamic -o $@ $^
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: auth
+ * CMDLEVEL: QCMD_ALIAS | QCMD_SECURE | QCMD_NOTAUTHED
+ * CMDARGS: 2
+ * CMDDESC: Authenticates you on the bot.
+ * CMDFUNC: csa_doauth
+ * CMDPROTO: int csa_doauth(void *source, int cargc, char **cargv);
+ */
+
+/* Actual function is in login.c */
--- /dev/null
+/* Automatically generated by mkcommandlist.pl, do not edit. */
+
+#include "../chanserv.h"
+
+/* Prototypes */
+int csa_doauth(void *source, int cargc, char **cargv);
+int csa_doemail(void *source, int cargc, char **cargv);
+int csa_dohello(void *source, int cargc, char **cargv);
+int csa_doauth(void *source, int cargc, char **cargv);
+int csa_donewpw(void *source, int cargc, char **cargv);
+int csa_doreqmasterpw(void *source, int cargc, char **cargv);
+int csa_doreqpw(void *source, int cargc, char **cargv);
+int csa_dosetmail(void *source, int cargc, char **cargv);
+int csa_dosetmasterpw(void *source, int cargc, char **cargv);
+int csa_dosetpw(void *source, int cargc, char **cargv);
+
+void _init() {
+ chanservaddcommand("auth", QCMD_ALIAS | QCMD_SECURE | QCMD_NOTAUTHED, 2, csa_doauth, "Authenticates you on the bot.");
+ chanservaddcommand("email", QCMD_AUTHED, 3, csa_doemail, "Change your email address.");
+ chanservaddcommand("hello", QCMD_NOTAUTHED, 2, csa_dohello, "Creates a new user account.");
+ chanservaddcommand("login", QCMD_SECURE | QCMD_NOTAUTHED, 2, csa_doauth, "Authenticates you on the bot.");
+ chanservaddcommand("newpass", QCMD_AUTHED, 3, csa_donewpw, "Change your password.");
+ chanservaddcommand("requestmasterpassword", QCMD_AUTHED, 1, csa_doreqmasterpw, "Requests a new master password by email.");
+ chanservaddcommand("requestpassword", QCMD_NOTAUTHED, 2, csa_doreqpw, "Requests the current password by email.");
+ chanservaddcommand("setemail", QCMD_OPER, 2, csa_dosetmail, "Set the email address.");
+ chanservaddcommand("setmasterpassword", QCMD_OPER, 2, csa_dosetmasterpw, "Set the master password.");
+ chanservaddcommand("setpassword", QCMD_OPER, 2, csa_dosetpw, "Set a new password.");
+}
+
+void _fini() {
+ chanservremovecommand("auth", csa_doauth);
+ chanservremovecommand("email", csa_doemail);
+ chanservremovecommand("hello", csa_dohello);
+ chanservremovecommand("login", csa_doauth);
+ chanservremovecommand("newpass", csa_donewpw);
+ chanservremovecommand("requestmasterpassword", csa_doreqmasterpw);
+ chanservremovecommand("requestpassword", csa_doreqpw);
+ chanservremovecommand("setemail", csa_dosetmail);
+ chanservremovecommand("setmasterpassword", csa_dosetmasterpw);
+ chanservremovecommand("setpassword", csa_dosetpw);
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: email
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 3
+ * CMDDESC: Change your email address.
+ * CMDFUNC: csa_doemail
+ * CMDPROTO: int csa_doemail(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../authlib.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csa_doemail(void *source, int cargc, char **cargv) {
+ reguser *rup;
+ nick *sender=source;
+
+ if (cargc<3) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "email");
+ return CMD_ERROR;
+ }
+
+ if (!(rup=getreguserfromnick(sender)))
+ return CMD_ERROR;
+
+ if (!checkmasterpassword(rup, cargv[0])) {
+ chanservstdmessage(sender, QM_AUTHFAIL);
+ cs_log(sender,"EMAIL FAIL username %s bad masterpass %s",rup->username,cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (strcmp(cargv[1],cargv[2])) {
+ chanservstdmessage(sender, QM_EMAILDONTMATCH);
+ cs_log(sender,"EMAIL FAIL username %s email don't match (%s vs %s)",rup->username,cargv[1],cargv[2]);
+ return CMD_ERROR;
+ }
+
+ if (csa_checkeboy(sender, cargv[1]))
+ return CMD_ERROR;
+
+// rup2->ID = rup->ID;
+// rup2->email=getsstring(rup->email->content,EMAILLEN); /* save previous email addy */
+
+ csdb_createmail(rup, QMAIL_NEWEMAIL);
+ freesstring(rup->email);
+ rup->email=getsstring(cargv[1],EMAILLEN);
+ rup->lastemailchange=time(NULL);
+ chanservstdmessage(sender, QM_EMAILCHANGED, cargv[1]);
+ cs_log(sender,"EMAIL OK username %s",rup->username);
+ csdb_updateuser(rup);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: hello
+ * CMDLEVEL: QCMD_NOTAUTHED
+ * CMDARGS: 2
+ * CMDDESC: Creates a new user account.
+ * CMDFUNC: csa_dohello
+ * CMDPROTO: int csa_dohello(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../authlib.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csa_dohello(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup;
+ char userhost[USERLEN+HOSTLEN+2];
+
+ if (getreguserfromnick(sender))
+ return CMD_ERROR;
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "hello");
+ return CMD_ERROR;
+ }
+
+ if (findreguserbynick(sender->nick)) {
+ chanservstdmessage(sender, QM_AUTHNAMEINUSE, sender->nick);
+ return CMD_ERROR;
+ }
+
+ if (strcmp(cargv[0],cargv[1])) {
+ chanservstdmessage(sender, QM_EMAILDONTMATCH);
+ cs_log(sender,"HELLO FAIL username %s email don't match (%s vs %s)",sender->nick,cargv[0],cargv[1]);
+ return CMD_ERROR;
+ }
+
+ if (csa_checkeboy(sender, cargv[0]))
+ return CMD_ERROR;
+
+ rup=getreguser();
+ rup->status=0;
+ rup->ID=++lastuserID;
+ strncpy(rup->username,sender->nick,NICKLEN); rup->username[NICKLEN]='\0';
+ rup->created=time(NULL);
+ rup->lastauth=time(NULL);
+ rup->lastemailchange=time(NULL);
+ rup->flags=QUFLAG_NOTICE;
+ rup->languageid=0;
+ rup->suspendby=0;
+ rup->suspendexp=0;
+ rup->password[0]='\0';
+ rup->masterpass[0]='\0';
+ rup->email=getsstring(cargv[0],EMAILLEN);
+ rup->info=NULL;
+ sprintf(userhost,"%s@%s",sender->ident,sender->host->name->content);
+ rup->lastuserhost=getsstring(userhost,USERLEN+HOSTLEN+1);
+ rup->suspendreason=NULL;
+ rup->comment=NULL;
+ rup->knownon=NULL;
+ rup->checkshd=NULL;
+ rup->stealcount=0;
+ rup->fakeuser=NULL;
+ rup->nicks=NULL;
+ addregusertohash(rup);
+ csa_createrandompw(rup->password, PASSLEN);
+ csa_createrandompw(rup->masterpass, PASSLEN);
+ chanservstdmessage(sender, QM_NEWACCOUNT, rup->username,rup->email->content);
+ cs_log(sender,"HELLO OK created auth %s (%s)",rup->username,rup->email->content);
+ csdb_createuser(rup);
+ csdb_createmail(rup, QMAIL_NEWACCOUNT);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: login
+ * CMDLEVEL: QCMD_SECURE | QCMD_NOTAUTHED
+ * CMDARGS: 2
+ * CMDDESC: Authenticates you on the bot.
+ * CMDFUNC: csa_doauth
+ * CMDPROTO: int csa_doauth(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../authlib.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csa_doauth(void *source, int cargc, char **cargv) {
+ reguser *rup;
+ activeuser* aup;
+ nick *sender=source;
+ nicklist *nl = NULL;
+ char userhost[USERLEN+HOSTLEN+2];
+ int ucount=0;
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "auth");
+ return CMD_ERROR;
+ }
+
+ if (!(aup = getactiveuserfromnick(sender)))
+ return CMD_ERROR;
+
+ aup->authattempts++;
+ if (aup->authattempts > MAXAUTHATTEMPT) {
+ if ((aup->authattempts % 100) == 0)
+ chanservwallmessage("Warning: User %s!%s@%s attempted to auth %d times. Last attempt: AUTH %s %s",
+ nl->np->nick, nl->np->ident, nl->np->host->name->content, cargv[0], cargv[1]);
+ chanservstdmessage(sender, QM_AUTHFAIL);
+ cs_log(sender,"AUTH FAIL too many auth attempts (last attempt: AUTH %s %s)",cargv[0], cargv[1]);
+ return CMD_ERROR;
+ }
+
+ if (!(rup=findreguserbynick(cargv[0]))) {
+ chanservstdmessage(sender, QM_AUTHFAIL);
+ cs_log(sender,"AUTH FAIL bad username %s",cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (!checkpassword(rup, cargv[1])) {
+ chanservstdmessage(sender, QM_AUTHFAIL);
+ cs_log(sender,"AUTH FAIL username %s bad password %s",rup->username,cargv[1]);
+ return CMD_ERROR;
+ }
+
+ rup->lastauth=time(NULL);
+ sprintf(userhost,"%s@%s",sender->ident,sender->host->name->content);
+ if (rup->lastuserhost)
+ freesstring(rup->lastuserhost);
+ rup->lastuserhost=getsstring(userhost,USERLEN+HOSTLEN+1);
+
+ if (UHasSuspension(rup) && rup->suspendexp && (time(0) >= rup->suspendexp)) {
+ /* suspension has expired, remove it */
+ rup->flags&=(~(QUFLAG_SUSPENDED|QUFLAG_GLINE|QUFLAG_DELAYEDGLINE));
+ rup->suspendby=0;
+ rup->suspendexp=0;
+ freesstring(rup->suspendreason);
+ rup->suspendreason=0;
+ }
+
+ if (UIsNeedAuth(rup))
+ rup->flags&=~(QUFLAG_NEEDAUTH);
+ csdb_updateuser(rup);
+
+ if (UIsDelayedGline(rup)) {
+ /* delayed-gline - schedule the user's squelching */
+ deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
+ scheduleoneshot(time(NULL)+rand()%900, &chanservdgline, (void*)rup);
+ }
+ else if (UIsGline(rup)) {
+ /* instant-gline - lets be lazy and set a schedule expiring now :) */
+ deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
+ scheduleoneshot(time(NULL), &chanservdgline, (void*)rup);
+ }
+ else if (UIsSuspended(rup)) {
+ /* plain suspend */
+ chanservstdmessage(sender, QM_AUTHSUSPENDED);
+ chanservstdmessage(sender, QM_REASON, rup->suspendreason->content);
+ if (rup->suspendexp) {
+ struct tm* tmp;
+ char buf[200];
+
+ tmp=gmtime(&(rup->suspendexp));
+ strftime(buf, 15, "%d/%m/%y %H:%M", tmp);
+ chanservstdmessage(sender, QM_EXPIRES, buf);
+ }
+ return CMD_ERROR;
+ }
+
+ if (!UHasHelperPriv(rup) && !UIsNoAuthLimit(rup)) {
+ for (nl=rup->nicks; nl; nl=nl->next)
+ ucount++;
+
+ if (ucount >= MAXAUTHCOUNT) {
+ chanservstdmessage(sender, QM_TOOMANYAUTHS);
+ return CMD_ERROR;
+ }
+ }
+
+ chanservstdmessage(sender, QM_AUTHOK, rup->username);
+ cs_log(sender,"AUTH OK username %s", rup->username);
+ localusersetaccount(sender, rup->username);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: newpass
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 3
+ * CMDDESC: Change your password.
+ * CMDFUNC: csa_donewpw
+ * CMDPROTO: int csa_donewpw(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../authlib.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csa_donewpw(void *source, int cargc, char **cargv) {
+ reguser *rup;
+ nick *sender=source;
+
+ if (cargc<3) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "newpass");
+ return CMD_ERROR;
+ }
+
+ if (!(rup=getreguserfromnick(sender)))
+ return CMD_ERROR;
+
+ if (!checkmasterpassword(rup, cargv[0])) {
+ chanservstdmessage(sender, QM_AUTHFAIL);
+ cs_log(sender,"NEWPASS FAIL username %s bad masterpassword %s",rup->username,cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (strcmp(cargv[1],cargv[2])) {
+ chanservstdmessage(sender, QM_PWDONTMATCH); /* Sorry, passwords do not match */
+ cs_log(sender,"NEWPASS FAIL username %s new passwords don't match (%s vs %s)",rup->username,cargv[1],cargv[2]);
+ return CMD_ERROR;
+ }
+
+ if (strlen(cargv[1]) < 6) {
+ chanservstdmessage(sender, QM_PWTOSHORT); /* new password to short */
+ cs_log(sender,"NEWPASS FAIL username %s password to short %s (%d characters)",rup->username,cargv[1],strlen(cargv[1]));
+ return CMD_ERROR;
+ }
+
+ setpassword(rup, cargv[1]);
+ rup->lastauth=time(NULL);
+ chanservstdmessage(sender, QM_PWCHANGED);
+ cs_log(sender,"NEWPASS OK username %s", rup->username);
+ csdb_updateuser(rup);
+ csdb_createmail(rup, QMAIL_NEWPW);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: requestmasterpassword
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Requests a new master password by email.
+ * CMDFUNC: csa_doreqmasterpw
+ * CMDPROTO: int csa_doreqmasterpw(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../authlib.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csa_doreqmasterpw(void *source, int cargc, char **cargv) {
+ reguser *rup;
+ nick *sender=source;
+
+ if (!(rup=getreguserfromnick(sender)))
+ return CMD_ERROR;
+
+ if (csa_checkthrottled(sender, rup, "REQUESTMASTERPASSWORD"))
+ return CMD_ERROR;
+
+ csa_createrandompw(rup->masterpass, PASSLEN);
+ chanservstdmessage(sender, QM_MASTERPWCHANGED);
+ cs_log(sender,"REQUESTMASTERPASSWORD OK username %s",rup->username);
+ csdb_updateuser(rup);
+ csdb_createmail(rup, QMAIL_NEWMASTERPW);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: requestpassword
+ * CMDLEVEL: QCMD_NOTAUTHED
+ * CMDARGS: 2
+ * CMDDESC: Requests the current password by email.
+ * CMDFUNC: csa_doreqpw
+ * CMDPROTO: int csa_doreqpw(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../authlib.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csa_doreqpw(void *source, int cargc, char **cargv) {
+ reguser *rup;
+ nick *sender=source;
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "requestpassword");
+ return CMD_ERROR;
+ }
+
+ if (!(rup=findreguser(sender, cargv[0])))
+ return CMD_ERROR;
+
+ if (ircd_strcmp(cargv[1],rup->email->content)) {
+ chanservstdmessage(sender, QM_BADEMAIL, rup->username);
+ cs_log(sender,"REQUESTPASSWORD FAIL wrong email, username %s email %s",rup->username,cargv[1]);
+ return CMD_ERROR;
+ }
+
+ if (csa_checkthrottled(sender, rup, "REQUESTPASSWORD"))
+ return CMD_ERROR;
+
+ rup->lastemailchange=time(NULL);
+ csdb_updateuser(rup);
+ csdb_createmail(rup, QMAIL_REQPW);
+ chanservstdmessage(sender, QM_MAILQUEUED, rup->username);
+ cs_log(sender,"REQUESTPASSWORD OK username %s email %s", rup->username,rup->email->content);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: setemail
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 2
+ * CMDDESC: Set the email address.
+ * CMDFUNC: csa_dosetmail
+ * CMDPROTO: int csa_dosetmail(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../authlib.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csa_dosetmail(void *source, int cargc, char **cargv) {
+ reguser *rup;
+ nick *sender=source;
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "setemail");
+ return CMD_ERROR;
+ }
+
+ if (!(rup=findreguser(sender, cargv[0])))
+ return CMD_ERROR;
+
+ if (csa_checkeboy(sender, cargv[1]))
+ return CMD_ERROR;
+
+ freesstring(rup->email);
+ rup->email=getsstring(cargv[1],EMAILLEN);
+ rup->lastemailchange=time(NULL);
+ chanservstdmessage(sender, QM_EMAILCHANGED, cargv[1]);
+ cs_log(sender,"SETEMAIL OK username %s <%s>",rup->username,rup->email->content);
+ csdb_updateuser(rup);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: setmasterpassword
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 2
+ * CMDDESC: Set the master password.
+ * CMDFUNC: csa_dosetmasterpw
+ * CMDPROTO: int csa_dosetmasterpw(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../authlib.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csa_dosetmasterpw(void *source, int cargc, char **cargv) {
+ reguser *rup;
+ nick *sender=source;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "setmasterpassword");
+ return CMD_ERROR;
+ }
+
+ if (!(rup=findreguser(sender, cargv[0])))
+ return CMD_ERROR;
+
+ csa_createrandompw(rup->masterpass, PASSLEN);
+ chanservstdmessage(sender, QM_MASTERPWCHANGED);
+ cs_log(sender,"SETMASTERPASSWORD OK username %s",rup->username);
+ csdb_updateuser(rup);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: setpassword
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 2
+ * CMDDESC: Set a new password.
+ * CMDFUNC: csa_dosetpw
+ * CMDPROTO: int csa_dosetpw(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../authlib.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csa_dosetpw(void *source, int cargc, char **cargv) {
+ reguser *rup;
+ nick *sender=source;
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "setpassword");
+ return CMD_ERROR;
+ }
+
+ if (!(rup=findreguser(sender, cargv[0])))
+ return CMD_ERROR;
+
+ strncpy(rup->password,cargv[1],PASSLEN);
+ rup->password[PASSLEN]='\0';
+ chanservstdmessage(sender, QM_PWCHANGED);
+ cs_log(sender,"SETPASSWORD OK username %s",rup->username);
+ csdb_updateuser(rup);
+
+ return CMD_OK;
+}
}
pw[n] = '\0';
}
+
+/*
+ * check if account is "throttled"
+ */
+int csa_checkthrottled(nick *sender, reguser *rup, char *s)
+{
+ time_t now;
+ long d;
+ float t;
+
+ now=time(NULL);
+ d=MAX_RESEND_TIME+rup->lastemailchange-now;
+
+ if (d>MAX_RESEND_TIME)
+ d=MAX_RESEND_TIME;
+
+ if (d>0L) {
+ t = ((float) d) / ((float) 3600);
+ chanservstdmessage(sender, QM_MAILTHROTTLED, t);
+ cs_log(sender,"%s FAIL username %s, new request throttled for %.1f hours",s,rup->username,t);
+ return 1;
+ }
+ return 0;
+}
+++ /dev/null
-/*
- * chancmds.c:
- * Provides basic channel commands:
- * CHANLEV
- * WHOIS
- * CHANFLAGS
- * etc.
- */
-
-#include "chanserv.h"
-#include "../nick/nick.h"
-#include "../lib/flags.h"
-#include "../lib/irc_string.h"
-#include "../channel/channel.h"
-#include "../parser/parser.h"
-#include "../irc/irc.h"
-#include "../localuser/localuserchannel.h"
-
-#include <string.h>
-#include <stdio.h>
-
-int csc_dochanlev(void *source, int cargc, char **cargv);
-int csc_dochanflags(void *source, int cargc, char **cargv);
-int csc_dochanmode(void *source, int cargc, char **cargv);
-int csc_doautolimit(void *source, int cargc, char **cargv);
-int csc_dobantimer(void *source, int cargc, char **cargv);
-int csc_doaddchan(void *source, int cargc, char **cargv);
-int csc_dosuspendchan(void *source, int cargc, char **cargv);
-int csc_dosuspendchanlist(void *source, int cargc, char **cargv);
-int csc_dounsuspendchan(void *source, int cargc, char **cargv);
-int csc_dodelchan(void *source, int cargc, char **cargv);
-int csc_dorenchan(void *source, int cargc, char **cargv);
-int csc_dowelcome(void *source, int cargc, char **cargv);
-int csc_doinvite(void *source, int cargc, char **cargv);
-int csc_doop(void *source, int cargc, char **cargv);
-int csc_dovoice(void *source, int cargc, char **cargv);
-int csc_dodeopall(void *source, int cargc, char **cargv);
-int csc_dounbanall(void *source, int cargc, char **cargv);
-int csc_doclearchan(void *source, int cargc, char **cargv);
-int csc_dorecover(void *source, int cargc, char **cargv);
-int csc_dounbanme(void *source, int cargc, char **cargv);
-int csc_dodevoiceall(void *source, int cargc, char **cargv);
-int csc_dosettopic(void *source, int cargc, char **cargv);
-int csc_dopermban(void *source, int cargc, char **cargv);
-int csc_dotempban(void *source, int cargc, char **cargv);
-int csc_dobanlist(void *source, int cargc, char **cargv);
-int csc_dounbanmask(void *source, int cargc, char **cargv);
-int csc_dobandel(void *source, int cargc, char **cargv);
-int csc_dochannelcomment(void *source, int cargc, char **cargv);
-int csc_dorejoin(void *source, int cargc, char **cargv);
-int csc_doadduser(void *source, int cargc, char **cargv);
-int csc_doremoveuser(void *source, int cargc, char **cargv);
-int csc_dobanclear(void *source, int cargc, char **cargv);
-int csc_dochantype(void *source, int cargc, char **cargv);
-int csc_dochanstat(void *source, int cargc, char **cargv);
-
-char *getchanmode(regchan *rcp);
-
-void _init() {
- chanservaddcommand("chanflags", QCMD_AUTHED, 2, csc_dochanflags, "Shows or changes the flags on a channel.");
- chanservaddcommand("chanmode", QCMD_AUTHED, 4, csc_dochanmode, "Shows which modes are forced or denied on a channel.");
- chanservaddcommand("chanlev", QCMD_AUTHED, 3, csc_dochanlev, "Shows or modifies user access on a channel.");
- chanservaddcommand("autolimit", QCMD_AUTHED, 2, csc_doautolimit, "Shows or changes the autolimit threshold on a channel.");
- chanservaddcommand("bantimer", QCMD_AUTHED, 2, csc_dobantimer, "Shows or changes the time after which bans are removed.");
- chanservaddcommand("addchan", QCMD_OPER, 4, csc_doaddchan, "Adds a new channel to the bot.");
- chanservaddcommand("suspendchan", QCMD_OPER, 2, csc_dosuspendchan, "Suspends a channel from the bot.");
- chanservaddcommand("suspendchanlist", QCMD_HELPER, 1, csc_dosuspendchanlist, "Lists suspended channels.");
- chanservaddcommand("unsuspendchan", QCMD_OPER, 1, csc_dounsuspendchan, "Unsuspends a channel from the bot.");
- chanservaddcommand("delchan", QCMD_OPER, 2, csc_dodelchan, "Removes a channel from the bot.");
- chanservaddcommand("renchan", QCMD_OPER, 2, csc_dorenchan, "Renames a channel on the bot.");
- chanservaddcommand("welcome", QCMD_AUTHED, 2, csc_dowelcome, "Shows or changes the welcome message on a channel.");
- chanservaddcommand("invite", QCMD_AUTHED, 1, csc_doinvite, "Invites you to a channel.");
- chanservaddcommand("op", QCMD_AUTHED, 20,csc_doop, "Ops you or other users on channel(s).");
- chanservaddcommand("voice", QCMD_AUTHED, 20,csc_dovoice, "Voices you or other users on channel(s).");
- chanservaddcommand("deopall", QCMD_AUTHED, 1, csc_dodeopall, "Deops all users on channel.");
- chanservaddcommand("devoiceall",QCMD_AUTHED, 1, csc_dodevoiceall,"Devoices all users on a channel.");
- chanservaddcommand("unbanall", QCMD_AUTHED, 1, csc_dounbanall, "Removes all bans from a channel.");
- chanservaddcommand("unbanme", QCMD_AUTHED, 1, csc_dounbanme, "Removes any bans affecting you from a channel.");
- chanservaddcommand("clearchan", QCMD_AUTHED, 1, csc_doclearchan, "Removes all modes from a channel.");
- chanservaddcommand("recover", QCMD_AUTHED, 1, csc_dorecover, "Recovers a channel (same as deopall, unbanall, clearchan).");
- chanservaddcommand("settopic", QCMD_AUTHED, 2, csc_dosettopic, "Changes the topic on a channel.");
- chanservaddcommand("permban", QCMD_AUTHED, 3, csc_dopermban, "Permanently bans a hostmask on a channel.");
- chanservaddcommand("tempban", QCMD_AUTHED, 4, csc_dotempban, "Bans a hostmask on a channel for a specified time period.");
- chanservaddcommand("banlist", QCMD_AUTHED, 1, csc_dobanlist, "Displays all persistent bans on a channel.");
- chanservaddcommand("unbanmask", QCMD_AUTHED, 2, csc_dounbanmask, "Removes bans matching a particular mask from a channel.");
- chanservaddcommand("bandel", QCMD_AUTHED, 2, csc_dobandel, "Removes a single ban from a channel.");
- chanservaddcommand("banclear", QCMD_AUTHED, 1, csc_dobanclear, "Removes all bans from a channel including persistent bans.");
- chanservaddcommand("channelcomment",QCMD_OPER,2,csc_dochannelcomment,"Shows or changes the staff comment for a channel.");
- chanservaddcommand("rejoin", QCMD_OPER, 1, csc_dorejoin, "Makes the bot rejoin a channel.");
- chanservaddcommand("adduser", QCMD_AUTHED, 20,csc_doadduser, "Adds one or more users to a channel as +aot.");
- chanservaddcommand("removeuser",QCMD_AUTHED, 20,csc_doremoveuser,"Removes one or more users from a channel.");
- chanservaddcommand("chantype", QCMD_OPER, 2,csc_dochantype, "Shows or changes a channel's type.");
- chanservaddcommand("chanstat", QCMD_AUTHED, 1,csc_dochanstat, "Displays channel activity statistics.");
-}
-
-void _fini() {
- chanservremovecommand("chanflags", csc_dochanflags);
- chanservremovecommand("chanmode", csc_dochanmode);
- chanservremovecommand("chanlev", csc_dochanlev);
- chanservremovecommand("autolimit", csc_doautolimit);
- chanservremovecommand("bantimer", csc_dobantimer);
- chanservremovecommand("addchan", csc_doaddchan);
- chanservremovecommand("suspendchan",csc_dosuspendchan);
- chanservremovecommand("suspendchanlist",csc_dosuspendchanlist);
- chanservremovecommand("unsuspendchan",csc_dounsuspendchan);
- chanservremovecommand("delchan", csc_dodelchan);
- chanservremovecommand("renchan", csc_dorenchan);
- chanservremovecommand("welcome", csc_dowelcome);
- chanservremovecommand("invite", csc_doinvite);
- chanservremovecommand("op", csc_doop);
- chanservremovecommand("voice", csc_dovoice);
- chanservremovecommand("deopall", csc_dodeopall);
- chanservremovecommand("devoiceall",csc_dodevoiceall);
- chanservremovecommand("unbanall", csc_dounbanall);
- chanservremovecommand("unbanme", csc_dounbanme);
- chanservremovecommand("clearchan", csc_doclearchan);
- chanservremovecommand("recover", csc_dorecover);
- chanservremovecommand("settopic", csc_dosettopic);
- chanservremovecommand("permban", csc_dopermban);
- chanservremovecommand("tempban", csc_dotempban);
- chanservremovecommand("banlist", csc_dobanlist);
- chanservremovecommand("unbanmask", csc_dounbanmask);
- chanservremovecommand("bandel", csc_dobandel);
- chanservremovecommand("banclear", csc_dobanclear);
- chanservremovecommand("channelcomment",csc_dochannelcomment);
- chanservremovecommand("rejoin", csc_dorejoin);
- chanservremovecommand("adduser", csc_doadduser);
- chanservremovecommand("removeuser",csc_doremoveuser);
- chanservremovecommand("chantype", csc_dochantype);
- chanservremovecommand("chanstat", csc_dochanstat);
-}
-
-int csc_dochanflags(void *source, int cargc, char **cargv) {
- regchan *rcp;
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- chanindex *cip;
- flag_t oldflags,changemask;
- char flagbuf[20];
-
- if (cargc<1) {
- chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanflags");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL,
- "chanflags", QPRIV_VIEWCHANFLAGS, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cargc>1) {
- if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, "chanflags",
- QPRIV_CHANGECHANFLAGS, 0))
- return CMD_ERROR;
-
- oldflags=rcp->flags;
- changemask=QCFLAG_USERCONTROL;
- if (UIsDev(rup)) {
- changemask=QCFLAG_ALL;
- }
- setflags(&rcp->flags, changemask, cargv[1], rcflags, REJECT_NONE);
-
- /* We might need to do things in response to the flag changes.. */
- if (cip->channel) {
- if ((oldflags ^ rcp->flags) & (QCFLAG_JOINED | QCFLAG_SUSPENDED)) {
- chanservjoinchan(cip->channel);
- rcp->status |= (QCSTAT_OPCHECK | QCSTAT_MODECHECK | QCSTAT_BANCHECK);
- rcp->lastbancheck=0;
- cs_timerfunc(cip);
- } else {
- if (CIsEnforce(rcp)) {
- rcp->lastbancheck=0;
- cs_checkbans(cip->channel);
- }
-
- if (CIsProtect(rcp) || CIsBitch(rcp) || CIsAutoOp(rcp) || CIsAutoVoice(rcp) || CIsKnownOnly(rcp)) {
- rcp->status |= QCSTAT_OPCHECK;
- cs_timerfunc(cip);
- }
- }
- }
-
- if (CIsAutoLimit(rcp) && !(oldflags & QCFLAG_AUTOLIMIT)) {
- rcp->forcemodes |= CHANMODE_LIMIT;
- rcp->denymodes &= ~CHANMODE_LIMIT;
- rcp->limit=0;
- cs_timerfunc(cip);
- }
-
- if (!CIsAutoLimit(rcp) && (oldflags & QCFLAG_AUTOLIMIT)) {
- rcp->forcemodes &= ~CHANMODE_LIMIT;
- if (cip->channel)
- cs_checkchanmodes(cip->channel);
- }
-
- strcpy(flagbuf,printflags(oldflags, rcflags));
- cs_log(sender,"CHANFLAGS %s %s (%s -> %s)",cip->name->content,cargv[1],flagbuf,printflags(rcp->flags,rcflags));
- chanservstdmessage(sender, QM_DONE);
- csdb_updatechannel(rcp);
- }
-
- chanservstdmessage(sender,QM_CURCHANFLAGS,cip->name->content,printflags(rcp->flags, rcflags));
- return CMD_OK;
-}
-
-int csc_dochanmode(void *source, int cargc, char **cargv) {
- regchan *rcp;
- nick *sender=source;
- chanindex *cip;
- flag_t forceflags,denyflags;
- char buf1[60];
- int carg=2,limdone=0;
- sstring *newkey=NULL;
- unsigned int newlim=0;
-
- if (cargc<1) {
- chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV,
- NULL, "chanmode", QPRIV_VIEWCHANMODES, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cargc>1) {
- if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV,
- cip, "chanmode", QPRIV_CHANGECHANMODES, 0))
- return CMD_ERROR;
-
- /* Save the current modes.. */
- strcpy(buf1,getchanmode(rcp));
-
- /* Pick out the + flags: start from 0 */
- forceflags=0;
- setflags(&forceflags, CHANMODE_ALL, cargv[1], cmodeflags, REJECT_NONE);
-
- /* Pick out the - flags: start from everything and invert afterwards.. */
- denyflags=CHANMODE_ALL;
- setflags(&denyflags, CHANMODE_ALL, cargv[1], cmodeflags, REJECT_NONE);
- denyflags = (~denyflags) & CHANMODE_ALL;
-
- forceflags &= ~denyflags; /* Can't force and deny the same mode (shouldn't be possible anyway) */
- if (forceflags & CHANMODE_SECRET) {
- forceflags &= ~CHANMODE_PRIVATE;
- denyflags |= CHANMODE_PRIVATE;
- }
- if (forceflags & CHANMODE_PRIVATE) {
- forceflags &= ~CHANMODE_SECRET;
- denyflags |= CHANMODE_SECRET;
- }
-
- if ((forceflags & CHANMODE_LIMIT) &&
- (!(forceflags & CHANMODE_KEY) || strrchr(cargv[1],'l') < strrchr(cargv[1],'k'))) {
- if (cargc<=carg) {
- chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
- return CMD_ERROR;
- }
- newlim=strtol(cargv[carg++],NULL,10);
- limdone=1;
- }
-
- if (forceflags & CHANMODE_KEY) {
- if (cargc<=carg) {
- chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
- return CMD_ERROR;
- }
- newkey=getsstring(cargv[carg++], KEYLEN);
- }
-
- if ((forceflags & CHANMODE_LIMIT) && !limdone) {
- if (cargc<=carg) {
- chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
- return CMD_ERROR;
- }
- newlim=strtol(cargv[carg++],NULL,10);
- limdone=1;
- }
-
- if (CIsAutoLimit(rcp)) {
- forceflags |= CHANMODE_LIMIT;
- denyflags &= ~CHANMODE_LIMIT;
- newlim=rcp->limit;
- }
-
- /* It parsed OK, so update the structure.. */
- rcp->forcemodes=forceflags;
- rcp->denymodes=denyflags;
- if (rcp->key)
- freesstring(rcp->key);
- rcp->key=newkey;
- rcp->limit=newlim;
-
- chanservstdmessage(sender, QM_DONE);
- cs_log(sender,"CHANMODE %s %s (%s -> %s)",cip->name->content,cargv[1],buf1,getchanmode(rcp));
- csdb_updatechannel(rcp);
- cs_checkchanmodes(cip->channel);
- }
-
- chanservstdmessage(sender,QM_CURFORCEMODES,cip->name->content,getchanmode(rcp));
-
- return CMD_OK;
-}
-
-char *getchanmode(regchan *rcp) {
- static char buf1[50];
- char buf2[30];
-
- if (rcp->forcemodes) {
- strcpy(buf1,printflags(rcp->forcemodes, cmodeflags));
- } else {
- buf1[0]='\0';
- }
-
- strcpy(buf2,printflagdiff(CHANMODE_ALL, ~(rcp->denymodes), cmodeflags));
- strcat(buf1, buf2);
-
- if (rcp->forcemodes & CHANMODE_LIMIT) {
- sprintf(buf2, " %d",rcp->limit);
- strcat(buf1, buf2);
- }
-
- if (rcp->forcemodes & CHANMODE_KEY) {
- sprintf(buf2, " %s",rcp->key->content);
- strcat(buf1, buf2);
- }
-
- if (*buf1=='\0') {
- strcpy(buf1,"(none)");
- }
-
- return buf1;
-}
-
-int compareflags(const void *u1, const void *u2) {
- const regchanuser *r1=*(void **)u1, *r2=*(void **)u2;
- flag_t f1,f2;
-
- for (f1=QCUFLAG_OWNER;f1;f1>>=1)
- if (r1->flags & f1)
- break;
-
- for (f2=QCUFLAG_OWNER;f2;f2>>=1)
- if (r2->flags & f2)
- break;
-
- if (f1==f2) {
- return ircd_strcmp(r1->user->username, r2->user->username);
- } else {
- return f2-f1;
- }
-}
-
-int csc_dochanlev(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regchan *rcp;
- regchanuser *rcup, *rcuplist;
- regchanuser **rusers;
- reguser *rup=getreguserfromnick(sender), *target;
- char time1[15],time2[15];
- char flagbuf[30];
- struct tm *tmp;
- flag_t flagmask, changemask, flags, oldflags;
- int showtimes=0;
- int donehead=0;
- int i,j;
- int newuser=0;
- int usercount;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "chanlev");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_KNOWN,
- NULL, "chanlev", QPRIV_VIEWFULLCHANLEV, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
- rcup=findreguseronchannel(rcp, rup);
-
- /* Set flagmask for +v/+o users (can't see bans etc.) */
- flagmask = (QCUFLAG_OWNER | QCUFLAG_MASTER | QCUFLAG_OP | QCUFLAG_VOICE | QCUFLAG_AUTOVOICE |
- QCUFLAG_AUTOOP | QCUFLAG_TOPIC | QCUFLAG_SPAMCON | QCUFLAG_PROTECT | QCUFLAG_KNOWN);
-
- /* If user has +m or above, or helper access, show everything */
- if (cs_privcheck(QPRIV_VIEWFULLCHANLEV, sender) || CUHasMasterPriv(rcup)) {
- flagmask = QCUFLAG_ALL;
- showtimes=1;
- }
-
- if (cargc==1) {
- /* One arg: list chanlev */
- if (cs_privcheck(QPRIV_VIEWFULLCHANLEV, sender)) {
- reguser *founder=NULL, *addedby=NULL;
- addedby=findreguserbyID(rcp->addedby);
- chanservstdmessage(sender, QM_ADDEDBY, addedby ? addedby->username : "(unknown)");
- founder=findreguserbyID(rcp->founder);
- chanservstdmessage(sender, QM_FOUNDER, founder ? founder->username : "(unknown)");
- if (rcp->chantype) {
- chanservstdmessage(sender, QM_CHANTYPE, chantypes[rcp->chantype]->content);
- }
- }
-
- /* Count users */
- for (i=0,usercount=0;i<REGCHANUSERHASHSIZE;i++)
- for (rcuplist=rcp->regusers[i];rcuplist;rcuplist=rcuplist->nextbychan)
- usercount++;
-
- /* Allocate array */
- rusers=(regchanuser **)malloc(usercount * sizeof(regchanuser *));
-
- /* Fill array */
- for (j=i=0;i<REGCHANUSERHASHSIZE;i++) {
- for (rcuplist=rcp->regusers[i];rcuplist;rcuplist=rcuplist->nextbychan) {
- if (!(flags=rcuplist->flags & flagmask))
- continue;
-
- rusers[j++]=rcuplist;
- }
- }
-
- /* Sort */
- qsort(rusers, j, sizeof(regchanuser *), compareflags);
-
- /* List */
- for (i=0;i<j;i++) {
- rcuplist=rusers[i];
-
- if (!(flags=rcuplist->flags & flagmask))
- continue;
-
- if (!donehead) {
- chanservstdmessage(sender, QM_CHANLEVHEADER, cip->name->content);
- if (showtimes)
- chanservstdmessage(sender, QM_CHANLEVCOLFULL);
- else
- chanservstdmessage(sender, QM_CHANLEVCOLSHORT);
- donehead=1;
- }
-
- if (showtimes) {
- if (!rcuplist->usetime) {
- strcpy(time1,"Never");
- } else {
- tmp=localtime(&(rcuplist->usetime));
- strftime(time1,15,"%d/%m/%y %H:%M",tmp);
- }
- if (!rcuplist->changetime) {
- strcpy(time2, "Unknown");
- } else {
- tmp=localtime(&(rcuplist->changetime));
- strftime(time2,15,"%d/%m/%y %H:%M",tmp);
- }
- chanservsendmessage(sender, " %-15s %-13s %-14s %-14s %s", rcuplist->user->username,
- printflags(flags, rcuflags), time1, time2, rcuplist->info?rcuplist->info->content:"");
- } else
- chanservsendmessage(sender, " %-15s %s", rcuplist->user->username, printflags(flags, rcuflags));
- }
-
- if (donehead) {
- chanservstdmessage(sender, QM_ENDOFLIST);
- } else {
- chanservstdmessage(sender, QM_NOUSERSONCHANLEV, cip->name->content);
- }
-
- free(rusers);
- } else {
- /* 2 or more args.. relates to one specific user */
- if (!(target=findreguser(sender, cargv[1])))
- return CMD_ERROR; /* If there was an error, findreguser will have sent a message saying why.. */
-
- rcuplist=findreguseronchannel(rcp, target);
-
- if (cargc>2) {
- /* To change chanlev you have to either.. */
- if (!( cs_privcheck(QPRIV_CHANGECHANLEV, sender) || /* Have override privilege */
- (rcup && rcuplist && (rcup==rcuplist) && CUKnown(rcup)) || /* Be manipulting yourself (oo er..) */
- (rcup && CUHasMasterPriv(rcup) && /* Have +m or +n on the channel */
- !(rcuplist && CUIsOwner(rcuplist) && !CUIsOwner(rcup))) /* masters can't screw with owners */
- )) {
- chanservstdmessage(sender, QM_NOACCESSONCHAN, cip->name->content, "chanlev");
- return CMD_ERROR;
- }
-
- if (!rcuplist) {
- rcuplist=getregchanuser();
- rcuplist->user=target;
- rcuplist->chan=rcp;
- rcuplist->flags=0;
- rcuplist->changetime=time(NULL);
- rcuplist->usetime=0;
- rcuplist->info=NULL;
- newuser=1;
- }
-
- if (cs_privcheck(QPRIV_CHANGECHANLEV, sender)) {
- /* Opers are allowed to change everything */
- changemask = QCUFLAG_ALL;
- } else {
- changemask=0;
-
- /* Everyone can change their own flags (except +dqb), and turn +iwj on/off */
- if (rcup==rcuplist) {
- changemask = (rcup->flags | QCUFLAG_HIDEWELCOME | QCUFLAG_HIDEINFO | QCUFLAG_AUTOINVITE) &
- ~(QCUFLAG_BANNED | QCUFLAG_DENY | QCUFLAG_QUIET);
- flagmask |= (QCUFLAG_HIDEWELCOME | QCUFLAG_HIDEINFO | QCUFLAG_AUTOINVITE);
- }
-
- /* Masters are allowed to manipulate +ovagtbqdpk */
- if (CUHasMasterPriv(rcup))
- changemask |= ( QCUFLAG_KNOWN | QCUFLAG_OP | QCUFLAG_VOICE | QCUFLAG_AUTOOP | QCUFLAG_AUTOVOICE |
- QCUFLAG_TOPIC | QCUFLAG_BANNED | QCUFLAG_QUIET | QCUFLAG_DENY | QCUFLAG_PROTECT);
-
- /* Owners are allowed to manipulate +ms as well */
- if (CUIsOwner(rcup))
- changemask |= ( QCUFLAG_MASTER | QCUFLAG_SPAMCON );
- }
-
- oldflags=rcuplist->flags;
- if (setflags(&(rcuplist->flags), changemask, cargv[2], rcuflags, REJECT_UNKNOWN | REJECT_DISALLOWED)) {
- chanservstdmessage(sender, QM_INVALIDCHANLEVCHANGE);
- return CMD_ERROR;
- }
-
- /* Now fix up some "impossible" combinations.. */
- /* +m can't be any of +qdb */
- if (CUHasMasterPriv(rcuplist))
- rcuplist->flags &= ~(QCUFLAG_BANNED | QCUFLAG_QUIET | QCUFLAG_DENY);
-
- /* +d can't be +o */
- if (CUIsDeny(rcuplist))
- rcuplist->flags &= ~QCUFLAG_OP;
-
- /* +q can't be +v */
- if (CUIsQuiet(rcuplist))
- rcuplist->flags &= ~QCUFLAG_VOICE;
-
- /* -o or +p can't be +a */
- if (!CUIsOp(rcuplist) || CUIsProtect(rcuplist))
- rcuplist->flags &= ~QCUFLAG_AUTOOP;
-
- /* +a or -v or +p can't be +g */
- if (!CUIsVoice(rcuplist) || CUIsAutoOp(rcuplist) || CUIsProtect(rcuplist))
- rcuplist->flags &= ~QCUFLAG_AUTOVOICE;
-
- /* and -ov can't be +p */
- if (!CUIsOp(rcuplist) && !CUIsVoice(rcuplist))
- rcuplist->flags &= ~QCUFLAG_PROTECT;
-
- /* Check if anything "significant" has changed */
- if ((oldflags ^ rcuplist->flags) & (QCUFLAG_OWNER | QCUFLAG_MASTER | QCUFLAG_OP))
- rcuplist->changetime=time(NULL);
-
- strcpy(flagbuf,printflags(oldflags,rcuflags));
- cs_log(sender,"CHANLEV %s #%s %s (%s -> %s)",cip->name->content,rcuplist->user->username,cargv[2],
- flagbuf,printflags(rcuplist->flags,rcuflags));
-
- /* Now see what we do next */
- if (rcuplist->flags) {
- /* User still valid: update or create */
- if (newuser) {
- addregusertochannel(rcuplist);
- csdb_createchanuser(rcuplist);
- } else {
- csdb_updatechanuser(rcuplist);
- }
- } else {
- /* User has no flags: delete */
- if (!newuser) {
- csdb_deletechanuser(rcuplist);
- delreguserfromchannel(rcp, target);
- }
- freeregchanuser(rcuplist);
- rcuplist=NULL;
- for (i=0;i<REGCHANUSERHASHSIZE;i++)
- if (rcp->regusers[i])
- break;
- if (i==REGCHANUSERHASHSIZE) {
- cs_log(sender,"DELCHAN %s (Cleared chanlev)",cip->name->content);
- cs_removechannel(rcp);
- }
- }
-
- /* Say we've done it */
- chanservstdmessage(sender, QM_DONE);
- rcp->status |= QCSTAT_OPCHECK;
- cs_timerfunc(cip);
- }
-
- if (rcuplist && (rcuplist->flags & flagmask)) {
- chanservstdmessage(sender, QM_CHANUSERFLAGS, cargv[1], cip->name->content,
- printflags(rcuplist->flags & flagmask, rcuflags));
- } else {
- chanservstdmessage(sender, QM_CHANUSERUNKNOWN, cargv[1], cip->name->content);
- }
- }
-
- return CMD_OK;
-}
-
-int csc_doautolimit(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regchan *rcp;
- int oldlimit;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "autolimit");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV,
- NULL, "autolimit", QPRIV_VIEWAUTOLIMIT, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cargc>1) {
- if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV,
- cip, "autolimit", QPRIV_CHANGEAUTOLIMIT, 0))
- return CMD_ERROR;
-
- oldlimit=rcp->autolimit;
- rcp->autolimit=strtol(cargv[1],NULL,10);
-
- if (rcp->autolimit<1)
- rcp->autolimit=1;
-
- csdb_updatechannel(rcp);
-
- cs_log(sender,"AUTOLIMIT %s %s (%d -> %d)",cip->name->content,cargv[1],oldlimit,rcp->autolimit);
- chanservstdmessage(sender, QM_DONE);
- rcp->limit=0;
- cs_timerfunc(cip);
- }
-
- chanservstdmessage(sender, QM_CHANAUTOLIMIT, cargv[0], rcp->autolimit);
- return CMD_OK;
-}
-
-int csc_dobantimer(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regchan *rcp;
- int oldtimer;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "bantimer");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "bantimer",
- QPRIV_VIEWBANTIMER, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cargc>1) {
- if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, "bantimer",
- QPRIV_CHANGEBANTIMER, 0))
- return CMD_ERROR;
-
- oldtimer=rcp->banduration;
- rcp->banduration=durationtolong(cargv[1]);
-
- if (rcp->banduration<0)
- rcp->banduration=0;
-
- /* Arbitrary limit */
- if (rcp->banduration > 31622400)
- rcp->banduration = 31622400;
-
- csdb_updatechannel(rcp);
-
- cs_log(sender,"BANTIMER %s %s (%u -> %u)",cip->name->content,cargv[1],oldtimer,rcp->banduration);
- chanservstdmessage(sender, QM_DONE);
- cs_timerfunc(cip);
- }
-
- if (rcp->banduration)
- chanservstdmessage(sender, QM_CHANBANAUTOREMOVE, cargv[0], longtoduration(rcp->banduration, 1));
- else
- chanservstdmessage(sender, QM_NOCHANBANAUTOREMOVE, cargv[0]);
-
- return CMD_OK;
-}
-
-int csc_dowelcome(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regchan *rcp;
- sstring *oldwelcome;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "welcome");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "welcome",
- QPRIV_VIEWWELCOME, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cargc>1) {
- if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, "welcome",
- QPRIV_CHANGEWELCOME, 0))
- return CMD_ERROR;
-
- oldwelcome=rcp->welcome;
-
- rcp->welcome=getsstring(cargv[1], 500);
- csdb_updatechannel(rcp);
-
- cs_log(sender,"WELCOME %s %s (was %s)",cip->name->content,rcp->welcome->content,oldwelcome?oldwelcome->content:"unset");
- freesstring(oldwelcome);
- chanservstdmessage(sender, QM_DONE);
- }
-
- chanservstdmessage(sender, QM_WELCOMEMESSAGEIS, rcp->index->name->content,
- rcp->welcome?rcp->welcome->content:"(none)");
-
- return CMD_OK;
-}
-
-int csc_doaddchan(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- chanindex *cip;
- regchan *rcp;
- regchanuser *rcup;
- reguser *founder;
- flag_t flags;
- short type=0;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "addchan");
- return CMD_ERROR;
- }
-
- if (*cargv[0] != '#') {
- chanservstdmessage(sender, QM_INVALIDCHANNAME, cargv[0]);
- return CMD_ERROR;
- }
-
- if (cargc>1) {
- if (!(founder=findreguser(sender, cargv[1])))
- return CMD_ERROR;
- } else {
- founder=rup;
- }
-
- if (cargc>2) {
- flags=0;
- setflags(&flags, QCFLAG_ALL, cargv[2], rcflags, REJECT_NONE);
- } else {
- flags = (QCFLAG_JOINED | QCFLAG_BITCH | QCFLAG_PROTECT | QCFLAG_ENFORCE);
- }
-
- /* Pick up the chantype */
- if (cargc>3) {
- for (type=CHANTYPES-1;type;type--) {
- if (!ircd_strcmp(chantypes[type]->content, cargv[3]))
- break;
- }
- if (!type) {
- chanservstdmessage(sender, QM_UNKNOWNCHANTYPE, cargv[3]);
- return CMD_ERROR;
- }
- }
-
- if (!(cip=findorcreatechanindex(cargv[0]))) {
- chanservstdmessage(sender, QM_INVALIDCHANNAME, cargv[0]);
- return CMD_ERROR;
- }
-
- if (cip->exts[chanservext]) {
- chanservstdmessage(sender, QM_ALREADYREGISTERED, cip->name->content);
- return CMD_ERROR;
- }
-
- /* Initialise the channel */
- rcp=getregchan();
-
- /* ID, index */
- rcp->ID=++lastchannelID;
- rcp->index=cip;
- cip->exts[chanservext]=rcp;
-
- rcp->chantype=type;
- rcp->flags=flags;
- rcp->status=0;
- rcp->bans=NULL;
- rcp->lastcountersync=0;
-
- rcp->limit=0;
- rcp->forcemodes=CHANMODE_NOEXTMSG | CHANMODE_TOPICLIMIT;
- rcp->denymodes=0;
-
- if (CIsAutoLimit(rcp)) {
- rcp->forcemodes |= CHANMODE_LIMIT;
- }
-
- rcp->autolimit=5;
- rcp->banstyle=0;
-
- rcp->created=rcp->lastactive=rcp->statsreset=rcp->ostatsreset=time(NULL);
- rcp->banduration=1800;
- rcp->autoupdate=0;
- rcp->lastbancheck=0;
-
- /* Added by */
- rcp->addedby=rup->ID;
-
- /* Founder */
- rcp->founder=founder->ID;
-
- /* Suspend by */
- rcp->suspendby=0;
-
- rcp->totaljoins=rcp->tripjoins=rcp->otripjoins=rcp->maxusers=rcp->tripusers=rcp->otripusers=0;
- rcp->welcome=rcp->topic=rcp->key=rcp->suspendreason=rcp->comment=NULL;
-
- /* Users */
- memset(rcp->regusers,0,REGCHANUSERHASHSIZE*sizeof(reguser *));
-
- rcp->checksched=NULL;
- rcp->ltimestamp=0;
-
- /* Add new channel to db.. */
- csdb_createchannel(rcp);
-
- /* Add the founder as +ano */
- rcup=getregchanuser();
- rcup->chan=rcp;
- rcup->user=founder;
- rcup->flags=(QCUFLAG_OWNER | QCUFLAG_OP | QCUFLAG_AUTOOP);
- rcup->usetime=0;
- rcup->info=NULL;
- rcup->changetime=time(NULL);
-
- addregusertochannel(rcup);
- csdb_createchanuser(rcup);
-
- /* If the channel exists, get the ball rolling */
- if (cip->channel) {
- chanservjoinchan(cip->channel);
- rcp->status |= QCSTAT_MODECHECK | QCSTAT_OPCHECK | QCSTAT_BANCHECK;
- cs_timerfunc(cip);
- }
-
- cs_log(sender, "ADDCHAN %s #%s %s %s",cip->name->content,founder->username,printflags(rcp->flags,rcflags), chantypes[type]->content);
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csc_dosuspendchan(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- chanindex *cip;
- regchan *rcp;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspendchan");
- return CMD_ERROR;
- }
-
- if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
- chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
- return CMD_ERROR;
- }
-
- if (CIsSuspended(rcp)) {
- chanservstdmessage(sender, QM_CHANNELALREADYSUSPENDED, cip->name->content);
- return CMD_ERROR;
- }
-
- CSetSuspended(rcp);
- rcp->suspendreason = getsstring(cargv[1], 250);
- rcp->suspendby = rup->ID;
- cs_log(sender,"SUSPENDCHAN %s (%s)",cip->name->content,rcp->suspendreason->content);
- chanservjoinchan(cip->channel);
-
- csdb_updatechannel(rcp);
- chanservstdmessage(sender, QM_DONE);
-
- return CMD_OK;
-}
-
-int csc_dosuspendchanlist(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- chanindex *cip;
- regchan *rcp;
- int i;
- char *bywhom;
- unsigned int count=0;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc < 1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspendchanlist");
- return CMD_ERROR;
- }
-
- chanservstdmessage(sender, QM_SUSPENDCHANLISTHEADER);
- for (i=0; i<CHANNELHASHSIZE; i++) {
- for (cip=chantable[i]; cip; cip=cip->next) {
- if (!(rcp=(regchan*)cip->exts[chanservext]))
- continue;
-
- if (!CIsSuspended(rcp))
- continue;
-
- if ((rcp->suspendby != rup->ID) && match(cargv[0], cip->name->content))
- continue;
-
- if (rcp->suspendby == rup->ID)
- bywhom=rup->username;
- else {
- reguser *trup=findreguserbyID(rcp->suspendby);
- if (trup)
- bywhom=trup->username;
- else
- bywhom="unknown";
- }
- count++;
- chanservsendmessage(sender, "%-30s %-15s %s", cip->name->content, bywhom, rcp->suspendreason->content);
- if (count >= 2000) {
- chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "channels");
- return CMD_ERROR;
- }
- }
- }
- chanservstdmessage(sender, QM_RESULTCOUNT, count, "channel", (count==1)?"":"s");
-
- return CMD_OK;
-}
-
-int csc_dounsuspendchan(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- chanindex *cip;
- regchan *rcp;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unsuspendchan");
- return CMD_ERROR;
- }
-
- if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
- chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
- return CMD_ERROR;
- }
-
- if(!CIsSuspended(rcp)) {
- chanservstdmessage(sender, QM_CHANNELNOTSUSPENDED, cip->name->content);
- cs_log(sender,"UNSUSPENDCHAN %s is not suspended",cip->name->content);
- return CMD_ERROR;
- }
-
- CClearSuspended(rcp);
- cs_log(sender,"UNSUSPENDCHAN %s (%s)",cip->name->content,rcp->suspendreason->content);
- freesstring(rcp->suspendreason);
- rcp->suspendreason = NULL;
- rcp->suspendby = 0;
-
- chanservjoinchan(cip->channel);
-
- csdb_updatechannel(rcp);
- chanservstdmessage(sender, QM_DONE);
-
- return CMD_OK;
-}
-
-int csc_dodelchan(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- chanindex *cip;
- regchan *rcp;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "delchan");
- return CMD_ERROR;
- }
-
- if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
- chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
- return CMD_ERROR;
- }
-
- cs_log(sender,"DELCHAN %s (%s)",cip->name->content,cargc>1?cargv[1]:"");
- cs_removechannel(rcp);
- chanservstdmessage(sender, QM_DONE);
-
- return CMD_OK;
-}
-
-int csc_doinvite(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "invite");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_KNOWN | CA_OFFCHAN,
- NULL, "invite", 0, 0)))
- return CMD_ERROR;
-
- if (cip->channel) {
- localinvite(chanservnick, cip->channel, sender);
- }
- chanservstdmessage(sender, QM_DONE);
-
- return CMD_OK;
-}
-
-int csc_dosettopic(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regchan *rcp;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "settopic");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_TOPICPRIV,
- NULL, "settopic", 0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cargc>1) {
- if (rcp->topic)
- freesstring(rcp->topic);
- rcp->topic=getsstring(cargv[1],TOPICLEN);
- }
-
- if (rcp->topic && cip->channel) {
- localsettopic(chanservnick, cip->channel, rcp->topic->content);
- }
-
- chanservstdmessage(sender, QM_DONE);
- csdb_updatechannel(rcp);
- return CMD_OK;
-}
-
-int csc_doop(void *source, int cargc, char **cargv) {
- nick *sender=source, *np;
- reguser *rup=getreguserfromnick(sender);
- chanindex *cip;
- regchan *rcp=NULL;
- regchanuser *rcup;
- channel **ca;
- unsigned long *lp;
- int i;
- modechanges changes;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc==0) {
- /* No args: "op me on every channel you can */
- ca=sender->channels->content;
- for (i=0;i<sender->channels->cursi;i++) {
- if ((rcp=ca[i]->index->exts[chanservext]) && !CIsSuspended(rcp)) {
- /* It's a Q channel */
- if (!(*(getnumerichandlefromchanhash(ca[i]->users, sender->numeric)) &
- CUMODE_OP)) {
- /* They're not opped */
- if ((rcup=findreguseronchannel(rcp, rup)) && CUHasOpPriv(rcup) &&
- !CUIsDeny(rcup)) {
- /* And they have op priv on the chan: op them */
- localsetmodeinit(&changes, ca[i], chanservnick);
- localdosetmode_nick(&changes, sender, MC_OP);
- localsetmodeflush(&changes,1);
- }
- }
- }
- }
-
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
- }
-
- /* If there is at least one arg, the first is a channel */
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "op", 0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cargc==1) {
- /* Only one arg: "op me" */
- if (!cs_checkaccess(sender, NULL, CA_OPPRIV | CA_DEOPPED, cip, "op", 0, 0))
- return CMD_ERROR;
-
- localsetmodeinit(&changes, cip->channel, chanservnick);
- localdosetmode_nick(&changes, sender, MC_OP);
- localsetmodeflush(&changes,1);
-
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
- }
-
- /* Set up the modes */
- localsetmodeinit(&changes, cip->channel, chanservnick);
-
- for(i=1;i<cargc;i++) {
- if (!(np=getnickbynick(cargv[i]))) {
- chanservstdmessage(sender, QM_UNKNOWNUSER, cargv[i]);
- continue;
- }
-
- if (!(lp=getnumerichandlefromchanhash(cip->channel->users, np->numeric))) {
- chanservstdmessage(sender, QM_USERNOTONCHAN, np->nick, cip->name->content);
- continue;
- }
-
- if (*lp & CUMODE_OP) {
- chanservstdmessage(sender, QM_USEROPPEDONCHAN, np->nick, cip->name->content);
- continue;
- }
-
- rup=getreguserfromnick(np);
- if (rup)
- rcup=findreguseronchannel(rcp,rup);
- else
- rcup=NULL;
-
- /* Bitch mode: check that this user is allowed to be opped.. */
- if ((CIsBitch(rcp) && (!rcup || !CUHasOpPriv(rcup))) || (rcup && CUIsDeny(rcup))) {
- chanservstdmessage(sender, QM_CANTOP, np->nick, cip->name->content);
- continue;
- }
-
- localdosetmode_nick(&changes, np, MC_OP);
- }
-
- localsetmodeflush(&changes, 1);
- chanservstdmessage(sender, QM_DONE);
-
- return CMD_OK;
-}
-
-int csc_dovoice(void *source, int cargc, char **cargv) {
- nick *sender=source, *np;
- reguser *rup=getreguserfromnick(sender);
- chanindex *cip;
- regchan *rcp=NULL;
- regchanuser *rcup;
- channel **ca;
- unsigned long *lp;
- int i;
- modechanges changes;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc==0) {
- /* No args: "voice me on every channel you can */
- ca=sender->channels->content;
- for (i=0;i<sender->channels->cursi;i++) {
- if ((rcp=ca[i]->index->exts[chanservext]) && !CIsSuspended(rcp)) {
- /* It's a Q channel */
- if (!(*(getnumerichandlefromchanhash(ca[i]->users, sender->numeric)) &
- (CUMODE_OP|CUMODE_VOICE))) {
- /* They're not opped or voiced */
- rcup=findreguseronchannel(rcp, rup);
- if ((!rcup || !CUIsQuiet(rcup)) &&
- ((rcup && CUHasVoicePriv(rcup)) ||
- (CIsVoiceAll(rcp)))) {
- /* And they have voice priv on the chan (or it's autovoice):
- * voice them */
- localsetmodeinit(&changes, ca[i], chanservnick);
- localdosetmode_nick(&changes, sender, MC_VOICE);
- localsetmodeflush(&changes,1);
- }
- }
- }
- }
-
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
- }
-
- /* If there is at least one arg, the first is a channel */
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_VOICEPRIV, NULL, "voice", 0, 0)))
- return CMD_ERROR;
-
- if (cargc==1) {
- /* Only one arg: "voice me" */
- if (!cs_checkaccess(sender, NULL, CA_VOICEPRIV | CA_DEVOICED, cip,
- "voice", 0, 0))
- return CMD_ERROR;
-
- localsetmodeinit(&changes, cip->channel, chanservnick);
- localdosetmode_nick(&changes, sender, MC_VOICE);
- localsetmodeflush(&changes,1);
-
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
- }
-
- if (!(cip=cs_checkaccess(sender, NULL, CA_OPPRIV, cip, "voice", 0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- /* Set up the modes */
- localsetmodeinit(&changes, cip->channel, chanservnick);
-
- for(i=1;i<cargc;i++) {
- if (!(np=getnickbynick(cargv[i]))) {
- chanservstdmessage(sender, QM_UNKNOWNUSER, cargv[i]);
- continue;
- }
-
- if (!(lp=getnumerichandlefromchanhash(cip->channel->users, np->numeric))) {
- chanservstdmessage(sender, QM_USERNOTONCHAN, np->nick, cip->name->content);
- continue;
- }
-
- if (*lp & CUMODE_VOICE) {
- chanservstdmessage(sender, QM_USERVOICEDONCHAN, np->nick, cip->name->content);
- continue;
- }
-
- if ((rup=getreguserfromnick(np)) && (rcup=findreguseronchannel(rcp, rup)) && CUIsQuiet(rcup)) {
- chanservstdmessage(sender, QM_CANTVOICE, np->nick, cip->name->content);
- continue;
- }
-
- localdosetmode_nick(&changes, np, MC_VOICE);
- }
-
- localsetmodeflush(&changes, 1);
- chanservstdmessage(sender, QM_DONE);
-
- return CMD_OK;
-}
-
-int csc_dodeopall(void *source, int cargc, char **cargv) {
- nick *sender=source,*np;
- reguser *rup;
- regchanuser *rcup;
- regchan *rcp;
- chanindex *cip;
- unsigned long *lp;
- int i;
- modechanges changes;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "deopall");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "deopall",0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cip->channel) {
- localsetmodeinit(&changes, cip->channel, chanservnick);
-
- for (i=0,lp=cip->channel->users->content;
- i<cip->channel->users->hashsize;i++,lp++) {
- if (*lp!=nouser && (*lp & CUMODE_OP)) {
- if (!(np=getnickbynumeric(*lp)) ||
- (!IsService(np) && (!(rup=getreguserfromnick(np)) ||
- !(rcup=findreguseronchannel(rcp, rup)) || !(CUHasOpPriv(rcup)) ||
- !(CUIsProtect(rcup) || CIsProtect(rcp))))) {
- localdosetmode_nick(&changes, np, MC_DEOP);
- }
- }
- }
-
- localsetmodeflush(&changes, 1);
- }
-
- cs_log(sender,"DEOPALL %s",cip->name->content);
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csc_dodevoiceall(void *source, int cargc, char **cargv) {
- nick *sender=source,*np;
- reguser *rup;
- regchanuser *rcup;
- regchan *rcp;
- chanindex *cip;
- unsigned long *lp;
- int i;
- modechanges changes;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "devoiceall");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "devoiceall",0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cip->channel) {
- localsetmodeinit(&changes, cip->channel, chanservnick);
-
- for (i=0,lp=cip->channel->users->content;
- i<cip->channel->users->hashsize;i++,lp++) {
- if (*lp!=nouser && (*lp & CUMODE_VOICE)) {
- if (!(np=getnickbynumeric(*lp)) ||
- (!IsService(np) && (!(rup=getreguserfromnick(np)) ||
- !(rcup=findreguseronchannel(rcp, rup)) || !(CUHasVoicePriv(rcup)) ||
- !(CUIsProtect(rcup) || CIsProtect(rcp))))) {
- localdosetmode_nick(&changes, np, MC_DEVOICE);
- }
- }
- }
-
- localsetmodeflush(&changes, 1);
- }
-
- cs_log(sender,"DEVOICEALL %s",cip->name->content);
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csc_dounbanall(void *source, int cargc, char **cargv) {
- nick *sender=source;
- regchan *rcp;
- chanindex *cip;
- modechanges changes;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unbanall");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "unbanall",0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cip->channel) {
- localsetmodeinit(&changes, cip->channel, chanservnick);
-
- while (cip->channel->bans) {
- localdosetmode_ban(&changes, bantostring(cip->channel->bans), MCB_DEL);
- }
-
- localsetmodeflush(&changes, 1);
- }
-
- cs_log(sender,"UNBANALL %s",cip->name->content);
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csc_dounbanme(void *source, int cargc, char **cargv) {
- nick *sender=source;
- regchan *rcp;
- chanindex *cip;
- modechanges changes;
- chanban **cbh;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unbanme");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "unbanme", 0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cip->channel) {
- localsetmodeinit(&changes, cip->channel, chanservnick);
-
- for (cbh=&(cip->channel->bans);*cbh;) {
- if (nickmatchban(sender, *cbh))
- localdosetmode_ban(&changes, bantostring(*cbh), MCB_DEL);
- else
- cbh=&((*cbh)->next);
- }
-
- localsetmodeflush(&changes, 1);
- }
-
- cs_log(sender,"UNBANME %s",cip->name->content);
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csc_doclearchan(void *source, int cargc, char **cargv) {
- nick *sender=source;
- regchan *rcp;
- chanindex *cip;
- modechanges changes;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "clearchan");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "clearchan",0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cip->channel) {
- localsetmodeinit(&changes, cip->channel, chanservnick);
- localdosetmode_key(&changes, NULL, MCB_DEL);
- localdosetmode_simple(&changes, 0, cip->channel->flags);
- cs_docheckchanmodes(cip->channel, &changes);
- localsetmodeflush(&changes, 1);
- }
-
- cs_log(sender,"CLEARCHAN %s",cip->name->content);
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csc_dorecover(void *source, int cargc, char **cargv) {
- nick *sender=source,*np;
- reguser *rup;
- regchanuser *rcup;
- regchan *rcp;
- chanindex *cip;
- unsigned long *lp;
- int i;
- modechanges changes;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "recover");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "recover",0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cip->channel) {
- localsetmodeinit(&changes, cip->channel, chanservnick);
-
- /* clearchan */
- localdosetmode_key(&changes, NULL, MCB_DEL);
- localdosetmode_simple(&changes, 0, cip->channel->flags);
- cs_docheckchanmodes(cip->channel, &changes);
-
- /* unbanall */
- while (cip->channel->bans) {
- localdosetmode_ban(&changes, bantostring(cip->channel->bans), MCB_DEL);
- }
-
- /* deopall */
- for (i=0,lp=cip->channel->users->content;
- i<cip->channel->users->hashsize;i++,lp++) {
- if (*lp!=nouser && (*lp & CUMODE_OP)) {
- if (!(np=getnickbynumeric(*lp)) ||
- (!IsService(np) && (!(rup=getreguserfromnick(np)) ||
- !(rcup=findreguseronchannel(rcp, rup)) || !(CUHasOpPriv(rcup)) ||
- !(CUIsProtect(rcup) || CIsProtect(rcp))))) {
- localdosetmode_nick(&changes, np, MC_DEOP);
- }
- }
- }
-
- localsetmodeflush(&changes, 1);
- }
-
- cs_log(sender,"RECOVER %s",cip->name->content);
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csc_dopermban(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regban *rbp;
- regchan *rcp;
- reguser *rup=getreguserfromnick(sender);
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "permban");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "permban",0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- rbp=getregban();
- rbp->ID=++lastbanID;
- rbp->cbp=makeban(cargv[1]);
- rbp->setby=rup->ID;
- rbp->expiry=0;
- if (cargc>2)
- rbp->reason=getsstring(cargv[2],200);
- else
- rbp->reason=NULL;
- rbp->next=rcp->bans;
- rcp->bans=rbp;
-
- cs_setregban(cip, rbp);
- csdb_createban(rcp, rbp);
-
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csc_dotempban(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regban *rbp;
- regchan *rcp;
- reguser *rup=getreguserfromnick(sender);
- unsigned int duration;
-
- if (cargc<3) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "tempban");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "tempban",0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- duration=durationtolong(cargv[2]);
-
- rbp=getregban();
- rbp->ID=++lastbanID;
- rbp->cbp=makeban(cargv[1]);
- rbp->setby=rup->ID;
- rbp->expiry=time(NULL)+duration;
- if (cargc>3)
- rbp->reason=getsstring(cargv[3],200);
- else
- rbp->reason=NULL;
- rbp->next=rcp->bans;
- rcp->bans=rbp;
-
- cs_setregban(cip, rbp);
- csdb_createban(rcp, rbp);
-
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csc_dobanlist(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regchan *rcp;
- regban *rbp;
- reguser *rup;
- chanban *cbp;
- int i=0;
- int exp;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "banlist");
- return CMD_ERROR;
- }
-
- if(!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "banlist", 0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (rcp->bans || cip->channel->bans) {
- chanservstdmessage(sender, QM_REGBANHEADER, cip->name->content);
- for(rbp=rcp->bans;rbp;rbp=rbp->next) {
- rup=findreguserbyID(rbp->setby);
- chanservsendmessage(sender," #%-2d %-29s %-18s %-15s %s",++i,bantostring(rbp->cbp),
- rbp->expiry?longtoduration(rbp->expiry-time(NULL),0):"Permanent",
- rup?rup->username:"<unknown>",
- rbp->reason?rbp->reason->content:"");
- }
- for (cbp=cip->channel->bans;cbp;cbp=cbp->next) {
- for (rbp=rcp->bans;rbp;rbp=rbp->next) {
- if (banequal(rbp->cbp, cbp))
- break;
- }
- if (!rbp) {
- if (rcp->banduration) {
- exp=(cbp->timeset + rcp->banduration) - time(NULL);
- } else {
- exp=0;
- }
- chanservsendmessage(sender, " #%-2d %-29s %-18s %-15s",++i,bantostring(cbp),
- exp ? longtoduration(exp,0) : "Permanent",
- "(channel ban)");
- }
- }
- chanservstdmessage(sender, QM_ENDOFLIST);
- } else {
- chanservstdmessage(sender, QM_NOBANS, cip->name->content);
- }
-
- return CMD_OK;
-}
-
-int csc_dobandel(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regban **rbh, *rbp;
- chanban *cbp;
- regchan *rcp;
- chanban *theban=NULL;
- modechanges changes;
- int i,banid=0;
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unban");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "unban", 0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- /* OK, let's see what they want to remove.. */
- if (*cargv[1]=='#') {
- /* Remove by ID number */
- if (!(banid=strtoul(cargv[1]+1, NULL, 10))) {
- chanservstdmessage(sender, QM_UNKNOWNBAN, cargv[1], cip->name->content);
- return CMD_ERROR;
- }
- } else {
- /* Remove by ban string */
- theban=makeban(cargv[1]);
- }
-
- i=0;
- for (rbh=&(rcp->bans);*rbh;rbh=&((*rbh)->next)) {
- i++;
- if ((banid && i==banid) ||
- (theban && banequal(theban, (*rbh)->cbp))) {
- /* got it - they will need master access to remove this */
- rbp=*rbh;
-
- if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, "unban", 0, 0))
- return CMD_ERROR;
-
- chanservstdmessage(sender, QM_REMOVEDPERMBAN, bantostring(rbp->cbp), cip->name->content);
- if (cip->channel) {
- localsetmodeinit(&changes, cip->channel, chanservnick);
- localdosetmode_ban(&changes, bantostring(rbp->cbp), MCB_DEL);
- localsetmodeflush(&changes, 1);
- }
-
- /* Remove from database */
- csdb_deleteban(rbp);
- /* Remove from list */
- (*rbh)=rbp->next;
- /* Free ban/string and actual regban */
- freesstring(rbp->reason);
- freechanban(rbp->cbp);
- freeregban(rbp);
-
- if (theban)
- freechanban(theban);
-
- return CMD_OK;
- }
- }
-
- /* If we've run out of registered bans, let's try channel bans */
- if (cip->channel && cip->channel->bans) {
- for (cbp=cip->channel->bans;cbp;cbp=cbp->next) {
- for (rbp=rcp->bans;rbp;rbp=rbp->next) {
- if (banequal(rbp->cbp,cbp))
- break;
- }
-
- if (rbp)
- continue;
-
- i++;
- if ((banid && (i==banid)) ||
- (theban && banequal(theban, cbp))) {
- /* got it - this is just a channel ban */
- chanservstdmessage(sender, QM_REMOVEDCHANBAN, bantostring(cbp), cip->name->content);
- localsetmodeinit(&changes, cip->channel, chanservnick);
- localdosetmode_ban(&changes, cargv[1], MCB_DEL);
- localsetmodeflush(&changes, 1);
-
- if (theban)
- freechanban(theban);
-
- return CMD_OK;
- }
- }
- }
-
- chanservstdmessage(sender, QM_UNKNOWNBAN, cargv[1], cip->name->content);
-
- return CMD_OK;
-}
-
-int csc_dobanclear(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regban **rbh, *rbp;
- chanban **cbh, *cbp;
- regchan *rcp;
- modechanges changes;
- char *banstr;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "banclear");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "banclear", 0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- if (cip->channel)
- localsetmodeinit(&changes, cip->channel, chanservnick);
-
- for (rbh=&(rcp->bans); *rbh; ) {
- rbp=*rbh;
- banstr=bantostring(rbp->cbp);
- chanservstdmessage(sender, QM_REMOVEDPERMBAN, banstr, cip->name->content);
- if (cip->channel)
- localdosetmode_ban(&changes, banstr, MCB_DEL);
- /* Remove from database */
- csdb_deleteban(rbp);
- /* Remove from list */
- (*rbh)=rbp->next;
- /* Free ban/string and update setby refcount, and free actual regban */
- freesstring(rbp->reason);
- freechanban(rbp->cbp);
- freeregban(rbp);
- }
-
- if (cip->channel) {
- for (cbh=&(cip->channel->bans); *cbh; ) {
- cbp=*cbh;
- banstr=bantostring(cbp);
- chanservstdmessage(sender, QM_REMOVEDCHANBAN, banstr, cip->name->content);
- localdosetmode_ban(&changes, banstr, MCB_DEL);
- }
- localsetmodeflush(&changes,1);
- }
-
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csc_dounbanmask(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regban **rbh, *rbp;
- chanban **cbh, *cbp;
- regchan *rcp;
- chanban *theban;
- modechanges changes;
- char *banstr;
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unbanmask");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "unbanmask", 0, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
- theban=makeban(cargv[1]);
-
- if (cip->channel)
- localsetmodeinit(&changes, cip->channel, chanservnick);
-
- for (rbh=&(rcp->bans); *rbh; ) {
- rbp=*rbh;
- if (banoverlap(theban, rbp->cbp)) {
- banstr=bantostring(rbp->cbp);
- /* Check perms and remove */
- if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, NULL, 0, 1)) {
- chanservstdmessage(sender, QM_NOTREMOVEDPERMBAN, banstr, cip->name->content);
- rbh=&(rbp->next);
- } else {
- chanservstdmessage(sender, QM_REMOVEDPERMBAN, banstr, cip->name->content);
- if (cip->channel)
- localdosetmode_ban(&changes, banstr, MCB_DEL);
- /* Remove from database */
- csdb_deleteban(rbp);
- /* Remove from list */
- (*rbh)=rbp->next;
- /* Free ban/string and update setby refcount, and free actual regban */
- freesstring(rbp->reason);
- freechanban(rbp->cbp);
- freeregban(rbp);
- }
- } else {
- rbh=&(rbp->next);
- }
- }
-
- if (cip->channel) {
- for (cbh=&(cip->channel->bans); *cbh; ) {
- cbp=*cbh;
- if (banoverlap(theban, cbp)) {
- /* Remove */
- banstr=bantostring(cbp);
- chanservstdmessage(sender, QM_REMOVEDCHANBAN, banstr, cip->name->content);
- localdosetmode_ban(&changes, banstr, MCB_DEL);
- } else {
- cbh=&(cbp->next);
- }
- }
- localsetmodeflush(&changes,1);
- }
-
-
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csc_dorenchan(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- chanindex *cip1,*cip2;
- regchan *rcp;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "renchan");
- return CMD_ERROR;
- }
-
- if (!(cip1=findchanindex(cargv[0])) || !(rcp=cip1->exts[chanservext])) {
- chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
- return CMD_ERROR;
- }
-
- if (*cargv[1] != '#') {
- chanservstdmessage(sender, QM_INVALIDCHANNAME, cargv[0]);
- return CMD_ERROR;
- }
-
- if (!(cip2=findorcreatechanindex(cargv[1])) || cip2->exts[chanservext]) {
- chanservstdmessage(sender, QM_ALREADYREGISTERED, cip2->name->content);
- return CMD_ERROR;
- }
-
- cs_log(sender,"RENCHAN %s -> %s",cip1->name->content,cip2->name->content);
-
- /* Remove from the channel. Don't bother if the channel doesn't exist. */
- if (!CIsSuspended(rcp) && cip1->channel) {
- CSetSuspended(rcp);
- chanservjoinchan(cip1->channel);
- CClearSuspended(rcp);
- }
-
- cip1->exts[chanservext]=NULL;
- releasechanindex(cip1);
-
- cip2->exts[chanservext]=rcp;
- rcp->index=cip2;
- if (cip2->channel) {
- chanservjoinchan(cip2->channel);
- }
-
- csdb_updatechannel(rcp);
- chanservstdmessage(sender, QM_DONE);
-
- return CMD_OK;
-}
-
-int csc_dochannelcomment(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- regchan *rcp;
- chanindex *cip;
- char buf[300];
- int bufpos;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "channelcomment");
- return CMD_ERROR;
- }
-
- if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
- chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
- return CMD_ERROR;
- }
-
- if (cargc>1) {
- if (!ircd_strcmp(cargv[1],"none")) {
- freesstring(rcp->comment);
- rcp->comment=NULL;
- } else {
- if (*cargv[1]=='+') {
- if (rcp->comment) {
- strcpy(buf,rcp->comment->content);
- bufpos=rcp->comment->length;
- buf[bufpos++]=' ';
- } else {
- bufpos=0;
- }
- strncpy(buf+bufpos, cargv[1]+1, 250-bufpos);
- } else {
- strncpy(buf, cargv[1], 250);
- }
-
- freesstring(rcp->comment);
- rcp->comment=getsstring(buf,250);
- }
- csdb_updatechannel(rcp);
- }
-
- if (rcp->comment)
- chanservstdmessage(sender, QM_COMMENT, cip->name->content, rcp->comment->content);
- else
- chanservstdmessage(sender, QM_NOCOMMENT, cip->name->content);
-
- return CMD_OK;
-}
-
-int csc_dorejoin(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regchan *rcp;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "rejoin");
- return CMD_ERROR;
- }
-
- if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
- chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
- return CMD_ERROR;
- }
-
- if (CIsJoined(rcp) && !CIsSuspended(rcp)) {
- CSetSuspended(rcp);
- chanservjoinchan(cip->channel);
- CClearSuspended(rcp);
- chanservjoinchan(cip->channel);
- }
-
- chanservstdmessage(sender, QM_DONE);
-
- return CMD_OK;
-}
-
-int csc_dochantype(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regchan *rcp;
- int type;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "chantype");
- return CMD_ERROR;
- }
-
- if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
- chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
- return CMD_ERROR;
- }
-
- if (cargc>1) {
- /* Set type */
- for (type=CHANTYPES-1;type;type--) {
- if (!ircd_strcmp(chantypes[type]->content, cargv[1]))
- break;
- }
- if (!type) {
- chanservstdmessage(sender, QM_UNKNOWNCHANTYPE, cargv[1]);
- return CMD_ERROR;
- }
- rcp->chantype=type;
-
- csdb_updatechannel(rcp);
- chanservstdmessage(sender, QM_DONE);
- }
-
- chanservstdmessage(sender, QM_CHANTYPEIS, cip->name->content, chantypes[rcp->chantype]->content);
-
- return CMD_OK;
-}
-
-int csc_doadduser(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regchanuser *rcup;
- regchan *rcp;
- reguser *rup;
- int i;
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "adduser");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "adduser", QPRIV_CHANGECHANLEV, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- for (i=1;i<cargc;i++) {
- if (!(rup=findreguser(sender, cargv[i])))
- continue;
-
- if ((rcup=findreguseronchannel(rcp, rup))) {
- chanservstdmessage(sender, QM_ALREADYKNOWNONCHAN, cargv[i], cip->name->content);
- continue;
- }
-
- rcup=getregchanuser();
- rcup->chan=rcp;
- rcup->user=rup;
- rcup->flags = QCUFLAG_OP | QCUFLAG_AUTOOP | QCUFLAG_TOPIC;
- rcup->changetime=time(NULL);
- rcup->usetime=0;
- rcup->info=NULL;
-
- cs_log(sender,"CHANLEV %s #%s +aot (+ -> +aot)",cip->name->content,rup->username);
- addregusertochannel(rcup);
- csdb_createchanuser(rcup);
- }
-
- rcp->status |= QCSTAT_OPCHECK;
- cs_timerfunc(cip);
-
- chanservstdmessage(sender, QM_DONE);
-
- return CMD_OK;
-}
-
-int csc_doremoveuser(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regchanuser *rcup;
- regchan *rcp;
- reguser *rup;
- int isowner=0;
- int i;
-
- if (cargc<2) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "removeuser");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "adduser", QPRIV_CHANGECHANLEV, 0)))
- return CMD_ERROR;
-
- if (cs_checkaccess(sender, NULL, CA_OWNERPRIV, cip, "adduser", QPRIV_CHANGECHANLEV, 1))
- isowner=1;
-
- rcp=cip->exts[chanservext];
-
- for (i=1;i<cargc;i++) {
- if (!(rup=findreguser(sender, cargv[i])))
- continue;
-
- if (!(rcup=findreguseronchannel(rcp, rup))) {
- chanservstdmessage(sender, QM_CHANUSERUNKNOWN, cargv[i], cip->name->content);
- continue;
- }
-
- if (CUIsOwner(rcup)) {
- chanservstdmessage(sender, QM_CANNOTREMOVEOWNER, cargv[i], cip->name->content);
- continue;
- }
-
- if (CUIsMaster(rcup) && !isowner && (rup != getreguserfromnick(sender))) {
- chanservstdmessage(sender, QM_CANNOTREMOVEMASTER, cargv[i], cip->name->content);
- continue;
- }
-
- cs_log(sender,"CHANLEV %s #%s -%s (%s -> +)",cip->name->content,rup->username,
- printflags_noprefix(rcup->flags, rcuflags), printflags(rcup->flags, rcuflags));
-
- csdb_deletechanuser(rcup);
- delreguserfromchannel(rcp, rup);
- }
-
- rcp->status |= QCSTAT_OPCHECK;
- cs_timerfunc(cip);
-
- chanservstdmessage(sender, QM_DONE);
-
- return CMD_OK;
-}
-
-int csc_dochanstat(void *source, int cargc, char **cargv) {
- nick *sender=source;
- chanindex *cip;
- regchan *rcp;
- char timebuf[30];
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "chanstat");
- return CMD_ERROR;
- }
-
- if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV,
- NULL, "chanstat", QPRIV_VIEWFULLCHANLEV, 0)))
- return CMD_ERROR;
-
- rcp=cip->exts[chanservext];
-
- chanservstdmessage(sender, QM_STATSHEADER, cip->name->content);
-
- strftime(timebuf, 30, "%d/%m/%y %H:%M", localtime(&(rcp->created)));
- chanservstdmessage(sender, QM_STATSADDED, timebuf);
-
- /* Show opers founder/addedby/type info */
- if (cs_privcheck(QPRIV_VIEWFULLCHANLEV, sender)) {
- reguser *founder=NULL, *addedby=NULL;
-
- strftime(timebuf, 30, "%d/%m/%y %H:%M", localtime(&(rcp->lastactive)));
- chanservstdmessage(sender, QM_STATSLASTACTIVE, timebuf);
-
-
- addedby=findreguserbyID(rcp->addedby);
- chanservstdmessage(sender, QM_ADDEDBY, addedby ? addedby->username : "(unknown)");
- founder=findreguserbyID(rcp->founder);
- chanservstdmessage(sender, QM_FOUNDER, founder ? founder->username : "(unknown)");
- chanservstdmessage(sender, QM_CHANTYPE, chantypes[rcp->chantype]->content);
- }
-
- strftime(timebuf, 30, "%d/%m/%y %H:%M", localtime(&(rcp->created)));
-
- chanservstdmessage(sender, QM_STATSJOINS, timebuf, rcp->maxusers, rcp->totaljoins,
- (float)rcp->totaljoins/ ((time(NULL)-rcp->created)/(3600*24)));
-
- strftime(timebuf, 30, "%d/%m/%y %H:%M", localtime(&(rcp->statsreset)));
-
- chanservstdmessage(sender, QM_STATSJOINS, timebuf, rcp->tripusers, rcp->tripjoins,
- (float)rcp->tripjoins / ((time(NULL)-rcp->statsreset)/(3600*24)));
-
- return CMD_OK;
-}
--- /dev/null
+# Automatically generated Makefile, do not edit.
+
+.PHONY: all Makefile
+all: Makefile chanserv_chancmds.so
+
+Makefile:
+ ../mkcommandlist.pl chanserv_chancmds.so
+
+chanserv_chancmds.so: addchan.o adduser.o autolimit.o banclear.o bandel.o banlist.o bantimer.o chanflags.o chanlev.o chanmode.o channelcomment.o chanstat.o chantype.o clearchan.o delchan.o deopall.o devoiceall.o invite.o op.o permban.o recover.o rejoin.o removeuser.o renchan.o settopic.o suspendchan.o suspendchanlist.o tempban.o unbanall.o unbanmask.o unbanme.o unsuspendchan.o voice.o welcome.o commandlist.o
+ ld -shared -Bdynamic -o $@ $^
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: addchan
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 4
+ * CMDDESC: Adds a new channel to the bot.
+ * CMDFUNC: csc_doaddchan
+ * CMDPROTO: int csc_doaddchan(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_doaddchan(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ chanindex *cip;
+ regchan *rcp;
+ regchanuser *rcup;
+ reguser *founder;
+ flag_t flags;
+ short type=0;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "addchan");
+ return CMD_ERROR;
+ }
+
+ if (*cargv[0] != '#') {
+ chanservstdmessage(sender, QM_INVALIDCHANNAME, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (cargc>1) {
+ if (!(founder=findreguser(sender, cargv[1])))
+ return CMD_ERROR;
+ } else {
+ founder=rup;
+ }
+
+ if (cargc>2) {
+ flags=0;
+ setflags(&flags, QCFLAG_ALL, cargv[2], rcflags, REJECT_NONE);
+ } else {
+ flags = (QCFLAG_JOINED | QCFLAG_BITCH | QCFLAG_PROTECT | QCFLAG_ENFORCE);
+ }
+
+ /* Pick up the chantype */
+ if (cargc>3) {
+ for (type=CHANTYPES-1;type;type--) {
+ if (!ircd_strcmp(chantypes[type]->content, cargv[3]))
+ break;
+ }
+ if (!type) {
+ chanservstdmessage(sender, QM_UNKNOWNCHANTYPE, cargv[3]);
+ return CMD_ERROR;
+ }
+ }
+
+ if (!(cip=findorcreatechanindex(cargv[0]))) {
+ chanservstdmessage(sender, QM_INVALIDCHANNAME, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (cip->exts[chanservext]) {
+ chanservstdmessage(sender, QM_ALREADYREGISTERED, cip->name->content);
+ return CMD_ERROR;
+ }
+
+ /* Initialise the channel */
+ rcp=getregchan();
+
+ /* ID, index */
+ rcp->ID=++lastchannelID;
+ rcp->index=cip;
+ cip->exts[chanservext]=rcp;
+
+ rcp->chantype=type;
+ rcp->flags=flags;
+ rcp->status=0;
+ rcp->bans=NULL;
+ rcp->lastcountersync=0;
+
+ rcp->limit=0;
+ rcp->forcemodes=CHANMODE_NOEXTMSG | CHANMODE_TOPICLIMIT;
+ rcp->denymodes=0;
+
+ if (CIsAutoLimit(rcp)) {
+ rcp->forcemodes |= CHANMODE_LIMIT;
+ }
+
+ rcp->autolimit=5;
+ rcp->banstyle=0;
+
+ rcp->created=rcp->lastactive=rcp->statsreset=rcp->ostatsreset=time(NULL);
+ rcp->banduration=1800;
+ rcp->autoupdate=0;
+ rcp->lastbancheck=0;
+
+ /* Added by */
+ rcp->addedby=rup->ID;
+
+ /* Founder */
+ rcp->founder=founder->ID;
+
+ /* Suspend by */
+ rcp->suspendby=0;
+
+ rcp->totaljoins=rcp->tripjoins=rcp->otripjoins=rcp->maxusers=rcp->tripusers=rcp->otripusers=0;
+ rcp->welcome=rcp->topic=rcp->key=rcp->suspendreason=rcp->comment=NULL;
+
+ /* Users */
+ memset(rcp->regusers,0,REGCHANUSERHASHSIZE*sizeof(reguser *));
+
+ rcp->checksched=NULL;
+ rcp->ltimestamp=0;
+
+ /* Add new channel to db.. */
+ csdb_createchannel(rcp);
+
+ /* Add the founder as +ano */
+ rcup=getregchanuser();
+ rcup->chan=rcp;
+ rcup->user=founder;
+ rcup->flags=(QCUFLAG_OWNER | QCUFLAG_OP | QCUFLAG_AUTOOP);
+ rcup->usetime=0;
+ rcup->info=NULL;
+ rcup->changetime=time(NULL);
+
+ addregusertochannel(rcup);
+ csdb_createchanuser(rcup);
+
+ /* If the channel exists, get the ball rolling */
+ if (cip->channel) {
+ chanservjoinchan(cip->channel);
+ rcp->status |= QCSTAT_MODECHECK | QCSTAT_OPCHECK | QCSTAT_BANCHECK;
+ cs_timerfunc(cip);
+ }
+
+ cs_log(sender, "ADDCHAN %s #%s %s %s",cip->name->content,founder->username,printflags(rcp->flags,rcflags), chantypes[type]->content);
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: adduser
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 20
+ * CMDDESC: Adds one or more users to a channel as +aot.
+ * CMDFUNC: csc_doadduser
+ * CMDPROTO: int csc_doadduser(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_doadduser(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regchanuser *rcup;
+ regchan *rcp;
+ reguser *rup;
+ int i;
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "adduser");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "adduser", QPRIV_CHANGECHANLEV, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ for (i=1;i<cargc;i++) {
+ if (!(rup=findreguser(sender, cargv[i])))
+ continue;
+
+ if ((rcup=findreguseronchannel(rcp, rup))) {
+ chanservstdmessage(sender, QM_ALREADYKNOWNONCHAN, cargv[i], cip->name->content);
+ continue;
+ }
+
+ rcup=getregchanuser();
+ rcup->chan=rcp;
+ rcup->user=rup;
+ rcup->flags = QCUFLAG_OP | QCUFLAG_AUTOOP | QCUFLAG_TOPIC;
+ rcup->changetime=time(NULL);
+ rcup->usetime=0;
+ rcup->info=NULL;
+
+ cs_log(sender,"CHANLEV %s #%s +aot (+ -> +aot)",cip->name->content,rup->username);
+ addregusertochannel(rcup);
+ csdb_createchanuser(rcup);
+ }
+
+ rcp->status |= QCSTAT_OPCHECK;
+ cs_timerfunc(cip);
+
+ chanservstdmessage(sender, QM_DONE);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: autolimit
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 2
+ * CMDDESC: Shows or changes the autolimit threshold on a channel.
+ * CMDFUNC: csc_doautolimit
+ * CMDPROTO: int csc_doautolimit(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_doautolimit(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regchan *rcp;
+ int oldlimit;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "autolimit");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV,
+ NULL, "autolimit", QPRIV_VIEWAUTOLIMIT, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cargc>1) {
+ if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV,
+ cip, "autolimit", QPRIV_CHANGEAUTOLIMIT, 0))
+ return CMD_ERROR;
+
+ oldlimit=rcp->autolimit;
+ rcp->autolimit=strtol(cargv[1],NULL,10);
+
+ if (rcp->autolimit<1)
+ rcp->autolimit=1;
+
+ csdb_updatechannel(rcp);
+
+ cs_log(sender,"AUTOLIMIT %s %s (%d -> %d)",cip->name->content,cargv[1],oldlimit,rcp->autolimit);
+ chanservstdmessage(sender, QM_DONE);
+ rcp->limit=0;
+ cs_timerfunc(cip);
+ }
+
+ chanservstdmessage(sender, QM_CHANAUTOLIMIT, cargv[0], rcp->autolimit);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: banclear
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Removes all bans from a channel including persistent bans.
+ * CMDFUNC: csc_dobanclear
+ * CMDPROTO: int csc_dobanclear(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dobanclear(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regban **rbh, *rbp;
+ chanban **cbh, *cbp;
+ regchan *rcp;
+ modechanges changes;
+ char *banstr;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "banclear");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "banclear", 0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cip->channel)
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+
+ for (rbh=&(rcp->bans); *rbh; ) {
+ rbp=*rbh;
+ banstr=bantostring(rbp->cbp);
+ chanservstdmessage(sender, QM_REMOVEDPERMBAN, banstr, cip->name->content);
+ if (cip->channel)
+ localdosetmode_ban(&changes, banstr, MCB_DEL);
+ /* Remove from database */
+ csdb_deleteban(rbp);
+ /* Remove from list */
+ (*rbh)=rbp->next;
+ /* Free ban/string and update setby refcount, and free actual regban */
+ freesstring(rbp->reason);
+ freechanban(rbp->cbp);
+ freeregban(rbp);
+ }
+
+ if (cip->channel) {
+ for (cbh=&(cip->channel->bans); *cbh; ) {
+ cbp=*cbh;
+ banstr=bantostring(cbp);
+ chanservstdmessage(sender, QM_REMOVEDCHANBAN, banstr, cip->name->content);
+ localdosetmode_ban(&changes, banstr, MCB_DEL);
+ }
+ localsetmodeflush(&changes,1);
+ }
+
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: bandel
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 2
+ * CMDDESC: Removes a single ban from a channel.
+ * CMDFUNC: csc_dobandel
+ * CMDPROTO: int csc_dobandel(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dobandel(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regban **rbh, *rbp;
+ chanban *cbp;
+ regchan *rcp;
+ chanban *theban=NULL;
+ modechanges changes;
+ int i,banid=0;
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unban");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "unban", 0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ /* OK, let's see what they want to remove.. */
+ if (*cargv[1]=='#') {
+ /* Remove by ID number */
+ if (!(banid=strtoul(cargv[1]+1, NULL, 10))) {
+ chanservstdmessage(sender, QM_UNKNOWNBAN, cargv[1], cip->name->content);
+ return CMD_ERROR;
+ }
+ } else {
+ /* Remove by ban string */
+ theban=makeban(cargv[1]);
+ }
+
+ i=0;
+ for (rbh=&(rcp->bans);*rbh;rbh=&((*rbh)->next)) {
+ i++;
+ if ((banid && i==banid) ||
+ (theban && banequal(theban, (*rbh)->cbp))) {
+ /* got it - they will need master access to remove this */
+ rbp=*rbh;
+
+ if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, "unban", 0, 0))
+ return CMD_ERROR;
+
+ chanservstdmessage(sender, QM_REMOVEDPERMBAN, bantostring(rbp->cbp), cip->name->content);
+ if (cip->channel) {
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+ localdosetmode_ban(&changes, bantostring(rbp->cbp), MCB_DEL);
+ localsetmodeflush(&changes, 1);
+ }
+
+ /* Remove from database */
+ csdb_deleteban(rbp);
+ /* Remove from list */
+ (*rbh)=rbp->next;
+ /* Free ban/string and actual regban */
+ freesstring(rbp->reason);
+ freechanban(rbp->cbp);
+ freeregban(rbp);
+
+ if (theban)
+ freechanban(theban);
+
+ return CMD_OK;
+ }
+ }
+
+ /* If we've run out of registered bans, let's try channel bans */
+ if (cip->channel && cip->channel->bans) {
+ for (cbp=cip->channel->bans;cbp;cbp=cbp->next) {
+ for (rbp=rcp->bans;rbp;rbp=rbp->next) {
+ if (banequal(rbp->cbp,cbp))
+ break;
+ }
+
+ if (rbp)
+ continue;
+
+ i++;
+ if ((banid && (i==banid)) ||
+ (theban && banequal(theban, cbp))) {
+ /* got it - this is just a channel ban */
+ chanservstdmessage(sender, QM_REMOVEDCHANBAN, bantostring(cbp), cip->name->content);
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+ localdosetmode_ban(&changes, cargv[1], MCB_DEL);
+ localsetmodeflush(&changes, 1);
+
+ if (theban)
+ freechanban(theban);
+
+ return CMD_OK;
+ }
+ }
+ }
+
+ chanservstdmessage(sender, QM_UNKNOWNBAN, cargv[1], cip->name->content);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: banlist
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Displays all persistent bans on a channel.
+ * CMDFUNC: csc_dobanlist
+ * CMDPROTO: int csc_dobanlist(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dobanlist(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regchan *rcp;
+ regban *rbp;
+ reguser *rup;
+ chanban *cbp;
+ int i=0;
+ int exp;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "banlist");
+ return CMD_ERROR;
+ }
+
+ if(!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "banlist", 0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (rcp->bans || cip->channel->bans) {
+ chanservstdmessage(sender, QM_REGBANHEADER, cip->name->content);
+ for(rbp=rcp->bans;rbp;rbp=rbp->next) {
+ rup=findreguserbyID(rbp->setby);
+ chanservsendmessage(sender," #%-2d %-29s %-18s %-15s %s",++i,bantostring(rbp->cbp),
+ rbp->expiry?longtoduration(rbp->expiry-time(NULL),0):"Permanent",
+ rup?rup->username:"<unknown>",
+ rbp->reason?rbp->reason->content:"");
+ }
+ for (cbp=cip->channel->bans;cbp;cbp=cbp->next) {
+ for (rbp=rcp->bans;rbp;rbp=rbp->next) {
+ if (banequal(rbp->cbp, cbp))
+ break;
+ }
+ if (!rbp) {
+ if (rcp->banduration) {
+ exp=(cbp->timeset + rcp->banduration) - time(NULL);
+ } else {
+ exp=0;
+ }
+ chanservsendmessage(sender, " #%-2d %-29s %-18s %-15s",++i,bantostring(cbp),
+ exp ? longtoduration(exp,0) : "Permanent",
+ "(channel ban)");
+ }
+ }
+ chanservstdmessage(sender, QM_ENDOFLIST);
+ } else {
+ chanservstdmessage(sender, QM_NOBANS, cip->name->content);
+ }
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: bantimer
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 2
+ * CMDDESC: Shows or changes the time after which bans are removed.
+ * CMDFUNC: csc_dobantimer
+ * CMDPROTO: int csc_dobantimer(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dobantimer(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regchan *rcp;
+ int oldtimer;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "bantimer");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "bantimer",
+ QPRIV_VIEWBANTIMER, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cargc>1) {
+ if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, "bantimer",
+ QPRIV_CHANGEBANTIMER, 0))
+ return CMD_ERROR;
+
+ oldtimer=rcp->banduration;
+ rcp->banduration=durationtolong(cargv[1]);
+
+ if (rcp->banduration<0)
+ rcp->banduration=0;
+
+ /* Arbitrary limit */
+ if (rcp->banduration > 31622400)
+ rcp->banduration = 31622400;
+
+ csdb_updatechannel(rcp);
+
+ cs_log(sender,"BANTIMER %s %s (%u -> %u)",cip->name->content,cargv[1],oldtimer,rcp->banduration);
+ chanservstdmessage(sender, QM_DONE);
+ cs_timerfunc(cip);
+ }
+
+ if (rcp->banduration)
+ chanservstdmessage(sender, QM_CHANBANAUTOREMOVE, cargv[0], longtoduration(rcp->banduration, 1));
+ else
+ chanservstdmessage(sender, QM_NOCHANBANAUTOREMOVE, cargv[0]);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: chanflags
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 2
+ * CMDDESC: Shows or changes the flags on a channel.
+ * CMDFUNC: csc_dochanflags
+ * CMDPROTO: int csc_dochanflags(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dochanflags(void *source, int cargc, char **cargv) {
+ regchan *rcp;
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ chanindex *cip;
+ flag_t oldflags,changemask;
+ char flagbuf[20];
+
+ if (cargc<1) {
+ chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanflags");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL,
+ "chanflags", QPRIV_VIEWCHANFLAGS, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cargc>1) {
+ if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, "chanflags",
+ QPRIV_CHANGECHANFLAGS, 0))
+ return CMD_ERROR;
+
+ oldflags=rcp->flags;
+ changemask=QCFLAG_USERCONTROL;
+ if (UIsDev(rup)) {
+ changemask=QCFLAG_ALL;
+ }
+ setflags(&rcp->flags, changemask, cargv[1], rcflags, REJECT_NONE);
+
+ /* We might need to do things in response to the flag changes.. */
+ if (cip->channel) {
+ if ((oldflags ^ rcp->flags) & (QCFLAG_JOINED | QCFLAG_SUSPENDED)) {
+ chanservjoinchan(cip->channel);
+ rcp->status |= (QCSTAT_OPCHECK | QCSTAT_MODECHECK | QCSTAT_BANCHECK);
+ rcp->lastbancheck=0;
+ cs_timerfunc(cip);
+ } else {
+ if (CIsEnforce(rcp)) {
+ rcp->lastbancheck=0;
+ cs_checkbans(cip->channel);
+ }
+
+ if (CIsProtect(rcp) || CIsBitch(rcp) || CIsAutoOp(rcp) || CIsAutoVoice(rcp) || CIsKnownOnly(rcp)) {
+ rcp->status |= QCSTAT_OPCHECK;
+ cs_timerfunc(cip);
+ }
+ }
+ }
+
+ if (CIsAutoLimit(rcp) && !(oldflags & QCFLAG_AUTOLIMIT)) {
+ rcp->forcemodes |= CHANMODE_LIMIT;
+ rcp->denymodes &= ~CHANMODE_LIMIT;
+ rcp->limit=0;
+ cs_timerfunc(cip);
+ }
+
+ if (!CIsAutoLimit(rcp) && (oldflags & QCFLAG_AUTOLIMIT)) {
+ rcp->forcemodes &= ~CHANMODE_LIMIT;
+ if (cip->channel)
+ cs_checkchanmodes(cip->channel);
+ }
+
+ strcpy(flagbuf,printflags(oldflags, rcflags));
+ cs_log(sender,"CHANFLAGS %s %s (%s -> %s)",cip->name->content,cargv[1],flagbuf,printflags(rcp->flags,rcflags));
+ chanservstdmessage(sender, QM_DONE);
+ csdb_updatechannel(rcp);
+ }
+
+ chanservstdmessage(sender,QM_CURCHANFLAGS,cip->name->content,printflags(rcp->flags, rcflags));
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: chanlev
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 3
+ * CMDDESC: Shows or modifies user access on a channel.
+ * CMDFUNC: csc_dochanlev
+ * CMDPROTO: int csc_dochanlev(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int compareflags(const void *u1, const void *u2) {
+ const regchanuser *r1=*(void **)u1, *r2=*(void **)u2;
+ flag_t f1,f2;
+
+ for (f1=QCUFLAG_OWNER;f1;f1>>=1)
+ if (r1->flags & f1)
+ break;
+
+ for (f2=QCUFLAG_OWNER;f2;f2>>=1)
+ if (r2->flags & f2)
+ break;
+
+ if (f1==f2) {
+ return ircd_strcmp(r1->user->username, r2->user->username);
+ } else {
+ return f2-f1;
+ }
+}
+
+int csc_dochanlev(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regchan *rcp;
+ regchanuser *rcup, *rcuplist;
+ regchanuser **rusers;
+ reguser *rup=getreguserfromnick(sender), *target;
+ char time1[15],time2[15];
+ char flagbuf[30];
+ struct tm *tmp;
+ flag_t flagmask, changemask, flags, oldflags;
+ int showtimes=0;
+ int donehead=0;
+ int i,j;
+ int newuser=0;
+ int usercount;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "chanlev");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_KNOWN,
+ NULL, "chanlev", QPRIV_VIEWFULLCHANLEV, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+ rcup=findreguseronchannel(rcp, rup);
+
+ /* Set flagmask for +v/+o users (can't see bans etc.) */
+ flagmask = (QCUFLAG_OWNER | QCUFLAG_MASTER | QCUFLAG_OP | QCUFLAG_VOICE | QCUFLAG_AUTOVOICE |
+ QCUFLAG_AUTOOP | QCUFLAG_TOPIC | QCUFLAG_SPAMCON | QCUFLAG_PROTECT | QCUFLAG_KNOWN);
+
+ /* If user has +m or above, or helper access, show everything */
+ if (cs_privcheck(QPRIV_VIEWFULLCHANLEV, sender) || CUHasMasterPriv(rcup)) {
+ flagmask = QCUFLAG_ALL;
+ showtimes=1;
+ }
+
+ if (cargc==1) {
+ /* One arg: list chanlev */
+ if (cs_privcheck(QPRIV_VIEWFULLCHANLEV, sender)) {
+ reguser *founder=NULL, *addedby=NULL;
+ addedby=findreguserbyID(rcp->addedby);
+ chanservstdmessage(sender, QM_ADDEDBY, addedby ? addedby->username : "(unknown)");
+ founder=findreguserbyID(rcp->founder);
+ chanservstdmessage(sender, QM_FOUNDER, founder ? founder->username : "(unknown)");
+ if (rcp->chantype) {
+ chanservstdmessage(sender, QM_CHANTYPE, chantypes[rcp->chantype]->content);
+ }
+ }
+
+ /* Count users */
+ for (i=0,usercount=0;i<REGCHANUSERHASHSIZE;i++)
+ for (rcuplist=rcp->regusers[i];rcuplist;rcuplist=rcuplist->nextbychan)
+ usercount++;
+
+ /* Allocate array */
+ rusers=(regchanuser **)malloc(usercount * sizeof(regchanuser *));
+
+ /* Fill array */
+ for (j=i=0;i<REGCHANUSERHASHSIZE;i++) {
+ for (rcuplist=rcp->regusers[i];rcuplist;rcuplist=rcuplist->nextbychan) {
+ if (!(flags=rcuplist->flags & flagmask))
+ continue;
+
+ rusers[j++]=rcuplist;
+ }
+ }
+
+ /* Sort */
+ qsort(rusers, j, sizeof(regchanuser *), compareflags);
+
+ /* List */
+ for (i=0;i<j;i++) {
+ rcuplist=rusers[i];
+
+ if (!(flags=rcuplist->flags & flagmask))
+ continue;
+
+ if (!donehead) {
+ chanservstdmessage(sender, QM_CHANLEVHEADER, cip->name->content);
+ if (showtimes)
+ chanservstdmessage(sender, QM_CHANLEVCOLFULL);
+ else
+ chanservstdmessage(sender, QM_CHANLEVCOLSHORT);
+ donehead=1;
+ }
+
+ if (showtimes) {
+ if (!rcuplist->usetime) {
+ strcpy(time1,"Never");
+ } else {
+ tmp=localtime(&(rcuplist->usetime));
+ strftime(time1,15,"%d/%m/%y %H:%M",tmp);
+ }
+ if (!rcuplist->changetime) {
+ strcpy(time2, "Unknown");
+ } else {
+ tmp=localtime(&(rcuplist->changetime));
+ strftime(time2,15,"%d/%m/%y %H:%M",tmp);
+ }
+ chanservsendmessage(sender, " %-15s %-13s %-14s %-14s %s", rcuplist->user->username,
+ printflags(flags, rcuflags), time1, time2, rcuplist->info?rcuplist->info->content:"");
+ } else
+ chanservsendmessage(sender, " %-15s %s", rcuplist->user->username, printflags(flags, rcuflags));
+ }
+
+ if (donehead) {
+ chanservstdmessage(sender, QM_ENDOFLIST);
+ } else {
+ chanservstdmessage(sender, QM_NOUSERSONCHANLEV, cip->name->content);
+ }
+
+ free(rusers);
+ } else {
+ /* 2 or more args.. relates to one specific user */
+ if (!(target=findreguser(sender, cargv[1])))
+ return CMD_ERROR; /* If there was an error, findreguser will have sent a message saying why.. */
+
+ rcuplist=findreguseronchannel(rcp, target);
+
+ if (cargc>2) {
+ /* To change chanlev you have to either.. */
+ if (!( cs_privcheck(QPRIV_CHANGECHANLEV, sender) || /* Have override privilege */
+ (rcup && rcuplist && (rcup==rcuplist) && CUKnown(rcup)) || /* Be manipulting yourself (oo er..) */
+ (rcup && CUHasMasterPriv(rcup) && /* Have +m or +n on the channel */
+ !(rcuplist && CUIsOwner(rcuplist) && !CUIsOwner(rcup))) /* masters can't screw with owners */
+ )) {
+ chanservstdmessage(sender, QM_NOACCESSONCHAN, cip->name->content, "chanlev");
+ return CMD_ERROR;
+ }
+
+ if (!rcuplist) {
+ rcuplist=getregchanuser();
+ rcuplist->user=target;
+ rcuplist->chan=rcp;
+ rcuplist->flags=0;
+ rcuplist->changetime=time(NULL);
+ rcuplist->usetime=0;
+ rcuplist->info=NULL;
+ newuser=1;
+ }
+
+ if (cs_privcheck(QPRIV_CHANGECHANLEV, sender)) {
+ /* Opers are allowed to change everything */
+ changemask = QCUFLAG_ALL;
+ } else {
+ changemask=0;
+
+ /* Everyone can change their own flags (except +dqb), and turn +iwj on/off */
+ if (rcup==rcuplist) {
+ changemask = (rcup->flags | QCUFLAG_HIDEWELCOME | QCUFLAG_HIDEINFO | QCUFLAG_AUTOINVITE) &
+ ~(QCUFLAG_BANNED | QCUFLAG_DENY | QCUFLAG_QUIET);
+ flagmask |= (QCUFLAG_HIDEWELCOME | QCUFLAG_HIDEINFO | QCUFLAG_AUTOINVITE);
+ }
+
+ /* Masters are allowed to manipulate +ovagtbqdpk */
+ if (CUHasMasterPriv(rcup))
+ changemask |= ( QCUFLAG_KNOWN | QCUFLAG_OP | QCUFLAG_VOICE | QCUFLAG_AUTOOP | QCUFLAG_AUTOVOICE |
+ QCUFLAG_TOPIC | QCUFLAG_BANNED | QCUFLAG_QUIET | QCUFLAG_DENY | QCUFLAG_PROTECT);
+
+ /* Owners are allowed to manipulate +ms as well */
+ if (CUIsOwner(rcup))
+ changemask |= ( QCUFLAG_MASTER | QCUFLAG_SPAMCON );
+ }
+
+ oldflags=rcuplist->flags;
+ if (setflags(&(rcuplist->flags), changemask, cargv[2], rcuflags, REJECT_UNKNOWN | REJECT_DISALLOWED)) {
+ chanservstdmessage(sender, QM_INVALIDCHANLEVCHANGE);
+ return CMD_ERROR;
+ }
+
+ /* Now fix up some "impossible" combinations.. */
+ /* +m can't be any of +qdb */
+ if (CUHasMasterPriv(rcuplist))
+ rcuplist->flags &= ~(QCUFLAG_BANNED | QCUFLAG_QUIET | QCUFLAG_DENY);
+
+ /* +d can't be +o */
+ if (CUIsDeny(rcuplist))
+ rcuplist->flags &= ~QCUFLAG_OP;
+
+ /* +q can't be +v */
+ if (CUIsQuiet(rcuplist))
+ rcuplist->flags &= ~QCUFLAG_VOICE;
+
+ /* -o or +p can't be +a */
+ if (!CUIsOp(rcuplist) || CUIsProtect(rcuplist))
+ rcuplist->flags &= ~QCUFLAG_AUTOOP;
+
+ /* +a or -v or +p can't be +g */
+ if (!CUIsVoice(rcuplist) || CUIsAutoOp(rcuplist) || CUIsProtect(rcuplist))
+ rcuplist->flags &= ~QCUFLAG_AUTOVOICE;
+
+ /* and -ov can't be +p */
+ if (!CUIsOp(rcuplist) && !CUIsVoice(rcuplist))
+ rcuplist->flags &= ~QCUFLAG_PROTECT;
+
+ /* Check if anything "significant" has changed */
+ if ((oldflags ^ rcuplist->flags) & (QCUFLAG_OWNER | QCUFLAG_MASTER | QCUFLAG_OP))
+ rcuplist->changetime=time(NULL);
+
+ strcpy(flagbuf,printflags(oldflags,rcuflags));
+ cs_log(sender,"CHANLEV %s #%s %s (%s -> %s)",cip->name->content,rcuplist->user->username,cargv[2],
+ flagbuf,printflags(rcuplist->flags,rcuflags));
+
+ /* Now see what we do next */
+ if (rcuplist->flags) {
+ /* User still valid: update or create */
+ if (newuser) {
+ addregusertochannel(rcuplist);
+ csdb_createchanuser(rcuplist);
+ } else {
+ csdb_updatechanuser(rcuplist);
+ }
+ } else {
+ /* User has no flags: delete */
+ if (!newuser) {
+ csdb_deletechanuser(rcuplist);
+ delreguserfromchannel(rcp, target);
+ }
+ freeregchanuser(rcuplist);
+ rcuplist=NULL;
+ for (i=0;i<REGCHANUSERHASHSIZE;i++)
+ if (rcp->regusers[i])
+ break;
+ if (i==REGCHANUSERHASHSIZE) {
+ cs_log(sender,"DELCHAN %s (Cleared chanlev)",cip->name->content);
+ cs_removechannel(rcp);
+ }
+ }
+
+ /* Say we've done it */
+ chanservstdmessage(sender, QM_DONE);
+ rcp->status |= QCSTAT_OPCHECK;
+ cs_timerfunc(cip);
+ }
+
+ if (rcuplist && (rcuplist->flags & flagmask)) {
+ chanservstdmessage(sender, QM_CHANUSERFLAGS, cargv[1], cip->name->content,
+ printflags(rcuplist->flags & flagmask, rcuflags));
+ } else {
+ chanservstdmessage(sender, QM_CHANUSERUNKNOWN, cargv[1], cip->name->content);
+ }
+ }
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: chanmode
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 4
+ * CMDDESC: Shows which modes are forced or denied on a channel.
+ * CMDFUNC: csc_dochanmode
+ * CMDPROTO: int csc_dochanmode(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+char *getchanmode(regchan *rcp) {
+ static char buf1[50];
+ char buf2[30];
+
+ if (rcp->forcemodes) {
+ strcpy(buf1,printflags(rcp->forcemodes, cmodeflags));
+ } else {
+ buf1[0]='\0';
+ }
+
+ strcpy(buf2,printflagdiff(CHANMODE_ALL, ~(rcp->denymodes), cmodeflags));
+ strcat(buf1, buf2);
+
+ if (rcp->forcemodes & CHANMODE_LIMIT) {
+ sprintf(buf2, " %d",rcp->limit);
+ strcat(buf1, buf2);
+ }
+
+ if (rcp->forcemodes & CHANMODE_KEY) {
+ sprintf(buf2, " %s",rcp->key->content);
+ strcat(buf1, buf2);
+ }
+
+ if (*buf1=='\0') {
+ strcpy(buf1,"(none)");
+ }
+
+ return buf1;
+}
+
+int csc_dochanmode(void *source, int cargc, char **cargv) {
+ regchan *rcp;
+ nick *sender=source;
+ chanindex *cip;
+ flag_t forceflags,denyflags;
+ char buf1[60];
+ int carg=2,limdone=0;
+ sstring *newkey=NULL;
+ unsigned int newlim=0;
+
+ if (cargc<1) {
+ chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV,
+ NULL, "chanmode", QPRIV_VIEWCHANMODES, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cargc>1) {
+ if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV,
+ cip, "chanmode", QPRIV_CHANGECHANMODES, 0))
+ return CMD_ERROR;
+
+ /* Save the current modes.. */
+ strcpy(buf1,getchanmode(rcp));
+
+ /* Pick out the + flags: start from 0 */
+ forceflags=0;
+ setflags(&forceflags, CHANMODE_ALL, cargv[1], cmodeflags, REJECT_NONE);
+
+ /* Pick out the - flags: start from everything and invert afterwards.. */
+ denyflags=CHANMODE_ALL;
+ setflags(&denyflags, CHANMODE_ALL, cargv[1], cmodeflags, REJECT_NONE);
+ denyflags = (~denyflags) & CHANMODE_ALL;
+
+ forceflags &= ~denyflags; /* Can't force and deny the same mode (shouldn't be possible anyway) */
+ if (forceflags & CHANMODE_SECRET) {
+ forceflags &= ~CHANMODE_PRIVATE;
+ denyflags |= CHANMODE_PRIVATE;
+ }
+ if (forceflags & CHANMODE_PRIVATE) {
+ forceflags &= ~CHANMODE_SECRET;
+ denyflags |= CHANMODE_SECRET;
+ }
+
+ if ((forceflags & CHANMODE_LIMIT) &&
+ (!(forceflags & CHANMODE_KEY) || strrchr(cargv[1],'l') < strrchr(cargv[1],'k'))) {
+ if (cargc<=carg) {
+ chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
+ return CMD_ERROR;
+ }
+ newlim=strtol(cargv[carg++],NULL,10);
+ limdone=1;
+ }
+
+ if (forceflags & CHANMODE_KEY) {
+ if (cargc<=carg) {
+ chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
+ return CMD_ERROR;
+ }
+ newkey=getsstring(cargv[carg++], KEYLEN);
+ }
+
+ if ((forceflags & CHANMODE_LIMIT) && !limdone) {
+ if (cargc<=carg) {
+ chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
+ return CMD_ERROR;
+ }
+ newlim=strtol(cargv[carg++],NULL,10);
+ limdone=1;
+ }
+
+ if (CIsAutoLimit(rcp)) {
+ forceflags |= CHANMODE_LIMIT;
+ denyflags &= ~CHANMODE_LIMIT;
+ newlim=rcp->limit;
+ }
+
+ /* It parsed OK, so update the structure.. */
+ rcp->forcemodes=forceflags;
+ rcp->denymodes=denyflags;
+ if (rcp->key)
+ freesstring(rcp->key);
+ rcp->key=newkey;
+ rcp->limit=newlim;
+
+ chanservstdmessage(sender, QM_DONE);
+ cs_log(sender,"CHANMODE %s %s (%s -> %s)",cip->name->content,cargv[1],buf1,getchanmode(rcp));
+ csdb_updatechannel(rcp);
+ cs_checkchanmodes(cip->channel);
+ }
+
+ chanservstdmessage(sender,QM_CURFORCEMODES,cip->name->content,getchanmode(rcp));
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: channelcomment
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 2
+ * CMDDESC: Shows or changes the staff comment for a channel.
+ * CMDFUNC: csc_dochannelcomment
+ * CMDPROTO: int csc_dochannelcomment(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dochannelcomment(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ regchan *rcp;
+ chanindex *cip;
+ char buf[300];
+ int bufpos;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "channelcomment");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
+ chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (cargc>1) {
+ if (!ircd_strcmp(cargv[1],"none")) {
+ freesstring(rcp->comment);
+ rcp->comment=NULL;
+ } else {
+ if (*cargv[1]=='+') {
+ if (rcp->comment) {
+ strcpy(buf,rcp->comment->content);
+ bufpos=rcp->comment->length;
+ buf[bufpos++]=' ';
+ } else {
+ bufpos=0;
+ }
+ strncpy(buf+bufpos, cargv[1]+1, 250-bufpos);
+ } else {
+ strncpy(buf, cargv[1], 250);
+ }
+
+ freesstring(rcp->comment);
+ rcp->comment=getsstring(buf,250);
+ }
+ csdb_updatechannel(rcp);
+ }
+
+ if (rcp->comment)
+ chanservstdmessage(sender, QM_COMMENT, cip->name->content, rcp->comment->content);
+ else
+ chanservstdmessage(sender, QM_NOCOMMENT, cip->name->content);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: chanstat
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Displays channel activity statistics.
+ * CMDFUNC: csc_dochanstat
+ * CMDPROTO: int csc_dochanstat(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dochanstat(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regchan *rcp;
+ char timebuf[30];
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "chanstat");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV,
+ NULL, "chanstat", QPRIV_VIEWFULLCHANLEV, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ chanservstdmessage(sender, QM_STATSHEADER, cip->name->content);
+
+ strftime(timebuf, 30, "%d/%m/%y %H:%M", localtime(&(rcp->created)));
+ chanservstdmessage(sender, QM_STATSADDED, timebuf);
+
+ /* Show opers founder/addedby/type info */
+ if (cs_privcheck(QPRIV_VIEWFULLCHANLEV, sender)) {
+ reguser *founder=NULL, *addedby=NULL;
+
+ strftime(timebuf, 30, "%d/%m/%y %H:%M", localtime(&(rcp->lastactive)));
+ chanservstdmessage(sender, QM_STATSLASTACTIVE, timebuf);
+
+
+ addedby=findreguserbyID(rcp->addedby);
+ chanservstdmessage(sender, QM_ADDEDBY, addedby ? addedby->username : "(unknown)");
+ founder=findreguserbyID(rcp->founder);
+ chanservstdmessage(sender, QM_FOUNDER, founder ? founder->username : "(unknown)");
+ chanservstdmessage(sender, QM_CHANTYPE, chantypes[rcp->chantype]->content);
+ }
+
+ strftime(timebuf, 30, "%d/%m/%y %H:%M", localtime(&(rcp->created)));
+
+ chanservstdmessage(sender, QM_STATSJOINS, timebuf, rcp->maxusers, rcp->totaljoins,
+ (float)rcp->totaljoins/ ((time(NULL)-rcp->created)/(3600*24)));
+
+ strftime(timebuf, 30, "%d/%m/%y %H:%M", localtime(&(rcp->statsreset)));
+
+ chanservstdmessage(sender, QM_STATSJOINS, timebuf, rcp->tripusers, rcp->tripjoins,
+ (float)rcp->tripjoins / ((time(NULL)-rcp->statsreset)/(3600*24)));
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: chantype
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 2
+ * CMDDESC: Shows or changes a channel's type.
+ * CMDFUNC: csc_dochantype
+ * CMDPROTO: int csc_dochantype(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dochantype(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regchan *rcp;
+ int type;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "chantype");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
+ chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (cargc>1) {
+ /* Set type */
+ for (type=CHANTYPES-1;type;type--) {
+ if (!ircd_strcmp(chantypes[type]->content, cargv[1]))
+ break;
+ }
+ if (!type) {
+ chanservstdmessage(sender, QM_UNKNOWNCHANTYPE, cargv[1]);
+ return CMD_ERROR;
+ }
+ rcp->chantype=type;
+
+ csdb_updatechannel(rcp);
+ chanservstdmessage(sender, QM_DONE);
+ }
+
+ chanservstdmessage(sender, QM_CHANTYPEIS, cip->name->content, chantypes[rcp->chantype]->content);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: clearchan
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Removes all modes from a channel.
+ * CMDFUNC: csc_doclearchan
+ * CMDPROTO: int csc_doclearchan(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_doclearchan(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ regchan *rcp;
+ chanindex *cip;
+ modechanges changes;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "clearchan");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "clearchan",0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cip->channel) {
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+ localdosetmode_key(&changes, NULL, MCB_DEL);
+ localdosetmode_simple(&changes, 0, cip->channel->flags);
+ cs_docheckchanmodes(cip->channel, &changes);
+ localsetmodeflush(&changes, 1);
+ }
+
+ cs_log(sender,"CLEARCHAN %s",cip->name->content);
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by mkcommandlist.pl, do not edit. */
+
+#include "../chanserv.h"
+
+/* Prototypes */
+int csc_doaddchan(void *source, int cargc, char **cargv);
+int csc_doadduser(void *source, int cargc, char **cargv);
+int csc_doautolimit(void *source, int cargc, char **cargv);
+int csc_dobanclear(void *source, int cargc, char **cargv);
+int csc_dobandel(void *source, int cargc, char **cargv);
+int csc_dobanlist(void *source, int cargc, char **cargv);
+int csc_dobantimer(void *source, int cargc, char **cargv);
+int csc_dochanflags(void *source, int cargc, char **cargv);
+int csc_dochanlev(void *source, int cargc, char **cargv);
+int csc_dochanmode(void *source, int cargc, char **cargv);
+int csc_dochannelcomment(void *source, int cargc, char **cargv);
+int csc_dochanstat(void *source, int cargc, char **cargv);
+int csc_dochantype(void *source, int cargc, char **cargv);
+int csc_doclearchan(void *source, int cargc, char **cargv);
+int csc_dodelchan(void *source, int cargc, char **cargv);
+int csc_dodeopall(void *source, int cargc, char **cargv);
+int csc_dodevoiceall(void *source, int cargc, char **cargv);
+int csc_doinvite(void *source, int cargc, char **cargv);
+int csc_doop(void *source, int cargc, char **cargv);
+int csc_dopermban(void *source, int cargc, char **cargv);
+int csc_dorecover(void *source, int cargc, char **cargv);
+int csc_dorejoin(void *source, int cargc, char **cargv);
+int csc_doremoveuser(void *source, int cargc, char **cargv);
+int csc_dorenchan(void *source, int cargc, char **cargv);
+int csc_dosettopic(void *source, int cargc, char **cargv);
+int csc_dosuspendchan(void *source, int cargc, char **cargv);
+int csc_dosuspendchanlist(void *source, int cargc, char **cargv);
+int csc_dotempban(void *source, int cargc, char **cargv);
+int csc_dounbanall(void *source, int cargc, char **cargv);
+int csc_dounbanmask(void *source, int cargc, char **cargv);
+int csc_dounbanme(void *source, int cargc, char **cargv);
+int csc_dounsuspendchan(void *source, int cargc, char **cargv);
+int csc_dovoice(void *source, int cargc, char **cargv);
+int csc_dowelcome(void *source, int cargc, char **cargv);
+
+void _init() {
+ chanservaddcommand("addchan", QCMD_OPER, 4, csc_doaddchan, "Adds a new channel to the bot.");
+ chanservaddcommand("adduser", QCMD_AUTHED, 20, csc_doadduser, "Adds one or more users to a channel as +aot.");
+ chanservaddcommand("autolimit", QCMD_AUTHED, 2, csc_doautolimit, "Shows or changes the autolimit threshold on a channel.");
+ chanservaddcommand("banclear", QCMD_AUTHED, 1, csc_dobanclear, "Removes all bans from a channel including persistent bans.");
+ chanservaddcommand("bandel", QCMD_AUTHED, 2, csc_dobandel, "Removes a single ban from a channel.");
+ chanservaddcommand("banlist", QCMD_AUTHED, 1, csc_dobanlist, "Displays all persistent bans on a channel.");
+ chanservaddcommand("bantimer", QCMD_AUTHED, 2, csc_dobantimer, "Shows or changes the time after which bans are removed.");
+ chanservaddcommand("chanflags", QCMD_AUTHED, 2, csc_dochanflags, "Shows or changes the flags on a channel.");
+ chanservaddcommand("chanlev", QCMD_AUTHED, 3, csc_dochanlev, "Shows or modifies user access on a channel.");
+ chanservaddcommand("chanmode", QCMD_AUTHED, 4, csc_dochanmode, "Shows which modes are forced or denied on a channel.");
+ chanservaddcommand("channelcomment", QCMD_OPER, 2, csc_dochannelcomment, "Shows or changes the staff comment for a channel.");
+ chanservaddcommand("chanstat", QCMD_AUTHED, 1, csc_dochanstat, "Displays channel activity statistics.");
+ chanservaddcommand("chantype", QCMD_OPER, 2, csc_dochantype, "Shows or changes a channel's type.");
+ chanservaddcommand("clearchan", QCMD_AUTHED, 1, csc_doclearchan, "Removes all modes from a channel.");
+ chanservaddcommand("delchan", QCMD_OPER, 2, csc_dodelchan, "Removes a channel from the bot.");
+ chanservaddcommand("deopall", QCMD_AUTHED, 1, csc_dodeopall, "Deops all users on channel.");
+ chanservaddcommand("devoiceall", QCMD_AUTHED, 1, csc_dodevoiceall, "Devoices all users on a channel.");
+ chanservaddcommand("invite", QCMD_AUTHED, 1, csc_doinvite, "Invites you to a channel.");
+ chanservaddcommand("op", QCMD_AUTHED, 20, csc_doop, "Ops you or other users on channel(s).");
+ chanservaddcommand("permban", QCMD_AUTHED, 3, csc_dopermban, "Permanently bans a hostmask on a channel.");
+ chanservaddcommand("recover", QCMD_AUTHED, 1, csc_dorecover, "Recovers a channel (same as deopall, unbanall, clearchan).");
+ chanservaddcommand("rejoin", QCMD_OPER, 1, csc_dorejoin, "Makes the bot rejoin a channel.");
+ chanservaddcommand("removeuser", QCMD_AUTHED, 20, csc_doremoveuser, "Removes one or more users from a channel.");
+ chanservaddcommand("renchan", QCMD_OPER, 2, csc_dorenchan, "Renames a channel on the bot.");
+ chanservaddcommand("settopic", QCMD_AUTHED, 2, csc_dosettopic, "Changes the topic on a channel.");
+ chanservaddcommand("suspendchan", QCMD_OPER, 2, csc_dosuspendchan, "Suspends a channel from the bot.");
+ chanservaddcommand("suspendchanlist", QCMD_HELPER, 1, csc_dosuspendchanlist, "Lists suspended channels.");
+ chanservaddcommand("tempban", QCMD_AUTHED, 4, csc_dotempban, "Bans a hostmask on a channel for a specified time period.");
+ chanservaddcommand("unbanall", QCMD_AUTHED, 1, csc_dounbanall, "Removes all bans from a channel.");
+ chanservaddcommand("unbanmask", QCMD_AUTHED, 2, csc_dounbanmask, "Removes bans matching a particular mask from a channel.");
+ chanservaddcommand("unbanme", QCMD_AUTHED, 1, csc_dounbanme, "Removes any bans affecting you from a channel.");
+ chanservaddcommand("unsuspendchan", QCMD_OPER, 1, csc_dounsuspendchan, "Unsuspends a channel from the bot.");
+ chanservaddcommand("voice", QCMD_AUTHED, 20, csc_dovoice, "Voices you or other users on channel(s).");
+ chanservaddcommand("welcome", QCMD_AUTHED, 2, csc_dowelcome, "Shows or changes the welcome message on a channel.");
+}
+
+void _fini() {
+ chanservremovecommand("addchan", csc_doaddchan);
+ chanservremovecommand("adduser", csc_doadduser);
+ chanservremovecommand("autolimit", csc_doautolimit);
+ chanservremovecommand("banclear", csc_dobanclear);
+ chanservremovecommand("bandel", csc_dobandel);
+ chanservremovecommand("banlist", csc_dobanlist);
+ chanservremovecommand("bantimer", csc_dobantimer);
+ chanservremovecommand("chanflags", csc_dochanflags);
+ chanservremovecommand("chanlev", csc_dochanlev);
+ chanservremovecommand("chanmode", csc_dochanmode);
+ chanservremovecommand("channelcomment", csc_dochannelcomment);
+ chanservremovecommand("chanstat", csc_dochanstat);
+ chanservremovecommand("chantype", csc_dochantype);
+ chanservremovecommand("clearchan", csc_doclearchan);
+ chanservremovecommand("delchan", csc_dodelchan);
+ chanservremovecommand("deopall", csc_dodeopall);
+ chanservremovecommand("devoiceall", csc_dodevoiceall);
+ chanservremovecommand("invite", csc_doinvite);
+ chanservremovecommand("op", csc_doop);
+ chanservremovecommand("permban", csc_dopermban);
+ chanservremovecommand("recover", csc_dorecover);
+ chanservremovecommand("rejoin", csc_dorejoin);
+ chanservremovecommand("removeuser", csc_doremoveuser);
+ chanservremovecommand("renchan", csc_dorenchan);
+ chanservremovecommand("settopic", csc_dosettopic);
+ chanservremovecommand("suspendchan", csc_dosuspendchan);
+ chanservremovecommand("suspendchanlist", csc_dosuspendchanlist);
+ chanservremovecommand("tempban", csc_dotempban);
+ chanservremovecommand("unbanall", csc_dounbanall);
+ chanservremovecommand("unbanmask", csc_dounbanmask);
+ chanservremovecommand("unbanme", csc_dounbanme);
+ chanservremovecommand("unsuspendchan", csc_dounsuspendchan);
+ chanservremovecommand("voice", csc_dovoice);
+ chanservremovecommand("welcome", csc_dowelcome);
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: delchan
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 2
+ * CMDDESC: Removes a channel from the bot.
+ * CMDFUNC: csc_dodelchan
+ * CMDPROTO: int csc_dodelchan(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dodelchan(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ chanindex *cip;
+ regchan *rcp;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "delchan");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
+ chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ cs_log(sender,"DELCHAN %s (%s)",cip->name->content,cargc>1?cargv[1]:"");
+ cs_removechannel(rcp);
+ chanservstdmessage(sender, QM_DONE);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: deopall
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Deops all users on channel.
+ * CMDFUNC: csc_dodeopall
+ * CMDPROTO: int csc_dodeopall(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dodeopall(void *source, int cargc, char **cargv) {
+ nick *sender=source,*np;
+ reguser *rup;
+ regchanuser *rcup;
+ regchan *rcp;
+ chanindex *cip;
+ unsigned long *lp;
+ int i;
+ modechanges changes;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "deopall");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "deopall",0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cip->channel) {
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+
+ for (i=0,lp=cip->channel->users->content;
+ i<cip->channel->users->hashsize;i++,lp++) {
+ if (*lp!=nouser && (*lp & CUMODE_OP)) {
+ if (!(np=getnickbynumeric(*lp)) ||
+ (!IsService(np) && (!(rup=getreguserfromnick(np)) ||
+ !(rcup=findreguseronchannel(rcp, rup)) || !(CUHasOpPriv(rcup)) ||
+ !(CUIsProtect(rcup) || CIsProtect(rcp))))) {
+ localdosetmode_nick(&changes, np, MC_DEOP);
+ }
+ }
+ }
+
+ localsetmodeflush(&changes, 1);
+ }
+
+ cs_log(sender,"DEOPALL %s",cip->name->content);
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: devoiceall
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Devoices all users on a channel.
+ * CMDFUNC: csc_dodevoiceall
+ * CMDPROTO: int csc_dodevoiceall(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dodevoiceall(void *source, int cargc, char **cargv) {
+ nick *sender=source,*np;
+ reguser *rup;
+ regchanuser *rcup;
+ regchan *rcp;
+ chanindex *cip;
+ unsigned long *lp;
+ int i;
+ modechanges changes;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "devoiceall");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "devoiceall",0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cip->channel) {
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+
+ for (i=0,lp=cip->channel->users->content;
+ i<cip->channel->users->hashsize;i++,lp++) {
+ if (*lp!=nouser && (*lp & CUMODE_VOICE)) {
+ if (!(np=getnickbynumeric(*lp)) ||
+ (!IsService(np) && (!(rup=getreguserfromnick(np)) ||
+ !(rcup=findreguseronchannel(rcp, rup)) || !(CUHasVoicePriv(rcup)) ||
+ !(CUIsProtect(rcup) || CIsProtect(rcp))))) {
+ localdosetmode_nick(&changes, np, MC_DEVOICE);
+ }
+ }
+ }
+
+ localsetmodeflush(&changes, 1);
+ }
+
+ cs_log(sender,"DEVOICEALL %s",cip->name->content);
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: invite
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Invites you to a channel.
+ * CMDFUNC: csc_doinvite
+ * CMDPROTO: int csc_doinvite(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_doinvite(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "invite");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_KNOWN | CA_OFFCHAN,
+ NULL, "invite", 0, 0)))
+ return CMD_ERROR;
+
+ if (cip->channel) {
+ localinvite(chanservnick, cip->channel, sender);
+ }
+ chanservstdmessage(sender, QM_DONE);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: op
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 20
+ * CMDDESC: Ops you or other users on channel(s).
+ * CMDFUNC: csc_doop
+ * CMDPROTO: int csc_doop(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_doop(void *source, int cargc, char **cargv) {
+ nick *sender=source, *np;
+ reguser *rup=getreguserfromnick(sender);
+ chanindex *cip;
+ regchan *rcp=NULL;
+ regchanuser *rcup;
+ channel **ca;
+ unsigned long *lp;
+ int i;
+ modechanges changes;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc==0) {
+ /* No args: "op me on every channel you can */
+ ca=sender->channels->content;
+ for (i=0;i<sender->channels->cursi;i++) {
+ if ((rcp=ca[i]->index->exts[chanservext]) && !CIsSuspended(rcp)) {
+ /* It's a Q channel */
+ if (!(*(getnumerichandlefromchanhash(ca[i]->users, sender->numeric)) &
+ CUMODE_OP)) {
+ /* They're not opped */
+ if ((rcup=findreguseronchannel(rcp, rup)) && CUHasOpPriv(rcup) &&
+ !CUIsDeny(rcup)) {
+ /* And they have op priv on the chan: op them */
+ localsetmodeinit(&changes, ca[i], chanservnick);
+ localdosetmode_nick(&changes, sender, MC_OP);
+ localsetmodeflush(&changes,1);
+ }
+ }
+ }
+ }
+
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+ }
+
+ /* If there is at least one arg, the first is a channel */
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "op", 0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cargc==1) {
+ /* Only one arg: "op me" */
+ if (!cs_checkaccess(sender, NULL, CA_OPPRIV | CA_DEOPPED, cip, "op", 0, 0))
+ return CMD_ERROR;
+
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+ localdosetmode_nick(&changes, sender, MC_OP);
+ localsetmodeflush(&changes,1);
+
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+ }
+
+ /* Set up the modes */
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+
+ for(i=1;i<cargc;i++) {
+ if (!(np=getnickbynick(cargv[i]))) {
+ chanservstdmessage(sender, QM_UNKNOWNUSER, cargv[i]);
+ continue;
+ }
+
+ if (!(lp=getnumerichandlefromchanhash(cip->channel->users, np->numeric))) {
+ chanservstdmessage(sender, QM_USERNOTONCHAN, np->nick, cip->name->content);
+ continue;
+ }
+
+ if (*lp & CUMODE_OP) {
+ chanservstdmessage(sender, QM_USEROPPEDONCHAN, np->nick, cip->name->content);
+ continue;
+ }
+
+ rup=getreguserfromnick(np);
+ if (rup)
+ rcup=findreguseronchannel(rcp,rup);
+ else
+ rcup=NULL;
+
+ /* Bitch mode: check that this user is allowed to be opped.. */
+ if ((CIsBitch(rcp) && (!rcup || !CUHasOpPriv(rcup))) || (rcup && CUIsDeny(rcup))) {
+ chanservstdmessage(sender, QM_CANTOP, np->nick, cip->name->content);
+ continue;
+ }
+
+ localdosetmode_nick(&changes, np, MC_OP);
+ }
+
+ localsetmodeflush(&changes, 1);
+ chanservstdmessage(sender, QM_DONE);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: permban
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 3
+ * CMDDESC: Permanently bans a hostmask on a channel.
+ * CMDFUNC: csc_dopermban
+ * CMDPROTO: int csc_dopermban(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dopermban(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regban *rbp;
+ regchan *rcp;
+ reguser *rup=getreguserfromnick(sender);
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "permban");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "permban",0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ rbp=getregban();
+ rbp->ID=++lastbanID;
+ rbp->cbp=makeban(cargv[1]);
+ rbp->setby=rup->ID;
+ rbp->expiry=0;
+ if (cargc>2)
+ rbp->reason=getsstring(cargv[2],200);
+ else
+ rbp->reason=NULL;
+ rbp->next=rcp->bans;
+ rcp->bans=rbp;
+
+ cs_setregban(cip, rbp);
+ csdb_createban(rcp, rbp);
+
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: recover
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Recovers a channel (same as deopall, unbanall, clearchan).
+ * CMDFUNC: csc_dorecover
+ * CMDPROTO: int csc_dorecover(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dorecover(void *source, int cargc, char **cargv) {
+ nick *sender=source,*np;
+ reguser *rup;
+ regchanuser *rcup;
+ regchan *rcp;
+ chanindex *cip;
+ unsigned long *lp;
+ int i;
+ modechanges changes;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "recover");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "recover",0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cip->channel) {
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+
+ /* clearchan */
+ localdosetmode_key(&changes, NULL, MCB_DEL);
+ localdosetmode_simple(&changes, 0, cip->channel->flags);
+ cs_docheckchanmodes(cip->channel, &changes);
+
+ /* unbanall */
+ while (cip->channel->bans) {
+ localdosetmode_ban(&changes, bantostring(cip->channel->bans), MCB_DEL);
+ }
+
+ /* deopall */
+ for (i=0,lp=cip->channel->users->content;
+ i<cip->channel->users->hashsize;i++,lp++) {
+ if (*lp!=nouser && (*lp & CUMODE_OP)) {
+ if (!(np=getnickbynumeric(*lp)) ||
+ (!IsService(np) && (!(rup=getreguserfromnick(np)) ||
+ !(rcup=findreguseronchannel(rcp, rup)) || !(CUHasOpPriv(rcup)) ||
+ !(CUIsProtect(rcup) || CIsProtect(rcp))))) {
+ localdosetmode_nick(&changes, np, MC_DEOP);
+ }
+ }
+ }
+
+ localsetmodeflush(&changes, 1);
+ }
+
+ cs_log(sender,"RECOVER %s",cip->name->content);
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: rejoin
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 1
+ * CMDDESC: Makes the bot rejoin a channel.
+ * CMDFUNC: csc_dorejoin
+ * CMDPROTO: int csc_dorejoin(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dorejoin(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regchan *rcp;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "rejoin");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
+ chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (CIsJoined(rcp) && !CIsSuspended(rcp)) {
+ CSetSuspended(rcp);
+ chanservjoinchan(cip->channel);
+ CClearSuspended(rcp);
+ chanservjoinchan(cip->channel);
+ }
+
+ chanservstdmessage(sender, QM_DONE);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: removeuser
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 20
+ * CMDDESC: Removes one or more users from a channel.
+ * CMDFUNC: csc_doremoveuser
+ * CMDPROTO: int csc_doremoveuser(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_doremoveuser(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regchanuser *rcup;
+ regchan *rcp;
+ reguser *rup;
+ int isowner=0;
+ int i;
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "removeuser");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "adduser", QPRIV_CHANGECHANLEV, 0)))
+ return CMD_ERROR;
+
+ if (cs_checkaccess(sender, NULL, CA_OWNERPRIV, cip, "adduser", QPRIV_CHANGECHANLEV, 1))
+ isowner=1;
+
+ rcp=cip->exts[chanservext];
+
+ for (i=1;i<cargc;i++) {
+ if (!(rup=findreguser(sender, cargv[i])))
+ continue;
+
+ if (!(rcup=findreguseronchannel(rcp, rup))) {
+ chanservstdmessage(sender, QM_CHANUSERUNKNOWN, cargv[i], cip->name->content);
+ continue;
+ }
+
+ if (CUIsOwner(rcup)) {
+ chanservstdmessage(sender, QM_CANNOTREMOVEOWNER, cargv[i], cip->name->content);
+ continue;
+ }
+
+ if (CUIsMaster(rcup) && !isowner && (rup != getreguserfromnick(sender))) {
+ chanservstdmessage(sender, QM_CANNOTREMOVEMASTER, cargv[i], cip->name->content);
+ continue;
+ }
+
+ cs_log(sender,"CHANLEV %s #%s -%s (%s -> +)",cip->name->content,rup->username,
+ printflags_noprefix(rcup->flags, rcuflags), printflags(rcup->flags, rcuflags));
+
+ csdb_deletechanuser(rcup);
+ delreguserfromchannel(rcp, rup);
+ }
+
+ rcp->status |= QCSTAT_OPCHECK;
+ cs_timerfunc(cip);
+
+ chanservstdmessage(sender, QM_DONE);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: renchan
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 2
+ * CMDDESC: Renames a channel on the bot.
+ * CMDFUNC: csc_dorenchan
+ * CMDPROTO: int csc_dorenchan(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dorenchan(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ chanindex *cip1,*cip2;
+ regchan *rcp;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "renchan");
+ return CMD_ERROR;
+ }
+
+ if (!(cip1=findchanindex(cargv[0])) || !(rcp=cip1->exts[chanservext])) {
+ chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (*cargv[1] != '#') {
+ chanservstdmessage(sender, QM_INVALIDCHANNAME, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (!(cip2=findorcreatechanindex(cargv[1])) || cip2->exts[chanservext]) {
+ chanservstdmessage(sender, QM_ALREADYREGISTERED, cip2->name->content);
+ return CMD_ERROR;
+ }
+
+ cs_log(sender,"RENCHAN %s -> %s",cip1->name->content,cip2->name->content);
+
+ /* Remove from the channel. Don't bother if the channel doesn't exist. */
+ if (!CIsSuspended(rcp) && cip1->channel) {
+ CSetSuspended(rcp);
+ chanservjoinchan(cip1->channel);
+ CClearSuspended(rcp);
+ }
+
+ cip1->exts[chanservext]=NULL;
+ releasechanindex(cip1);
+
+ cip2->exts[chanservext]=rcp;
+ rcp->index=cip2;
+ if (cip2->channel) {
+ chanservjoinchan(cip2->channel);
+ }
+
+ csdb_updatechannel(rcp);
+ chanservstdmessage(sender, QM_DONE);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: settopic
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 2
+ * CMDDESC: Changes the topic on a channel.
+ * CMDFUNC: csc_dosettopic
+ * CMDPROTO: int csc_dosettopic(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dosettopic(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regchan *rcp;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "settopic");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_TOPICPRIV,
+ NULL, "settopic", 0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cargc>1) {
+ if (rcp->topic)
+ freesstring(rcp->topic);
+ rcp->topic=getsstring(cargv[1],TOPICLEN);
+ }
+
+ if (rcp->topic && cip->channel) {
+ localsettopic(chanservnick, cip->channel, rcp->topic->content);
+ }
+
+ chanservstdmessage(sender, QM_DONE);
+ csdb_updatechannel(rcp);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: suspendchan
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 2
+ * CMDDESC: Suspends a channel from the bot.
+ * CMDFUNC: csc_dosuspendchan
+ * CMDPROTO: int csc_dosuspendchan(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dosuspendchan(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ chanindex *cip;
+ regchan *rcp;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspendchan");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
+ chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (CIsSuspended(rcp)) {
+ chanservstdmessage(sender, QM_CHANNELALREADYSUSPENDED, cip->name->content);
+ return CMD_ERROR;
+ }
+
+ CSetSuspended(rcp);
+ rcp->suspendreason = getsstring(cargv[1], 250);
+ rcp->suspendby = rup->ID;
+ cs_log(sender,"SUSPENDCHAN %s (%s)",cip->name->content,rcp->suspendreason->content);
+ chanservjoinchan(cip->channel);
+
+ csdb_updatechannel(rcp);
+ chanservstdmessage(sender, QM_DONE);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: suspendchanlist
+ * CMDLEVEL: QCMD_HELPER
+ * CMDARGS: 1
+ * CMDDESC: Lists suspended channels.
+ * CMDFUNC: csc_dosuspendchanlist
+ * CMDPROTO: int csc_dosuspendchanlist(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dosuspendchanlist(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ chanindex *cip;
+ regchan *rcp;
+ int i;
+ char *bywhom;
+ unsigned int count=0;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc < 1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspendchanlist");
+ return CMD_ERROR;
+ }
+
+ chanservstdmessage(sender, QM_SUSPENDCHANLISTHEADER);
+ for (i=0; i<CHANNELHASHSIZE; i++) {
+ for (cip=chantable[i]; cip; cip=cip->next) {
+ if (!(rcp=(regchan*)cip->exts[chanservext]))
+ continue;
+
+ if (!CIsSuspended(rcp))
+ continue;
+
+ if ((rcp->suspendby != rup->ID) && match(cargv[0], cip->name->content))
+ continue;
+
+ if (rcp->suspendby == rup->ID)
+ bywhom=rup->username;
+ else {
+ reguser *trup=findreguserbyID(rcp->suspendby);
+ if (trup)
+ bywhom=trup->username;
+ else
+ bywhom="unknown";
+ }
+ count++;
+ chanservsendmessage(sender, "%-30s %-15s %s", cip->name->content, bywhom, rcp->suspendreason->content);
+ if (count >= 2000) {
+ chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "channels");
+ return CMD_ERROR;
+ }
+ }
+ }
+ chanservstdmessage(sender, QM_RESULTCOUNT, count, "channel", (count==1)?"":"s");
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: tempban
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 4
+ * CMDDESC: Bans a hostmask on a channel for a specified time period.
+ * CMDFUNC: csc_dotempban
+ * CMDPROTO: int csc_dotempban(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dotempban(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regban *rbp;
+ regchan *rcp;
+ reguser *rup=getreguserfromnick(sender);
+ unsigned int duration;
+
+ if (cargc<3) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "tempban");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "tempban",0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ duration=durationtolong(cargv[2]);
+
+ rbp=getregban();
+ rbp->ID=++lastbanID;
+ rbp->cbp=makeban(cargv[1]);
+ rbp->setby=rup->ID;
+ rbp->expiry=time(NULL)+duration;
+ if (cargc>3)
+ rbp->reason=getsstring(cargv[3],200);
+ else
+ rbp->reason=NULL;
+ rbp->next=rcp->bans;
+ rcp->bans=rbp;
+
+ cs_setregban(cip, rbp);
+ csdb_createban(rcp, rbp);
+
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: unbanall
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Removes all bans from a channel.
+ * CMDFUNC: csc_dounbanall
+ * CMDPROTO: int csc_dounbanall(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dounbanall(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ regchan *rcp;
+ chanindex *cip;
+ modechanges changes;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unbanall");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "unbanall",0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cip->channel) {
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+
+ while (cip->channel->bans) {
+ localdosetmode_ban(&changes, bantostring(cip->channel->bans), MCB_DEL);
+ }
+
+ localsetmodeflush(&changes, 1);
+ }
+
+ cs_log(sender,"UNBANALL %s",cip->name->content);
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: unbanmask
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 2
+ * CMDDESC: Removes bans matching a particular mask from a channel.
+ * CMDFUNC: csc_dounbanmask
+ * CMDPROTO: int csc_dounbanmask(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dounbanmask(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regban **rbh, *rbp;
+ chanban **cbh, *cbp;
+ regchan *rcp;
+ chanban *theban;
+ modechanges changes;
+ char *banstr;
+
+ if (cargc<2) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unbanmask");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "unbanmask", 0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+ theban=makeban(cargv[1]);
+
+ if (cip->channel)
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+
+ for (rbh=&(rcp->bans); *rbh; ) {
+ rbp=*rbh;
+ if (banoverlap(theban, rbp->cbp)) {
+ banstr=bantostring(rbp->cbp);
+ /* Check perms and remove */
+ if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, NULL, 0, 1)) {
+ chanservstdmessage(sender, QM_NOTREMOVEDPERMBAN, banstr, cip->name->content);
+ rbh=&(rbp->next);
+ } else {
+ chanservstdmessage(sender, QM_REMOVEDPERMBAN, banstr, cip->name->content);
+ if (cip->channel)
+ localdosetmode_ban(&changes, banstr, MCB_DEL);
+ /* Remove from database */
+ csdb_deleteban(rbp);
+ /* Remove from list */
+ (*rbh)=rbp->next;
+ /* Free ban/string and update setby refcount, and free actual regban */
+ freesstring(rbp->reason);
+ freechanban(rbp->cbp);
+ freeregban(rbp);
+ }
+ } else {
+ rbh=&(rbp->next);
+ }
+ }
+
+ if (cip->channel) {
+ for (cbh=&(cip->channel->bans); *cbh; ) {
+ cbp=*cbh;
+ if (banoverlap(theban, cbp)) {
+ /* Remove */
+ banstr=bantostring(cbp);
+ chanservstdmessage(sender, QM_REMOVEDCHANBAN, banstr, cip->name->content);
+ localdosetmode_ban(&changes, banstr, MCB_DEL);
+ } else {
+ cbh=&(cbp->next);
+ }
+ }
+ localsetmodeflush(&changes,1);
+ }
+
+
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: unbanme
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Removes any bans affecting you from a channel.
+ * CMDFUNC: csc_dounbanme
+ * CMDPROTO: int csc_dounbanme(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dounbanme(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ regchan *rcp;
+ chanindex *cip;
+ modechanges changes;
+ chanban **cbh;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unbanme");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "unbanme", 0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cip->channel) {
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+
+ for (cbh=&(cip->channel->bans);*cbh;) {
+ if (nickmatchban(sender, *cbh))
+ localdosetmode_ban(&changes, bantostring(*cbh), MCB_DEL);
+ else
+ cbh=&((*cbh)->next);
+ }
+
+ localsetmodeflush(&changes, 1);
+ }
+
+ cs_log(sender,"UNBANME %s",cip->name->content);
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: unsuspendchan
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 1
+ * CMDDESC: Unsuspends a channel from the bot.
+ * CMDFUNC: csc_dounsuspendchan
+ * CMDPROTO: int csc_dounsuspendchan(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dounsuspendchan(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ chanindex *cip;
+ regchan *rcp;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unsuspendchan");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext])) {
+ chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if(!CIsSuspended(rcp)) {
+ chanservstdmessage(sender, QM_CHANNELNOTSUSPENDED, cip->name->content);
+ cs_log(sender,"UNSUSPENDCHAN %s is not suspended",cip->name->content);
+ return CMD_ERROR;
+ }
+
+ CClearSuspended(rcp);
+ cs_log(sender,"UNSUSPENDCHAN %s (%s)",cip->name->content,rcp->suspendreason->content);
+ freesstring(rcp->suspendreason);
+ rcp->suspendreason = NULL;
+ rcp->suspendby = 0;
+
+ chanservjoinchan(cip->channel);
+
+ csdb_updatechannel(rcp);
+ chanservstdmessage(sender, QM_DONE);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: voice
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 20
+ * CMDDESC: Voices you or other users on channel(s).
+ * CMDFUNC: csc_dovoice
+ * CMDPROTO: int csc_dovoice(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dovoice(void *source, int cargc, char **cargv) {
+ nick *sender=source, *np;
+ reguser *rup=getreguserfromnick(sender);
+ chanindex *cip;
+ regchan *rcp=NULL;
+ regchanuser *rcup;
+ channel **ca;
+ unsigned long *lp;
+ int i;
+ modechanges changes;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc==0) {
+ /* No args: "voice me on every channel you can */
+ ca=sender->channels->content;
+ for (i=0;i<sender->channels->cursi;i++) {
+ if ((rcp=ca[i]->index->exts[chanservext]) && !CIsSuspended(rcp)) {
+ /* It's a Q channel */
+ if (!(*(getnumerichandlefromchanhash(ca[i]->users, sender->numeric)) &
+ (CUMODE_OP|CUMODE_VOICE))) {
+ /* They're not opped or voiced */
+ rcup=findreguseronchannel(rcp, rup);
+ if ((!rcup || !CUIsQuiet(rcup)) &&
+ ((rcup && CUHasVoicePriv(rcup)) ||
+ (CIsVoiceAll(rcp)))) {
+ /* And they have voice priv on the chan (or it's autovoice):
+ * voice them */
+ localsetmodeinit(&changes, ca[i], chanservnick);
+ localdosetmode_nick(&changes, sender, MC_VOICE);
+ localsetmodeflush(&changes,1);
+ }
+ }
+ }
+ }
+
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+ }
+
+ /* If there is at least one arg, the first is a channel */
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_VOICEPRIV, NULL, "voice", 0, 0)))
+ return CMD_ERROR;
+
+ if (cargc==1) {
+ /* Only one arg: "voice me" */
+ if (!cs_checkaccess(sender, NULL, CA_VOICEPRIV | CA_DEVOICED, cip,
+ "voice", 0, 0))
+ return CMD_ERROR;
+
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+ localdosetmode_nick(&changes, sender, MC_VOICE);
+ localsetmodeflush(&changes,1);
+
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+ }
+
+ if (!(cip=cs_checkaccess(sender, NULL, CA_OPPRIV, cip, "voice", 0, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ /* Set up the modes */
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+
+ for(i=1;i<cargc;i++) {
+ if (!(np=getnickbynick(cargv[i]))) {
+ chanservstdmessage(sender, QM_UNKNOWNUSER, cargv[i]);
+ continue;
+ }
+
+ if (!(lp=getnumerichandlefromchanhash(cip->channel->users, np->numeric))) {
+ chanservstdmessage(sender, QM_USERNOTONCHAN, np->nick, cip->name->content);
+ continue;
+ }
+
+ if (*lp & CUMODE_VOICE) {
+ chanservstdmessage(sender, QM_USERVOICEDONCHAN, np->nick, cip->name->content);
+ continue;
+ }
+
+ if ((rup=getreguserfromnick(np)) && (rcup=findreguseronchannel(rcp, rup)) && CUIsQuiet(rcup)) {
+ chanservstdmessage(sender, QM_CANTVOICE, np->nick, cip->name->content);
+ continue;
+ }
+
+ localdosetmode_nick(&changes, np, MC_VOICE);
+ }
+
+ localsetmodeflush(&changes, 1);
+ chanservstdmessage(sender, QM_DONE);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: welcome
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 2
+ * CMDDESC: Shows or changes the welcome message on a channel.
+ * CMDFUNC: csc_dowelcome
+ * CMDPROTO: int csc_dowelcome(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../nick/nick.h"
+#include "../../lib/flags.h"
+#include "../../lib/irc_string.h"
+#include "../../channel/channel.h"
+#include "../../parser/parser.h"
+#include "../../irc/irc.h"
+#include "../../localuser/localuserchannel.h"
+#include <string.h>
+#include <stdio.h>
+
+int csc_dowelcome(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ chanindex *cip;
+ regchan *rcp;
+ sstring *oldwelcome;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "welcome");
+ return CMD_ERROR;
+ }
+
+ if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "welcome",
+ QPRIV_VIEWWELCOME, 0)))
+ return CMD_ERROR;
+
+ rcp=cip->exts[chanservext];
+
+ if (cargc>1) {
+ if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, "welcome",
+ QPRIV_CHANGEWELCOME, 0))
+ return CMD_ERROR;
+
+ oldwelcome=rcp->welcome;
+
+ rcp->welcome=getsstring(cargv[1], 500);
+ csdb_updatechannel(rcp);
+
+ cs_log(sender,"WELCOME %s %s (was %s)",cip->name->content,rcp->welcome->content,oldwelcome?oldwelcome->content:"unset");
+ freesstring(oldwelcome);
+ chanservstdmessage(sender, QM_DONE);
+ }
+
+ chanservstdmessage(sender, QM_WELCOMEMESSAGEIS, rcp->index->name->content,
+ rcp->welcome?rcp->welcome->content:"(none)");
+
+ return CMD_OK;
+}
/* authlib.c */
int csa_checkeboy(nick *sender, char *eboy);
void csa_createrandompw(char *pw, int n);
+int csa_checkthrottled(nick *sender, reguser *rup, char *s);
#endif
--- /dev/null
+#!/usr/bin/perl -w
+
+use strict;
+
+my @cmdnames;
+my @cmdlevels;
+my @cmdargs;
+my @cmddesc;
+my @cmdfunc;
+my @protos;
+my @files;
+
+my @filelist = <*.c>;
+
+my $modname;
+
+unless (@ARGV) {
+ print "Usage: $0 <module name>\n";
+ exit(0);
+} else {
+ $modname=$ARGV[0];
+}
+
+for (@filelist) {
+ next if (/commandlist.c/);
+
+ my $fname = $_;
+ my ($cn, $cl, $ca, $cd, $cf, $cp);
+
+ open INFILE,"<$fname";
+
+ while(<INFILE>) {
+ chomp;
+
+ if (/CMDNAME: (.*)/) {
+ $cn=$1;
+ }
+
+ if (/CMDLEVEL: (.*)/) {
+ $cl=$1;
+ }
+
+ if (/CMDARGS: (.*)/) {
+ $ca=$1;
+ }
+
+ if (/CMDDESC: (.*)/) {
+ $cd=$1;
+ }
+
+ if (/CMDFUNC: (.*)/) {
+ $cf=$1;
+ }
+
+ if (/CMDPROTO: (.*)/) {
+ $cp=$1;
+ }
+ }
+
+ if (defined $cn and defined $cl and defined $ca and defined $cd and defined $cf and defined $cp) {
+ # valid command found
+ push @files, $fname;
+ push @cmdnames, $cn;
+ push @cmdlevels, $cl;
+ push @cmdargs, $ca;
+ push @cmddesc, $cd;
+ push @cmdfunc, $cf;
+ push @protos, $cp;
+ } else {
+ print "Warning: found source file $fname without complete tags, skipping...\n";
+ }
+}
+
+if (@files < 1) {
+ print "No commands found - are you in the right directory?\n";
+ print "Exiting before I destroy something important.\n";
+ exit(0);
+}
+
+
+open CL, ">commandlist.c";
+
+print CL "/* Automatically generated by mkcommandlist.pl, do not edit. */\n\n";
+print CL "#include \"../chanserv.h\"\n\n";
+
+# Print prototypes
+print CL "/* Prototypes */\n";
+foreach (@protos) {
+ print CL "$_\n";
+}
+
+my @names2 = @cmdnames;
+my @func2 = @cmdfunc;
+
+print CL "\nvoid _init() {\n";
+
+while (my $cn = shift @cmdnames) {
+ print CL " chanservaddcommand(\"".$cn."\", ".(shift @cmdlevels).", ".(shift @cmdargs).", ";
+ print CL (shift @cmdfunc).", \"".(shift @cmddesc)."\");\n";
+}
+
+print CL "}\n\nvoid _fini() {\n";
+
+while (my $cn = shift @names2) {
+ print CL " chanservremovecommand(\"".$cn."\", ".(shift @func2).");\n";
+}
+
+print CL "}\n";
+
+close CL;
+
+open MF,">Makefile";
+
+print MF "# Automatically generated Makefile, do not edit.\n\n";
+
+print MF ".PHONY: all Makefile\n";
+
+print MF "all: Makefile $modname\n\n";
+
+print MF "Makefile:\n";
+print MF "\t../mkcommandlist.pl $modname\n";
+
+print MF "\n$modname: ";
+
+push @files,"commandlist.c";
+
+foreach (@files) {
+ s/.c$/.o/;
+ print MF "$_ ";
+}
+
+print MF "\n";
+print MF "\t ld -shared -Bdynamic -o \$\@ \$\^ \n";
+
+close MF;
--- /dev/null
+#!/usr/bin/perl -w
+
+my @includes;
+
+my %cmdnames;
+my %cmdlevels;
+my %cmdargs;
+my %cmddesc;
+my %protos;
+
+my $infunc = 0;
+
+while (<>) {
+ chomp;
+
+ if (/^#include (.*)$/) {
+# print "Adding include: $1\n";
+ push @includes, $1;
+ next;
+ }
+
+ if (/chanservaddcommand\((.*)\)/) {
+# print "Found \"addcommand\" stanza\n";
+ my $args=$1;
+
+ unless ($args =~ m!^\s*"([^"]+)"\s*,\s*([^,]+?)\s*,\s*(\d+)\s*,\s*([^, ]+)\s*,\s*"([^"]+)! ) {
+ print "Can't decode addcommand() args: $args\n";
+ next;
+ }
+# print "Command function is: $4\n";
+
+ $cmdnames{$4} = $1;
+ $cmdlevels{$4} = $2;
+ $cmdargs{$4} = $3;
+ $cmddesc{$4} = $5;
+ }
+
+ if (/^int (.*?)\(.*;/) {
+ print "Found prototype for function: $1\n";
+ $protos{$1}=$_;
+ }
+
+ if (/^int (\S+)\s*\(.*{/) {
+ print "Found start of function declaration: $1\n";
+ unless (defined $cmdnames{$1}) {
+ print "Found function $1 without definition, skipping ...\n";
+ next;
+ }
+
+ my $fname = $cmdnames{$1}.".c";
+
+ open CMDF, ">".$fname;
+
+ print CMDF "/* Automatically generated by refactor.pl.\n *\n *\n";
+ print CMDF " * CMDNAME: $cmdnames{$1}\n";
+ print CMDF " * CMDLEVEL: $cmdlevels{$1}\n";
+ print CMDF " * CMDARGS: $cmdargs{$1}\n";
+ print CMDF " * CMDDESC: $cmddesc{$1}\n";
+ print CMDF " * CMDFUNC: $1\n";
+ print CMDF " * CMDPROTO: $protos{$1}\n";
+ print CMDF " */\n\n";
+
+ for (@includes) {
+ print CMDF "#include $_\n";
+ }
+
+ print CMDF "\n";
+ print CMDF "$_\n";
+
+ $infunc=1;
+ next;
+ }
+
+ if ($infunc) {
+ print CMDF "$_\n";
+ if (/^}/) {
+ close CMDF;
+ $infunc=0;
+ }
+ }
+}
+++ /dev/null
-/* usercmds.c */
-
-#include "chanserv.h"
-#include "../lib/irc_string.h"
-
-#include <stdio.h>
-#include <string.h>
-
-int csu_douserflags(void *source, int cargc, char **cargv);
-int csu_doinfo(void *source, int cargc, char **cargv);
-int csu_dowhois(void *source, int cargc, char **cargv);
-int csu_dousercomment(void *source, int cargc, char **cargv);
-int csu_dodeluser(void *source, int cargc, char **cargv);
-int csu_dolanguage(void *source, int cargc, char **cargv);
-int csu_dosuspenduser(void *source, int cargc, char **cargv);
-int csu_dounsuspenduser(void *source, int cargc, char **cargv);
-int csu_dospewdb(void *source, int cargc, char **cargv);
-int csu_dospewpass(void *source, int cargc, char **cargv);
-int csu_dospewemail(void *source, int cargc, char **cargv);
-int csu_dolistflags(void *source, int cargc, char **cargv);
-int csu_dosuspenduserlist(void *source, int cargc, char **cargv);
-
-void _init() {
- chanservaddcommand("userflags" , QCMD_AUTHED, 2, csu_douserflags ,"Shows or changes user flags.");
- chanservaddcommand("info" , QCMD_AUTHED, 2, csu_doinfo ,"Shows or changes info line.");
- chanservaddcommand("whois" , QCMD_AUTHED, 1, csu_dowhois ,"Displays information about a user.");
- chanservaddcommand("usercomment" , QCMD_OPER , 2, csu_dousercomment ,"Shows or changes staff comment for a user.");
- chanservaddcommand("deluser" , QCMD_OPER , 2, csu_dodeluser ,"Removes a user from the bot.");
- chanservaddcommand("language" , QCMD_AUTHED, 1, csu_dolanguage ,"Shows or changes your current language.");
- chanservaddcommand("suspenduser" , QCMD_OPER , 1, csu_dosuspenduser ,"Suspend/Delay GLINE/Instantly GLINE a user.");
- chanservaddcommand("unsuspenduser" , QCMD_OPER , 1, csu_dounsuspenduser ,"Unsuspend a user.");
- chanservaddcommand("spewdb" , QCMD_OPER , 1, csu_dospewdb ,"Search for a user in the database.");
- chanservaddcommand("spewpass" , QCMD_OPER , 1, csu_dospewpass ,"Search for a password in the database.");
- chanservaddcommand("spewemail" , QCMD_OPER , 1, csu_dospewemail ,"Search for an e-mail in the database.");
- chanservaddcommand("listflags" , QCMD_OPER , 1, csu_dolistflags ,"List users with the specified user flags.");
- chanservaddcommand("suspenduserlist", QCMD_HELPER, 1, csu_dosuspenduserlist,"Lists suspended/locked users.");
-}
-
-void _fini() {
- chanservremovecommand("userflags", csu_douserflags);
- chanservremovecommand("info", csu_doinfo);
- chanservremovecommand("whois", csu_dowhois);
- chanservremovecommand("usercomment", csu_dousercomment);
- chanservremovecommand("deluser", csu_dodeluser);
- chanservremovecommand("language", csu_dolanguage);
- chanservremovecommand("suspenduser", csu_dosuspenduser);
- chanservremovecommand("unsuspenduser", csu_dounsuspenduser);
- chanservremovecommand("spewdb", csu_dospewdb);
- chanservremovecommand("spewpass", csu_dospewpass);
- chanservremovecommand("spewemail", csu_dospewemail);
- chanservremovecommand("listflags", csu_dolistflags);
- chanservremovecommand("suspenduserlist", csu_dosuspenduserlist);
-}
-
-int csu_douserflags(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender), *target;
- int arg=0;
- flag_t flagmask, changemask;
- char flagbuf[30];
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "userflags");
- return CMD_ERROR;
- }
-
- if (*cargv[0]!='+' && *cargv[0]!='-') {
- arg++;
- /* If the first char isn't a "change" character, it must specify a target */
-
- if (!(target=findreguser(sender,cargv[0])))
- return CMD_ERROR;
-
- if (target!=rup && !cs_privcheck(QPRIV_VIEWUSERFLAGS, sender)) {
- chanservstdmessage(sender, QM_NOACCESS, "userflags");
- return CMD_ERROR;
- }
- } else {
- target=rup;
- }
-
- if (cargc>arg) {
- /* OK, now we have a changestring.. */
- if (target!=rup && !cs_privcheck(QPRIV_CHANGEUSERFLAGS, sender)) {
- chanservstdmessage(sender, QM_NOACCESS, "userflags");
- return CMD_ERROR;
- }
-
- strcpy(flagbuf,printflags(target->flags, ruflags));
-
- changemask=QUFLAG_NOTICE | QUFLAG_INFO;
-
- if (target==rup) {
- /* If you're changing yourself, you can give up the "status" flags and add/remove notice */
- changemask|=(target->flags & (QUFLAG_OPER | QUFLAG_DEV | QUFLAG_PROTECT | QUFLAG_HELPER | QUFLAG_ADMIN));
- }
-
- /* Warning, policy ahead */
-
- if (UHasOperPriv(rup))
- changemask |= QUFLAG_GLINE | QUFLAG_DELAYEDGLINE | QUFLAG_RESTRICTED | QUFLAG_PROTECT;
-
- if (UHasAdminPriv(rup))
- changemask |= (QUFLAG_OPER | QUFLAG_HELPER);
-
- if (UIsDev(rup))
- changemask=QUFLAG_ALL;
-
- setflags(&target->flags, changemask, cargv[arg], ruflags, REJECT_NONE);
-
- /* More policy */
- if (!UHasHelperPriv(target)) {
- target->flags &= ~QUFLAG_PROTECT;
- }
-
- cs_log(sender,"USERFLAGS #%s %s (%s -> %s)",target->username,cargv[arg],flagbuf,printflags(target->flags, ruflags));
- csdb_updateuser(target);
- chanservstdmessage(sender, QM_DONE);
- }
-
- if (cs_privcheck(QPRIV_VIEWUSERFLAGS, sender))
- flagmask=QUFLAG_ALL;
- else
- flagmask=QUFLAG_INFO | QUFLAG_NOTICE | QUFLAG_OPER | QUFLAG_HELPER | QUFLAG_DEV | QUFLAG_ADMIN;
-
- chanservstdmessage(sender, QM_CURUSERFLAGS, target->username, printflags(target->flags & flagmask, ruflags));
-
- return CMD_OK;
-}
-
-int csu_doinfo(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- chanindex *cip;
- regchan *rcp;
- regchanuser *rcup;
- char linebuf[INFOLEN+10];
- char *newline="";
- int doupdate=0;
-
- if (cargc==0 || *cargv[0]!='#') {
- /* Global info line */
- if (cargc==1) {
- /* Setting to either one word or "none" */
- if (!ircd_strcmp(cargv[0],"none")) {
- newline="";
- doupdate=1;
- } else {
- newline=cargv[0];
- doupdate=1;
- }
- } else if (cargc>1) {
- /* More than one word: we need to stick them back together */
- snprintf(linebuf,INFOLEN,"%s %s",cargv[0],cargv[1]);
- newline=linebuf;
- doupdate=1;
- }
-
- if (doupdate) {
- if (rup->info)
- freesstring(rup->info);
-
- rup->info=getsstring(newline, INFOLEN);
-
- chanservstdmessage(sender, QM_DONE);
- csdb_updateuser(rup);
- }
-
- chanservstdmessage(sender, QM_GLOBALINFO, rup->info?rup->info->content:"(none)");
- } else {
- /* Channel info line */
-
- if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext]) ||
- (CIsSuspended(rcp) && !cs_privcheck(QPRIV_SUSPENDBYPASS, sender))) {
- chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
- return CMD_ERROR;
- }
-
- if ((!(rcup=findreguseronchannel(rcp, rup)) || !CUHasVoicePriv(rcup))) {
- chanservstdmessage(sender, QM_NOACCESSONCHAN, cargv[0], "info");
- return CMD_ERROR;
- }
-
- if (cargc>1) {
- if (rcup->info)
- freesstring(rcup->info);
-
- if (!ircd_strcmp(cargv[1],"none"))
- rcup->info=NULL;
- else
- rcup->info=getsstring(cargv[1],INFOLEN);
-
- csdb_updatechanuser(rcup);
- chanservstdmessage(sender, QM_DONE);
- }
-
- chanservstdmessage(sender, QM_CHANNELINFO, cip->name->content,
- rcup->info?rcup->info->content:"(none)");
- }
-
- return CMD_OK;
-}
-
-int csu_dowhois(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender), *target;
- char buf[200];
- char nbpos=0;
- nicklist *nlp;
- struct tm *tmp;
- regchanuser *rcup, *rcup2;
- flag_t flagmask, flags;
- int doneheader=0;
-
- if (!(rup=getreguserfromnick(sender)))
- return CMD_ERROR;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "whois");
- return CMD_ERROR;
- }
-
- if (!(target=findreguser(sender, cargv[0]))) {
- nick* np;
-
- if ((np=getnickbynick(cargv[0]))) {
- activeuser* aup=getactiveuserfromnick(np);
- chanservsendmessage(sender, "%s has attempted to auth %d time%s.", np->nick, aup->authattempts,
- aup->authattempts==1?"":"s");
- }
- return CMD_ERROR;
- }
-
- if (cargv[0][0]=='#') {
- chanservstdmessage(sender, QM_WHOISHEADER_AUTH, target->username);
- } else {
- chanservstdmessage(sender, QM_WHOISHEADER_NICK, cargv[0], target->username);
- }
-
- if (rup==target || cs_privcheck(QPRIV_VIEWFULLWHOIS, sender)) {
- chanservstdmessage(sender, QM_WHOIS_USERID, target->ID);
- }
-
- if (cs_privcheck(QPRIV_VIEWUSERFLAGS, sender)) {
- flagmask=QUFLAG_ALL;
- } else {
- if (UIsAdmin(target))
- chanservstdmessage(sender, QM_USERISADMIN, target->username);
- else if (UIsOper(target))
- chanservstdmessage(sender, QM_USERISOPER, target->username);
- else if (UIsHelper(target))
- chanservstdmessage(sender, QM_USERISHELPER, target->username);
-
- if (UIsDev(target))
- chanservstdmessage(sender, QM_USERISDEV, target->username);
-
- flagmask=0;
- }
-
- if (rup==target)
- flagmask|=(QUFLAG_OPER | QUFLAG_DEV | QUFLAG_HELPER |
- QUFLAG_ADMIN | QUFLAG_INFO | QUFLAG_NOTICE);
-
- if (flagmask & target->flags)
- chanservstdmessage(sender, QM_WHOIS_FLAGS, printflags(flagmask & target->flags, ruflags));
-
- if (!target->nicks) {
- chanservstdmessage(sender, QM_WHOIS_USERS, "(none)");
- } else {
- for (nlp=target->nicks; ;nlp=nlp->next) {
- if (nbpos>0 && (!nlp || nbpos+strlen(nlp->np->nick) > 60)) {
- chanservstdmessage(sender, QM_WHOIS_USERS, buf);
- nbpos=0;
- }
-
- if (!nlp)
- break;
-
- nbpos+=sprintf(buf+nbpos,"%s ",nlp->np->nick);
- }
- }
-
- if (target->created) {
- tmp=gmtime(&(target->created));
- strftime(buf,15,"%d/%m/%y %H:%M",tmp);
-
- chanservstdmessage(sender, QM_WHOIS_CREATED, buf);
- }
-
- tmp=gmtime(&(target->lastauth));
- strftime(buf,15,"%d/%m/%y %H:%M",tmp);
-
- chanservstdmessage(sender, QM_WHOIS_LASTAUTH, buf);
-
- if (target->lastuserhost && (rup==target || cs_privcheck(QPRIV_VIEWFULLWHOIS, sender))) {
- chanservstdmessage(sender, QM_WHOIS_USERLANG, cslanguages[target->languageid] ?
- cslanguages[target->languageid]->name->content : "(unknown)");
- chanservstdmessage(sender, QM_WHOIS_LASTUSERHOST, target->lastuserhost->content);
- }
-
- if (target->email && (rup==target || cs_privcheck(QPRIV_VIEWEMAIL, sender))) {
- chanservstdmessage(sender, QM_WHOIS_EMAIL, target->email->content);
-
- tmp=gmtime(&(target->lastemailchange));
- strftime(buf,15,"%d/%m/%y %H:%M",tmp);
-
- chanservstdmessage(sender, QM_WHOIS_EMAILSET, buf);
- }
-
- if (target->info) {
- chanservstdmessage(sender, QM_WHOIS_INFO, target->info->content);
- }
-
- if (target->comment && (cs_privcheck(QPRIV_VIEWCOMMENTS, sender))) {
- chanservstdmessage(sender, QM_WHOIS_COMMENT, target->comment->content);
- }
-
- for (rcup=target->knownon;rcup;rcup=rcup->nextbyuser) {
- if (!UHasHelperPriv(rup)) {
- if (!(rcup2=findreguseronchannel(rcup->chan,rup)))
- continue;
-
- if (!CUHasVoicePriv(rcup2))
- continue;
-
- flagmask = (QCUFLAG_OWNER | QCUFLAG_MASTER | QCUFLAG_OP | QCUFLAG_VOICE | QCUFLAG_AUTOVOICE |
- QCUFLAG_AUTOOP | QCUFLAG_TOPIC | QCUFLAG_SPAMCON);
-
- if (CUHasMasterPriv(rcup2))
- flagmask |= (QCUFLAG_DENY | QCUFLAG_QUIET | QCUFLAG_BANNED);
- } else {
- flagmask=QCUFLAG_ALL;
- }
-
- if (!(flags=rcup->flags & flagmask))
- continue;
-
- if (!doneheader) {
- doneheader=1;
- chanservstdmessage(sender, QM_WHOIS_CHANHEADER, target->username);
- }
-
- chanservsendmessage(sender, " %-30s %s",rcup->chan->index->name->content,printflags(flags, rcuflags));
- }
-
- chanservstdmessage(sender, QM_ENDOFLIST);
-
- return CMD_OK;
-}
-
-int csu_dodeluser(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender), *target;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "deluser");
- return CMD_ERROR;
- }
-
- if (!(target=findreguser(sender, cargv[0])))
- return CMD_ERROR;
-
- cs_log(sender,"DELUSER %s (%s)",target->username,cargc>1?cargv[1]:"");
- cs_removeuser(target);
-
- chanservstdmessage(sender, QM_DONE);
-
- return CMD_OK;
-}
-
-int csu_dousercomment(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender), *target;
- char buf[300];
- int bufpos;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc<1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "usercomment");
- return CMD_ERROR;
- }
-
- if (!(target=findreguser(sender, cargv[0])))
- return CMD_ERROR;
-
- if (cargc>1) {
- if (!ircd_strcmp(cargv[1],"none")) {
- freesstring(target->comment);
- target->comment=NULL;
- } else {
- if (*cargv[1]=='+') {
- if (target->comment) {
- strcpy(buf,target->comment->content);
- bufpos=target->comment->length;
- buf[bufpos++]=' ';
- } else {
- bufpos=0;
- }
- strncpy(buf+bufpos, cargv[1]+1, 250-bufpos);
- } else {
- strncpy(buf, cargv[1], 250);
- }
-
- freesstring(target->comment);
- target->comment=getsstring(buf,250);
- }
- csdb_updateuser(target);
- }
-
- if (target->comment)
- chanservstdmessage(sender, QM_COMMENT, target->username, target->comment->content);
- else
- chanservstdmessage(sender, QM_NOCOMMENT, target->username);
-
- return CMD_OK;
-}
-
-int csu_dolanguage(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- char buf[300];
- int bufpos=0;
- int i;
- int len;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc==0) {
- /* Display language */
- i=rup->languageid;
- chanservstdmessage(sender, QM_YOURLANGUAGE, cslanguages[i] ? cslanguages[i]->name->content : "Unknown");
-
- /* Display available lanaguages */
- chanservstdmessage(sender, QM_LANGUAGELIST);
-
- for (i=0;i<MAXLANG;i++) {
- if (cslanguages[i]) {
- if (bufpos > 70) {
- chanservsendmessage(sender, "%s", buf);
- bufpos=0;
- }
- len=sprintf(buf+bufpos, "%.14s (%.2s)",cslanguages[i]->name->content,cslanguages[i]->code);
- memset(buf+bufpos+len,' ',20-len);
- bufpos+=20;
- buf[bufpos]='\0';
- }
- }
-
- if (bufpos)
- chanservsendmessage(sender, "%s", buf);
-
- chanservstdmessage(sender, QM_ENDOFLIST);
- } else {
- /* Set language */
- for (i=0;i<MAXLANG;i++) {
- if (cslanguages[i] && !ircd_strcmp(cargv[0],cslanguages[i]->code)) {
- /* Match. */
- rup->languageid=i;
- csdb_updateuser(rup);
-
- chanservstdmessage(sender, QM_DONE);
- chanservstdmessage(sender, QM_YOURLANGUAGE, cslanguages[i]->name->content);
- break;
- }
- }
-
- if (i==MAXLANG)
- chanservstdmessage(sender, QM_UNKNOWNLANGUAGE, cargv[0]);
- }
-
- return CMD_OK;
-}
-
-int csu_dosuspenduser(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- reguser *vrup;
- char* flag;
- char* victim;
- char* dur_p;
- char* reason;
- int kill=1, gline=0, email=0, password=0, hitcount=0;
- time_t expires=0;
- int duration=0;
- struct tm* tmp;
- char buf[200]="";
- int dgwait;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc < 1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
- return CMD_ERROR;
- }
-
- if (cargv[0][0] == '-') {
- flag=cargv[0];
- if (!(victim=strchr(flag, ' '))) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
- return CMD_ERROR;
- }
- *(victim++)='\0';
- if (!(dur_p=strchr(victim, ' '))) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
- return CMD_ERROR;
- }
- *(dur_p++)='\0';
- if ((reason=strchr(dur_p, ' '))) {
- *(reason++)='\0';
- if ((duration=durationtolong(dur_p))) {
- if ((duration < 86400) || (duration > 2592000)) {
- chanservstdmessage(sender, QM_INVALIDDURATION);
- return CMD_ERROR;
- }
- expires=time(0)+duration;
- }
- else {
- *(reason-1)=' ';
- reason=dur_p;
- expires=0;
- }
- }
- else {
- reason=dur_p;
- expires=0;
- }
-
- if (!ircd_strcmp(flag, "-nokill")) {
- kill=0;
- }
- else if (!ircd_strcmp(flag, "-gline")) {
- gline=1;
- }
- else if (!ircd_strcmp(flag, "-instantgline")) {
- gline=2;
- }
- else if (!ircd_strcmp(flag, "-email")) {
- email=1;
- }
- else if (!ircd_strcmp(flag, "-password")) {
- password=1;
- }
- else {
- chanservstdmessage(sender, QM_INVALIDCHANLEVCHANGE);
- return CMD_ERROR;
- }
- }
- else {
- victim=cargv[0];
- if (!(dur_p=strchr(victim, ' '))) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
- return CMD_ERROR;
- }
- *(dur_p++)='\0';
- if ((reason=strchr(dur_p, ' '))) {
- *(reason++)='\0';
- if ((duration=durationtolong(dur_p))) {
- if ((duration < 86400) || (duration > 2592000)) {
- chanservstdmessage(sender, QM_INVALIDDURATION);
- return CMD_ERROR;
- }
- expires=time(0)+duration;
- }
- else {
- *(reason-1)=' ';
- reason=dur_p;
- expires=0;
- }
- }
- else {
- reason=dur_p;
- expires=0;
- }
- }
-
- if (expires) {
- tmp=gmtime(&expires);
- strftime(buf,15,"%d/%m/%y %H:%M",tmp);
- }
-
- if (email) {
- int i;
-
- for (i=0;i<REGUSERHASHSIZE;i++) {
- for (vrup=regusernicktable[i]; vrup; vrup=vrup->nextbyname) {
- if (!ircd_strcmp(vrup->email->content, victim)) {
- if (UHasSuspension(vrup))
- continue;
-
- if (UHasOperPriv(vrup) && !UHasAdminPriv(rup))
- continue;
-
- hitcount++;
- vrup->flags|=QUFLAG_SUSPENDED;
- vrup->suspendby=rup->ID;
- vrup->suspendexp=expires;
- vrup->suspendreason=getsstring(reason, strlen(reason)+1);
-
- while (vrup->nicks) {
- if (!vrup->nicks->np)
- continue;
-
- chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username);
- chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL);
- }
- csdb_updateuser(vrup);
- }
- }
- }
-
- chanservwallmessage("%s (%s) bulk suspended <%s>, hit %d account/s (expires: %s)", sender->nick, rup->username, victim, hitcount, expires?buf:"never");
- }
- else if (password) {
- int i;
-
- for (i=0;i<REGUSERHASHSIZE;i++) {
- for (vrup=regusernicktable[i]; vrup; vrup=vrup->nextbyname) {
- if (!strcmp(vrup->password, victim)) {
- if (UHasSuspension(vrup))
- continue;
-
- if (UHasOperPriv(vrup) && !UHasAdminPriv(rup))
- continue;
-
- hitcount++;
- vrup->flags|=QUFLAG_SUSPENDED;
- vrup->suspendby=rup->ID;
- vrup->suspendexp=expires;
- vrup->suspendreason=getsstring(reason, strlen(reason)+1);
-
- while (vrup->nicks) {
- if (!vrup->nicks->np)
- continue;
-
- chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username);
- chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL);
- }
- csdb_updateuser(vrup);
- }
- }
- }
-
- chanservwallmessage("%s (%s) bulk suspended password \"%s\", hit %d account/s (expires: %s)", sender->nick, rup->username, victim, hitcount, expires?buf:"never");
- }
- else {
- if (!(vrup=findreguser(sender, victim)))
- return CMD_ERROR;
-
- if (!ircd_strcmp(vrup->username, rup->username)) {
- chanservsendmessage(sender, "You can't suspend yourself, silly.");
- return CMD_ERROR;
- }
-
- if (UHasSuspension(vrup)) {
- chanservstdmessage(sender, QM_USERALREADYSUSPENDED);
- return CMD_ERROR;
- }
-
- if (UHasOperPriv(vrup) && !UHasAdminPriv(rup)) {
- snprintf(buf, 199, "suspenduser on %s", vrup->username);
- chanservstdmessage(sender, QM_NOACCESS, buf);
- chanservwallmessage("%s (%s) FAILED to suspend %s", sender->nick, rup->username, vrup->username);
- return CMD_ERROR;
- }
-
- if (gline == 2)
- vrup->flags|=QUFLAG_GLINE;
- else if (gline == 1)
- vrup->flags|=QUFLAG_DELAYEDGLINE;
- else
- vrup->flags|=QUFLAG_SUSPENDED;
- vrup->suspendby=rup->ID;
- vrup->suspendexp=expires;
- vrup->suspendreason=getsstring(reason, strlen(reason)+1);
-
- chanservwallmessage("%s (%s) %s %s (expires: %s)", sender->nick, rup->username, (gline)?((gline == 2)?"instantly glined":"delayed glined"):"suspended", vrup->username, expires?buf:"never");
- if (gline) {
- dgwait=(gline==2)?0:rand()%900;
- chanservsendmessage(sender, "Scheduling delayed GLINE for account %s in %d %s",
- vrup->username, (dgwait>60)?(dgwait/60):dgwait, (dgwait>60)?"minutes":"seconds");
- deleteschedule(NULL, &chanservdgline, (void*)vrup);
- scheduleoneshot(time(NULL)+dgwait, &chanservdgline, (void*)vrup);
- }
- else if (kill) {
- while (vrup->nicks) {
- if (!vrup->nicks->np)
- continue;
-
- chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username);
- chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL);
- hitcount++;
- }
- }
-
- csdb_updateuser(vrup);
- }
-
- return CMD_OK;
-}
-
-int csu_dounsuspenduser(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- reguser *vrup;
- char action[100];
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc < 1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unsuspenduser");
- return CMD_ERROR;
- }
-
- if (cargv[0][0] == '#') {
- if (!(vrup=findreguserbynick(&cargv[0][1]))) {
- chanservstdmessage(sender, QM_UNKNOWNUSER, &cargv[0][1]);
- return CMD_ERROR;
- }
- }
- else {
- nick *np;
-
- if (!(np=getnickbynick(cargv[0]))) {
- chanservstdmessage(sender, QM_UNKNOWNUSER, cargv[0]);
- return CMD_ERROR;
- }
-
- if (!(vrup=getreguserfromnick(np)) && sender) {
- chanservstdmessage(sender, QM_USERNOTAUTHED, cargv[0]);
- return CMD_ERROR;
- }
- }
-
- if (!UHasSuspension(vrup)) {
- chanservstdmessage(sender, QM_USERNOTSUSPENDED, cargv[0]);
- return CMD_ERROR;
- }
-
- if (UHasOperPriv(vrup) && !UHasAdminPriv(rup)) {
- snprintf(action, 99, "unsuspenduser on %s", vrup->username);
- chanservstdmessage(sender, QM_NOACCESS, action);
- chanservwallmessage("%s (%s) FAILED to unsuspend %s", sender->nick, rup->username, vrup->username);
- return CMD_ERROR;
- }
-
- if (UIsDelayedGline(vrup)) {
- strcpy(action, "removed delayed gline on");
- }
- else if (UIsGline(vrup)) {
- strcpy(action, "removed instant gline on");
- }
- else if (UIsSuspended(vrup)) {
- strcpy(action, "unsuspended");
- }
- else if (UIsNeedAuth(vrup)) {
- strcpy(action, "enabled");
- }
- else {
- chanservsendmessage(sender, "Unknown suspend type encountered.");
- return CMD_ERROR;
- }
-
- vrup->flags&=(~(QUFLAG_GLINE|QUFLAG_DELAYEDGLINE|QUFLAG_SUSPENDED|QUFLAG_NEEDAUTH));
- vrup->suspendby=0;
- vrup->suspendexp=0;
- freesstring(vrup->suspendreason);
- vrup->suspendreason=0;
- csdb_updateuser(vrup);
-
- chanservwallmessage("%s (%s) %s %s", sender->nick, rup->username, action, vrup->username);
- chanservstdmessage(sender, QM_DONE);
- return CMD_OK;
-}
-
-int csu_dospewdb(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- reguser *dbrup;
- int i;
- unsigned int count=0;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc < 1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewdb");
- return CMD_ERROR;
- }
-
- chanservstdmessage(sender, QM_SPEWHEADER);
- for (i=0;i<REGUSERHASHSIZE;i++) {
- for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
- if (!match(cargv[0], dbrup->username)) {
- chanservsendmessage(sender, "%-15s %-10s %-30s %s", dbrup->username, UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set", dbrup->lastuserhost?dbrup->lastuserhost->content:"none");
- count++;
- if (count >= 2000) {
- chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
- return CMD_ERROR;
- }
- }
- }
- }
- chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
-
- return CMD_OK;
-}
-
-int csu_dospewpass(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- reguser *dbrup;
- int i;
- unsigned int count=0;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc < 1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewpass");
- return CMD_ERROR;
- }
-
- chanservstdmessage(sender, QM_SPEWHEADER);
- for (i=0;i<REGUSERHASHSIZE;i++) {
- for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
- if (!match(cargv[0], dbrup->password)) {
- chanservsendmessage(sender, "%-15s %-10s %-30s %s", dbrup->username, UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set", dbrup->lastuserhost?dbrup->lastuserhost->content:"none");
- count++;
- if (count >= 2000) {
- chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
- return CMD_ERROR;
- }
- }
- }
- }
- chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
-
- return CMD_OK;
-}
-
-int csu_dospewemail(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- reguser *dbrup;
- int i;
- unsigned int count=0;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc < 1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewemail");
- return CMD_ERROR;
- }
-
- chanservstdmessage(sender, QM_SPEWHEADER);
- for (i=0;i<REGUSERHASHSIZE;i++) {
- for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
- if (!dbrup->email)
- continue;
- if (!match(cargv[0], dbrup->email->content)) {
- chanservsendmessage(sender, "%-15s %-10s %-30s %s", dbrup->username, UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set", dbrup->lastuserhost?dbrup->lastuserhost->content:"none");
- count++;
- if (count >= 2000) {
- chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
- return CMD_ERROR;
- }
- }
- }
- }
- chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
-
- return CMD_OK;
-}
-
-int csu_dolistflags(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- reguser *dbrup;
- flag_t matchflags = 0;
- char *ch;
- int i, j;
- unsigned int count=0;
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc < 1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "listflags");
- return CMD_ERROR;
- }
-
- ch=cargv[0][0]=='+'?cargv[0]+1:cargv[0];
-
- for (i=0; ch[i]; i++) {
- for (j = 0; ruflags[j].flagchar; j++) {
- if (ruflags[j].flagchar == ch[i]) {
- matchflags|=ruflags[j].flagbit;
- break;
- }
- }
- }
-
- chanservstdmessage(sender, QM_LISTFLAGSHEADER);
- for (i=0;i<REGUSERHASHSIZE;i++) {
- for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
- if ((dbrup->flags & matchflags) == matchflags) {
- chanservsendmessage(sender, "%-15s %-17s %-10s %-30s %s", dbrup->username, printflags(dbrup->flags, ruflags),
- UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set",
- dbrup->lastuserhost?dbrup->lastuserhost->content:"none");
- count++;
- if (count >= 2000) {
- chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
- return CMD_ERROR;
- }
- }
- }
- }
- chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
-
- return CMD_OK;
-}
-
-int csu_dosuspenduserlist(void *source, int cargc, char **cargv) {
- nick *sender=source;
- reguser *rup=getreguserfromnick(sender);
- reguser *vrup;
- reguser *dbrup;
- int i;
- unsigned int count=0;
- struct tm *tmp;
- char buf[200];
-
- if (!rup)
- return CMD_ERROR;
-
- if (cargc < 1) {
- chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduserlist");
- return CMD_ERROR;
- }
-
- vrup=findreguserbynick(cargv[0]);
-
- chanservstdmessage(sender, QM_SUSPENDUSERLISTHEADER);
- for (i=0;i<REGUSERHASHSIZE;i++) {
- for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
- if (!UHasSuspension(dbrup))
- continue;
-
- /*if (!ircd_strcmp(dbrup->username, cargv[0]) || (dbrup->suspendby == vrup->ID)) {*/
- if (!match(cargv[0], dbrup->username) || (vrup && (dbrup->suspendby == vrup->ID))) {
- char suspendtype[100];
- char *bywhom=0;
-
- if ((UIsGline(dbrup) || UIsDelayedGline(dbrup)) && !UHasOperPriv(rup))
- continue;
-
- if (UIsDelayedGline(dbrup))
- strcpy(suspendtype, "delayed gline");
- else if (UIsGline(dbrup))
- strcpy(suspendtype, "instant gline");
- else if (UIsSuspended(dbrup))
- strcpy(suspendtype, "suspended");
- else
- strcpy(suspendtype, "not used");
-
- if (vrup && (dbrup->suspendby == vrup->ID)) {
- bywhom=vrup->username;
- }
- else {
- reguser* trup=findreguserbyID(dbrup->suspendby);
- if (trup)
- bywhom=trup->username;
- }
-
- if (dbrup->suspendexp) {
- tmp=gmtime(&(dbrup->suspendexp));
- strftime(buf,15,"%d/%m/%y %H:%M",tmp);
- }
-
- count++;
- chanservsendmessage(sender, "%-15s %-13s %-15s %-15s %s", dbrup->username, suspendtype, UHasOperPriv(rup)?(bywhom?bywhom:"unknown"):"not shown", (dbrup->suspendexp)?((time(0) >= dbrup->suspendexp)?"next auth":buf):"never", dbrup->suspendreason->content);
- if (count >= 2000) {
- chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
- return CMD_ERROR;
- }
- }
- }
- }
- chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
-
- return CMD_OK;
-}
--- /dev/null
+# Automatically generated Makefile, do not edit.
+
+.PHONY: all Makefile
+all: Makefile chanserv_usercmds.so
+
+Makefile:
+ ../mkcommandlist.pl chanserv_usercmds.so
+
+chanserv_usercmds.so: deluser.o info.o language.o listflags.o spewdb.o spewemail.o spewpass.o suspenduser.o suspenduserlist.o unsuspenduser.o usercomment.o userflags.o whois.o commandlist.o
+ ld -shared -Bdynamic -o $@ $^
--- /dev/null
+/* Automatically generated by mkcommandlist.pl, do not edit. */
+
+#include "../chanserv.h"
+
+/* Prototypes */
+int csu_dodeluser(void *source, int cargc, char **cargv);
+int csu_doinfo(void *source, int cargc, char **cargv);
+int csu_dolanguage(void *source, int cargc, char **cargv);
+int csu_dolistflags(void *source, int cargc, char **cargv);
+int csu_dospewdb(void *source, int cargc, char **cargv);
+int csu_dospewemail(void *source, int cargc, char **cargv);
+int csu_dospewpass(void *source, int cargc, char **cargv);
+int csu_dosuspenduser(void *source, int cargc, char **cargv);
+int csu_dosuspenduserlist(void *source, int cargc, char **cargv);
+int csu_dounsuspenduser(void *source, int cargc, char **cargv);
+int csu_dousercomment(void *source, int cargc, char **cargv);
+int csu_douserflags(void *source, int cargc, char **cargv);
+int csu_dowhois(void *source, int cargc, char **cargv);
+
+void _init() {
+ chanservaddcommand("deluser", QCMD_OPER, 2, csu_dodeluser, "Removes a user from the bot.");
+ chanservaddcommand("info", QCMD_AUTHED, 2, csu_doinfo, "Shows or changes info line.");
+ chanservaddcommand("language", QCMD_AUTHED, 1, csu_dolanguage, "Shows or changes your current language.");
+ chanservaddcommand("listflags", QCMD_OPER, 1, csu_dolistflags, "List users with the specified user flags.");
+ chanservaddcommand("spewdb", QCMD_OPER, 1, csu_dospewdb, "Search for a user in the database.");
+ chanservaddcommand("spewemail", QCMD_OPER, 1, csu_dospewemail, "Search for an e-mail in the database.");
+ chanservaddcommand("spewpass", QCMD_OPER, 1, csu_dospewpass, "Search for a password in the database.");
+ chanservaddcommand("suspenduser", QCMD_OPER, 1, csu_dosuspenduser, "Suspend/Delay GLINE/Instantly GLINE a user.");
+ chanservaddcommand("suspenduserlist", QCMD_HELPER, 1, csu_dosuspenduserlist, "Lists suspended/locked users.");
+ chanservaddcommand("unsuspenduser", QCMD_OPER, 1, csu_dounsuspenduser, "Unsuspend a user.");
+ chanservaddcommand("usercomment", QCMD_OPER, 2, csu_dousercomment, "Shows or changes staff comment for a user.");
+ chanservaddcommand("userflags", QCMD_AUTHED, 2, csu_douserflags, "Shows or changes user flags.");
+ chanservaddcommand("whois", QCMD_AUTHED, 1, csu_dowhois, "Displays information about a user.");
+}
+
+void _fini() {
+ chanservremovecommand("deluser", csu_dodeluser);
+ chanservremovecommand("info", csu_doinfo);
+ chanservremovecommand("language", csu_dolanguage);
+ chanservremovecommand("listflags", csu_dolistflags);
+ chanservremovecommand("spewdb", csu_dospewdb);
+ chanservremovecommand("spewemail", csu_dospewemail);
+ chanservremovecommand("spewpass", csu_dospewpass);
+ chanservremovecommand("suspenduser", csu_dosuspenduser);
+ chanservremovecommand("suspenduserlist", csu_dosuspenduserlist);
+ chanservremovecommand("unsuspenduser", csu_dounsuspenduser);
+ chanservremovecommand("usercomment", csu_dousercomment);
+ chanservremovecommand("userflags", csu_douserflags);
+ chanservremovecommand("whois", csu_dowhois);
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: deluser
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 2
+ * CMDDESC: Removes a user from the bot.
+ * CMDFUNC: csu_dodeluser
+ * CMDPROTO: int csu_dodeluser(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_dodeluser(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender), *target;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "deluser");
+ return CMD_ERROR;
+ }
+
+ if (!(target=findreguser(sender, cargv[0])))
+ return CMD_ERROR;
+
+ cs_log(sender,"DELUSER %s (%s)",target->username,cargc>1?cargv[1]:"");
+ cs_removeuser(target);
+
+ chanservstdmessage(sender, QM_DONE);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: info
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 2
+ * CMDDESC: Shows or changes info line.
+ * CMDFUNC: csu_doinfo
+ * CMDPROTO: int csu_doinfo(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_doinfo(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ chanindex *cip;
+ regchan *rcp;
+ regchanuser *rcup;
+ char linebuf[INFOLEN+10];
+ char *newline="";
+ int doupdate=0;
+
+ if (cargc==0 || *cargv[0]!='#') {
+ /* Global info line */
+ if (cargc==1) {
+ /* Setting to either one word or "none" */
+ if (!ircd_strcmp(cargv[0],"none")) {
+ newline="";
+ doupdate=1;
+ } else {
+ newline=cargv[0];
+ doupdate=1;
+ }
+ } else if (cargc>1) {
+ /* More than one word: we need to stick them back together */
+ snprintf(linebuf,INFOLEN,"%s %s",cargv[0],cargv[1]);
+ newline=linebuf;
+ doupdate=1;
+ }
+
+ if (doupdate) {
+ if (rup->info)
+ freesstring(rup->info);
+
+ rup->info=getsstring(newline, INFOLEN);
+
+ chanservstdmessage(sender, QM_DONE);
+ csdb_updateuser(rup);
+ }
+
+ chanservstdmessage(sender, QM_GLOBALINFO, rup->info?rup->info->content:"(none)");
+ } else {
+ /* Channel info line */
+
+ if (!(cip=findchanindex(cargv[0])) || !(rcp=cip->exts[chanservext]) ||
+ (CIsSuspended(rcp) && !cs_privcheck(QPRIV_SUSPENDBYPASS, sender))) {
+ chanservstdmessage(sender, QM_UNKNOWNCHAN, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if ((!(rcup=findreguseronchannel(rcp, rup)) || !CUHasVoicePriv(rcup))) {
+ chanservstdmessage(sender, QM_NOACCESSONCHAN, cargv[0], "info");
+ return CMD_ERROR;
+ }
+
+ if (cargc>1) {
+ if (rcup->info)
+ freesstring(rcup->info);
+
+ if (!ircd_strcmp(cargv[1],"none"))
+ rcup->info=NULL;
+ else
+ rcup->info=getsstring(cargv[1],INFOLEN);
+
+ csdb_updatechanuser(rcup);
+ chanservstdmessage(sender, QM_DONE);
+ }
+
+ chanservstdmessage(sender, QM_CHANNELINFO, cip->name->content,
+ rcup->info?rcup->info->content:"(none)");
+ }
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: language
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Shows or changes your current language.
+ * CMDFUNC: csu_dolanguage
+ * CMDPROTO: int csu_dolanguage(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_dolanguage(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ char buf[300];
+ int bufpos=0;
+ int i;
+ int len;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc==0) {
+ /* Display language */
+ i=rup->languageid;
+ chanservstdmessage(sender, QM_YOURLANGUAGE, cslanguages[i] ? cslanguages[i]->name->content : "Unknown");
+
+ /* Display available lanaguages */
+ chanservstdmessage(sender, QM_LANGUAGELIST);
+
+ for (i=0;i<MAXLANG;i++) {
+ if (cslanguages[i]) {
+ if (bufpos > 70) {
+ chanservsendmessage(sender, "%s", buf);
+ bufpos=0;
+ }
+ len=sprintf(buf+bufpos, "%.14s (%.2s)",cslanguages[i]->name->content,cslanguages[i]->code);
+ memset(buf+bufpos+len,' ',20-len);
+ bufpos+=20;
+ buf[bufpos]='\0';
+ }
+ }
+
+ if (bufpos)
+ chanservsendmessage(sender, "%s", buf);
+
+ chanservstdmessage(sender, QM_ENDOFLIST);
+ } else {
+ /* Set language */
+ for (i=0;i<MAXLANG;i++) {
+ if (cslanguages[i] && !ircd_strcmp(cargv[0],cslanguages[i]->code)) {
+ /* Match. */
+ rup->languageid=i;
+ csdb_updateuser(rup);
+
+ chanservstdmessage(sender, QM_DONE);
+ chanservstdmessage(sender, QM_YOURLANGUAGE, cslanguages[i]->name->content);
+ break;
+ }
+ }
+
+ if (i==MAXLANG)
+ chanservstdmessage(sender, QM_UNKNOWNLANGUAGE, cargv[0]);
+ }
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: listflags
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 1
+ * CMDDESC: List users with the specified user flags.
+ * CMDFUNC: csu_dolistflags
+ * CMDPROTO: int csu_dolistflags(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_dolistflags(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ reguser *dbrup;
+ flag_t matchflags = 0;
+ char *ch;
+ int i, j;
+ unsigned int count=0;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc < 1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "listflags");
+ return CMD_ERROR;
+ }
+
+ ch=cargv[0][0]=='+'?cargv[0]+1:cargv[0];
+
+ for (i=0; ch[i]; i++) {
+ for (j = 0; ruflags[j].flagchar; j++) {
+ if (ruflags[j].flagchar == ch[i]) {
+ matchflags|=ruflags[j].flagbit;
+ break;
+ }
+ }
+ }
+
+ chanservstdmessage(sender, QM_LISTFLAGSHEADER);
+ for (i=0;i<REGUSERHASHSIZE;i++) {
+ for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
+ if ((dbrup->flags & matchflags) == matchflags) {
+ chanservsendmessage(sender, "%-15s %-17s %-10s %-30s %s", dbrup->username, printflags(dbrup->flags, ruflags),
+ UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set",
+ dbrup->lastuserhost?dbrup->lastuserhost->content:"none");
+ count++;
+ if (count >= 2000) {
+ chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
+ return CMD_ERROR;
+ }
+ }
+ }
+ }
+ chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: spewdb
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 1
+ * CMDDESC: Search for a user in the database.
+ * CMDFUNC: csu_dospewdb
+ * CMDPROTO: int csu_dospewdb(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_dospewdb(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ reguser *dbrup;
+ int i;
+ unsigned int count=0;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc < 1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewdb");
+ return CMD_ERROR;
+ }
+
+ chanservstdmessage(sender, QM_SPEWHEADER);
+ for (i=0;i<REGUSERHASHSIZE;i++) {
+ for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
+ if (!match(cargv[0], dbrup->username)) {
+ chanservsendmessage(sender, "%-15s %-10s %-30s %s", dbrup->username, UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set", dbrup->lastuserhost?dbrup->lastuserhost->content:"none");
+ count++;
+ if (count >= 2000) {
+ chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
+ return CMD_ERROR;
+ }
+ }
+ }
+ }
+ chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: spewemail
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 1
+ * CMDDESC: Search for an e-mail in the database.
+ * CMDFUNC: csu_dospewemail
+ * CMDPROTO: int csu_dospewemail(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_dospewemail(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ reguser *dbrup;
+ int i;
+ unsigned int count=0;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc < 1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewemail");
+ return CMD_ERROR;
+ }
+
+ chanservstdmessage(sender, QM_SPEWHEADER);
+ for (i=0;i<REGUSERHASHSIZE;i++) {
+ for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
+ if (!dbrup->email)
+ continue;
+ if (!match(cargv[0], dbrup->email->content)) {
+ chanservsendmessage(sender, "%-15s %-10s %-30s %s", dbrup->username, UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set", dbrup->lastuserhost?dbrup->lastuserhost->content:"none");
+ count++;
+ if (count >= 2000) {
+ chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
+ return CMD_ERROR;
+ }
+ }
+ }
+ }
+ chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: spewpass
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 1
+ * CMDDESC: Search for a password in the database.
+ * CMDFUNC: csu_dospewpass
+ * CMDPROTO: int csu_dospewpass(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_dospewpass(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ reguser *dbrup;
+ int i;
+ unsigned int count=0;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc < 1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "spewpass");
+ return CMD_ERROR;
+ }
+
+ chanservstdmessage(sender, QM_SPEWHEADER);
+ for (i=0;i<REGUSERHASHSIZE;i++) {
+ for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
+ if (!match(cargv[0], dbrup->password)) {
+ chanservsendmessage(sender, "%-15s %-10s %-30s %s", dbrup->username, UHasSuspension(dbrup)?"yes":"no", dbrup->email?dbrup->email->content:"none set", dbrup->lastuserhost?dbrup->lastuserhost->content:"none");
+ count++;
+ if (count >= 2000) {
+ chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
+ return CMD_ERROR;
+ }
+ }
+ }
+ }
+ chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: suspenduser
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 1
+ * CMDDESC: Suspend/Delay GLINE/Instantly GLINE a user.
+ * CMDFUNC: csu_dosuspenduser
+ * CMDPROTO: int csu_dosuspenduser(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_dosuspenduser(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ reguser *vrup;
+ char* flag;
+ char* victim;
+ char* dur_p;
+ char* reason;
+ int kill=1, gline=0, email=0, password=0, hitcount=0;
+ time_t expires=0;
+ int duration=0;
+ struct tm* tmp;
+ char buf[200]="";
+ int dgwait;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc < 1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
+ return CMD_ERROR;
+ }
+
+ if (cargv[0][0] == '-') {
+ flag=cargv[0];
+ if (!(victim=strchr(flag, ' '))) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
+ return CMD_ERROR;
+ }
+ *(victim++)='\0';
+ if (!(dur_p=strchr(victim, ' '))) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
+ return CMD_ERROR;
+ }
+ *(dur_p++)='\0';
+ if ((reason=strchr(dur_p, ' '))) {
+ *(reason++)='\0';
+ if ((duration=durationtolong(dur_p))) {
+ if ((duration < 86400) || (duration > 2592000)) {
+ chanservstdmessage(sender, QM_INVALIDDURATION);
+ return CMD_ERROR;
+ }
+ expires=time(0)+duration;
+ }
+ else {
+ *(reason-1)=' ';
+ reason=dur_p;
+ expires=0;
+ }
+ }
+ else {
+ reason=dur_p;
+ expires=0;
+ }
+
+ if (!ircd_strcmp(flag, "-nokill")) {
+ kill=0;
+ }
+ else if (!ircd_strcmp(flag, "-gline")) {
+ gline=1;
+ }
+ else if (!ircd_strcmp(flag, "-instantgline")) {
+ gline=2;
+ }
+ else if (!ircd_strcmp(flag, "-email")) {
+ email=1;
+ }
+ else if (!ircd_strcmp(flag, "-password")) {
+ password=1;
+ }
+ else {
+ chanservstdmessage(sender, QM_INVALIDCHANLEVCHANGE);
+ return CMD_ERROR;
+ }
+ }
+ else {
+ victim=cargv[0];
+ if (!(dur_p=strchr(victim, ' '))) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduser");
+ return CMD_ERROR;
+ }
+ *(dur_p++)='\0';
+ if ((reason=strchr(dur_p, ' '))) {
+ *(reason++)='\0';
+ if ((duration=durationtolong(dur_p))) {
+ if ((duration < 86400) || (duration > 2592000)) {
+ chanservstdmessage(sender, QM_INVALIDDURATION);
+ return CMD_ERROR;
+ }
+ expires=time(0)+duration;
+ }
+ else {
+ *(reason-1)=' ';
+ reason=dur_p;
+ expires=0;
+ }
+ }
+ else {
+ reason=dur_p;
+ expires=0;
+ }
+ }
+
+ if (expires) {
+ tmp=gmtime(&expires);
+ strftime(buf,15,"%d/%m/%y %H:%M",tmp);
+ }
+
+ if (email) {
+ int i;
+
+ for (i=0;i<REGUSERHASHSIZE;i++) {
+ for (vrup=regusernicktable[i]; vrup; vrup=vrup->nextbyname) {
+ if (!ircd_strcmp(vrup->email->content, victim)) {
+ if (UHasSuspension(vrup))
+ continue;
+
+ if (UHasOperPriv(vrup) && !UHasAdminPriv(rup))
+ continue;
+
+ hitcount++;
+ vrup->flags|=QUFLAG_SUSPENDED;
+ vrup->suspendby=rup->ID;
+ vrup->suspendexp=expires;
+ vrup->suspendreason=getsstring(reason, strlen(reason)+1);
+
+ while (vrup->nicks) {
+ if (!vrup->nicks->np)
+ continue;
+
+ chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username);
+ chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL);
+ }
+ csdb_updateuser(vrup);
+ }
+ }
+ }
+
+ chanservwallmessage("%s (%s) bulk suspended <%s>, hit %d account/s (expires: %s)", sender->nick, rup->username, victim, hitcount, expires?buf:"never");
+ }
+ else if (password) {
+ int i;
+
+ for (i=0;i<REGUSERHASHSIZE;i++) {
+ for (vrup=regusernicktable[i]; vrup; vrup=vrup->nextbyname) {
+ if (!strcmp(vrup->password, victim)) {
+ if (UHasSuspension(vrup))
+ continue;
+
+ if (UHasOperPriv(vrup) && !UHasAdminPriv(rup))
+ continue;
+
+ hitcount++;
+ vrup->flags|=QUFLAG_SUSPENDED;
+ vrup->suspendby=rup->ID;
+ vrup->suspendexp=expires;
+ vrup->suspendreason=getsstring(reason, strlen(reason)+1);
+
+ while (vrup->nicks) {
+ if (!vrup->nicks->np)
+ continue;
+
+ chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username);
+ chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL);
+ }
+ csdb_updateuser(vrup);
+ }
+ }
+ }
+
+ chanservwallmessage("%s (%s) bulk suspended password \"%s\", hit %d account/s (expires: %s)", sender->nick, rup->username, victim, hitcount, expires?buf:"never");
+ }
+ else {
+ if (!(vrup=findreguser(sender, victim)))
+ return CMD_ERROR;
+
+ if (!ircd_strcmp(vrup->username, rup->username)) {
+ chanservsendmessage(sender, "You can't suspend yourself, silly.");
+ return CMD_ERROR;
+ }
+
+ if (UHasSuspension(vrup)) {
+ chanservstdmessage(sender, QM_USERALREADYSUSPENDED);
+ return CMD_ERROR;
+ }
+
+ if (UHasOperPriv(vrup) && !UHasAdminPriv(rup)) {
+ snprintf(buf, 199, "suspenduser on %s", vrup->username);
+ chanservstdmessage(sender, QM_NOACCESS, buf);
+ chanservwallmessage("%s (%s) FAILED to suspend %s", sender->nick, rup->username, vrup->username);
+ return CMD_ERROR;
+ }
+
+ if (gline == 2)
+ vrup->flags|=QUFLAG_GLINE;
+ else if (gline == 1)
+ vrup->flags|=QUFLAG_DELAYEDGLINE;
+ else
+ vrup->flags|=QUFLAG_SUSPENDED;
+ vrup->suspendby=rup->ID;
+ vrup->suspendexp=expires;
+ vrup->suspendreason=getsstring(reason, strlen(reason)+1);
+
+ chanservwallmessage("%s (%s) %s %s (expires: %s)", sender->nick, rup->username, (gline)?((gline == 2)?"instantly glined":"delayed glined"):"suspended", vrup->username, expires?buf:"never");
+ if (gline) {
+ dgwait=(gline==2)?0:rand()%900;
+ chanservsendmessage(sender, "Scheduling delayed GLINE for account %s in %d %s",
+ vrup->username, (dgwait>60)?(dgwait/60):dgwait, (dgwait>60)?"minutes":"seconds");
+ deleteschedule(NULL, &chanservdgline, (void*)vrup);
+ scheduleoneshot(time(NULL)+dgwait, &chanservdgline, (void*)vrup);
+ }
+ else if (kill) {
+ while (vrup->nicks) {
+ if (!vrup->nicks->np)
+ continue;
+
+ chanservstdmessage(sender, QM_DISCONNECTINGUSER, vrup->nicks->np->nick, vrup->username);
+ chanservkillstdmessage(vrup->nicks->np, QM_SUSPENDKILL);
+ hitcount++;
+ }
+ }
+
+ csdb_updateuser(vrup);
+ }
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: suspenduserlist
+ * CMDLEVEL: QCMD_HELPER
+ * CMDARGS: 1
+ * CMDDESC: Lists suspended/locked users.
+ * CMDFUNC: csu_dosuspenduserlist
+ * CMDPROTO: int csu_dosuspenduserlist(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_dosuspenduserlist(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ reguser *vrup;
+ reguser *dbrup;
+ int i;
+ unsigned int count=0;
+ struct tm *tmp;
+ char buf[200];
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc < 1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "suspenduserlist");
+ return CMD_ERROR;
+ }
+
+ vrup=findreguserbynick(cargv[0]);
+
+ chanservstdmessage(sender, QM_SUSPENDUSERLISTHEADER);
+ for (i=0;i<REGUSERHASHSIZE;i++) {
+ for (dbrup=regusernicktable[i]; dbrup; dbrup=dbrup->nextbyname) {
+ if (!UHasSuspension(dbrup))
+ continue;
+
+ /*if (!ircd_strcmp(dbrup->username, cargv[0]) || (dbrup->suspendby == vrup->ID)) {*/
+ if (!match(cargv[0], dbrup->username) || (vrup && (dbrup->suspendby == vrup->ID))) {
+ char suspendtype[100];
+ char *bywhom=0;
+
+ if ((UIsGline(dbrup) || UIsDelayedGline(dbrup)) && !UHasOperPriv(rup))
+ continue;
+
+ if (UIsDelayedGline(dbrup))
+ strcpy(suspendtype, "delayed gline");
+ else if (UIsGline(dbrup))
+ strcpy(suspendtype, "instant gline");
+ else if (UIsSuspended(dbrup))
+ strcpy(suspendtype, "suspended");
+ else
+ strcpy(suspendtype, "not used");
+
+ if (vrup && (dbrup->suspendby == vrup->ID)) {
+ bywhom=vrup->username;
+ }
+ else {
+ reguser* trup=findreguserbyID(dbrup->suspendby);
+ if (trup)
+ bywhom=trup->username;
+ }
+
+ if (dbrup->suspendexp) {
+ tmp=gmtime(&(dbrup->suspendexp));
+ strftime(buf,15,"%d/%m/%y %H:%M",tmp);
+ }
+
+ count++;
+ chanservsendmessage(sender, "%-15s %-13s %-15s %-15s %s", dbrup->username, suspendtype, UHasOperPriv(rup)?(bywhom?bywhom:"unknown"):"not shown", (dbrup->suspendexp)?((time(0) >= dbrup->suspendexp)?"next auth":buf):"never", dbrup->suspendreason->content);
+ if (count >= 2000) {
+ chanservstdmessage(sender, QM_TOOMANYRESULTS, 2000, "users");
+ return CMD_ERROR;
+ }
+ }
+ }
+ }
+ chanservstdmessage(sender, QM_RESULTCOUNT, count, "user", (count==1)?"":"s");
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: unsuspenduser
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 1
+ * CMDDESC: Unsuspend a user.
+ * CMDFUNC: csu_dounsuspenduser
+ * CMDPROTO: int csu_dounsuspenduser(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_dounsuspenduser(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender);
+ reguser *vrup;
+ char action[100];
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc < 1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unsuspenduser");
+ return CMD_ERROR;
+ }
+
+ if (cargv[0][0] == '#') {
+ if (!(vrup=findreguserbynick(&cargv[0][1]))) {
+ chanservstdmessage(sender, QM_UNKNOWNUSER, &cargv[0][1]);
+ return CMD_ERROR;
+ }
+ }
+ else {
+ nick *np;
+
+ if (!(np=getnickbynick(cargv[0]))) {
+ chanservstdmessage(sender, QM_UNKNOWNUSER, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (!(vrup=getreguserfromnick(np)) && sender) {
+ chanservstdmessage(sender, QM_USERNOTAUTHED, cargv[0]);
+ return CMD_ERROR;
+ }
+ }
+
+ if (!UHasSuspension(vrup)) {
+ chanservstdmessage(sender, QM_USERNOTSUSPENDED, cargv[0]);
+ return CMD_ERROR;
+ }
+
+ if (UHasOperPriv(vrup) && !UHasAdminPriv(rup)) {
+ snprintf(action, 99, "unsuspenduser on %s", vrup->username);
+ chanservstdmessage(sender, QM_NOACCESS, action);
+ chanservwallmessage("%s (%s) FAILED to unsuspend %s", sender->nick, rup->username, vrup->username);
+ return CMD_ERROR;
+ }
+
+ if (UIsDelayedGline(vrup)) {
+ strcpy(action, "removed delayed gline on");
+ }
+ else if (UIsGline(vrup)) {
+ strcpy(action, "removed instant gline on");
+ }
+ else if (UIsSuspended(vrup)) {
+ strcpy(action, "unsuspended");
+ }
+ else if (UIsNeedAuth(vrup)) {
+ strcpy(action, "enabled");
+ }
+ else {
+ chanservsendmessage(sender, "Unknown suspend type encountered.");
+ return CMD_ERROR;
+ }
+
+ vrup->flags&=(~(QUFLAG_GLINE|QUFLAG_DELAYEDGLINE|QUFLAG_SUSPENDED|QUFLAG_NEEDAUTH));
+ vrup->suspendby=0;
+ vrup->suspendexp=0;
+ freesstring(vrup->suspendreason);
+ vrup->suspendreason=0;
+ csdb_updateuser(vrup);
+
+ chanservwallmessage("%s (%s) %s %s", sender->nick, rup->username, action, vrup->username);
+ chanservstdmessage(sender, QM_DONE);
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: usercomment
+ * CMDLEVEL: QCMD_OPER
+ * CMDARGS: 2
+ * CMDDESC: Shows or changes staff comment for a user.
+ * CMDFUNC: csu_dousercomment
+ * CMDPROTO: int csu_dousercomment(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_dousercomment(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender), *target;
+ char buf[300];
+ int bufpos;
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "usercomment");
+ return CMD_ERROR;
+ }
+
+ if (!(target=findreguser(sender, cargv[0])))
+ return CMD_ERROR;
+
+ if (cargc>1) {
+ if (!ircd_strcmp(cargv[1],"none")) {
+ freesstring(target->comment);
+ target->comment=NULL;
+ } else {
+ if (*cargv[1]=='+') {
+ if (target->comment) {
+ strcpy(buf,target->comment->content);
+ bufpos=target->comment->length;
+ buf[bufpos++]=' ';
+ } else {
+ bufpos=0;
+ }
+ strncpy(buf+bufpos, cargv[1]+1, 250-bufpos);
+ } else {
+ strncpy(buf, cargv[1], 250);
+ }
+
+ freesstring(target->comment);
+ target->comment=getsstring(buf,250);
+ }
+ csdb_updateuser(target);
+ }
+
+ if (target->comment)
+ chanservstdmessage(sender, QM_COMMENT, target->username, target->comment->content);
+ else
+ chanservstdmessage(sender, QM_NOCOMMENT, target->username);
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: userflags
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 2
+ * CMDDESC: Shows or changes user flags.
+ * CMDFUNC: csu_douserflags
+ * CMDPROTO: int csu_douserflags(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_douserflags(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender), *target;
+ int arg=0;
+ flag_t flagmask, changemask;
+ char flagbuf[30];
+
+ if (!rup)
+ return CMD_ERROR;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "userflags");
+ return CMD_ERROR;
+ }
+
+ if (*cargv[0]!='+' && *cargv[0]!='-') {
+ arg++;
+ /* If the first char isn't a "change" character, it must specify a target */
+
+ if (!(target=findreguser(sender,cargv[0])))
+ return CMD_ERROR;
+
+ if (target!=rup && !cs_privcheck(QPRIV_VIEWUSERFLAGS, sender)) {
+ chanservstdmessage(sender, QM_NOACCESS, "userflags");
+ return CMD_ERROR;
+ }
+ } else {
+ target=rup;
+ }
+
+ if (cargc>arg) {
+ /* OK, now we have a changestring.. */
+ if (target!=rup && !cs_privcheck(QPRIV_CHANGEUSERFLAGS, sender)) {
+ chanservstdmessage(sender, QM_NOACCESS, "userflags");
+ return CMD_ERROR;
+ }
+
+ strcpy(flagbuf,printflags(target->flags, ruflags));
+
+ changemask=QUFLAG_NOTICE | QUFLAG_INFO;
+
+ if (target==rup) {
+ /* If you're changing yourself, you can give up the "status" flags and add/remove notice */
+ changemask|=(target->flags & (QUFLAG_OPER | QUFLAG_DEV | QUFLAG_PROTECT | QUFLAG_HELPER | QUFLAG_ADMIN));
+ }
+
+ /* Warning, policy ahead */
+
+ if (UHasOperPriv(rup))
+ changemask |= QUFLAG_GLINE | QUFLAG_DELAYEDGLINE | QUFLAG_RESTRICTED | QUFLAG_PROTECT;
+
+ if (UHasAdminPriv(rup))
+ changemask |= (QUFLAG_OPER | QUFLAG_HELPER);
+
+ if (UIsDev(rup))
+ changemask=QUFLAG_ALL;
+
+ setflags(&target->flags, changemask, cargv[arg], ruflags, REJECT_NONE);
+
+ /* More policy */
+ if (!UHasHelperPriv(target)) {
+ target->flags &= ~QUFLAG_PROTECT;
+ }
+
+ cs_log(sender,"USERFLAGS #%s %s (%s -> %s)",target->username,cargv[arg],flagbuf,printflags(target->flags, ruflags));
+ csdb_updateuser(target);
+ chanservstdmessage(sender, QM_DONE);
+ }
+
+ if (cs_privcheck(QPRIV_VIEWUSERFLAGS, sender))
+ flagmask=QUFLAG_ALL;
+ else
+ flagmask=QUFLAG_INFO | QUFLAG_NOTICE | QUFLAG_OPER | QUFLAG_HELPER | QUFLAG_DEV | QUFLAG_ADMIN;
+
+ chanservstdmessage(sender, QM_CURUSERFLAGS, target->username, printflags(target->flags & flagmask, ruflags));
+
+ return CMD_OK;
+}
--- /dev/null
+/* Automatically generated by refactor.pl.
+ *
+ *
+ * CMDNAME: whois
+ * CMDLEVEL: QCMD_AUTHED
+ * CMDARGS: 1
+ * CMDDESC: Displays information about a user.
+ * CMDFUNC: csu_dowhois
+ * CMDPROTO: int csu_dowhois(void *source, int cargc, char **cargv);
+ */
+
+#include "../chanserv.h"
+#include "../../lib/irc_string.h"
+#include <stdio.h>
+#include <string.h>
+
+int csu_dowhois(void *source, int cargc, char **cargv) {
+ nick *sender=source;
+ reguser *rup=getreguserfromnick(sender), *target;
+ char buf[200];
+ char nbpos=0;
+ nicklist *nlp;
+ struct tm *tmp;
+ regchanuser *rcup, *rcup2;
+ flag_t flagmask, flags;
+ int doneheader=0;
+
+ if (!(rup=getreguserfromnick(sender)))
+ return CMD_ERROR;
+
+ if (cargc<1) {
+ chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "whois");
+ return CMD_ERROR;
+ }
+
+ if (!(target=findreguser(sender, cargv[0]))) {
+ nick* np;
+
+ if ((np=getnickbynick(cargv[0]))) {
+ activeuser* aup=getactiveuserfromnick(np);
+ chanservsendmessage(sender, "%s has attempted to auth %d time%s.", np->nick, aup->authattempts,
+ aup->authattempts==1?"":"s");
+ }
+ return CMD_ERROR;
+ }
+
+ if (cargv[0][0]=='#') {
+ chanservstdmessage(sender, QM_WHOISHEADER_AUTH, target->username);
+ } else {
+ chanservstdmessage(sender, QM_WHOISHEADER_NICK, cargv[0], target->username);
+ }
+
+ if (rup==target || cs_privcheck(QPRIV_VIEWFULLWHOIS, sender)) {
+ chanservstdmessage(sender, QM_WHOIS_USERID, target->ID);
+ }
+
+ if (cs_privcheck(QPRIV_VIEWUSERFLAGS, sender)) {
+ flagmask=QUFLAG_ALL;
+ } else {
+ if (UIsAdmin(target))
+ chanservstdmessage(sender, QM_USERISADMIN, target->username);
+ else if (UIsOper(target))
+ chanservstdmessage(sender, QM_USERISOPER, target->username);
+ else if (UIsHelper(target))
+ chanservstdmessage(sender, QM_USERISHELPER, target->username);
+
+ if (UIsDev(target))
+ chanservstdmessage(sender, QM_USERISDEV, target->username);
+
+ flagmask=0;
+ }
+
+ if (rup==target)
+ flagmask|=(QUFLAG_OPER | QUFLAG_DEV | QUFLAG_HELPER |
+ QUFLAG_ADMIN | QUFLAG_INFO | QUFLAG_NOTICE);
+
+ if (flagmask & target->flags)
+ chanservstdmessage(sender, QM_WHOIS_FLAGS, printflags(flagmask & target->flags, ruflags));
+
+ if (!target->nicks) {
+ chanservstdmessage(sender, QM_WHOIS_USERS, "(none)");
+ } else {
+ for (nlp=target->nicks; ;nlp=nlp->next) {
+ if (nbpos>0 && (!nlp || nbpos+strlen(nlp->np->nick) > 60)) {
+ chanservstdmessage(sender, QM_WHOIS_USERS, buf);
+ nbpos=0;
+ }
+
+ if (!nlp)
+ break;
+
+ nbpos+=sprintf(buf+nbpos,"%s ",nlp->np->nick);
+ }
+ }
+
+ if (target->created) {
+ tmp=gmtime(&(target->created));
+ strftime(buf,15,"%d/%m/%y %H:%M",tmp);
+
+ chanservstdmessage(sender, QM_WHOIS_CREATED, buf);
+ }
+
+ tmp=gmtime(&(target->lastauth));
+ strftime(buf,15,"%d/%m/%y %H:%M",tmp);
+
+ chanservstdmessage(sender, QM_WHOIS_LASTAUTH, buf);
+
+ if (target->lastuserhost && (rup==target || cs_privcheck(QPRIV_VIEWFULLWHOIS, sender))) {
+ chanservstdmessage(sender, QM_WHOIS_USERLANG, cslanguages[target->languageid] ?
+ cslanguages[target->languageid]->name->content : "(unknown)");
+ chanservstdmessage(sender, QM_WHOIS_LASTUSERHOST, target->lastuserhost->content);
+ }
+
+ if (target->email && (rup==target || cs_privcheck(QPRIV_VIEWEMAIL, sender))) {
+ chanservstdmessage(sender, QM_WHOIS_EMAIL, target->email->content);
+
+ tmp=gmtime(&(target->lastemailchange));
+ strftime(buf,15,"%d/%m/%y %H:%M",tmp);
+
+ chanservstdmessage(sender, QM_WHOIS_EMAILSET, buf);
+ }
+
+ if (target->info) {
+ chanservstdmessage(sender, QM_WHOIS_INFO, target->info->content);
+ }
+
+ if (target->comment && (cs_privcheck(QPRIV_VIEWCOMMENTS, sender))) {
+ chanservstdmessage(sender, QM_WHOIS_COMMENT, target->comment->content);
+ }
+
+ for (rcup=target->knownon;rcup;rcup=rcup->nextbyuser) {
+ if (!UHasHelperPriv(rup)) {
+ if (!(rcup2=findreguseronchannel(rcup->chan,rup)))
+ continue;
+
+ if (!CUHasVoicePriv(rcup2))
+ continue;
+
+ flagmask = (QCUFLAG_OWNER | QCUFLAG_MASTER | QCUFLAG_OP | QCUFLAG_VOICE | QCUFLAG_AUTOVOICE |
+ QCUFLAG_AUTOOP | QCUFLAG_TOPIC | QCUFLAG_SPAMCON);
+
+ if (CUHasMasterPriv(rcup2))
+ flagmask |= (QCUFLAG_DENY | QCUFLAG_QUIET | QCUFLAG_BANNED);
+ } else {
+ flagmask=QCUFLAG_ALL;
+ }
+
+ if (!(flags=rcup->flags & flagmask))
+ continue;
+
+ if (!doneheader) {
+ doneheader=1;
+ chanservstdmessage(sender, QM_WHOIS_CHANHEADER, target->username);
+ }
+
+ chanservsendmessage(sender, " %-30s %s",rcup->chan->index->name->content,printflags(flags, rcuflags));
+ }
+
+ chanservstdmessage(sender, QM_ENDOFLIST);
+
+ return CMD_OK;
+}