3 #include "../lib/strlfunc.h"
4 #include "../core/config.h"
5 #include "../core/schedule.h"
6 #include "../localuser/localuser.h"
9 static sstring
*patrol_hostpool
[PATROL_POOLSIZE
], *patrol_tailpool
[PATROL_POOLSIZE
];
10 static unsigned int patrol_hostpoolsize
, patrol_tailpoolsize
;
11 static int patrol_min_hosts
;
12 static char patrol_hostmode
;
14 int patrol_minmaxrand(float min
, float max
) {
15 return (int)((max
- min
+ 1) * rand() / (RAND_MAX
+ min
)) + min
;
18 nick
*patrol_selectuser(void) {
19 int target
= patrol_minmaxrand(0, 500), loops
= 150, j
;
23 for (j
= patrol_minmaxrand(0, NICKHASHSIZE
- 1); j
< NICKHASHSIZE
; j
++)
24 for (np
= nicktable
[j
]; np
; np
= np
->next
)
27 } while (--loops
> 0);
32 host
*patrol_selecthost(void) {
33 int target
= patrol_minmaxrand(0, 500), loops
= 150, j
;
37 for (j
= patrol_minmaxrand(0, HOSTHASHSIZE
- 1); j
< HOSTHASHSIZE
; j
++)
38 for (hp
= hosttable
[j
]; hp
; hp
= hp
->next
)
41 } while (--loops
> 0);
46 int patrol_isip(char *host
) {
47 struct irc_in_addr ip
;
50 return (ipmask_parse(host
, &ip
, &bits
));
53 static int specialuseronhost(host
*hp
) {
56 for (np
= hp
->nicks
; np
; np
= np
->nextbyhost
)
57 if (IsOper(np
) || IsService(np
) || IsXOper(np
) || NickOnServiceServer(np
))
63 char patrol_genchar(int ty
) {
64 /* hostname and realname characters*/
66 if (!(patrol_minmaxrand(0, 40) % 10)) {
67 return patrol_minmaxrand(48, 57);
69 return patrol_minmaxrand(97, 122);
72 /* ident characters - without numbers*/
74 return patrol_minmaxrand(97, 122);
75 /* ident characters - with numbers*/
77 ty
= patrol_minmaxrand(97, 125);
79 if (ty
> 122) return patrol_minmaxrand(48, 57);
82 /* nick characters - with and without numbers*/
83 } else if (ty
== 3 || ty
== 4) {
84 if (!(patrol_minmaxrand(0, 59) % 16)) {
85 char weirdos
[6] = { '\\', '|', '[', '{', ']', '}' };
86 return weirdos
[patrol_minmaxrand(0, 5)];
90 ty
= patrol_minmaxrand(65, 93);
92 if (ty
> 90) return patrol_minmaxrand(48, 57);
94 ty
= patrol_minmaxrand(65, 90);
97 if (!(patrol_minmaxrand(0, 40) % 8)) return ty
;
106 void patrol_gennick(char *ptc
, char size
) {
109 for (i
= 0; i
< size
; i
++) {
111 ptc
[i
] = patrol_genchar(3);
113 ptc
[i
] = patrol_genchar(4);
120 void patrol_genident(char *ptc
, char size
) {
123 for (i
= 0; i
< size
; i
++) {
125 ptc
[i
] = patrol_genchar(1);
127 ptc
[i
] = patrol_genchar(2);
134 void patrol_genhost(char *ptc
, char size
, struct irc_in_addr
*ipaddress
) {
135 int dots
= patrol_minmaxrand(2, 5), i
, dotexist
= 0, cur
;
138 for (i
= 0; i
< size
; i
++) {
139 ptc
[i
] = patrol_genchar(0);
141 if ((i
> 5) && (i
< (size
- 4))) {
142 if ((ptc
[i
- 1] != '.') && (ptc
[i
- 1] != '-')) {
143 cur
= patrol_minmaxrand(1, size
/ dots
);
160 memset(ipaddress
, 0, sizeof(*ipaddress
));
161 ((unsigned short *)(ipaddress
->in6_16
))[5] = 65535;
162 ((unsigned short *)(ipaddress
->in6_16
))[6] = patrol_minmaxrand(0, 65535);
163 ((unsigned short *)(ipaddress
->in6_16
))[7] = patrol_minmaxrand(0, 65535);
166 void patrol_genreal(char *ptc
, char size
) {
167 int spaces
= patrol_minmaxrand(2, 4), i
;
169 for (i
= 0; i
< size
; i
++) {
170 ptc
[i
] = patrol_genchar(0);
172 if ((i
> 5) && (i
< (size
- 4))) {
173 if (ptc
[i
- 1] != ' ') {
174 if (patrol_minmaxrand(1, size
/ spaces
) == 1) ptc
[i
] = ' ';
182 void patrol_generatehost(char *buf
, int maxsize
, struct irc_in_addr
*ipaddress
) {
183 if (PATROL_HOST_MODE
== PATROL_STEAL_HOST
) {
190 hp
= patrol_selecthost();
192 if (hp
&& (hp
->clonecount
<= PATROL_MAX_CLONE_COUNT
) && !patrol_isip(hp
->name
->content
) && !specialuseronhost(hp
)) {
193 strlcpy(buf
, hp
->name
->content
, maxsize
+ 1);
196 memcpy(ipaddress
, &hp
->nicks
->ipaddress
, sizeof(struct irc_in_addr
));
198 memset(ipaddress
, 0, sizeof(struct irc_in_addr
));
199 ((unsigned short *)(ipaddress
->in6_16
))[5] = 65535;
200 ((unsigned short *)(ipaddress
->in6_16
))[6] = patrol_minmaxrand(0, 65535);
201 ((unsigned short *)(ipaddress
->in6_16
))[7] = patrol_minmaxrand(0, 65535);
206 } while (--loops
> 0);
209 int pieces
= patrol_minmaxrand(2, 4), totallen
= 0, a
= 0, i
;
210 int *choices
= malloc(sizeof(int) * (pieces
+ 1));
211 int *lengths
= malloc(sizeof(int) * (pieces
+ 1));
213 choices
[pieces
] = patrol_minmaxrand(0, patrol_tailpoolsize
- 1);
214 lengths
[pieces
] = strlen(patrol_tailpool
[choices
[pieces
]]->content
) + 1;
215 totallen
+= lengths
[pieces
];
217 for (i
= 0; i
< pieces
; i
++) {
218 choices
[i
] = patrol_minmaxrand(0, patrol_hostpoolsize
- 1);
219 lengths
[i
] = strlen(patrol_hostpool
[choices
[i
]]->content
) + 1;
221 if (totallen
+ lengths
[i
] > maxsize
) {
222 choices
[i
] = choices
[pieces
];
223 lengths
[i
] = lengths
[pieces
];
224 pieces
-= (pieces
- i
);
228 totallen
+= lengths
[i
];
231 for (i
= 0; i
< pieces
; i
++) {
232 for (cpos
= patrol_hostpool
[choices
[i
]]->content
; *cpos
;)
238 for (cpos
= patrol_tailpool
[choices
[i
]]->content
; *cpos
;) {
246 memset(ipaddress
, 0, sizeof(struct irc_in_addr
));
247 ((unsigned short *)(ipaddress
->in6_16
))[5] = 65535;
248 ((unsigned short *)(ipaddress
->in6_16
))[6] = patrol_minmaxrand(0, 65535);
249 ((unsigned short *)(ipaddress
->in6_16
))[7] = patrol_minmaxrand(0, 65535);
253 void patrol_generatenick(char *buf
, int maxsize
) {
254 int bits
= patrol_minmaxrand(2, 3), loops
= 0, wanttocopy
, len
= 0, i
, d
= 0, newmaxsize
= maxsize
- patrol_minmaxrand(0, 7);
258 maxsize
= newmaxsize
;
261 np
= patrol_selectuser();
264 wanttocopy
= patrol_minmaxrand(1, (strlen(np
->nick
) / 2) + 3);
266 for (i
= 0; ((i
< wanttocopy
) && (len
< maxsize
)); i
++)
267 buf
[len
++] = np
->nick
[i
];
274 } while (++loops
< 10);
279 void patrol_generateident(char *buf
, int maxsize
) {
280 nick
*np
= patrol_selectuser();
284 strlcpy(buf
, np
->ident
, maxsize
+ 1);
287 void patrol_generaterealname(char *buf
, int maxsize
) {
288 nick
*np
= patrol_selectuser();
292 strlcpy(buf
, np
->realname
->name
->content
, maxsize
+ 1);
295 nick
*patrol_generateclone(int extraumodes
, UserMessageHandler handler
) {
296 int loops
= 0, modes
= UMODE_XOPER
| UMODE_INV
| extraumodes
;
297 char c_nick
[NICKLEN
+ 1], c_ident
[USERLEN
+ 1], c_host
[HOSTLEN
+ 1], c_real
[REALLEN
+ 1];
298 struct irc_in_addr ipaddress
;
300 /* PPA: unlikely to be infinite */
304 if (!loops
&& patrol_hostmode
) /* only have one go at this */
305 patrol_generatenick(c_nick
, NICKLEN
);
308 patrol_gennick(c_nick
, patrol_minmaxrand(7, PATROL_MMIN(13, NICKLEN
)));
311 } while ((getnickbynick(c_nick
) != NULL
));
313 patrol_generateident(c_ident
, USERLEN
);
316 patrol_genident(c_ident
, patrol_minmaxrand(4, PATROL_MMIN(8, USERLEN
)));
318 if (patrol_hostmode
) {
319 patrol_generatehost(c_host
, HOSTLEN
, &ipaddress
);
322 patrol_genhost(c_host
, HOSTLEN
, &ipaddress
);
324 patrol_genhost(c_host
, HOSTLEN
, &ipaddress
);
327 patrol_generaterealname(c_real
, REALLEN
);
330 patrol_genreal(c_real
, patrol_minmaxrand(15, PATROL_MMIN(50, REALLEN
)));
332 return registerlocaluserflagsip(c_nick
, c_ident
, c_host
, c_real
, NULL
, 0, 0, modes
, &ipaddress
, handler
);
335 void patrol_nickchange(nick
*np
) {
336 char c_nick
[NICKLEN
+ 1];
339 /* PPA: unlikely to be infinite */
341 if ((loops
++ < 10) && patrol_hostmode
) {
342 patrol_generatenick(c_nick
, NICKLEN
);
344 patrol_gennick(c_nick
, patrol_minmaxrand(7, PATROL_MMIN(13, NICKLEN
)));
346 } while (c_nick
[0] && (getnickbynick(c_nick
) != NULL
));
348 renamelocaluser(np
, c_nick
);
351 int patrol_is_not_octet(char *begin
, int length
) {
357 for (i
= 0; i
< length
; i
++) {
358 if (!((*begin
>= '0') && (*begin
<= '9')))
367 int patrol_generatepool(void) {
368 int i
, k
= 0, j
= 0, loops
= 0;
372 for (i
= 0; i
< NICKHASHSIZE
; i
++)
373 for (np
= nicktable
[i
]; np
; np
= np
->next
)
376 if (j
< patrol_min_hosts
)
379 if (PATROL_HOST_MODE
== PATROL_STEAL_HOST
)
380 return PATROL_MINPOOLSIZE
;
385 for (j
= patrol_minmaxrand(0, NICKHASHSIZE
- 1); j
< NICKHASHSIZE
; j
++) {
387 for (p
= nicktable
[j
]->host
->name
->content
, pp
= p
; *p
;) {
389 if (!patrol_is_not_octet(pp
, p
- pp
)) {
390 if (i
< PATROL_POOLSIZE
) {
391 if (i
< patrol_hostpoolsize
)
392 freesstring(patrol_hostpool
[i
]);
394 patrol_hostpool
[i
] = getsstring(pp
, p
- pp
);
397 if (k
>= PATROL_POOLSIZE
)
406 if (!patrol_is_not_octet(pp
, p
- pp
)) {
407 if (k
< PATROL_POOLSIZE
) {
408 if (k
< patrol_tailpoolsize
)
409 freesstring(patrol_tailpool
[k
]);
411 patrol_tailpool
[k
] = getsstring(pp
, p
- pp
);
414 if (i
>= PATROL_POOLSIZE
)
422 } while ((loops
< 5) && ((i
< PATROL_POOLSIZE
) || (k
< PATROL_POOLSIZE
)));
424 patrol_hostpoolsize
= i
;
425 patrol_tailpoolsize
= k
;
429 int patrol_repool(void) {
430 if (patrol_generatepool() < PATROL_MINPOOLSIZE
) {
439 void patrol_sched_repool(void *arg
) {
443 delta
= PATROL_POOL_REGENERATION
;
447 scheduleoneshot(time(NULL
) + delta
, &patrol_sched_repool
, NULL
);
454 snprintf(buf
, sizeof(buf
), "%d", PATROL_MINIMUM_HOSTS_BEFORE_POOL
);
455 m
= getcopyconfigitem("patrol", "minpoolhosts", buf
, 32);
456 patrol_min_hosts
= atoi(m
->content
);
459 scheduleoneshot(time(NULL
) + 5, &patrol_sched_repool
, NULL
);
465 deleteallschedules(&patrol_sched_repool
);
467 for (i
= 0; i
< patrol_hostpoolsize
; i
++)
468 freesstring(patrol_hostpool
[i
]);
470 for (i
= 0; i
< patrol_tailpoolsize
; i
++)
471 freesstring(patrol_tailpool
[i
]);