- std::string::size_type colon = parameter.find(':');
- if (colon == std::string::npos)
- return MODEACTION_DENY;
- int len = atoi(parameter.substr(0, colon).c_str());
- int time = ServerInstance->Duration(parameter.substr(colon+1));
- if (len <= 0 || time < 0 || len > 50)
- return MODEACTION_DENY;
- ext.set(channel, new HistoryList(len, time));
- channel->SetModeParam('H', parameter);
+ source->WriteNumeric(Numerics::InvalidModeParameter(channel, this, parameter));
+ return MODEACTION_DENY;
+ }
+
+ std::string duration(parameter, colon+1);
+ if ((IS_LOCAL(source)) && ((duration.length() > 10) || (!InspIRCd::IsValidDuration(duration))))
+ {
+ source->WriteNumeric(Numerics::InvalidModeParameter(channel, this, parameter));
+ return MODEACTION_DENY;
+ }
+
+ unsigned int len = ConvToNum<unsigned int>(parameter.substr(0, colon));
+ unsigned long time;
+ if (!InspIRCd::Duration(duration, time) || len == 0 || (len > maxlines && IS_LOCAL(source)))
+ {
+ source->WriteNumeric(Numerics::InvalidModeParameter(channel, this, parameter));
+ return MODEACTION_DENY;
+ }
+ if (len > maxlines)
+ len = maxlines;
+
+ HistoryList* history = ext.get(channel);
+ if (history)
+ {
+ // Shrink the list if the new line number limit is lower than the old one
+ if (len < history->lines.size())
+ history->lines.erase(history->lines.begin(), history->lines.begin() + (history->lines.size() - len));
+
+ history->maxlen = len;
+ history->maxtime = time;