]> jfr.im git - irc/quakenet/newserv.git/blob - newsearch/ns-notice.c
newsearch changes to support addition of trust_search/patriciasearch
[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;
31 int len;
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 parseError = "notice: invalid search type";
44 return NULL;
45 }
46 if (argc==1) {
47 char *p = argv[0];
48 if(*p == '\"')
49 p++;
50 len = strlcpy(localdata->message, p, sizeof(localdata->message));
51 if(len >= sizeof(localdata->message)) {
52 localdata->message[sizeof(localdata->message)-1] = '\0';
53 } else {
54 localdata->message[len-1] = '\0';
55 }
56 }
57 else {
58 /* no notice to send out ... */
59 parseError = "Warning: you did not specify a message to notice out.";
60 free(localdata);
61 return NULL;
62 }
63
64 if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
65 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
66 parseError = "malloc: could not allocate memory for this search.";
67 free(localdata);
68 return NULL;
69 }
70
71 thenode->returntype = RETURNTYPE_BOOL;
72 thenode->localdata = localdata;
73 thenode->exe = notice_exe;
74 thenode->free = notice_free;
75
76 return thenode;
77 }
78
79 void *notice_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
80 struct notice_localdata *localdata;
81 nick *np;
82 chanindex *cip;
83
84 localdata = thenode->localdata;
85
86 if (ctx->searchcmd == reg_chansearch) {
87 cip = (chanindex *)theinput;
88 cip->marker = localdata->marker;
89 localdata->count += cip->channel->users->totalusers;
90 }
91 else {
92 np = (nick *)theinput;
93 np->marker = localdata->marker;
94 localdata->count++;
95 }
96
97 return (void *)1;
98 }
99
100 void notice_free(searchCtx *ctx, struct searchNode *thenode) {
101 struct notice_localdata *localdata;
102 nick *np, *nnp;
103 chanindex *cip, *ncip;
104 int i, j;
105 unsigned int nickmarker;
106
107 localdata = thenode->localdata;
108
109 if (ctx->searchcmd == reg_chansearch) {
110 nickmarker=nextnickmarker();
111 for (i=0;i<CHANNELHASHSIZE;i++) {
112 for (cip=chantable[i];cip;cip=ncip) {
113 ncip = cip->next;
114 if (cip != NULL && cip->channel != NULL && cip->marker == localdata->marker) {
115 for (j=0;j<cip->channel->users->hashsize;j++) {
116 if (cip->channel->users->content[j]==nouser)
117 continue;
118
119 if ((np=getnickbynumeric(cip->channel->users->content[j])))
120 np->marker=nickmarker;
121 }
122 }
123 }
124 }
125 for (i=0;i<NICKHASHSIZE;i++) {
126 for(np=nicktable[i];np;np=nnp) {
127 nnp = np->next;
128 if (np->marker == nickmarker)
129 controlnotice(np, localdata->message);
130 }
131 }
132 }
133 else {
134 for (i=0;i<NICKHASHSIZE;i++) {
135 for (np=nicktable[i];np;np=nnp) {
136 nnp = np->next;
137 if (np->marker == localdata->marker)
138 controlnotice(np, localdata->message);
139 }
140 }
141 }
142 /* notify opers of the action */
143 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);
144 free(localdata);
145 free(thenode);
146 }