+enum
+{
+ RPL_CHECK = 802
+};
+
+class CheckContext
+{
+ private:
+ User* const user;
+ const std::string& target;
+
+ std::string FormatTime(time_t ts)
+ {
+ std::string timestr(InspIRCd::TimeString(ts, "%Y-%m-%d %H:%M:%S UTC (", true));
+ timestr.append(ConvToStr(ts));
+ timestr.push_back(')');
+ return timestr;
+ }
+
+ public:
+ CheckContext(User* u, const std::string& targetstr)
+ : user(u)
+ , target(targetstr)
+ {
+ Write("START", target);
+ }
+
+ ~CheckContext()
+ {
+ Write("END", target);
+ }
+
+ void Write(const std::string& type, const std::string& text)
+ {
+ user->WriteRemoteNumeric(RPL_CHECK, type, text);
+ }
+
+ void Write(const std::string& type, time_t ts)
+ {
+ user->WriteRemoteNumeric(RPL_CHECK, type, FormatTime(ts));
+ }
+
+ User* GetUser() const { return user; }
+
+ void DumpListMode(ListModeBase* mode, Channel* chan)
+ {
+ const ListModeBase::ModeList* list = mode->GetList(chan);
+ if (!list)
+ return;
+
+ for (ListModeBase::ModeList::const_iterator i = list->begin(); i != list->end(); ++i)
+ {
+ CheckContext::List listmode(*this, "listmode");
+ listmode.Add(ConvToStr(mode->GetModeChar()));
+ listmode.Add(i->mask);
+ listmode.Add(i->setter);
+ listmode.Add(FormatTime(i->time));
+ listmode.Flush();
+ }
+ }
+
+ void DumpExt(Extensible* ext)
+ {
+ CheckContext::List extlist(*this, "metadata");
+ for(Extensible::ExtensibleStore::const_iterator i = ext->GetExtList().begin(); i != ext->GetExtList().end(); ++i)
+ {
+ ExtensionItem* item = i->first;
+ std::string value = item->serialize(FORMAT_USER, ext, i->second);
+ if (!value.empty())
+ Write("meta:" + item->name, value);
+ else if (!item->name.empty())
+ extlist.Add(item->name);
+ }
+
+ extlist.Flush();
+ }
+
+ class List : public Numeric::GenericBuilder<' ', false, Numeric::WriteRemoteNumericSink>
+ {
+ public:
+ List(CheckContext& context, const char* checktype)
+ : Numeric::GenericBuilder<' ', false, Numeric::WriteRemoteNumericSink>(Numeric::WriteRemoteNumericSink(context.GetUser()), RPL_CHECK, false, (IS_LOCAL(context.GetUser()) ? context.GetUser()->nick.length() : ServerInstance->Config->Limits.NickMax) + strlen(checktype) + 1)
+ {
+ GetNumeric().push(checktype).push(std::string());
+ }
+ };
+};
+