+ bool go_again = true;
+
+ while (go_again)
+ {
+ go_again = false;
+ for (UserList::iterator iter = listusers.begin(); iter != listusers.end(); iter++)
+ {
+ /*
+ * What we do here:
+ * - Get where they are up to
+ * - If it's more than total number of channels, erase
+ * them from the iterator, set go_again to true
+ * - If not, spool more channels
+ */
+ userrec* u = (userrec*)(*iter);
+ ListData* ld;
+ u->GetExt("safelist_cache", ld);
+ if ((size_t)ld->list_position > ServerInstance->chanlist.size())
+ {
+ u->Shrink("safelist_cache");
+ DELETE(ld);
+ listusers.erase(iter);
+ go_again = true;
+ break;
+ }
+
+ ServerInstance->Log(DEBUG, "m_safelist.so: resuming spool of list to client %s at channel %ld", u->nick, ld->list_position);
+ chan = NULL;
+ /* Attempt to fill up to half the user's sendq with /LIST output */
+ long amount_sent = 0;
+ do
+ {
+ ServerInstance->Log(DEBUG,"Channel %ld",ld->list_position);
+ if (!ld->list_position)
+ u->WriteServ("321 %s Channel :Users Name",u->nick);
+ chan = ServerInstance->GetChannelIndex(ld->list_position);
+ /* spool details */
+ bool has_user = (chan && chan->HasUser(u));
+ if ((chan) && (((!(chan->modes[CM_PRIVATE])) && (!(chan->modes[CM_SECRET]))) || (has_user)))
+ {
+ long users = chan->GetUserCounter();
+ if (users)
+ {
+ int counter = snprintf(buffer,MAXBUF,"322 %s %s %ld :[+%s] %s",u->nick,chan->name,users,chan->ChanModes(has_user),chan->topic);
+ /* Increment total plus linefeed */
+ amount_sent += counter + 4 + strlen(ServerInstance->Config->ServerName);
+ ServerInstance->Log(DEBUG,"m_safelist.so: Sent %ld of safe %ld / 4",amount_sent,u->sendqmax);
+ u->WriteServ(std::string(buffer));
+ }
+ }
+ else
+ {
+ if (!chan)
+ {
+ if (!ld->list_ended)
+ {
+ ld->list_ended = true;
+ u->WriteServ("323 %s :End of channel list.",u->nick);
+ }
+ }
+ }
+
+ ld->list_position++;
+ }
+ while ((chan != NULL) && (amount_sent < (u->sendqmax / 4)));
+ }
+ }
+
+ ListTimer* MyTimer = new ListTimer(ServerInstance,1);
+ ServerInstance->Timers->AddTimer(MyTimer);