File: read.c

package info (click to toggle)
atheme-services 7.2.12-2.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 17,256 kB
  • sloc: ansic: 95,899; sh: 8,462; php: 5,032; perl: 3,327; makefile: 1,279; sed: 16; ruby: 15; python: 3
file content (151 lines) | stat: -rw-r--r-- 3,929 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * Copyright (c) 2005-2007 Atheme Development Group
 * Rights to this code are as documented in doc/LICENSE.
 *
 * This file contains code for the Memoserv READ function
 *
 */

#include "atheme.h"

DECLARE_MODULE_V1
(
	"memoserv/read", false, _modinit, _moddeinit,
	PACKAGE_STRING,
	VENDOR_STRING
);

#define MAX_READ_AT_ONCE 5

static void ms_cmd_read(sourceinfo_t *si, int parc, char *parv[]);

command_t ms_read = { "READ", N_("Reads a memo."),
                        AC_AUTHENTICATED, 2, ms_cmd_read, { .path = "memoserv/read" } };

void _modinit(module_t *m)
{
        service_named_bind_command("memoserv", &ms_read);
}

void _moddeinit(module_unload_intent_t intent)
{
	service_named_unbind_command("memoserv", &ms_read);
}

static void ms_cmd_read(sourceinfo_t *si, int parc, char *parv[])
{
	/* Misc structs etc */
	myuser_t *tmu;
	mymemo_t *memo, *receipt;
	mowgli_node_t *n;
	unsigned int i = 1, memonum = 0, numread = 0;
	char strfbuf[BUFSIZE];
	struct tm tm;
	bool readnew;

	/* Grab arg */
	char *arg1 = parv[0];

	if (!arg1)
	{
		command_fail(si, fault_needmoreparams,
			STR_INSUFFICIENT_PARAMS, "READ");

		command_fail(si, fault_needmoreparams, _("Syntax: READ <memo number>"));
		return;
	}

	/* Check to see if any memos */
	if (!si->smu->memos.count)
	{
		command_fail(si, fault_nosuch_key, _("You have no memos."));
		return;
	}

	memonum = atoi(arg1);
	readnew = !strcasecmp(arg1, "NEW");
	if (!readnew && !memonum)
	{
		command_fail(si, fault_badparams, _("Invalid message index."));
		return;
	}

	/* Check to see if memonum is greater than memocount */
	if (memonum > si->smu->memos.count)
	{
		command_fail(si, fault_nosuch_key, _("Invalid message index."));
		return;
	}

	/* Go to reading memos */
	MOWGLI_ITER_FOREACH(n, si->smu->memos.head)
	{
		memo = (mymemo_t *)n->data;
		if (i == memonum || (readnew && !(memo->status & MEMO_READ)))
		{
			tm = *localtime(&memo->sent);
			strftime(strfbuf, sizeof strfbuf,
				TIME_FORMAT, &tm);

			if (!(memo->status & MEMO_READ))
			{
				memo->status |= MEMO_READ;
				si->smu->memoct_new--;
				tmu = myuser_find(memo->sender);

				/* If the sender is logged in, tell them the memo's been read */
				/* but not for channel memos */
				if (memo->status & MEMO_CHANNEL)
					;
				else if (strcasecmp(si->service->nick, memo->sender) && (tmu != NULL) && (tmu->logins.count > 0))
					myuser_notice(si->service->me->nick, tmu, "%s has read your memo, which was sent at %s", entity(si->smu)->name, strfbuf);
				else
				{
					/* If they have an account, their inbox is not full and they aren't memoserv */
					if ( (tmu != NULL) && (tmu->memos.count < me.mdlimit) && strcasecmp(si->service->nick, memo->sender))
					{
						/* Malloc and populate memo struct */
						receipt = smalloc(sizeof(mymemo_t));
						receipt->sent = CURRTIME;
						receipt->status = 0;
						mowgli_strlcpy(receipt->sender, si->service->nick, NICKLEN);
						snprintf(receipt->text, MEMOLEN, "%s has read a memo from you sent at %s", entity(si->smu)->name, strfbuf);

						/* Attach to their linked list */
						n = mowgli_node_create();
						mowgli_node_add(receipt, n, &tmu->memos);
						tmu->memoct_new++;
					}
				}
			}

			command_success_nodata(si,
				"\2Memo %d - Sent by %s, %s\2",i,memo->sender, strfbuf);

			command_success_nodata(si,
				"------------------------------------------");

			command_success_nodata(si, "%s", memo->text);

			if (!readnew)
				return;
			if (++numread >= MAX_READ_AT_ONCE && si->smu->memoct_new > 0)
			{
				command_success_nodata(si, _("Stopping command after %d memos."), numread);
				return;
			}
		}
		i++;
	}

	if (readnew && numread == 0)
		command_fail(si, fault_nosuch_key, _("You have no new memos."));
	else if (readnew)
		command_success_nodata(si, _("Read %d memos."), numread);
}

/* 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
 */