static void funserv_cmd_requestbot(sourceinfo_t *si, int parc, char *parv[]) { char *name = parv[0]; mychan_t *mc; if (!name) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "REQUESTBOT"); command_fail(si, fault_needmoreparams, _("Syntax: REQUESTBOT <#channel>")); } if (*name != '#') { command_fail(si, fault_needmoreparams, STR_INVALID_PARAMS, "REQUESTBOT"); command_fail(si, fault_needmoreparams, _("Syntax: REQUESTBOT <#channel>")); } if (!(mc = mychan_find(name))) { command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), name); return; } if (!is_founder(mc, entity(si->smu))) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); return; } myuser_notice(funserv->nick, myuser_find_ext(BOTNAME), "JOIN %s", name); command_success_nodata(si, "The bot should now be in %s.", name); }
static void ns_cmd_acc(sourceinfo_t *si, int parc, char *parv[]) { const char *targuser = parv[0]; const char *targaccount = parv[1]; user_t *u; myuser_t *mu; mynick_t *mn; bool show_id = config_options.show_entity_id || has_priv(si, PRIV_USER_AUSPEX); if (!targuser) { u = si->su; targuser = u != NULL ? u->nick : "?"; } else u = user_find_named(targuser); if (!u) { command_fail(si, fault_nosuch_target, _("%s%s%s ACC 0 (offline)"), targuser, parc >= 2 ? " -> " : "", parc >= 2 ? targaccount : ""); return; } if (!targaccount) targaccount = u->nick; if (!strcmp(targaccount, "*")) mu = u->myuser; else mu = myuser_find_ext(targaccount); if (!mu) { command_fail(si, fault_nosuch_target, _("%s%s%s ACC 0 (not registered)"), u->nick, parc >= 2 ? " -> " : "", parc >= 2 ? targaccount : ""); return; } if (u->myuser == mu) command_success_nodata(si, "%s%s%s ACC 3 %s", u->nick, parc >= 2 ? " -> " : "", parc >= 2 ? entity(mu)->name : "", show_id ? entity(mu)->id : ""); else if ((mn = mynick_find(u->nick)) != NULL && mn->owner == mu && myuser_access_verify(u, mu)) command_success_nodata(si, "%s%s%s ACC 2 %s", u->nick, parc >= 2 ? " -> " : "", parc >= 2 ? entity(mu)->name : "", show_id ? entity(mu)->id : ""); else command_success_nodata(si, "%s%s%s ACC 1 %s", u->nick, parc >= 2 ? " -> " : "", parc >= 2 ? entity(mu)->name : "", show_id ? entity(mu)->id : ""); }
static void ns_cmd_staff(sourceinfo_t *si, int parc, char *parv[]) { char *target = parv[0]; char *action = parv[1]; myuser_t *mu; if (!target || !action) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "STAFF"); command_fail(si, fault_needmoreparams, _("Usage: STAFF <account> <ON|OFF>")); return; } if (!(mu = myuser_find_ext(target))) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), target); return; } if (!strcasecmp(action, "ON")) { if (metadata_find(mu, "private:staff:setter")) { command_fail(si, fault_badparams, _("\2%s\2 is already a member of staff."), entity(mu)->name); return; } metadata_add(mu, "private:staff:setter", get_oper_name(si)); metadata_add(mu, "private:staff:timestamp", number_to_string(CURRTIME)); wallops("%s set the STAFF option for the account \2%s\2.", get_oper_name(si), entity(mu)->name); logcommand(si, CMDLOG_ADMIN, "STAFF:ON: \2%s\2", entity(mu)->name); command_success_nodata(si, _("\2%s\2 is now a member of staff."), entity(mu)->name); } else if (!strcasecmp(action, "OFF")) { if (!metadata_find(mu, "private:staff:setter")) { command_fail(si, fault_badparams, _("\2%s\2 is not a member of staff."), entity(mu)->name); return; } metadata_delete(mu, "private:staff:setter"); metadata_delete(mu, "private:staff:timestamp"); wallops("%s removed the STAFF option on the account \2%s\2.", get_oper_name(si), entity(mu)->name); logcommand(si, CMDLOG_ADMIN, "STAFF:OFF: \2%s\2", entity(mu)->name); command_success_nodata(si, _("\2%s\2 is no longer a member of staff."), entity(mu)->name); } else { command_fail(si, fault_needmoreparams, STR_INVALID_PARAMS, "STAFF"); command_fail(si, fault_needmoreparams, _("Usage: STAFF <account> <ON|OFF>")); } }
static void ns_cmd_hold(struct sourceinfo *si, int parc, char *parv[]) { char *target = parv[0]; char *action = parv[1]; struct myuser *mu; if (!target || !action) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "HOLD"); command_fail(si, fault_needmoreparams, _("Usage: HOLD <account> <ON|OFF>")); return; } if (!(mu = myuser_find_ext(target))) { command_fail(si, fault_nosuch_target, STR_IS_NOT_REGISTERED, target); return; } if (!strcasecmp(action, "ON")) { if (mu->flags & MU_HOLD) { command_fail(si, fault_badparams, _("\2%s\2 is already held."), entity(mu)->name); return; } mu->flags |= MU_HOLD; wallops("%s set the HOLD option for the account \2%s\2.", get_oper_name(si), entity(mu)->name); logcommand(si, CMDLOG_ADMIN, "HOLD:ON: \2%s\2", entity(mu)->name); command_success_nodata(si, _("\2%s\2 is now held."), entity(mu)->name); } else if (!strcasecmp(action, "OFF")) { if (!(mu->flags & MU_HOLD)) { command_fail(si, fault_badparams, _("\2%s\2 is not held."), entity(mu)->name); return; } mu->flags &= ~MU_HOLD; wallops("%s removed the HOLD option on the account \2%s\2.", get_oper_name(si), entity(mu)->name); logcommand(si, CMDLOG_ADMIN, "HOLD:OFF: \2%s\2", entity(mu)->name); command_success_nodata(si, _("\2%s\2 is no longer held."), entity(mu)->name); } else { command_fail(si, fault_needmoreparams, STR_INVALID_PARAMS, "HOLD"); command_fail(si, fault_needmoreparams, _("Usage: HOLD <account> <ON|OFF>")); } }
static void ns_cmd_regnolimit(struct sourceinfo *si, int parc, char *parv[]) { char *target = parv[0]; char *action = parv[1]; struct myuser *mu; if (!target || !action) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "REGNOLIMIT"); command_fail(si, fault_needmoreparams, _("Usage: REGNOLIMIT <account> <ON|OFF>")); return; } if (!(mu = myuser_find_ext(target))) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), target); return; } if (!strcasecmp(action, "ON")) { if (mu->flags & MU_REGNOLIMIT) { command_fail(si, fault_badparams, _("\2%s\2 can already bypass registration limits."), entity(mu)->name); return; } mu->flags |= MU_REGNOLIMIT; wallops("%s set the REGNOLIMIT option for the account \2%s\2.", get_oper_name(si), entity(mu)->name); logcommand(si, CMDLOG_ADMIN, "REGNOLIMIT:ON: \2%s\2", entity(mu)->name); command_success_nodata(si, _("\2%s\2 can now bypass registration limits."), entity(mu)->name); } else if (!strcasecmp(action, "OFF")) { if (!(mu->flags & MU_REGNOLIMIT)) { command_fail(si, fault_badparams, _("\2%s\2 cannot bypass registration limits."), entity(mu)->name); return; } mu->flags &= ~MU_REGNOLIMIT; wallops("%s removed the REGNOLIMIT option on the account \2%s\2.", get_oper_name(si), entity(mu)->name); logcommand(si, CMDLOG_ADMIN, "REGNOLIMIT:OFF: \2%s\2", entity(mu)->name); command_success_nodata(si, _("\2%s\2 cannot bypass registration limits anymore."), entity(mu)->name); } else { command_fail(si, fault_needmoreparams, STR_INVALID_PARAMS, "REGNOLIMIT"); command_fail(si, fault_needmoreparams, _("Usage: REGNOLIMIT <account> <ON|OFF>")); } }
static void ns_cmd_fenforce(sourceinfo_t *si, int parc, char *parv[]) { char *setting; myuser_t *mu; if (parc < 2) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FENFORCE"); command_fail(si, fault_needmoreparams, _("Syntax: FENFORCE <account> ON|OFF")); return; } mu = myuser_find_ext(parv[0]); if (!mu) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), parv[0]); return; } setting = parv[1]; if (strcasecmp(setting, "ON") == 0) { if (metadata_find(mu, "private:doenforce")) { command_fail(si, fault_nochange, _("The \2%s\2 flag is already set for account \2%s\2."), "ENFORCE", entity(mu)->name); } else { wallops("%s enabled ENFORCE on the account \2%s\2.", get_oper_name(si), entity(mu)->name); logcommand(si, CMDLOG_ADMIN, "FENFORCE:ON: \2%s\2", entity(mu)->name); metadata_add(mu, "private:doenforce", "1"); command_success_nodata(si, _("The \2%s\2 flag has been set for account \2%s\2."), "ENFORCE", entity(mu)->name); } } else if (strcasecmp(setting, "OFF") == 0) { if (metadata_find(mu, "private:doenforce")) { wallops("%s disabled ENFORCE on the account \2%s\2.", get_oper_name(si), entity(mu)->name); logcommand(si, CMDLOG_ADMIN, "FENFORCE:OFF: \2%s\2", entity(mu)->name); metadata_delete(mu, "private:doenforce"); command_success_nodata(si, _("The \2%s\2 flag has been removed for account \2%s\2."), "ENFORCE", entity(mu)->name); } else { command_fail(si, fault_nochange, _("The \2%s\2 flag is not set for account \2%s\2."), "ENFORCE", entity(mu)->name); } } else { command_fail(si, fault_badparams, STR_INVALID_PARAMS, "FENFORCE"); } }
static void gs_cmd_invite(struct sourceinfo *si, int parc, char *parv[]) { struct mygroup *mg; struct myuser *mu; struct groupacs *ga; char *group = parv[0]; char *user = parv[1]; char buf[BUFSIZE]; struct service *svs; if (!group || !user) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "INVITE"); command_fail(si, fault_needmoreparams, _("Syntax: INVITE <!group> <user>")); return; } if ((mg = mygroup_find(group)) == NULL) { command_fail(si, fault_nosuch_target, _("The group \2%s\2 does not exist."), group); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_INVITE)) { command_fail(si, fault_noprivs, STR_NOT_AUTHORIZED); return; } if ((mu = myuser_find_ext(user)) == NULL) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not a registered account."), user); return; } if ((ga = groupacs_find(mg, entity(mu), 0, false)) != NULL) { command_fail(si, fault_badparams, _("\2%s\2 is already a member of \2%s\2."), user, group); return; } if (metadata_find(mu, "private:groupinvite")) { command_fail(si, fault_badparams, _("\2%s\2 can not be invited to a group currently because they already \ have another invitation pending."), user); return; }
static void ns_cmd_freeze(char *origin) { myuser_t *mu; user_t *source = user_find_named(origin); char *target = strtok(NULL, " "); char *action = strtok(NULL, " "); char *reason = strtok(NULL, ""); if (source == NULL) return; if (!target || !action) { notice(nicksvs.nick, origin, STR_INSUFFICIENT_PARAMS, "FREEZE"); notice(nicksvs.nick, origin, "Usage: FREEZE <username> <ON|OFF> [reason]"); return; } mu = myuser_find_ext(target); if (!mu) { notice(nicksvs.nick, origin, "\2%s\2 is not a registered nickname.", target); return; } if (!strcasecmp(action, "ON")) { if (!reason) { notice(nicksvs.nick, origin, STR_INSUFFICIENT_PARAMS, "FREEZE"); notice(nicksvs.nick, origin, "Usage: FREEZE <username> ON <reason>"); return; } if (is_soper(mu)) { notice(nicksvs.nick, origin, "The nickname \2%s\2 belongs to a services operator; it cannot be frozen.", target); return; } if (metadata_find(mu, METADATA_USER, "private:freeze:freezer")) { notice(nicksvs.nick, origin, "\2%s\2 is already frozen.", target); return; } metadata_add(mu, METADATA_USER, "private:freeze:freezer", origin); metadata_add(mu, METADATA_USER, "private:freeze:reason", reason); metadata_add(mu, METADATA_USER, "private:freeze:timestamp", itoa(CURRTIME)); wallops("%s froze the nickname \2%s\2 (%s).", origin, target, reason); logcommand(nicksvs.me, source, CMDLOG_ADMIN, "FREEZE %s ON", target); notice(nicksvs.nick, origin, "\2%s\2 is now frozen.", target); } else if (!strcasecmp(action, "OFF")) { if (!metadata_find(mu, METADATA_USER, "private:freeze:freezer")) { notice(nicksvs.nick, origin, "\2%s\2 is not frozen.", target); return; } metadata_delete(mu, METADATA_USER, "private:freeze:freezer"); metadata_delete(mu, METADATA_USER, "private:freeze:reason"); metadata_delete(mu, METADATA_USER, "private:freeze:timestamp"); wallops("%s thawed the nickname \2%s\2.", origin, target); logcommand(nicksvs.me, source, CMDLOG_ADMIN, "FREEZE %s OFF", target); notice(nicksvs.nick, origin, "\2%s\2 has been thawed", target); } else { notice(nicksvs.nick, origin, STR_INSUFFICIENT_PARAMS, "FREEZE"); notice(nicksvs.nick, origin, "Usage: FREEZE <account> <ON|OFF> [reason]"); } }
/* FFLAGS <channel> <user> <flags> */ static void cs_cmd_fflags(sourceinfo_t *si, int parc, char *parv[]) { char *channel = parv[0]; char *target = parv[1]; char *flagstr = parv[2]; mychan_t *mc; myuser_t *tmu; unsigned int addflags, removeflags; if (parc < 3) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FFLAGS"); command_fail(si, fault_needmoreparams, _("Syntax: FFLAGS <channel> <target> <flags>")); return; } mc = mychan_find(channel); if (!mc) { command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), channel); return; } if (*flagstr == '+' || *flagstr == '-' || *flagstr == '=') { flags_make_bitmasks(flagstr, chanacs_flags, &addflags, &removeflags); if (addflags == 0 && removeflags == 0) { command_fail(si, fault_badparams, _("No valid flags given, use /%s%s HELP FLAGS for a list"), ircd->uses_rcommand ? "" : "msg ", chansvs.me->disp); return; } } else { addflags = get_template_flags(mc, flagstr); if (addflags == 0) { /* Hack -- jilles */ if (*target == '+' || *target == '-' || *target == '=') command_fail(si, fault_badparams, _("Usage: FFLAGS %s <target> <flags>"), mc->name); else command_fail(si, fault_badparams, _("Invalid template name given, use /%s%s TEMPLATE %s for a list"), ircd->uses_rcommand ? "" : "msg ", chansvs.me->disp, mc->name); return; } removeflags = ca_all & ~addflags; } if (!validhostmask(target)) { if (!(tmu = myuser_find_ext(target))) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), target); return; } target = tmu->name; /* XXX this should be more like flags.c */ if (removeflags & CA_FLAGS) removeflags |= CA_FOUNDER, addflags &= ~CA_FOUNDER; else if (addflags & CA_FOUNDER) addflags |= CA_FLAGS, removeflags &= ~CA_FLAGS; if (is_founder(mc, tmu) && removeflags & CA_FOUNDER && mychan_num_founders(mc) == 1) { command_fail(si, fault_noprivs, _("You may not remove the last founder.")); return; } if (!chanacs_change(mc, tmu, NULL, &addflags, &removeflags, ca_all)) { /* this shouldn't happen */ command_fail(si, fault_noprivs, _("You are not allowed to set \2%s\2 on \2%s\2 in \2%s\2."), bitmask_to_flags2(addflags, removeflags, chanacs_flags), tmu->name, mc->name); return; } } else { if (addflags & CA_FOUNDER) { command_fail(si, fault_badparams, _("You may not set founder status on a hostmask.")); return; } if (!chanacs_change(mc, NULL, target, &addflags, &removeflags, ca_all)) { /* this shouldn't happen */ command_fail(si, fault_noprivs, _("You are not allowed to set \2%s\2 on \2%s\2 in \2%s\2."), bitmask_to_flags2(addflags, removeflags, chanacs_flags), target, mc->name); return; } } if ((addflags | removeflags) == 0) { command_fail(si, fault_nochange, _("Channel access to \2%s\2 for \2%s\2 unchanged."), channel, target); return; } flagstr = bitmask_to_flags2(addflags, removeflags, chanacs_flags); wallops("\2%s\2 is forcing flags change \2%s\2 on \2%s\2 in \2%s\2.", get_oper_name(si), flagstr, target, mc->name); snoop("FFLAGS: \2%s\2 \2%s\2 \2%s\2 by \2%s\2", channel, target, flagstr, get_oper_name(si)); command_success_nodata(si, _("Flags \2%s\2 were set on \2%s\2 in \2%s\2."), flagstr, target, channel); logcommand(si, CMDLOG_ADMIN, "%s FFLAGS %s %s", mc->name, target, flagstr); verbose(mc, "\2%s\2 forced flags change \2%s\2 on \2%s\2.", get_source_name(si), flagstr, target); }
static void ns_cmd_restrict(sourceinfo_t *si, int parc, char *parv[]) { char *target = parv[0]; char *action = parv[1]; char *info = parv[2]; myuser_t *mu; myuser_name_t *mun; if (!target || !action) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "RESTRICT"); command_fail(si, fault_needmoreparams, _("Usage: RESTRICT <target> <ON|OFF> [note]")); return; } if (!(mu = myuser_find_ext(target))) { mun = myuser_name_find(target); if (mun != NULL && !strcasecmp(action, "OFF")) { object_unref(mun); wallops("%s unrestricted the name \2%s\2.", get_oper_name(si), target); logcommand(si, CMDLOG_ADMIN, "RESTRICT:OFF: \2%s\2", target); command_success_nodata(si, _("\2%s\2 is now unrestricted."), target); return; } command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), target); return; } if (!strcasecmp(action, "ON")) { if (!info) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "RESTRICT"); command_fail(si, fault_needmoreparams, _("Usage: RESTRICT <target> ON <note>")); return; } if (metadata_find(mu, "private:restrict:setter")) { command_fail(si, fault_badparams, _("\2%s\2 is already restricted."), entity(mu)->name); return; } metadata_add(mu, "private:restrict:setter", get_oper_name(si)); metadata_add(mu, "private:restrict:reason", info); metadata_add(mu, "private:restrict:timestamp", number_to_string(time(NULL))); wallops("%s restricted the account \2%s\2.", get_oper_name(si), entity(mu)->name); logcommand(si, CMDLOG_ADMIN, "RESTRICT:ON: \2%s\2 (reason: \2%s\2)", entity(mu)->name, info); command_success_nodata(si, _("\2%s\2 is now restricted."), entity(mu)->name); } else if (!strcasecmp(action, "OFF")) { if (!metadata_find(mu, "private:restrict:setter")) { command_fail(si, fault_badparams, _("\2%s\2 is not restricted."), entity(mu)->name); return; } metadata_delete(mu, "private:restrict:setter"); metadata_delete(mu, "private:restrict:reason"); metadata_delete(mu, "private:restrict:timestamp"); wallops("%s unrestricted the account \2%s\2.", get_oper_name(si), entity(mu)->name); logcommand(si, CMDLOG_ADMIN, "RESTRICT:OFF: \2%s\2", entity(mu)->name); command_success_nodata(si, _("\2%s\2 is now unrestricted."), entity(mu)->name); } else { command_fail(si, fault_needmoreparams, STR_INVALID_PARAMS, "RESTRICT"); command_fail(si, fault_needmoreparams, _("Usage: RESTRICT <target> <ON|OFF> [note]")); } }
static void gs_cmd_invite(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; myuser_t *mu; groupacs_t *ga; char *group = parv[0]; char *user = parv[1]; char buf[BUFSIZE], description[256]; service_t *svs; if (!group || !user) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "INVITE"); command_fail(si, fault_needmoreparams, _("Syntax: INVITE <!group> <user>")); return; } if ((mg = mygroup_find(group)) == NULL) { command_fail(si, fault_nosuch_target, _("The group \2%s\2 does not exist."), group); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_INVITE)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); return; } if ((mu = myuser_find_ext(user)) == NULL) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not a registered account."), user); return; } if ((ga = groupacs_find(mg, entity(mu), 0, false)) != NULL) { command_fail(si, fault_badparams, _("\2%s\2 is already a member of: \2%s\2"), entity(mu)->name, entity(mg)->name); return; } if (metadata_find(mu, "private:groupinvite")) { command_fail(si, fault_badparams, _("\2%s\2 may not be invited to a group and already has another invitation pending."), entity(mu)->name); return; } if (MU_NEVERGROUP & mu->flags) { command_fail(si, fault_noprivs, _("\2%s\2 does not wish to belong to any groups."), entity(mu)->name); return; } metadata_add(mu, "private:groupinvite", entity(mg)->name); if ((svs = service_find("memoserv")) != NULL) { snprintf(buf, BUFSIZE, "%s [auto memo] You have been invited to the group: %s", entity(mu)->name, entity(mg)->name); command_exec_split(svs, si, "SEND", buf, svs->commands); } else { myuser_notice(si->service->nick, mu, "You have been invited to the group: %s", entity(mg)->name); } logcommand(si, CMDLOG_SET, "INVITE: \2%s\2 \2%s\2", entity(mg)->name, entity(mu)->name); command_success_nodata(si, _("\2%s\2 has been invited to \2%s\2"), entity(mu)->name, entity(mg)->name); snprintf(description, sizeof description, "Invited \2%s\2 to join.", entity(mu)->name); notify_group_misc_change(si, mg, description); }
static void ms_cmd_fsend(sourceinfo_t *si, int parc, char *parv[]) { /* misc structs etc */ user_t *tu; myuser_t *tmu; mowgli_node_t *n; mymemo_t *memo; service_t *memoserv; /* Grab args */ char *target = parv[0]; char *m = parv[1]; /* Arg validation */ if (!target || !m) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FSEND"); command_fail(si, fault_needmoreparams, "Syntax: FSEND <user> <memo>"); return; } if (!si->smu) { command_fail(si, fault_noprivs, _("You are not logged in.")); return; } /* rate limit it -- jilles */ if (CURRTIME - si->smu->memo_ratelimit_time > MEMO_MAX_TIME) si->smu->memo_ratelimit_num = 0; if (si->smu->memo_ratelimit_num > MEMO_MAX_NUM && !has_priv(si, PRIV_FLOOD)) { command_fail(si, fault_toomany, _("You have used this command too many times; please wait a while and try again.")); return; } /* Check for memo text length -- includes/common.h */ if (strlen(m) >= MEMOLEN) { command_fail(si, fault_badparams, "Please make sure your memo is less than %d characters", MEMOLEN); return; } /* Check to make sure the memo doesn't contain hostile CTCP responses. * realistically, we'll probably want to check the _entire_ message for this... --nenolod */ if (*m == '\001') { command_fail(si, fault_badparams, _("Your memo contains invalid characters.")); return; } memoserv = service_find("memoserv"); if (memoserv == NULL) memoserv = si->service; if (*target != '#' && *target != '!') { /* See if target is valid */ if (!(tmu = myuser_find_ext(target))) { command_fail(si, fault_nosuch_target, "\2%s\2 is not registered.", target); return; } si->smu->memo_ratelimit_num++; si->smu->memo_ratelimit_time = CURRTIME; /* Check to make sure target inbox not full */ if (tmu->memos.count >= me.mdlimit) { command_fail(si, fault_toomany, _("%s's inbox is full"), target); logcommand(si, CMDLOG_SET, "failed SEND to \2%s\2 (target inbox full)", entity(tmu)->name); return; } logcommand(si, CMDLOG_ADMIN, "FSEND: to \2%s\2", entity(tmu)->name); /* Malloc and populate struct */ memo = smalloc(sizeof(mymemo_t)); memo->sent = CURRTIME; memo->status = 0; mowgli_strlcpy(memo->sender,entity(si->smu)->name,NICKLEN); mowgli_strlcpy(memo->text, "[FORCE] ", FMEMOLEN); mowgli_strlcat(memo->text, m, FMEMOLEN); /* Create a linked list node and add to memos */ n = mowgli_node_create(); mowgli_node_add(memo, n, &tmu->memos); tmu->memoct_new++; /* Should we email this? */ if (tmu->flags & MU_EMAILMEMOS) { compat_sendemail(si->su, tmu, EMAIL_MEMO, tmu->email, memo->text); } /* Note: do not disclose other nicks they're logged in with * -- jilles * * Actually, I don't see the point in this at all. If they want this information, * they should use WHOIS. --nenolod */ tu = user_find_named(target); if (tu != NULL && tu->myuser == tmu) command_success_nodata(si, _("%s is currently online, and you may talk directly, by sending a private message."), target); /* Is the user online? If so, tell them about the new memo. */ if (si->su == NULL || !irccasecmp(si->su->nick, entity(si->smu)->name)) myuser_notice(memoserv->nick, tmu, "You have a new memo from %s (%zu).", entity(si->smu)->name, MOWGLI_LIST_LENGTH(&tmu->memos)); else myuser_notice(memoserv->nick, tmu, "You have a new memo from %s (nick: %s) (%zu).", entity(si->smu)->name, si->su->nick, MOWGLI_LIST_LENGTH(&tmu->memos)); myuser_notice(memoserv->nick, tmu, _("To read it, type /%s%s READ %zu"), ircd->uses_rcommand ? "" : "msg ", memoserv->disp, MOWGLI_LIST_LENGTH(&tmu->memos)); /* Tell user memo sent */ command_success_nodata(si, _("The memo has been successfully sent to \2%s\2."), target); } else if (*target == '#') { command_fail(si, fault_nosuch_target, _("Channel memos may not be forced.")); } else { command_fail(si, fault_nosuch_target, _("Group memos may not be forced.")); } return; }