]> jfr.im git - irc/quakenet/newserv.git/blame - glines/glines_formats.c
glstore: Don't save gline flags.
[irc/quakenet/newserv.git] / glines / glines_formats.c
CommitLineData
c60d02ed
GB
1#include <stdio.h>
2#include <string.h>
3#include <assert.h>
4#include "../lib/irc_string.h"
5#include "../lib/version.h"
6#include "../core/schedule.h"
7#include "../irc/irc.h"
8#include "../trusts/trusts.h"
9#include "../control/control.h"
10#include "glines.h"
11
12gline *makegline(const char *mask) {
13 /* populate gl-> user,host,node,nick and set appropriate flags */
14 gline *gl;
15 char nick[512], user[512], host[512];
16 const char *pnick = NULL, *puser = NULL, *phost = NULL;
27a53417
GB
17 const char *pos;
18 int count;
c60d02ed
GB
19
20 /* Make sure there are no spaces in the mask, glstore_* depends on this */
21 if (strchr(mask, ' ') != NULL)
22 return NULL;
23
24 gl = newgline();
25
26 if (!gl) {
27 Error("gline", ERR_ERROR, "Failed to allocate new gline");
28 return NULL;
29 }
30
a86fc0c4 31 if (mask[0] == '#' || mask[0] == '&') {
c60d02ed
GB
32 gl->flags |= GLINE_BADCHAN;
33 gl->user = getsstring(mask, CHANNELLEN);
34 return gl;
35 }
36
a86fc0c4 37 if (mask[0] == '$') {
c60d02ed
GB
38 if (mask[1] != 'R') {
39 freegline(gl);
40 return NULL;
41 }
42
43 gl->flags |= GLINE_REALNAME;
44 gl->user = getsstring(mask + 2, REALLEN);
45 return gl;
46 }
47
48 if (sscanf(mask, "%[^!]!%[^@]@%s", nick, user, host) == 3) {
49 pnick = nick;
50 puser = user;
51 phost = host;
52 } else if (sscanf(mask, "%[^@]@%s", user, host) == 2) {
53 puser = user;
54 phost = host;
55 } else {
56 phost = mask;
57 }
58
59 /* validate length of the mask components */
60 if ((pnick && (pnick[0] == '\0' || strlen(pnick) > NICKLEN)) ||
61 (puser && (puser[0] == '\0' || strlen(puser) > USERLEN)) ||
62 (phost && (phost[0] == '\0' || strlen(phost) > HOSTLEN))) {
63 freegline(gl);
64 return NULL;
65 }
66
67 /* ! and @ are not allowed in the mask components */
68 if ((pnick && (strchr(pnick, '!') || strchr(pnick, '@'))) ||
69 (puser && (strchr(puser, '!') || strchr(puser, '@'))) ||
70 (phost && (strchr(phost, '!') || strchr(phost, '@')))) {
71 freegline(gl);
72 return NULL;
73 }
74
75 if (phost && ipmask_parse(phost, &gl->ip, &gl->bits))
76 gl->flags |= GLINE_IPMASK;
77 else
78 gl->flags |= GLINE_HOSTMASK;
79
27a53417
GB
80 /* Don't allow invalid IPv6 bans as those match * on snircd 1.3.4 */
81 if (phost) {
82 count = 0;
83
84 for (pos = phost; *pos; pos++)
85 if (*pos == ':')
86 count++;
87
88 if (count >= 8) {
89 controlwall(NO_OPER, NL_GLINES, "Warning: Parsed invalid IPv6 G-Line: %s", mask);
90 freegline(gl);
91 return NULL;
92 }
93 }
94
c60d02ed
GB
95 if (pnick && strcmp(pnick, "*") != 0)
96 gl->nick = getsstring(pnick, NICKLEN);
97
98 if (puser && strcmp(puser, "*") != 0)
99 gl->user = getsstring(puser, USERLEN);
100
101 if (phost && strcmp(phost, "*") != 0)
102 gl->host = getsstring(phost, HOSTLEN);
103
104 return gl;
105}
106
107char *glinetostring(gline *gl) {
108 static char mask[512]; /* check */
109
110 if (gl->flags & GLINE_REALNAME) {
111 if (gl->user)
112 snprintf(mask, sizeof(mask), "$R%s", gl->user->content);
113 else
114 strncpy(mask, "$R*", sizeof(mask));
115
116 return mask;
117 }
118
119 if (gl->flags & GLINE_BADCHAN) {
120 assert(gl->user);
121
122 strncpy(mask, gl->user->content, sizeof(mask));
123 return mask;
124 }
125
126 snprintf(mask, sizeof(mask), "%s!%s@%s",
127 gl->nick ? gl->nick->content : "*",
128 gl->user ? gl->user->content : "*",
129 gl->host ? gl->host->content : "*");
130
131 return mask;
132}
133