Anope IRC Services  Version 1.8
ms_read.c
Go to the documentation of this file.
1 /* MemoServ core functions
2  *
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  * Based on the original code of Epona by Lara.
9  * Based on the original code of Services by Andy Church.
10  *
11  *
12  */
13 /*************************************************************************/
14 
15 #include "module.h"
16 
17 static int do_read(User * u);
18 static int read_memo_callback(User * u, int num, va_list args);
19 static int read_memo(User * u, int index, MemoInfo * mi, const char *chan);
20 static void myMemoServHelp(User * u);
21 extern void rsend_notify(User * u, Memo * m, const char *chan);
22 
23 
30 int AnopeInit(int argc, char **argv)
31 {
32  Command *c;
33 
34  moduleAddAuthor("Anope");
35  moduleAddVersion(VERSION_STRING);
37  c = createCommand("READ", do_read, NULL, MEMO_HELP_READ, -1, -1, -1,
38  -1);
41 
42  return MOD_CONT;
43 }
44 
48 void AnopeFini(void)
49 {
50 
51 }
52 
53 
54 
59 static void myMemoServHelp(User * u)
60 {
61  notice_lang(s_MemoServ, u, MEMO_HELP_CMD_READ);
62 }
63 
69 static int do_read(User * u)
70 {
71  MemoInfo *mi;
72  ChannelInfo *ci;
73  char *numstr = strtok(NULL, " "), *chan = NULL;
74  int num, count;
75 
76  if (numstr && *numstr == '#') {
77  chan = numstr;
78  numstr = strtok(NULL, " ");
79  if (!(ci = cs_findchan(chan))) {
80  notice_lang(s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan);
81  return MOD_CONT;
82  } else if (ci->flags & CI_VERBOTEN) {
83  notice_lang(s_MemoServ, u, CHAN_X_FORBIDDEN, chan);
84  return MOD_CONT;
85  } else if (!check_access(u, ci, CA_MEMO)) {
86  notice_lang(s_MemoServ, u, ACCESS_DENIED);
87  return MOD_CONT;
88  }
89  mi = &ci->memos;
90  } else {
91  if (!nick_identified(u)) {
92  notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ);
93  return MOD_CONT;
94  }
95  mi = &u->na->nc->memos;
96  }
97  num = numstr ? atoi(numstr) : -1;
98  if (!numstr
99  || (stricmp(numstr, "LAST") != 0 && stricmp(numstr, "NEW") != 0
100  && num <= 0)) {
101  syntax_error(s_MemoServ, u, "READ", MEMO_READ_SYNTAX);
102 
103  } else if (mi->memocount == 0) {
104  if (chan)
105  notice_lang(s_MemoServ, u, MEMO_X_HAS_NO_MEMOS, chan);
106  else
107  notice_lang(s_MemoServ, u, MEMO_HAVE_NO_MEMOS);
108 
109  } else {
110  int i;
111 
112  if (stricmp(numstr, "NEW") == 0) {
113  int readcount = 0;
114  for (i = 0; i < mi->memocount; i++) {
115  if (mi->memos[i].flags & MF_UNREAD) {
116  read_memo(u, i, mi, chan);
117  readcount++;
118  }
119  }
120  if (!readcount) {
121  if (chan)
122  notice_lang(s_MemoServ, u, MEMO_X_HAS_NO_NEW_MEMOS,
123  chan);
124  else
125  notice_lang(s_MemoServ, u, MEMO_HAVE_NO_NEW_MEMOS);
126  }
127  } else if (stricmp(numstr, "LAST") == 0) {
128  for (i = 0; i < mi->memocount - 1; i++);
129  read_memo(u, i, mi, chan);
130  } else { /* number[s] */
131  if (!process_numlist(numstr, &count, read_memo_callback, u,
132  mi, chan)) {
133  if (count == 1)
134  notice_lang(s_MemoServ, u, MEMO_DOES_NOT_EXIST, num);
135  else
136  notice_lang(s_MemoServ, u, MEMO_LIST_NOT_FOUND,
137  numstr);
138  }
139  }
140 
141  }
142  return MOD_CONT;
143 }
144 
152 static int read_memo_callback(User * u, int num, va_list args)
153 {
154  MemoInfo *mi = va_arg(args, MemoInfo *);
155  const char *chan = va_arg(args, const char *);
156  int i;
157 
158  for (i = 0; i < mi->memocount; i++) {
159  if (mi->memos[i].number == num)
160  break;
161  }
162  /* Range check done in read_memo */
163  return read_memo(u, i, mi, chan);
164 }
165 
174 static int read_memo(User * u, int index, MemoInfo * mi, const char *chan)
175 {
176  Memo *m;
177  char timebuf[64];
178  struct tm tm;
179 
180  if (index < 0 || index >= mi->memocount)
181  return 0;
182  m = &mi->memos[index];
183  tm = *localtime(&m->time);
184  strftime_lang(timebuf, sizeof(timebuf),
185  u, STRFTIME_DATE_TIME_FORMAT, &tm);
186  timebuf[sizeof(timebuf) - 1] = 0;
187  if (chan)
188  notice_lang(s_MemoServ, u, MEMO_CHAN_HEADER, m->number,
189  m->sender, timebuf, s_MemoServ, chan, m->number);
190  else
191  notice_lang(s_MemoServ, u, MEMO_HEADER, m->number,
192  m->sender, timebuf, s_MemoServ, m->number);
193  notice_lang(s_MemoServ, u, MEMO_TEXT, m->text);
194  m->flags &= ~MF_UNREAD;
195 
196  /* Check if a receipt notification was requested */
197  if (m->flags & MF_RECEIPT) {
198  rsend_notify(u, m, chan);
199  }
200 
201  return 1;
202 }
E int process_numlist(const char *numstr, int *count_ret, range_callback_t callback, User *u,...)
Definition: misc.c:292
void AnopeFini(void)
Definition: ms_read.c:48
char sender[NICKMAX]
Definition: services.h:494
int AnopeInit(int argc, char **argv)
Definition: ms_read.c:30
E int nick_identified(User *u)
Definition: nickserv.c:1111
E int check_access(User *user, ChannelInfo *ci, int what)
Definition: chanserv.c:1974
E int stricmp(const char *s1, const char *s2)
Definition: compat.c:58
#define CI_VERBOTEN
Definition: services.h:725
MemoInfo memos
Definition: services.h:552
int16 memocount
Definition: services.h:505
MDE void moduleAddAuthor(const char *author)
Definition: modules.c:1772
E void syntax_error(char *service, User *u, const char *command, int msgnum)
Definition: language.c:295
E void notice_lang(char *source, User *dest, int message,...)
Definition: send.c:169
MDE void moduleSetType(MODType type)
Definition: modules.c:818
NickCore * nc
Definition: services.h:533
void rsend_notify(User *u, Memo *m, const char *chan)
Definition: memoserv.c:419
uint16 flags
Definition: services.h:492
MDE void moduleSetMemoHelp(void(*func)(User *u))
Definition: modules.c:2102
E char * s_MemoServ
Definition: extern.h:286
uint32 flags
Definition: services.h:669
char * text
Definition: services.h:495
MDE void moduleAddVersion(const char *version)
Definition: modules.c:1760
static int read_memo_callback(User *u, int num, va_list args)
Definition: ms_read.c:152
Command * c
Definition: ns_recover.c:17
uint32 number
Definition: services.h:491
#define MOD_CONT
Definition: modules.h:54
static int read_memo(User *u, int index, MemoInfo *mi, const char *chan)
Definition: ms_read.c:174
#define MF_RECEIPT
Definition: services.h:1269
#define MEMOSERV
Definition: modules.h:58
Definition: modules.h:99
MDE Command * createCommand(const char *name, int(*func)(User *u), int(*has_priv)(User *u), int help_all, int help_reg, int help_oper, int help_admin, int help_root)
Definition: modules.c:987
#define CA_MEMO
Definition: services.h:761
MemoInfo memos
Definition: services.h:690
E ChannelInfo * cs_findchan(const char *chan)
Definition: db-merger.c:2000
time_t time
Definition: services.h:493
static void myMemoServHelp(User *u)
Definition: ms_read.c:59
Memo * memos
Definition: services.h:506
E int strftime_lang(char *buf, int size, User *u, int format, struct tm *tm)
Definition: language.c:240
E char * s_NickServ
Definition: extern.h:284
MDE int moduleAddCommand(CommandHash *cmdTable[], Command *c, int pos)
Definition: modules.c:1082
#define MF_UNREAD
Definition: services.h:1268
NickAlias * na
Definition: services.h:892
#define MOD_UNIQUE
Definition: module.h:11
static int do_read(User *u)
Definition: ms_read.c:69