]> jfr.im git - irc/quakenet/newserv.git/blame - request/request_block.c
LUA: port luadb to dbapi2 to drop postgres dependency
[irc/quakenet/newserv.git] / request / request_block.c
CommitLineData
25b7d0fa
P
1#include <stdio.h>
2#include <string.h>
3#include "../irc/irc.h"
4#include "../lib/irc_string.h"
5#include "request_block.h"
6
7/* array of blocks */
8array rqblocks;
9
25b7d0fa
P
10/* are we currently loading blocks? */
11int rq_loading;
12
8ee2e8b2 13int rq_initblocks(void) {
25b7d0fa
P
14 array_init(&rqblocks, sizeof(rq_block));
15 array_setlim1(&rqblocks, 5);
16 array_setlim2(&rqblocks, 20);
17
18 rq_loading = 0;
19
20 rq_loadblocks();
21
22 rq_addblock("#qnet*", "Reserved for QuakeNet use only.", "request", 0, 0);
23 rq_addblock("#help*", "Reserved for QuakeNet use only.", "request", 0, 0);
24
8ee2e8b2 25 return 1;
25b7d0fa
P
26}
27
28void rq_finiblocks(void) {
29 int i;
30 rq_block block;
25b7d0fa
P
31
32 for (i = 0; i < rqblocks.cursi; i++) {
33 block = ((rq_block*)rqblocks.content)[i];
34
35 freesstring(block.pattern);
36 freesstring(block.reason);
37 freesstring(block.creator);
38 }
39
40 array_free(&rqblocks);
25b7d0fa
P
41}
42
43rq_block *rq_findblock(const char *pattern) {
44 int i;
45 rq_block block;
46
47 for (i = rqblocks.cursi - 1; i >= 0; i--) {
48 block = ((rq_block*)rqblocks.content)[i];
49
50 if (match2strings(block.pattern->content, pattern)) {
51 if (block.expires != 0 && block.expires < getnettime())
52 rq_removeblock(block.pattern->content);
53 else
54 return &(((rq_block*)rqblocks.content)[i]);
55 }
56 }
57
58 return NULL;
59}
60
61void rq_addblock(const char *pattern, const char *reason, const char *creator, time_t created, time_t expires) {
62 int slot;
63 rq_block *block;
64
65 if (rq_findblock(pattern) != NULL)
66 return;
67
68 slot = array_getfreeslot(&rqblocks);
69
70 block = &(((rq_block*)rqblocks.content)[slot]);
71
72 block->pattern = getsstring(pattern, CHANNELLEN);
73 block->reason = getsstring(reason, RQ_BLOCKLEN);
74 block->creator = getsstring(creator, ACCOUNTLEN);
75 block->created = created == 0 ? getnettime() : created;
76 block->expires = expires;
77
78 rq_saveblocks();
79}
80
81int rq_removeblock(const char *pattern) {
82 int i;
83 rq_block block;
84
85 for (i = 0; i < rqblocks.cursi; i++) {
86 block = ((rq_block*)rqblocks.content)[i];
87
88 if (ircd_strcmp(block.pattern->content, pattern) == 0) {
89 freesstring(block.pattern);
90 freesstring(block.reason);
91 freesstring(block.creator);
92
93 array_delslot(&rqblocks, i);
94
95 rq_saveblocks();
96
97 return 1;
98 }
99 }
100
101 return 0;
102}
103
104/* pattern reason creator created expires */
105int rq_parseline(char *line) {
106 char pattern[CHANNELLEN+1];
107 char reason[RQ_BLOCKLEN+1];
108 char creator[ACCOUNTLEN+1];
109 time_t created, expires;
110
111 if (sscanf(line, "%s %s %lu %lu %[^\n]", pattern, creator, &created, &expires, reason) < 2) /* \n won't be there anyway, but %s won't return the whole string */
112 return 0; /* invalid block */
113
114 /* tell rq_addblock that it should not save the blocks to disk this time */
115 rq_loading = 1;
116 rq_addblock(pattern, reason, creator, created, expires);
117 rq_loading = 0;
118
119 return 1;
120}
121
122int rq_loadblocks(void) {
123 char line[4096];
124 FILE *rqdata;
125 int count;
126
127 rqdata = fopen(RQ_BLOCKFILE, "r");
128
129 if (rqdata == NULL)
130 return 0;
131
132 count = 0;
133
134 while (!feof(rqdata)) {
135 if (fgets(line, sizeof(line), rqdata) == NULL)
136 break;
137
138 if (line[strlen(line) - 1] == '\n')
139 line[strlen(line) - 1] = '\0';
140
141 if (line[strlen(line) - 1] == '\r')
142 line[strlen(line) - 1] = '\0';
143
144 if (line[0] != '\0') {
145 if (rq_parseline(line))
146 count++;
147 }
148 }
149
150 fclose(rqdata);
151
152 return count;
153}
154
155int rq_saveblocks(void) {
156 FILE *rqdata;
157 int i, count = 0;
158
159 /* don't save the blocks if we're currently loading them from the disk */
160 if (rq_loading)
161 return 0;
162
163 rqdata = fopen(RQ_BLOCKFILE, "w");
164
165 if (rqdata == NULL)
166 return 0;
167
168 rq_block block;
169
170 for (i = 0; i < rqblocks.cursi; i++) {
171 block = ((rq_block*)rqblocks.content)[i];
172
173 fprintf(rqdata, "%s %s %lu %lu %s\n", block.pattern->content, block.creator->content, block.created, block.expires, block.reason->content);
174 }
175
176 fclose(rqdata);
177
178 return count;
179}