]> jfr.im git - irc/quakenet/newserv.git/blobdiff - chanserv/chanservuser.c
CHANSERV: more checks on lastchannelID / lastuserID
[irc/quakenet/newserv.git] / chanserv / chanservuser.c
index a10902f5d338dcc2a22a012460b30f4616b3dfd7..0428050082ac734a2cb7debc510c15c8ed498114 100644 (file)
@@ -1131,7 +1131,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.");
   
@@ -1444,3 +1453,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;
+}