/* * Copyright (c) 2005 Atheme Development Group * Rights to this code are as documented in doc/LICENSE. * * This file contains code for the Memoserv FORWARD function * */ #include "atheme.h" DECLARE_MODULE_V1 ( "memoserv/forward", false, _modinit, _moddeinit, PACKAGE_STRING, VENDOR_STRING ); static void ms_cmd_forward(sourceinfo_t *si, int parc, char *parv[]); command_t ms_forward = { "FORWARD", N_(N_("Forwards a memo.")), AC_AUTHENTICATED, 2, ms_cmd_forward, { .path = "memoserv/forward" } }; void _modinit(module_t *m) { service_named_bind_command("memoserv", &ms_forward); } void _moddeinit(module_unload_intent_t intent) { service_named_unbind_command("memoserv", &ms_forward); } static void ms_cmd_forward(sourceinfo_t *si, int parc, char *parv[]) { /* Misc structs etc */ user_t *tu; myuser_t *tmu; mymemo_t *memo, *newmemo; mowgli_node_t *n, *temp; unsigned int i = 1, memonum = 0; /* Grab args */ char *target = parv[0]; char *arg = parv[1]; /* Arg validator */ if (!target || !arg) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FORWARD"); command_fail(si, fault_needmoreparams, "Syntax: FORWARD "); return; } else memonum = atoi(arg); if (si->smu->flags & MU_WAITAUTH) { command_fail(si, fault_notverified, _("You need to verify your email address before you may send memos.")); return; } /* Check to see if any memos */ if (!si->smu->memos.count) { command_fail(si, fault_nosuch_key, _("You have no memos to forward.")); return; } /* Check to see if target user exists */ if (!(tmu = myuser_find_ext(target))) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), target); return; } /* Make sure target isn't sender */ if (si->smu == tmu) { command_fail(si, fault_noprivs, _("You cannot send yourself a memo.")); return; } /* Make sure arg is an int */ if (!memonum) { command_fail(si, fault_badparams, _("Invalid message index.")); return; } /* check if targetuser has nomemo set */ if (tmu->flags & MU_NOMEMO) { command_fail(si, fault_noprivs, "\2%s\2 does not wish to receive memos.", target); return; } /* Check to see if memo n exists */ if (memonum > si->smu->memos.count) { command_fail(si, fault_nosuch_key, _("Invalid memo number.")); return; } /* Check to make sure target inbox not full */ if (tmu->memos.count >= me.mdlimit) { command_fail(si, fault_toomany, _("Target inbox is full.")); logcommand(si, CMDLOG_SET, "failed FORWARD to \2%s\2 (target inbox full)", entity(tmu)->name); 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, _("Too many memos; please wait a while and try again")); return; } si->smu->memo_ratelimit_num++; si->smu->memo_ratelimit_time = CURRTIME; /* Make sure we're not on ignore */ MOWGLI_ITER_FOREACH(n, tmu->memo_ignores.head) { mynick_t *mn; myuser_t *mu; if (nicksvs.no_nick_ownership) mu = myuser_find((const char *)n->data); else { mn = mynick_find((const char *)n->data); mu = mn != NULL ? mn->owner : NULL; } if (mu == si->smu) { /* Lie... change this if you want it to fail silent */ logcommand(si, CMDLOG_SET, "failed FORWARD to \2%s\2 (on ignore list)", entity(tmu)->name); command_success_nodata(si, _("The memo has been successfully forwarded to \2%s\2."), target); return; } } logcommand(si, CMDLOG_SET, "FORWARD: to \2%s\2", entity(tmu)->name); /* Go to forwarding memos */ MOWGLI_ITER_FOREACH(n, si->smu->memos.head) { if (i == memonum) { /* should have some function for send here... ask nenolod*/ memo = (mymemo_t *)n->data; newmemo = smalloc(sizeof(mymemo_t)); /* Create memo */ newmemo->sent = CURRTIME; newmemo->status = 0; mowgli_strlcpy(newmemo->sender,entity(si->smu)->name,NICKLEN); mowgli_strlcpy(newmemo->text,memo->text,MEMOLEN); /* Create node, add to their linked list of memos */ temp = mowgli_node_create(); mowgli_node_add(newmemo, temp, &tmu->memos); tmu->memoct_new++; /* Should we email this? */ if (tmu->flags & MU_EMAILMEMOS) { sendemail(si->su, tmu, EMAIL_MEMO, tmu->email, memo->text); } } i++; } /* Note: do not disclose other nicks they're logged in with * -- jilles */ 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); } if (si->su == NULL || !irccasecmp(si->su->nick, entity(si->smu)->name)) myuser_notice(si->service->nick, tmu, "You have a new forwarded memo from %s (%zu).", entity(si->smu)->name, MOWGLI_LIST_LENGTH(&tmu->memos)); else myuser_notice(si->service->nick, tmu, "You have a new forwarded memo from %s (nick: %s) (%zu).", entity(si->smu)->name, si->su->nick, MOWGLI_LIST_LENGTH(&tmu->memos)); myuser_notice(si->service->nick, tmu, _("To read it, type /%s%s READ %zu"), ircd->uses_rcommand ? "" : "msg ", si->service->disp, MOWGLI_LIST_LENGTH(&tmu->memos)); command_success_nodata(si, _("The memo has been successfully forwarded to \2%s\2."), target); return; } /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs * vim:ts=8 * vim:sw=8 * vim:noexpandtab */