]> jfr.im git - irc/quakenet/newserv.git/blobdiff - chanserv/chanservuser.c
A4STATS: remove E style escapes and switch to createtable for indices
[irc/quakenet/newserv.git] / chanserv / chanservuser.c
index 5d3a655fbcaff6793f9b2c632b1daf013e203ece..b606f3633cf1354de45b5be588b20a3684a9c410 100644 (file)
@@ -40,7 +40,7 @@ void chanservreguser(void *arg) {
   csuser=getcopyconfigitem("chanserv","user","TheQBot",USERLEN);
   cshost=getcopyconfigitem("chanserv","host","some.host",HOSTLEN);
   csrealname=getcopyconfigitem("chanserv","realname","ChannelService",REALLEN);
-  csaccount=getcopyconfigitem("chanserv","account",csnick&&csnick->content&&csnick->content[0]?csnick->content:"Q",ACCOUNTLEN);
+  csaccount=getcopyconfigitem("chanserv","account",csnick&&csnick->content[0]?csnick->content:"Q",ACCOUNTLEN);
 
   Error("chanserv",ERR_INFO,"Connecting %s...",csnick->content);
 
@@ -355,27 +355,28 @@ void chanservjoinchan(channel *cp) {
   }
 }
 
-void chanservstdmessage(nick *np, int messageid, ... ) {
+static void __chanservstdvmessage(nick *np, reguser *rup, int messageid, int max_line_len, void (*callback)(nick *, char *), ...) {
+  va_list va;
+  va_start(va, callback);
+  chanservstdvmessage(np, rup, messageid, max_line_len, callback, va);
+  va_end(va);
+}
+
+void chanservstdvmessage(nick *np, reguser *rup, int messageid, int max_line_len, void (*callback)(nick *, char *), va_list va) {
   char buf[5010];
   char buf2[512];
-  int notice;
-  reguser *rup;
   int language;
-  va_list va, va2;
+  va_list va2;
   char *message, *messageargs;
   char *bp2,*bp;
   int len;
 
-  if (getreguserfromnick(np) == NULL) { 
-    notice=1;
+  if(max_line_len <= 0)
+    max_line_len = 490 + max_line_len;
+
+  if (rup == NULL) {
     language=0;
   } else {
-    rup=getreguserfromnick(np);
-    if(UIsNotice(rup)) {
-      notice=1;
-    } else {
-      notice=0;
-    }
     language=rup->languageid;
   }
 
@@ -389,29 +390,22 @@ void chanservstdmessage(nick *np, int messageid, ... ) {
 
   messageargs=defaultmessages[messageid*2+1];
 
-  va_start(va,messageid);
   va_copy(va2, va);
   q9vsnprintf(buf,5000,message,messageargs,va);
-  va_end(va);
 
   len=0;
   bp2=buf2;
   for (bp=buf; ;bp++) {
     /* We send something if we hit a \n, fill the buffer or run out of source */
-    if (*bp=='\n' || len>490 || !*bp) {
+    if (*bp=='\n' || len>max_line_len || !*bp) {
       if (*bp && *bp!='\n') {
        bp--;
       }
       
       *bp2='\0';
 
-      if (chanservnick && *buf2) {
-       if (notice) {
-         sendnoticetouser(chanservnick,np,"%s",buf2);
-       } else {
-         sendmessagetouser(chanservnick,np,"%s",buf2);
-       }
-      }
+      if (chanservnick && *buf2)
+        callback(np, buf2);
 
       /* If we ran out of buffer, get out here */
       if (!*bp)
@@ -429,12 +423,33 @@ void chanservstdmessage(nick *np, int messageid, ... ) {
   if (messageid==QM_NOTENOUGHPARAMS) {
     char *command=va_arg(va2, char *);
     cs_sendhelp(np, command, 1);
-    chanservstdmessage(np, QM_TYPEHELPFORHELP, command); 
+    __chanservstdvmessage(np, rup, QM_TYPEHELPFORHELP, max_line_len, callback, command);
   }
   
   va_end(va2);
 }
 
+static void message_callback(nick *np, char *buf) {
+  sendmessagetouser(chanservnick,np,"%s",buf);
+}
+
+static void notice_callback(nick *np, char *buf) {
+  sendnoticetouser(chanservnick,np,"%s",buf);
+}
+
+void chanservstdmessage(nick *np, int messageid, ...) {
+  reguser *rup;
+  va_list va;
+  int notice;
+
+  rup = getreguserfromnick(np);
+  notice = rup == NULL ? 1 : UIsNotice(rup);
+
+  va_start(va, messageid);
+  chanservstdvmessage(np, rup, messageid, 0, notice ? notice_callback : message_callback, va);
+  va_end(va);
+}
+
 void chanservsendmessage_real(nick *np, int oneline, char *message, ... ) {
   char buf[5010]; /* Very large buffer.. */
   char buf2[512], *bp, *bp2;
@@ -792,7 +807,7 @@ void cs_doallautomodes(nick *np) {
           continue;
         }
 
-        if (CUKnown(rcup) && rcup->chan->index->channel->users->totalusers >= 3) {
+        if (CUHasOpPriv(rcup) && cs_ischannelactive(rcup->chan->index->channel, NULL)) {
           /* This meets the channel use criteria, update. */
           rcup->chan->lastactive=time(NULL);
           
@@ -1131,7 +1146,16 @@ int cs_removechannelifempty(nick *sender, regchan *rcp) {
         return 0;
     }
   }
-  
+
+  /*
+   * don't cleanup the last channel to prevent channel id reuse.
+   * the channel will be orphaned but will be cleaned up by cleanup eventually
+   */
+  if(rcp->ID == lastchannelID) {
+    cs_log(sender,"DELCHAN FAILED %s (last id)",rcp->index->name->content);
+    return 0;
+  }
+
   cs_log(sender,"DELCHAN %s (Empty)",rcp->index->name->content);
   cs_removechannel(rcp, "Last user removed - channel deleted.");
   
@@ -1368,7 +1392,7 @@ reguser *findreguser(nick *sender, const char *str) {
  *
  * Return 0 if it works, 1 if it don't.
  */
-int cs_unbanfn(nick *sender, chanindex *cip, UnbanFN fn, void *arg, int removepermbans, int abortonfailure) {
+int cs_unbanfn(nick *sender, chanindex *cip, int (*fn)(void *arg, struct chanban *ban), void *arg, int removepermbans, int abortonfailure) {
   regban **rbh, *rbp;
   chanban **cbh, *cbp;
   regchan *rcp;
@@ -1444,3 +1468,98 @@ int checkreason(nick *np, char *reason) {
 
   return 1;
 }
+
+regchan *cs_addchan(chanindex *cip, nick *sender, reguser *addedby, reguser *founder, flag_t flags, flag_t forcemodes, flag_t denymodes, short type) {
+  regchan *rcp;
+  regchanuser *rcup;
+  void *args[3];
+  int i;
+
+  if (cip->exts[chanservext])
+    return NULL;
+
+  /* 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=forcemodes;
+  rcp->denymodes=denymodes;
+
+  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=0;
+  rcp->autoupdate=0;
+  rcp->lastbancheck=0;
+
+  /* Added by */
+  rcp->addedby=addedby->ID;
+
+  /* Founder */
+  rcp->founder=founder->ID;
+
+  /* Suspend by */
+  rcp->suspendby=0;
+  rcp->suspendtime=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;
+  for (i=0;i<CHANOPHISTORY;i++) {
+    rcp->chanopnicks[i][0]='\0';
+    rcp->chanopaccts[i]=0;
+  }
+  rcp->chanoppos=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);
+  csdb_chanlevhistory_insert(rcp, sender, rcup->user, 0, rcup->flags);
+
+  args[0]=sender;
+  args[1]=rcup;
+  args[2]=(void *)0;
+
+  triggerhook(HOOK_CHANSERV_CHANLEVMOD, args);
+
+  /* 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);
+  }
+
+  return rcp;
+}