]> jfr.im git - irc/quakenet/newserv.git/blob - newsearch/ns-notice.c
LUA: port luadb to dbapi2 to drop postgres dependency
[irc/quakenet/newserv.git] / newsearch / ns-notice.c
1 /*
2 * NOTICE functionality
3 * ---------
4 * Use of markers allows us to use notice in both channel and nick searches so we can have newserv notice everyone on a channel and/or
5 * everyone matching a certain nick_search pattern.
6 */
7
8 #include "newsearch.h"
9
10 #include <stdio.h>
11 #include <stdlib.h>
12
13 #include "../control/control.h" /* controlreply() */
14 #include "../lib/irc_string.h" /* IPtostr() */
15 #include "../lib/strlfunc.h"
16
17 extern nick *senderNSExtern;
18
19 void *notice_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
20 void notice_free(searchCtx *ctx, struct searchNode *thenode);
21
22 struct notice_localdata {
23 unsigned int marker;
24 int count;
25 char message[NSMAX_NOTICE_LEN];
26 };
27
28 struct searchNode *notice_parse(searchCtx *ctx, int argc, char **argv) {
29 struct notice_localdata *localdata;
30 struct searchNode *thenode, *message;
31 char *p;
32
33 if (!(localdata = (struct notice_localdata *) malloc(sizeof(struct notice_localdata)))) {
34 parseError = "malloc: could not allocate memory for this search.";
35 return NULL;
36 }
37 localdata->count = 0;
38 if (ctx->searchcmd == reg_chansearch)
39 localdata->marker = nextchanmarker();
40 else if (ctx->searchcmd == reg_nicksearch)
41 localdata->marker = nextnickmarker();
42 else {
43 free(localdata);
44 parseError = "notice: invalid search type";
45 return NULL;
46 }
47 if (argc!=1) {
48 parseError = "notice: warning: you did not specify a message to notice out.";
49 free(localdata);
50 return NULL;
51 }
52
53 if (!(message=argtoconststr("notice", ctx, argv[0], &p))) {
54 free(localdata);
55 return NULL;
56 }
57
58 strlcpy(localdata->message, p, sizeof(localdata->message));
59 (message->free)(ctx, message);
60
61 if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
62 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
63 parseError = "malloc: could not allocate memory for this search.";
64 free(localdata);
65 return NULL;
66 }
67
68 thenode->returntype = RETURNTYPE_BOOL;
69 thenode->localdata = localdata;
70 thenode->exe = notice_exe;
71 thenode->free = notice_free;
72
73 return thenode;
74 }
75
76 void *notice_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
77 struct notice_localdata *localdata;
78 nick *np;
79 chanindex *cip;
80
81 localdata = thenode->localdata;
82
83 if (ctx->searchcmd == reg_chansearch) {
84 cip = (chanindex *)theinput;
85 cip->marker = localdata->marker;
86 localdata->count += cip->channel->users->totalusers;
87 }
88 else {
89 np = (nick *)theinput;
90 np->marker = localdata->marker;
91 localdata->count++;
92 }
93
94 return (void *)1;
95 }
96
97 void notice_free(searchCtx *ctx, struct searchNode *thenode) {
98 struct notice_localdata *localdata;
99 nick *np, *nnp;
100 chanindex *cip, *ncip;
101 int i, j;
102 unsigned int nickmarker;
103
104 localdata = thenode->localdata;
105
106 if (ctx->searchcmd == reg_chansearch) {
107 nickmarker=nextnickmarker();
108 for (i=0;i<CHANNELHASHSIZE;i++) {
109 for (cip=chantable[i];cip;cip=ncip) {
110 ncip = cip->next;
111 if (cip != NULL && cip->channel != NULL && cip->marker == localdata->marker) {
112 for (j=0;j<cip->channel->users->hashsize;j++) {
113 if (cip->channel->users->content[j]==nouser)
114 continue;
115
116 if ((np=getnickbynumeric(cip->channel->users->content[j])))
117 np->marker=nickmarker;
118 }
119 }
120 }
121 }
122 for (i=0;i<NICKHASHSIZE;i++) {
123 for(np=nicktable[i];np;np=nnp) {
124 nnp = np->next;
125 if (np->marker == nickmarker)
126 controlnotice(np, "%s", localdata->message);
127 }
128 }
129 }
130 else {
131 for (i=0;i<NICKHASHSIZE;i++) {
132 for (np=nicktable[i];np;np=nnp) {
133 nnp = np->next;
134 if (np->marker == localdata->marker)
135 controlnotice(np, "%s", localdata->message);
136 }
137 }
138 }
139 /* notify opers of the action */
140 ctx->wall(NL_BROADCASTS, "%s/%s sent the following message to %d %s: %s", senderNSExtern->nick, senderNSExtern->authname, localdata->count, localdata->count != 1 ? "users" : "user", localdata->message);
141 free(localdata);
142 free(thenode);
143 }