]> jfr.im git - irc/quakenet/newserv.git/blob - glines/glines_formats.c
BUILD: add require-all build mode
[irc/quakenet/newserv.git] / glines / glines_formats.c
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
12 /** Find canonical user and host for a string.
13 * If \a userhost starts with '$', assign \a userhost to *user_p and NULL to *host_p.
14 * Otherwise, if \a userhost contains '@', assign the earlier part of it to *user_p and the rest to *host_p.
15 * Otherwise, assign \a def_user to *user_p and \a userhost to *host_p.
16 *
17 * @param[in] userhost Input string from user.
18 * @param[out] nick_p Gets pointer to nick part of hostmask.
19 * @param[out] user_p Gets pointer to user (or channel/realname) part of hostmask.
20 * @param[out] host_p Gets point to host part of hostmask (may be assigned NULL).
21 * @param[in] def_user Default value for user part.
22 */
23 static void
24 canon_userhost(char *userhost, char **nick_p, char **user_p, char **host_p, char *def_user) {
25 char *tmp, *s;
26
27 if (*userhost == '$') {
28 *user_p = userhost;
29 *host_p = NULL;
30 *nick_p = NULL;
31 return;
32 }
33
34 if ((tmp = strchr(userhost, '!'))) {
35 *nick_p = userhost;
36 *(tmp++) = '\0';
37 } else {
38 *nick_p = def_user;
39 tmp = userhost;
40 }
41
42 if (!(s = strchr(tmp, '@'))) {
43 *user_p = def_user;
44 *host_p = tmp;
45 } else {
46 *user_p = tmp;
47 *(s++) = '\0';
48 *host_p = s;
49 }
50 }
51
52 gline *makegline(const char *mask) {
53 /* populate gl-> user,host,node,nick and set appropriate flags */
54 gline *gl;
55 char dupmask[512];
56 char *nick, *user, *host;
57 const char *pos;
58 int count;
59
60 /* Make sure there are no spaces in the mask */
61 if (strchr(mask, ' ') != NULL)
62 return NULL;
63
64 gl = newgline();
65
66 if (!gl) {
67 Error("gline", ERR_ERROR, "Failed to allocate new gline");
68 return NULL;
69 }
70
71 if (mask[0] == '#' || mask[0] == '&') {
72 gl->flags |= GLINE_BADCHAN;
73 gl->user = getsstring(mask, CHANNELLEN);
74 return gl;
75 }
76
77 if (mask[0] == '$') {
78 if (mask[1] != 'R') {
79 freegline(gl);
80 return NULL;
81 }
82
83 gl->flags |= GLINE_REALNAME;
84
85 if (strcmp(mask + 2, "*") != 0)
86 gl->user = getsstring(mask + 2, REALLEN);
87
88 return gl;
89 }
90
91 strncpy(dupmask, mask, sizeof(dupmask));
92 canon_userhost(dupmask, &nick, &user, &host, "*");
93
94 if (ipmask_parse(host, &gl->ip, &gl->bits))
95 gl->flags |= GLINE_IPMASK;
96 else
97 gl->flags |= GLINE_HOSTMASK;
98
99 /* Don't allow invalid IPv6 bans as those might match * on snircd 1.3.4 */
100 count = 0;
101
102 for (pos = host; *pos; pos++)
103 if (*pos == ':')
104 count++;
105
106 if (count >= 8) {
107 controlwall(NO_OPER, NL_GLINES_AUTO, "Warning: Parsed invalid IPv6 G-Line: %s", mask);
108 freegline(gl);
109 return NULL;
110 }
111
112 if (strcmp(nick, "*") != 0)
113 gl->nick = getsstring(nick, 512);
114
115 if (strcmp(user, "*") != 0)
116 gl->user = getsstring(user, 512);
117
118 if (strcmp(host, "*") != 0)
119 gl->host = getsstring(host, 512);
120
121 return gl;
122 }
123
124 char *glinetostring(gline *gl) {
125 static char mask[512]; /* check */
126
127 if (gl->flags & GLINE_REALNAME) {
128 snprintf(mask, sizeof(mask), "$R%s", (gl->user) ? gl->user->content : "*");
129 return mask;
130 }
131
132 if (gl->flags & GLINE_BADCHAN) {
133 assert(gl->user);
134
135 strncpy(mask, gl->user->content, sizeof(mask));
136 return mask;
137 }
138
139 snprintf(mask, sizeof(mask), "%s!%s@%s",
140 gl->nick ? gl->nick->content : "*",
141 gl->user ? gl->user->content : "*",
142 gl->host ? gl->host->content : "*");
143
144 return mask;
145 }
146