]> jfr.im git - irc/quakenet/newserv.git/blob - newsearch/ns-cumodes.c
LUA: port luadb to dbapi2 to drop postgres dependency
[irc/quakenet/newserv.git] / newsearch / ns-cumodes.c
1 /*
2 * CUMODES functionality
3 */
4
5 #include "newsearch.h"
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 struct cumodes_localdata {
11 long setmodes;
12 long clearmodes;
13 struct searchNode *xnode;
14 };
15
16 #define CU_OP 0x01
17 #define CU_VOICE 0x02
18 #define CU_ALL 0x03
19
20 const flag cumodelist[] = {
21 { 'o', 1 },
22 { 'v', 2 },
23 { '\0', 0 }
24 };
25
26 void *cumodes_nick_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
27 void *cumodes_chan_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
28 void cumodes_free(searchCtx *ctx, struct searchNode *thenode);
29
30 struct searchNode *cumodes_parse(searchCtx *ctx, int argc, char **argv) {
31 struct cumodes_localdata *localdata;
32 struct searchNode *thenode, *flagstr;
33 flag_t fset, fclear;
34 char *p;
35
36 if (argc!=2) {
37 parseError="cumodes: usage: cumodes (string) (mode string)";
38 return NULL;
39 }
40
41 if (!(ctx->searchcmd == reg_nicksearch) && !(ctx->searchcmd == reg_chansearch)) {
42 parseError="cumodes: cannot be used outside of nicksearch or chansearch";
43 return NULL;
44 }
45
46 if (!(localdata=(struct cumodes_localdata *)malloc(sizeof(struct cumodes_localdata)))) {
47 parseError = "malloc: could not allocate memory for this search.";
48 return NULL;
49 }
50
51 localdata->xnode = ctx->parser(ctx, argv[0]);
52 if (!(localdata->xnode = coerceNode(ctx, localdata->xnode, RETURNTYPE_STRING))) {
53 free(localdata);
54 return NULL;
55 }
56
57 fset=0;
58 fclear=~0;
59
60 if (!(flagstr=argtoconststr("cumodes", ctx, argv[1], &p))) {
61 localdata->xnode->free(ctx, localdata->xnode);
62 free(localdata);
63 return NULL;
64 }
65 setflags(&(fset), CU_ALL, p, cumodelist, REJECT_NONE);
66 setflags(&(fclear), CU_ALL, p, cumodelist, REJECT_NONE);
67 flagstr->free(ctx, flagstr);
68
69 localdata->setmodes=0;
70 localdata->clearmodes=~0;
71
72 if(fset & CU_OP)
73 localdata->setmodes|=CUMODE_OP;
74 if(fset & CU_VOICE)
75 localdata->setmodes|=CUMODE_VOICE;
76 if(!(fclear & CU_OP))
77 localdata->clearmodes&=~CUMODE_OP;
78 if(!(fclear & CU_VOICE))
79 localdata->clearmodes&=~CUMODE_VOICE;
80
81 localdata->clearmodes = ~(localdata->clearmodes);
82
83 if (!(thenode=(struct searchNode *)malloc(sizeof(struct searchNode)))) {
84 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
85 parseError = "malloc: could not allocate memory for this search.";
86 (localdata->xnode->free)(ctx, localdata->xnode);
87 free(localdata);
88 return NULL;
89 }
90
91 thenode->returntype = RETURNTYPE_BOOL;
92 thenode->localdata = (void *)localdata;
93
94 if (ctx->searchcmd == reg_nicksearch) {
95 thenode->exe = cumodes_nick_exe;
96 } else if (ctx->searchcmd == reg_chansearch) {
97 thenode->exe = cumodes_chan_exe;
98 } else { /* We really shouldn't get here */
99 parseError = "cumodes: internal code error.";
100 free(thenode);
101 (localdata->xnode->free)(ctx, localdata->xnode);
102 free(localdata);
103 return NULL;
104 }
105
106 thenode->free = cumodes_free;
107
108 return thenode;
109 }
110
111 void *cumodes_nick_exe(searchCtx *ctx, struct searchNode *thenode, void *value) {
112 struct cumodes_localdata *localdata;
113 nick *np = (nick *)value;
114 channel *cp;
115 char *channame;
116 unsigned long *lp, flags;
117
118 localdata = (struct cumodes_localdata *)thenode->localdata;
119
120 /* MEGA SLOW */
121 channame = (char *)(localdata->xnode->exe) (ctx, localdata->xnode, value);
122 cp = findchannel(channame);
123 if(!cp)
124 return (void *)0;
125
126 lp = getnumerichandlefromchanhash(cp->users,np->numeric);
127 if(!lp)
128 return (void *)0;
129
130 flags = *lp;
131
132 if (~flags & (localdata->setmodes))
133 return (void *)0;
134
135 if (flags & (localdata->clearmodes))
136 return (void *)0;
137
138 return (void *)1;
139 }
140
141 void *cumodes_chan_exe(searchCtx *ctx, struct searchNode *thenode, void *value) {
142 struct cumodes_localdata *localdata;
143 chanindex *cip = (chanindex *)value;
144 nick *np;
145 char *nickname;
146 unsigned long *lp, flags;
147
148 if(!cip->channel || !cip->channel->users)
149 return (void *)0;
150
151 localdata = (struct cumodes_localdata *)thenode->localdata;
152
153 /* MEGA SLOW */
154 nickname = (char *)(localdata->xnode->exe) (ctx, localdata->xnode, value);
155 np = getnickbynick(nickname);
156 if(!np)
157 return (void *)0;
158
159 lp = getnumerichandlefromchanhash(cip->channel->users,np->numeric);
160 if(!lp)
161 return (void *)0;
162
163 flags = *lp;
164
165 if (~flags & (localdata->setmodes))
166 return (void *)0;
167
168 if (flags & (localdata->clearmodes))
169 return (void *)0;
170
171 return (void *)1;
172 }
173
174 void cumodes_free(searchCtx *ctx, struct searchNode *thenode) {
175 struct cumodes_localdata *localdata = (struct cumodes_localdata *)thenode->localdata;
176 (localdata->xnode->free)(ctx, localdata->xnode);
177 free (thenode->localdata);
178 free (thenode);
179 }