]> jfr.im git - irc/quakenet/newserv.git/blame - newsearch/ns-notice.c
merge
[irc/quakenet/newserv.git] / newsearch / ns-notice.c
CommitLineData
16319f7c
IB
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
17extern nick *senderNSExtern;
18
c8be5183
CP
19void *notice_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
20void notice_free(searchCtx *ctx, struct searchNode *thenode);
16319f7c
IB
21
22struct notice_localdata {
23 unsigned int marker;
24 int count;
16319f7c
IB
25 char message[NSMAX_NOTICE_LEN];
26};
27
f33f3f52 28struct searchNode *notice_parse(searchCtx *ctx, int argc, char **argv) {
16319f7c
IB
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;
a92bb8e1 38 if (ctx->searchcmd == reg_chansearch)
16319f7c 39 localdata->marker = nextchanmarker();
a92bb8e1 40 else if (ctx->searchcmd == reg_nicksearch)
16319f7c 41 localdata->marker = nextnickmarker();
a92bb8e1
P
42 else {
43 parseError = "notice: invalid search type";
44 return NULL;
45 }
16319f7c
IB
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
c8be5183 79void *notice_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
16319f7c
IB
80 struct notice_localdata *localdata;
81 nick *np;
82 chanindex *cip;
83
84 localdata = thenode->localdata;
85
a92bb8e1 86 if (ctx->searchcmd == reg_chansearch) {
16319f7c
IB
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
c8be5183 100void notice_free(searchCtx *ctx, struct searchNode *thenode) {
16319f7c
IB
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
a92bb8e1 109 if (ctx->searchcmd == reg_chansearch) {
16319f7c
IB
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 */
0da2a4ae 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);
16319f7c
IB
144 free(localdata);
145 free(thenode);
146}