+#if defined(GCC_VARMACROS)
+# define opserv_debug(ARGS...) do { if (opserv_conf.debug_channel) send_channel_notice(opserv_conf.debug_channel, opserv, ARGS); } while (0)
+# define opserv_alert(ARGS...) do { if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel, opserv, ARGS); } while (0)
+# define opserv_custom_alert(CHAN, ARGS...) do { if (CHAN) send_target_message(4, (CHAN), opserv, ARGS); else if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel, opserv, ARGS); } while (0)
+#elif defined(C99_VARMACROS)
+# define opserv_debug(...) do { if (opserv_conf.debug_channel) send_channel_notice(opserv_conf.debug_channel, opserv, __VA_ARGS__); } while (0)
+# define opserv_alert(...) do { if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel, opserv, __VA_ARGS__); } while (0)
+# define opserv_custom_alert(chan, ...) do { if (chan) send_target_message(4, chan, opserv, __VA_ARGS__); else if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel, opserv, __VA_ARGS__); } while (0)
+#endif
+
+char *defconReverseModes(const char *modes)
+{
+ char *newmodes = NULL;
+ unsigned int i = 0;
+ if (!modes) {
+ return NULL;
+ }
+ if (!(newmodes = malloc(sizeof(char) * strlen(modes) + 1))) {
+ return NULL;
+ }
+ for (i = 0; i < strlen(modes); i++) {
+ if (modes[i] == '+')
+ newmodes[i] = '-';
+ else if (modes[i] == '-')
+ newmodes[i] = '+';
+ else
+ newmodes[i] = modes[i];
+ }
+ newmodes[i] = '\0';
+ return newmodes;
+}
+
+int checkDefCon(int level)
+{
+ return DefCon[DefConLevel] & level;
+}
+
+void showDefConSettings(struct userNode *user, struct svccmd *cmd)
+{
+ if (DefConLevel == 5) {
+ reply("OSMSG_DEFCON_ALLOWING_ALL");
+ return;
+ } else
+ reply("OSMSG_DEFCON_DISALLOWING", DefConLevel);
+
+ if (checkDefCon(DEFCON_NO_NEW_CHANNELS))
+ reply("OSMSG_DEFCON_NO_NEW_CHANNELS");
+
+ if (checkDefCon(DEFCON_NO_NEW_NICKS))
+ reply("OSMSG_DEFCON_NO_NEW_NICKS");
+
+ if (checkDefCon(DEFCON_NO_MODE_CHANGE))
+ reply("OSMSG_DEFCON_NO_MODE_CHANGE");
+
+ if (checkDefCon(DEFCON_FORCE_CHAN_MODES) && (DefConChanModes))
+ reply("OSMSG_DEFCON_FORCE_CHANMODES", DefConChanModes);
+
+ if (checkDefCon(DEFCON_REDUCE_SESSION))
+ reply("OSMSG_DEFCON_REDUCE_SESSION", DefConSessionLimit);
+
+ if (checkDefCon(DEFCON_NO_NEW_CLIENTS))
+ reply("OSMSG_DEFCON_NO_NEW_CLIENTS");
+
+ if (checkDefCon(DEFCON_OPER_ONLY))
+ reply("OSMSG_DEFCON_OPER_ONLY");
+
+ if (checkDefCon(DEFCON_SILENT_OPER_ONLY))
+ reply("OSMSG_DEFCON_SILENT_OPER_ONLY");
+
+ if (checkDefCon(DEFCON_GLINE_NEW_CLIENTS))
+ reply("OSMSG_DEFCON_GLINE_NEW_CLIENTS");
+
+ if (checkDefCon(DEFCON_SHUN_NEW_CLIENTS))
+ reply("OSMSG_DEFCON_SHUN_NEW_CLIENTS");
+
+ if (checkDefCon(DEFCON_NO_NEW_MEMOS))
+ reply("OSMSG_DEFCON_NO_NEW_MEMOS");
+
+ return;
+}
+
+void do_mass_mode(char *modes)
+{
+ dict_iterator_t it;
+
+ if (!modes)
+ return;
+
+ for (it = dict_first(channels); it; it = iter_next(it)) {
+ struct chanNode *chan = iter_data(it);
+
+ irc_mode(opserv, chan, modes);
+ }
+
+}
+
+void DefConProcess(struct userNode *user)
+{
+ char *newmodes;
+
+ if (GlobalOnDefcon)
+ global_message_args(MESSAGE_RECIPIENT_LUSERS, "DEFCON_NETWORK_CHANGED", DefConLevel);
+
+ if (GlobalOnDefconMore && GlobalOnDefcon)
+ global_message(MESSAGE_RECIPIENT_LUSERS, DefConMessage);
+
+ if ((DefConLevel == 5) && !GlobalOnDefconMore && !GlobalOnDefcon)
+ global_message(MESSAGE_RECIPIENT_LUSERS, DefConOffMessage);
+
+ if (user)
+ global_message_args(MESSAGE_RECIPIENT_OPERS, "DEFCON_OPER_LEVEL_CHANGE", user->nick, DefConLevel);
+ else
+ global_message_args(MESSAGE_RECIPIENT_OPERS, "DEFCON_TIMEOUT_LEVEL_CHANGE", DefConLevel);
+
+ if (checkDefCon(DEFCON_FORCE_CHAN_MODES)) {
+ if (DefConChanModes && !DefConModesSet) {
+ if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') {
+ do_mass_mode(DefConChanModes);
+ DefConModesSet = 1;
+ }
+ }
+ } else {
+ if (DefConChanModes && (DefConModesSet != 0)) {
+ if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') {
+ if ((newmodes = defconReverseModes(DefConChanModes))) {
+ do_mass_mode(newmodes);
+ free(newmodes);
+ }
+ DefConModesSet = 0;
+ }
+ }
+ }
+
+ return;
+}
+
+void
+defcon_timeout(UNUSED_ARG(void *data))
+{
+ DefConLevel = 5;
+ DefConProcess(NULL);
+}
+
+static MODCMD_FUNC(cmd_defcon)
+{
+ if ((argc < 2) || (atoi(argv[1]) == DefConLevel)) {
+ showDefConSettings(user, cmd);
+ return 1;
+ }
+
+ if ((atoi(argv[1]) < 1) || (atoi(argv[1]) > 5)) {
+ reply("OSMSG_DEFCON_INVALID", atoi(argv[1]));
+ return 0;
+ }
+
+ DefConLevel = atoi(argv[1]);
+ showDefConSettings(user, cmd);
+
+ if (DefConTimeOut > 0) {
+ timeq_del(0, defcon_timeout, NULL, TIMEQ_IGNORE_DATA | TIMEQ_IGNORE_WHEN);
+ timeq_add(now + DefConTimeOut, defcon_timeout, NULL);
+ }
+
+ DefConProcess(user);
+ return 1;
+}
+
+/* TODO
+static MODCMD_FUNC(cmd_privallow)
+{
+//privallow servername/username +/-flag (global is set in conf)
+}
+
+static MODCMD_FUNC(cmd_privdissallow)
+{
+//privdisallow servername/username +/-flag (global is set in conf)
+}
+
+static MODCMD_FUNC(cmd_privlist)
+{
+//privlist servername/user (global with none)
+}
+*/
+
+static MODCMD_FUNC(cmd_privset)
+{
+ struct userNode *target;
+ char *flag;
+ int add = PRIV_ADD;
+
+ flag = argv[2];
+ if (*flag == '-') {
+ add = PRIV_DEL;
+ flag++;
+ } else if (*flag == '+') {
+ add = PRIV_ADD;
+ flag++;
+ }
+
+ target = GetUserH(argv[1]);
+ if (!target) {
+ reply("MSG_NICK_UNKNOWN", argv[1]);
+ return 0;
+ }
+
+ if (check_priv(flag)) {
+ irc_privs(target, flag, add);
+ reply("OSMSG_PRIV_SET", argv[2], (add == 1) ? "" : "un");
+ } else {
+ reply("OSMSG_PRIV_UNKNOWN", argv[2]);
+ return 0;
+ }