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