1 /*
2  * whois.c: Some tricky routines for querying the server for information
3  * about a nickname using WHOIS.... all the time hiding this from the user.
4  *
5  * Written By Michael Sandrof
6  *
7  * Copyright (c) 1990 Michael Sandrof.
8  * Copyright (c) 1991, 1992 Troy Rollo.
9  * Copyright (c) 1992-2003 Matthew R. Green.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  * $Id: whois.c,v 1.22 2008-05-13 14:55:48 f Exp $
36  */
37 
38 #undef MONITOR_Q /* this one is for monitoring of the 'whois queue' (debug) */
39 
40 #include "irc.h"
41 
42 #include "whois.h"
43 #include "hook.h"
44 #include "lastlog.h"
45 #include "vars.h"
46 #include "server.h"
47 #include "ignore.h"
48 #include "ircaux.h"
49 #include "notify.h"
50 #include "numbers.h"
51 #include "window.h"
52 #include "edit.h"
53 #include "output.h"
54 #include "parse.h"
55 #include "ctcp.h"
56 
57 /**************************** PATCHED by Flier ******************************/
58 #include "myvars.h"
59 
60 extern void PrintWhoIsUser _((char *, char *, char *, char *, char *, char *, char *));
61 extern void PrintWhoIsChannels _((char *, char *));
62 extern void PrintWhoIsServer _((char *, char *, char *));
63 extern void BuildPrivs _((struct friends *, char *));
64 
65 #ifdef WANTANSI
66 extern void ColorUserHost _((char *, char *, char *, int));
67 #endif
68 
69 #ifdef CELECOSM
70 extern struct friends *whoisfriend;
71 #endif
72 /****************************************************************************/
73 
74 char	whois_nick[] = "#WHOIS#";
75 char	wait_nick[] = "#WAIT#";
76 char	redirect_nick[] = "#RED#";
77 
78 /* current setting for BEEP_ON_MSG */
79 int	beep_on_level;
80 
81 static	int	ignore_whois_crap = 0;
82 static	int	eat_away = 0;
83 /*
84 static	WhoisStuff whois_stuff =
85 {
86 	(char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0,
87 	(char *) 0, (char *) 0, (char *) 0, (char *) 0, 0, 0, 0
88 };
89 */
90 
91 /* WQ_head and WQ_tail point to the head and tail of the whois queue */
92 WhoisQueue *WQ_head = (WhoisQueue *) 0;
93 WhoisQueue *WQ_tail = (WhoisQueue *) 0;
94 
95 static	char	show_away_flag = 0;
96 
97 #ifdef HAVE_STDARG_H
98 static	void	typed_add_to_whois_queue _((int, char *, void (*)(WhoisStuff *, char *, char *), char *, va_list));
99 #else
100 static  void	typed_add_to_whois_queue();
101 #endif
102 static	char	* whois_queue_head _((int));
103 static	int	whois_type_head _((int));
104 static	void	(*whois_func_head _((int))) _((WhoisStuff *, char *, char *));
105 static	WhoisQueue	*remove_from_whois_queue _((int));
106 
107 void
set_beep_on_msg(str)108 set_beep_on_msg(str)
109 	char	*str;
110 {
111 	beep_on_level = parse_lastlog_level(str);
112 	set_string_var(BEEP_ON_MSG_VAR, bits_to_lastlog_level(beep_on_level));
113 }
114 
115 /*
116  * whois_queue_head: returns the nickname at the head of the whois queue, or
117  * NULL if the queue is empty.  It does not modify the queue in any way.
118  */
119 static	char	*
whois_queue_head(server_index)120 whois_queue_head(server_index)
121 int	server_index;
122 {
123 	if ((WQ_head = (WhoisQueue *) get_server_qhead(server_index)) != NULL)
124 		return (WQ_head->nick);
125 	else
126 		return ((char *) 0);
127 }
128 
129 static	int
whois_type_head(server_index)130 whois_type_head(server_index)
131 int	server_index;
132 {
133 	if ((WQ_head = (WhoisQueue *) get_server_qhead(server_index)) != NULL)
134 		return (WQ_head->type);
135 	else
136 		return -1;
137 }
138 
139 static	void (*
140 whois_func_head (server_index)) _((WhoisStuff *, char *, char *))
141  	int	server_index;
142 {
143 	if ((WQ_head = (WhoisQueue *) get_server_qhead(server_index)) != NULL)
144 		return (WQ_head->func);
145 	else
146 		return NULL;
147 }
148 
149 /*
150  * remove_from_whois_queue: removes the top element of the whois queue and
151  * returns the element as its function value.  This routine repairs handles
152  * all queue stuff, but the returned element is mallocd and must be freed by
153  * the calling routine
154  */
155 static	WhoisQueue *
remove_from_whois_queue(server_index)156 remove_from_whois_queue(server_index)
157 int	server_index;
158 {
159 	WhoisQueue *new;
160 
161 	new = (WhoisQueue *) get_server_qhead(server_index);
162 	set_server_qhead(server_index, new->next);
163 	if (new->next == (WhoisQueue *) 0)
164 		set_server_qtail(server_index, (WhoisQueue *) 0);
165 	return (new);
166 }
167 
168 /*
169  * clean_whois_queue: this empties out the whois queue.  This is used after
170  * server reconnection to assure that no bogus entries are left in the whois
171  * queue
172  */
173 void
clean_whois_queue()174 clean_whois_queue()
175 {
176 	WhoisQueue *thing;
177 
178 	while (whois_queue_head(from_server))
179 	{
180 		thing = remove_from_whois_queue(from_server);
181 		new_free(&thing->nick);
182 		new_free(&thing->text);
183 		new_free(&thing);
184 	}
185 	ignore_whois_crap = 0;
186 	eat_away = 0;
187 }
188 
189 /*
190  * ison_returned: this is called when numeric 303 is received in
191  * numbers.c. ISON must always be the property of the WHOIS queue.
192  * Although we will check first that the top element expected is
193  * actually an ISON.
194  */
195 /*ARGSUSED*/
196 void
ison_returned(from,ArgList)197 ison_returned(from, ArgList)
198 	char	*from,
199 		**ArgList;
200 {
201 	WhoisQueue *thing;
202 
203 /**************************** Patched by Flier ******************************/
204         /* fix ircd 2.10 lameness in HTM mode where ircd will NOT return
205          * valid userhost reply at all! */
206         while (inSZNotify && whois_type_head(parsing_server_index) == WHOIS_USERHOST) {
207             inSZNotify--;
208             if (inSZNotify==1) inSZNotify=0;
209             thing = remove_from_whois_queue(parsing_server_index);
210             new_free(&thing->nick);
211             new_free(&thing->text);
212             new_free(&thing);
213         }
214 /****************************************************************************/
215 	if (whois_type_head(parsing_server_index) == WHOIS_ISON)
216 	{
217 		thing = remove_from_whois_queue(parsing_server_index);
218 		thing->func((WhoisStuff *) 0, thing->nick, ArgList[0]? ArgList[0] : empty_string);
219 		new_free(&thing->nick);
220 		new_free(&thing->text);
221 		new_free(&thing);
222 	}
223 	else
224 		ison_now((WhoisStuff *) 0, ArgList[0] ? ArgList[0] : empty_string, (char *) 0);
225 }
226 
227 /* userhost_returned: this is called when numeric 302 is received in
228  * numbers.c. USERHOST must also remain the property of the WHOIS
229  * queue. Sending it without going via the WHOIS queue will cause
230  * the queue to become corrupted.
231  *
232  * While USERHOST gives us similar information to WHOIS, this routine's
233  * format is a little different to those that handle the WHOIS numerics.
234  * A list of nicks can be supplied to USERHOST, and any of those
235  * nicks are not currently signed on, it will just omit reporting it.
236  * this means we must go through the list of nicks returned and check
237  * them for missing entries. This means stepping through the requested
238  * nicks one at a time.
239  *
240  * A side effect of this is that user initiated USERHOST requests get
241  * reported as separate replies even though one request gets made and
242  * only one reply is actually received. This should make it easier for
243  * people wanting to use USERHOST for their own purposes.
244  *
245  * In this routine, cnick points to all the information in the next
246  * entry from the returned data.
247  */
248 /*ARGSUSED*/
249 void
userhost_returned(from,ArgList)250 userhost_returned(from, ArgList)
251 	char	*from,
252 		**ArgList;
253 {
254 	WhoisQueue *thing;
255 	WhoisStuff *whois_stuff = NULL;
256 	char	*nick,
257 		*cnick = NULL,
258 		*tnick;
259 	char	*user,
260 		*cuser = (char *) 0;
261 	char	*host,
262 		*chost = (char *) 0;
263 	int	ishere,
264 		cishere = 1;
265 	int	isoper,
266 		cisoper = 0;
267 	int	noton,
268 		isuser,
269 		parsed;
270 	char	*queue_nicks;
271 
272 	if (!ArgList[0])
273 		return;
274 	if (whois_type_head(parsing_server_index) == WHOIS_USERHOST)
275 	{
276 		isuser = (whois_func_head(parsing_server_index) == USERHOST_USERHOST);
277 		whois_stuff = get_server_whois_stuff(parsing_server_index);
278 		thing = remove_from_whois_queue(parsing_server_index);
279 		queue_nicks = thing->nick;
280 	}
281 	else
282 	{
283 		isuser = 1;
284 		thing = (WhoisQueue *) 0;
285 		queue_nicks = (char *) 0;
286 		whois_stuff = NULL;
287 	}
288 	parsed = 0;
289 	while ((parsed || (cnick = next_arg(ArgList[0], ArgList))) ||
290 			queue_nicks)
291 	{
292 		if (queue_nicks)
293 		{
294 			tnick = next_arg(queue_nicks, &queue_nicks);
295 			if (!*queue_nicks)
296 				queue_nicks = (char *) 0;
297 		}
298 		else
299 			tnick = NULL;
300 		if (cnick && !parsed)
301 		{
302 			if (!(cuser = index(cnick,'=')))
303 				break;
304 			if (*(cuser - 1) == '*')
305 			{
306 				*(cuser - 1) = '\0';
307 				cisoper = 1;
308 			}
309 			else
310 				cisoper = 0;
311 			*cuser++ = '\0';
312 			if (*cuser++ == '+')
313 				cishere = 1;
314 			else
315 				cishere = 0;
316 			if (!(chost = index(cuser, '@')))
317 				break;
318 			*chost++ = '\0';
319 			parsed = 1;
320 		}
321 		if (!cnick || (tnick && my_stricmp(cnick, tnick)))
322 		{
323 			if (tnick)
324 				nick = tnick;
325 			else
326 				nick = cnick;
327 			user = host = "<UNKNOWN>";
328 			isoper = 0;
329 			ishere = 1;
330 			noton = 1;
331 		}
332 		else
333 		{
334 			nick = cnick;
335 			user = cuser;
336 			host = chost;
337 			isoper = cisoper;
338 			ishere = cishere;
339 			noton = parsed = 0;
340 		}
341 		if (!isuser)
342 		{
343 			malloc_strcpy(&whois_stuff->nick, nick);
344 			malloc_strcpy(&whois_stuff->user, user);
345 			malloc_strcpy(&whois_stuff->host, host);
346 			whois_stuff->oper = isoper;
347 			whois_stuff->not_on = noton;
348 			if (!ishere)
349 				malloc_strcpy(&whois_stuff->away, empty_string);
350 			else
351 				new_free(&whois_stuff->away);
352 			thing->func(whois_stuff, tnick, thing->text);
353 			new_free(&whois_stuff->away);
354 		}
355 		else
356 		{
357 			if (do_hook(current_numeric, "%s %s %s %s %s", nick,
358 			    isoper ? "+" : "-", ishere ? "+" : "-", user, host))
359 /**************************** Patched by Flier ******************************/
360 				/*put_it("%s %s is %s@%s%s%s", numeric_banner(),*/
361 				put_it("%s%s is %s@%s%s%s", numeric_banner(),
362 /****************************************************************************/
363 					nick, user, host, isoper ?
364 					" (Is an IRC operator)" : empty_string,
365 					ishere ? empty_string : " (away)");
366 		}
367 	}
368 	if (thing)
369 	{
370 		new_free(&thing->nick);
371 		new_free(&thing->text);
372 		new_free(&thing);
373 	}
374 }
375 
376 /*
377  * whois_name: routine that is called when numeric 311 is received in
378  * numbers.c. This routine parses out the information in the numeric and
379  * saves it until needed (see whois_server()).  If the whois queue is empty,
380  * this routine simply displays the data in the normal fashion.  Why would
381  * the queue ever be empty, you ask? If the user does a "WHOIS *" or any
382  * other whois with a wildcard, you will get multiple returns from the
383  * server.  So, instead of attempting to handle each of these, only the first
384  * is handled, and the others fall through.  It is up to the programmer to
385  * prevent wildcards from interfering with what they want done.  See
386  * channel() in edit.c
387  */
388 void
whois_name(from,ArgList)389 whois_name(from, ArgList)
390 	char	*from;
391 	char	**ArgList;
392 {
393 	char	*nick,
394 		*user,
395 		*host,
396 		*channel,
397 		*ptr,
398 		*name;
399 	WhoisStuff *whois_stuff;
400 
401 	PasteArgs(ArgList, 4);
402 	nick = ArgList[0];
403 	user = ArgList[1];
404 	host = ArgList[2];
405 	channel = ArgList[3];
406 	name = ArgList[4];
407 	if (!nick || !user || !host || !channel || !name)
408 		return;
409 	whois_stuff = get_server_whois_stuff(parsing_server_index);
410 	if ((ptr = whois_queue_head(parsing_server_index))
411 	 && (whois_type_head(parsing_server_index) & (WHOIS_WHOIS|WHOIS_ISON2))
412 	 && (my_stricmp(ptr, nick) == 0))
413 	{
414 		malloc_strcpy(&whois_stuff->nick, nick);
415 		malloc_strcpy(&whois_stuff->user, user);
416 		malloc_strcpy(&whois_stuff->host, host);
417 		malloc_strcpy(&whois_stuff->name, name);
418 		malloc_strcpy(&whois_stuff->channel, channel);
419 		new_free(&whois_stuff->away);
420 		whois_stuff->oper = 0;
421 		whois_stuff->chop = 0;
422 		whois_stuff->not_on = 0;
423 		ignore_whois_crap = 1;
424 		eat_away = 1;
425 	}
426 	else
427 	{
428 		ignore_whois_crap = 0;
429 		eat_away = 0;
430 		if (do_hook(current_numeric, "%s %s %s %s %s %s", from, nick,
431 				user, host, channel, name))
432 /**************************** PATCHED by Flier ******************************/
433 			/*put_it("%s %s is %s@%s (%s)", numeric_banner(), nick,
434 					user, host, name);*/
435                         PrintWhoIsUser(numeric_banner(),"is",nick,user,host,name,"");
436 /****************************************************************************/
437 	}
438 }
439 
440 /*
441  * whowas_name: same as whois_name() above but it is called with a numeric of
442  * 314 when the user does a WHOWAS or when a WHOIS'd user is no longer on IRC
443  * and has set the AUTO_WHOWAS variable.
444  */
445 void
whowas_name(from,ArgList)446 whowas_name(from, ArgList)
447 	char	*from;
448 	char	**ArgList;
449 {
450 	char	*nick,
451 		*user,
452 		*host,
453 		*channel,
454 		*ptr,
455 		*name;
456 	WhoisStuff *whois_stuff;
457 	int	lastlog_level;
458 
459 	PasteArgs(ArgList, 4);
460 	nick = ArgList[0];
461 	user = ArgList[1];
462 	host = ArgList[2];
463 	channel = ArgList[3];
464 	name = ArgList[4];
465 	if (!nick || !user || !host || !channel || !name)
466 		return;
467 
468 	lastlog_level = set_lastlog_msg_level(LOG_CRAP);
469 	whois_stuff = get_server_whois_stuff(parsing_server_index);
470 	if ((ptr = whois_queue_head(parsing_server_index))
471 	 && (whois_type_head(parsing_server_index) & (WHOIS_WHOIS|WHOIS_ISON2))
472 	 && (my_stricmp(ptr, nick) == 0))
473 	{
474 		malloc_strcpy(&whois_stuff->nick, nick);
475 		malloc_strcpy(&whois_stuff->user, user);
476 		malloc_strcpy(&whois_stuff->host, host);
477 		malloc_strcpy(&whois_stuff->name, name);
478 		malloc_strcpy(&whois_stuff->channel, channel);
479 		new_free(&whois_stuff->away);
480 		whois_stuff->oper = 0;
481 		whois_stuff->chop = 0;
482 		whois_stuff->not_on = 1;
483 		ignore_whois_crap = 1;
484 	}
485 	else
486 	{
487 		ignore_whois_crap = 0;
488 		if (do_hook(current_numeric, "%s %s %s %s %s %s", from, nick,
489 				user, host, channel, name))
490 /**************************** PATCHED by Flier ******************************/
491 			/*put_it("%s %s was %s@%s (%s) on channel %s",
492 				numeric_banner(), nick, user, host, name,
493 				(*channel == '*') ? "*private*" : channel);*/
494                         PrintWhoIsUser(numeric_banner(),"was",nick,user,host,
495                                    name,(*channel=='*') ? "*private*":channel);
496 /****************************************************************************/
497 	}
498 	set_lastlog_msg_level(lastlog_level);
499 }
500 
501 void
whois_channels(from,ArgList)502 whois_channels(from, ArgList)
503 	char	*from;
504 	char	**ArgList;
505 {
506 	char	*ptr;
507 	char	*line;
508 	WhoisStuff *whois_stuff;
509 
510 	PasteArgs(ArgList, 1);
511 	line = ArgList[1];
512 	whois_stuff = get_server_whois_stuff(parsing_server_index);
513 	if ((ptr = whois_queue_head(parsing_server_index))
514 	 && (whois_type_head(parsing_server_index) & (WHOIS_WHOIS|WHOIS_ISON2))
515 	 && whois_stuff->nick
516 	 && (my_stricmp(ptr, whois_stuff->nick) == 0))
517 	{
518 		if (whois_stuff->channels == (char *) 0)
519 			malloc_strcpy(&whois_stuff->channels, line);
520 		else
521 			malloc_strcat(&whois_stuff->channels, line);
522 	}
523 	else
524 	{
525 		if (do_hook(current_numeric, "%s %s", from, line))
526 /**************************** PATCHED by Flier ******************************/
527 			/*put_it("%s on channels: %s", numeric_banner(), line);*/
528                         PrintWhoIsChannels(numeric_banner(),line);
529 /****************************************************************************/
530 	}
531 }
532 
533 /*
534  * whois_server: Called in numbers.c when a numeric of 312 is received.  If
535  * all went well, this routine collects the needed information, pops the top
536  * element off the queue and calls the function as described above in
537  * WhoisQueue.  It then releases all the mallocd data.  If the queue is empty
538  * (same case as described in whois_name() above), the information is simply
539  * displayed in the normal fashion. Added a check to see if whois_stuff->nick
540  * is NULL. This can happen if something is added to an empty whois queue
541  * between the whois name being received and the server.
542  */
543 void
whois_server(from,ArgList)544 whois_server(from, ArgList)
545 	char	*from;
546 	char	**ArgList;
547 {
548 	char	*server,
549 		*ptr;
550 	char	*line;
551 	WhoisStuff *whois_stuff;
552 
553 	show_away_flag = 1;
554 	if (!ArgList[0] || !ArgList[1])
555 		return;
556 	if (ArgList[2])
557 	{
558 		server = ArgList[1];
559 		line = ArgList[2];
560 	}
561 	else
562 	{
563 		server = ArgList[0];
564 		line = ArgList[1];
565 	}
566 	whois_stuff = get_server_whois_stuff(parsing_server_index);
567 	if ((ptr = whois_queue_head(parsing_server_index))
568 	 && (whois_type_head(parsing_server_index) & (WHOIS_WHOIS|WHOIS_ISON2))
569 	 && whois_stuff->nick && /* This is *weird* */
570 	(my_stricmp(ptr, whois_stuff->nick) == 0))
571 	{
572 		malloc_strcpy(&whois_stuff->server, server);
573 		malloc_strcpy(&whois_stuff->server_stuff, line);
574 	}
575 	else
576 	{
577 		if (do_hook(current_numeric, "%s %s %s", from, server, line))
578 /**************************** PATCHED by Flier ******************************/
579 			/*put_it("%s on irc via server %s (%s)",
580 				numeric_banner(), server, line);*/
581                         PrintWhoIsServer(numeric_banner(),server,line);
582 /****************************************************************************/
583 	}
584 }
585 
586 /*
587  * whois_oper: This displays the operator status of a user, as returned by
588  * numeric 313 from the server.  If the ignore_whois_crap flag is set,
589  * nothing is dispayed.
590  */
591 void
whois_oper(from,ArgList)592 whois_oper(from, ArgList)
593 	char	*from;
594 	char	**ArgList;
595 {
596 	WhoisStuff *whois_stuff;
597 
598 	whois_stuff = get_server_whois_stuff(parsing_server_index);
599 	PasteArgs(ArgList, 1);
600 	if (ignore_whois_crap)
601 		whois_stuff->oper = 1;
602 	else
603 	{
604 		char	*nick;
605 
606 		if ((nick = ArgList[0]) != NULL)
607 		{
608 			if (do_hook(current_numeric, "%s %s %s", from, nick,
609 					ArgList[1]))
610 /**************************** PATCHED by Flier ******************************/
611 				/*put_it("%s %s %s%s", numeric_banner(), nick,
612  					ArgList[1], (get_server_version(parsing_server_index) >
613 					Server2_7) ? empty_string
614 						   : " (is an IRC operator)");*/
615 #ifdef WANTANSI
616 #ifdef GENX
617                                 put_it("%s�    %sircop%s � %s %s",numeric_banner(),
618                                        CmdsColors[COLWHOIS].color5,Colors[COLOFF],nick,
619                                        ArgList[1]);
620 #elif defined(CELECOSM)
621                                 put_it("%s%sircop%s:      %s %s",
622                                        numeric_banner(),CmdsColors[COLWHOIS].color5,
623                                        Colors[COLOFF],nick,ArgList[1]);
624 #else
625                                 put_it("%s%sIrcOp%s     : %s %s",
626                                        numeric_banner(),CmdsColors[COLWHOIS].color5,
627                                        Colors[COLOFF],nick,ArgList[1]);
628 #endif
629 #else
630                                 put_it("%sIrcOp     : %s %s",
631                                        numeric_banner(),nick,ArgList[1]);
632 #endif
633 /****************************************************************************/
634 		}
635 	}
636 }
637 
638 /**************************** Patched by Flier ******************************/
639 /* by braneded */
whois_admin(from,ArgList)640 void whois_admin(from,ArgList)
641 char *from;
642 char **ArgList;
643 {
644     if (!ignore_whois_crap) {
645         char *nick;
646 
647         nick=ArgList[0];
648         if (nick) {
649             if (do_hook(current_numeric,"%s %s %s",from,nick,ArgList[1])) {
650 #ifdef WANTANSI
651 #ifdef GENX
652                 put_it("%s�    %sadmin%s � %s %s",
653                        numeric_banner(),CmdsColors[COLWHOIS].color5,
654                        Colors[COLOFF],nick,ArgList[1]);
655 #elif defined(CELECOSM)
656                 put_it("%s%sadmin%s:      %s %s",
657                        numeric_banner(),CmdsColors[COLWHOIS].color5,
658                        Colors[COLOFF],nick,ArgList[1]);
659 #else  /* CELECOSM */
660                 put_it("%s%sAdmin%s     : %s %s",
661                        numeric_banner(),CmdsColors[COLWHOIS].color5,
662                        Colors[COLOFF],nick,ArgList[1]);
663 #endif /* GENX */
664 #else  /* WANTANSI */
665                 put_it("%sAdmin     : %s %s",
666                        numeric_banner(),nick,ArgList[1]);
667 #endif /* WANTANSI */
668             }
669         }
670     }
671 }
672 
673 /* by flashback */
whois_secure(from,ArgList)674 void whois_secure(from,ArgList)
675     char *from;
676     char **ArgList;
677 {
678     if (!ignore_whois_crap) {
679         char *nick;
680 
681         nick = ArgList[0];
682         if (nick) {
683             if (do_hook(current_numeric, "%s %s %s", from, nick, ArgList[1])) {
684 #ifdef WANTANSI
685 #ifdef GENX
686                 put_it("%s�    %ssecure%s � %s %s",
687                        numeric_banner(), CmdsColors[COLWHOIS].color5,
688                        Colors[COLOFF], nick, ArgList[1]);
689 #elif defined(CELECOSM)
690                 put_it("%s%ssecure%s:     %s %s",
691                        numeric_banner(), CmdsColors[COLWHOIS].color5,
692                        Colors[COLOFF], nick, ArgList[1]);
693 #else  /* CELECOSM */
694                 put_it("%s%sSecure%s    : %s %s",
695                        numeric_banner(), CmdsColors[COLWHOIS].color5,
696                        Colors[COLOFF], nick, ArgList[1]);
697 #endif /* GENX */
698 #else  /* WANTANSI */
699                 put_it("%sSecure    : %s %s",
700                        numeric_banner(), nick, ArgList[1]);
701 #endif /* WANTANSI */
702             }
703         }
704     }
705 }
706 
707 /* by braneded */
whois_identified(from,ArgList)708 void whois_identified(from,ArgList)
709 char *from;
710 char **ArgList;
711 {
712     if (!ignore_whois_crap) {
713         char *nick;
714 
715         nick = ArgList[0];
716         if (nick) {
717             if (do_hook(current_numeric, "%s %s %s", from, nick, ArgList[1])) {
718 #ifdef WANTANSI
719 #ifdef GENX
720                 put_it("%s�    %sident%s � %s %s",
721                        numeric_banner(), CmdsColors[COLWHOIS].color5,
722                        Colors[COLOFF], nick, ArgList[1]);
723 #elif defined(CELECOSM)
724                 put_it("%s%sident%s:      %s %s",
725                        numeric_banner(), CmdsColors[COLWHOIS].color5,
726                        Colors[COLOFF], nick, ArgList[1]);
727 #else  /* CELECOSM */
728                 put_it("%s%sIdentified%s: %s %s",
729                        numeric_banner(), CmdsColors[COLWHOIS].color5,
730                        Colors[COLOFF], nick, ArgList[1]);
731 #endif /* GENX */
732 #else  /* WANTANSI */
733                 put_it("%sIdentified: %s %s",
734                        numeric_banner(), nick, ArgList[1]);
735 #endif /* WANTANSI */
736             }
737         }
738     }
739 }
740 
whois_actually(from,ArgList)741 void whois_actually(from,ArgList)
742 char *from;
743 char **ArgList;
744 {
745     if (!ignore_whois_crap) {
746         char *nick;
747         char *ip;
748 
749         nick = ArgList[0];
750         ip = ArgList[1];
751         if (nick && ip) {
752             if (do_hook(current_numeric, "%s %s %s", from, nick, ip)) {
753 #ifdef WANTANSI
754 #ifdef GENX
755                 put_it("%s� %sactually%s � %s%s%s",
756                        numeric_banner(), CmdsColors[COLWHOIS].color5, Colors[COLOFF],
757                        CmdsColors[COLWHOIS].color5, ip, Colors[COLOFF]);
758 #elif defined(CELECOSM)
759                 put_it("%s%sactually%s:   %s%s%s",
760                        numeric_banner(), CmdsColors[COLWHOIS].color5, Colors[COLOFF],
761                        CmdsColors[COLWHOIS].color5, ip, Colors[COLOFF]);
762 #else  /* CELECOSM */
763                 put_it("%s%sActually%s  : %s%s%s",
764                        numeric_banner(), CmdsColors[COLWHOIS].color5, Colors[COLOFF],
765                        CmdsColors[COLWHOIS].color5, ip, Colors[COLOFF]);
766 #endif /* GENX */
767 #else  /* WANTANSI */
768                 put_it("%sActually:   %s",
769                       numeric_banner(), ip);
770 #endif /* WANTANSI */
771             }
772         }
773     }
774 }
775 
whois_connecting(from,ArgList)776 void whois_connecting(from, ArgList)
777 char *from;
778 char **ArgList;
779 {
780     if (!ignore_whois_crap) {
781         char *str;
782         char *host = NULL;
783         char *ip = NULL;
784         char tmpbuf[mybufsize];
785 
786         str = ArgList[1];
787         strmcpy(tmpbuf, str, sizeof(tmpbuf));
788         if ((str = strstr(tmpbuf, " connecting from "))) {
789             str++;
790             str = index(str, ' ');
791             if (str) {
792                 str++;
793                 host = index(str, ' ');
794                 if (host) {
795                     host++;
796                     ip = index(host, ' ');
797                     if (ip) *ip++ = '\0';
798                 }
799             }
800         }
801         if (host && ip) {
802             if (do_hook(current_numeric, "%s %s %s", from, host, ip)) {
803 #ifdef WANTANSI
804 #ifdef GENX
805                 put_it("%s�%sconnecting%s� %s%s %s%s",
806                        numeric_banner(), CmdsColors[COLWHOIS].color5, Colors[COLOFF],
807                        CmdsColors[COLWHOIS].color2, host, ip, Colors[COLOFF]);
808 #elif defined(CELECOSM)
809                 put_it("%s%sconnecting%s:   %s%s %s%s",
810                        numeric_banner(), CmdsColors[COLWHOIS].color5, Colors[COLOFF],
811                        CmdsColors[COLWHOIS].color2, host, ip, Colors[COLOFF]);
812 #else  /* CELECOSM */
813                 put_it("%s%sConnecting%s: %s%s %s%s",
814                        numeric_banner(), CmdsColors[COLWHOIS].color5, Colors[COLOFF],
815                        CmdsColors[COLWHOIS].color2, host, ip, Colors[COLOFF]);
816 #endif /* GENX */
817 #else  /* WANTANSI */
818                 put_it("%sConnecting:   %s %s",
819                       numeric_banner(), host, ip);
820 #endif /* WANTANSI */
821             }
822         }
823     }
824 }
825 /****************************************************************************/
826 
827 void
whois_lastcom(from,ArgList)828 whois_lastcom(from, ArgList)
829 	char	*from;
830 	char	**ArgList;
831 {
832 	if (!ignore_whois_crap)
833 	{
834 		char	flag, *nick, *idle_str;
835 		int	idle;
836 /**************************** PATCHED by Flier ******************************/
837                 int     signedon=1;
838                 int     days;
839                 int     hours;
840                 int     mins;
841                 int     secs;
842                 char    tmpbuf[mybufsize/4];
843                 time_t  origidle;
844                 time_t  signontime;
845 
846                 for (nick=ArgList[2];nick && *nick;nick++)
847                     signedon&=(*nick>='0' && *nick<='9');
848                 if (signedon) {
849                     signontime=atoi(ArgList[2]);
850 #ifdef WANTANSI
851 #ifdef GENX
852                     snprintf(tmpbuf,sizeof(tmpbuf),"%ssigned on: %.16s",
853                             numeric_banner(),ctime(&signontime));
854 #elif defined(CELECOSM)
855                     snprintf(tmpbuf,sizeof(tmpbuf),"%s%ssignon%s:     %.24s",
856                             numeric_banner(),CmdsColors[COLWHOIS].color5,Colors[COLOFF],
857                             ctime(&signontime));
858 #else  /* CELE */
859                     snprintf(tmpbuf,sizeof(tmpbuf),"%s%sSignOn%s    : %.24s",
860                             numeric_banner(),CmdsColors[COLWHOIS].color5,Colors[COLOFF],
861                             ctime(&signontime));
862 #endif /* GENX */
863 #else  /* WANTANSI */
864                     snprintf(tmpbuf,sizeof(tmpbuf),"%sSignOn    : %.24s",
865                             numeric_banner(),ctime(&signontime));
866 #endif /* WANTANSI */
867                 }
868 /****************************************************************************/
869 
870 		PasteArgs(ArgList, 2);
871 		if ((nick = ArgList[0]) && (idle_str = ArgList[1]) &&
872 				do_hook(current_numeric, "%s %s %s %s", from,
873 					nick, idle_str, ArgList[2]))
874 		{
875 			if ((idle = atoi(idle_str)) > 59)
876 			{
877 /**************************** PATCHED by Flier ******************************/
878                                 origidle=idle;
879 /****************************************************************************/
880 				idle = idle/60;
881 				flag = 1;
882 			}
883 			else
884 /**************************** PATCHED by Flier ******************************/
885 				/*flag = 0;
886 			put_it("%s %s has been idle %d %ss", numeric_banner(),
887 				nick, idle, flag? "minute": "second");*/
888                         {
889 				flag = 0;
890                                 origidle=idle;
891                         }
892                         days=(origidle/86400);
893                         hours=((origidle-(days*86400))/3600);
894                         mins=((origidle-(days*86400)-(hours*3600))/60);
895                         secs=(origidle-(days*86400)-(hours*3600)-(mins*60));
896 #ifdef WANTANSI
897 #ifdef GENX
898                         if (signedon)
899                             put_it("%s�     %sidle%s � %dd %dh %dm %ds (%s)",
900                                    numeric_banner(),
901                                    CmdsColors[COLWHOIS].color5,Colors[COLOFF],
902                                    days,hours,mins,secs,tmpbuf);
903                         else put_it("%s�     %sidle%s � %dd %dh %dm %ds",
904                                     numeric_banner(),
905                                     CmdsColors[COLWHOIS].color5,Colors[COLOFF],
906                                     days,hours,mins,secs);
907 #elif defined(CELECOSM)
908                         if (signedon)
909                             put_it("%s    %sidle%s: %dd %dh %dm %ds",
910                                    tmpbuf,CmdsColors[COLWHOIS].color5,Colors[COLOFF],
911                                    days,hours,mins,secs);
912                         else put_it("%s%sdead%s:       %dd %dh %dm %ds",
913                                     numeric_banner(),CmdsColors[COLWHOIS].color5,Colors[COLOFF],
914                                     days,hours,mins,secs);
915 #else  /* CELECOSM */
916                         if (signedon)
917                             put_it("%s    %sIdle%s : %dd %dh %dm %ds",
918                                    tmpbuf,CmdsColors[COLWHOIS].color5,Colors[COLOFF],
919                                    days,hours,mins,secs);
920                         else put_it("%s%sIdle%s      : %dd %dh %dm %ds",
921                                     numeric_banner(),CmdsColors[COLWHOIS].color5,Colors[COLOFF],
922                                     days,hours,mins,secs);
923 #endif /* GENX */
924 #else  /* WANTANSI */
925                         if (signedon) put_it("%s    Idle : %dd %dh %dm %ds",
926                                              tmpbuf,days,hours,mins,secs);
927                         else put_it("%sIdle      : %dd %dh %dm %ds",
928                                     numeric_banner(),days,hours,mins,secs);
929 #endif /* WANTANSI */
930 /****************************************************************************/
931 		}
932 	}
933 }
934 
935 /*
936  * whois_chop: This displays the operator status of a user, as returned by
937  * numeric 313 from the server.  If the ignore_whois_crap flag is set,
938  * nothing is dispayed.
939  */
940 void
whois_chop(from,ArgList)941 whois_chop(from, ArgList)
942 	char	*from;
943 	char	**ArgList;
944 {
945 	WhoisStuff *whois_stuff;
946 
947 	whois_stuff = get_server_whois_stuff(parsing_server_index);
948 	PasteArgs(ArgList, 1);
949 	if (ignore_whois_crap)
950 		whois_stuff->chop = 1;
951 	else
952 	{
953 		char	*nick;
954 
955 		if ((nick = ArgList[0]) != NULL)
956 		{
957 			if (do_hook(current_numeric, "%s %s %s",from, nick,
958 					ArgList[1]))
959 /**************************** Patched by Flier ******************************/
960 				/*put_it("%s %s (is a channel operator)",*/
961 				put_it("%s%s (is a channel operator)",
962 /****************************************************************************/
963 					numeric_banner(), nick, ArgList[1]);
964 		}
965 	}
966 }
967 
968 void
end_of_whois(from,ArgList)969 end_of_whois(from, ArgList)
970 	char	*from;
971 	char	**ArgList;
972 {
973 	char	*nick;
974 	char	*ptr;
975 	WhoisStuff *whois_stuff;
976 /**************************** PATCHED by Flier ******************************/
977 #ifdef CELECOSM
978         char tmpbuf[mybufsize/4];
979 #endif
980 /****************************************************************************/
981 
982 	whois_stuff = get_server_whois_stuff(parsing_server_index);
983 
984 	show_away_flag = 0;
985 	set_server_whois(parsing_server_index,1);
986 	if ((nick = ArgList[0]) != NULL)
987 	{
988 		ptr = whois_queue_head(parsing_server_index);
989 		if (ptr && (whois_type_head(parsing_server_index) & (WHOIS_WHOIS|WHOIS_ISON2)) && (my_stricmp(ptr, nick) == 0))
990 		{
991 			WhoisQueue *thing;
992 
993 			thing = remove_from_whois_queue(parsing_server_index);
994 			whois_stuff->not_on = 0;
995 			thing->func(whois_stuff, thing->nick, thing->text);
996 			new_free(&whois_stuff->channels);
997 			new_free(&thing->nick);
998 			new_free(&thing->text);
999 			new_free(&thing);
1000 			ignore_whois_crap = 0;
1001 			return;
1002 		}
1003 		PasteArgs(ArgList, 0);
1004 		if (do_hook(current_numeric, "%s %s", from, ArgList[0]))
1005 			if (get_int_var(SHOW_END_OF_MSGS_VAR))
1006 				display_msg(from, ArgList);
1007 	}
1008 /**************************** PATCHED by Flier ******************************/
1009 #ifdef CELECOSM
1010     if (whoisfriend && whoisfriend->privs) {
1011         snprintf(tmpbuf,sizeof(tmpbuf),"%sfriend%s:     filter %s%s%s | flags %s",
1012                 CmdsColors[COLWHOIS].color5,Colors[COLOFF],
1013                 CmdsColors[COLWHOIS].color4,whoisfriend->userhost,Colors[COLOFF],
1014                 CmdsColors[COLWHOIS].color4);
1015         BuildPrivs(whoisfriend,tmpbuf);
1016         say("%s%s on %s%s%s",tmpbuf,Colors[COLOFF],
1017             CmdsColors[COLWHOIS].color6,whoisfriend->channels,Colors[COLOFF]);
1018     }
1019 #endif
1020 /****************************************************************************/
1021 }
1022 
1023 /*
1024  * no_such_nickname: Handler for numeric 401, the no such nickname error. If
1025  * the nickname given is at the head of the queue, then this routine pops the
1026  * top element from the queue, sets the whois_stuff->flag to indicate that the
1027  * user is no longer on irc, then calls the func() as normal.  It is up to
1028  * that function to set the ignore_whois_crap variable which will determine
1029  * if any other information is displayed or not.
1030  *
1031  * that is, it used to.  now it does bugger all, seeing all the functions that
1032  * used to use it, now use no such command.  -phone, april 1993.
1033  */
1034 /*ARGSUSED*/
1035 void
1036 /**************************** PATCHED by Flier ******************************/
1037 /*no_such_nickname(from, ArgList)*/
no_such_nickname(from,ArgList,dontshow)1038 no_such_nickname(from,ArgList,dontshow)
1039 /****************************************************************************/
1040 	char	*from,
1041 		**ArgList;
1042 /**************************** PATCHED by Flier ******************************/
1043         int     dontshow;
1044 /****************************************************************************/
1045 {
1046 	char	*nick;
1047 	char		*ptr;
1048 	WhoisStuff	*whois_stuff;
1049 
1050 	whois_stuff = get_server_whois_stuff(parsing_server_index);
1051 	ptr = whois_queue_head(parsing_server_index);
1052 	PasteArgs(ArgList, 1);
1053 	nick = ArgList[0];
1054 	if (*nick == '!')
1055 	{
1056 		char	*name = nick+1;
1057 
1058 		if (ptr && (whois_type_head(parsing_server_index) & (WHOIS_WHOIS|WHOIS_ISON2)) && !strcmp(ptr, name))
1059 		{
1060 			WhoisQueue *thing;
1061 
1062 			/* There's a query in the WhoisQueue : assume it's
1063 			   completed and remove it from the queue -Sol */
1064 
1065 			thing = remove_from_whois_queue(parsing_server_index);
1066 			whois_stuff->not_on = 0;
1067 			thing->func(whois_stuff, thing->nick, thing->text);
1068 			new_free(&whois_stuff->channels);
1069 			new_free(&thing->nick);
1070 			new_free(&thing->text);
1071 			new_free(&thing);
1072 			ignore_whois_crap = 0;
1073 			return;
1074 		}
1075 		return;
1076 	}
1077 	notify_mark(nick, 0, 0);
1078 	if (ptr && (whois_type_head(parsing_server_index) == WHOIS_ISON2) &&
1079 	    !strcmp(ptr, nick))
1080 	{
1081 		WhoisQueue *thing;
1082 
1083 		/* Remove query from queue. Don't display anything. -Sol */
1084 
1085 		thing = remove_from_whois_queue(parsing_server_index);
1086 		new_free(&whois_stuff->channels);
1087 		new_free(&thing->nick);
1088 		new_free(&thing->text);
1089 		new_free(&thing);
1090 		ignore_whois_crap = 0;
1091 		return;
1092 	}
1093 /**************************** PATCHED by Flier ******************************/
1094         if (dontshow) {
1095             WhoisQueue *thing;
1096 
1097             if (ptr && (whois_type_head(parsing_server_index)&(WHOIS_WHOIS|WHOIS_ISON2)) && !strcmp(ptr,nick)) {
1098                 thing=remove_from_whois_queue(parsing_server_index);
1099                 whois_stuff->not_on=0;
1100                 if (thing->func)
1101                     thing->func(whois_stuff,thing->nick,thing->text);
1102                 new_free(&whois_stuff->channels);
1103                 new_free(&thing->nick);
1104                 new_free(&thing->text);
1105                 new_free(&thing);
1106             }
1107         }
1108         else {
1109 /****************************************************************************/
1110 	    if (do_hook(current_numeric, "%s %s %s", from, nick, ArgList[1]))
1111 /**************************** Patched by Flier ******************************/
1112 		/*put_it("%s %s: %s", numeric_banner(), nick, ArgList[1]);*/
1113 		put_it("%s%s: %s", numeric_banner(), nick, ArgList[1]);
1114 /****************************************************************************/
1115 	    if ((get_server_version(parsing_server_index) > Server2_5) &&
1116 	        get_int_var(AUTO_WHOWAS_VAR))
1117 		    send_to_server("WHOWAS %s", nick);
1118 /**************************** PATCHED by Flier ******************************/
1119         }
1120 /****************************************************************************/
1121 }
1122 
1123 /*
1124  * user_is_away: called when a 301 numeric is received.  Nothing is displayed
1125  * by this routine if the ignore_whois_crap flag is set
1126  */
1127 /*ARGSUSED*/
1128 void
user_is_away(from,ArgList)1129 user_is_away(from, ArgList)
1130 	char	*from,
1131 		**ArgList;
1132 {
1133 	static	char	*last_away_msg = (char *) 0,
1134 			*last_away_nick = (char *) 0;
1135 	char	*message,
1136 		*who;
1137 	WhoisStuff *whois_stuff;
1138 
1139 if (!from)
1140 	return;
1141 
1142 	PasteArgs(ArgList, 1);
1143 	whois_stuff = get_server_whois_stuff(parsing_server_index);
1144 
1145 	if ((who = ArgList[0]) && (message = ArgList[1]))
1146 	{
1147 		if (whois_stuff->nick && (!strcmp(who, whois_stuff->nick)) &&
1148 				eat_away)
1149 			malloc_strcpy(&whois_stuff->away, message);
1150 		else
1151 		{
1152 			if (!show_away_flag && get_int_var(SHOW_AWAY_ONCE_VAR))
1153 			{
1154 				if (!last_away_msg || strcmp(last_away_nick,
1155 					from) || strcmp(last_away_msg, message))
1156 				{
1157 					malloc_strcpy(&last_away_nick, from);
1158 					malloc_strcpy(&last_away_msg, message);
1159 				}
1160 				else return;
1161 			}
1162 			if (do_hook(current_numeric, "%s %s", who, message))
1163 /**************************** PATCHED by Flier ******************************/
1164 				/*put_it("%s %s is away: %s",numeric_banner(),
1165 					who, message);*/
1166 #ifdef WANTANSI
1167 #ifdef GENX
1168                                 put_it("%s�     %saway%s � (%s) %s",numeric_banner(),
1169                                         CmdsColors[COLWHOIS].color5,Colors[COLOFF],
1170                                         who,message);
1171 #elif defined(CELECOSM)
1172                                 put_it("%s%saway%s:       (%s) %s",
1173                                        numeric_banner(),
1174                                        CmdsColors[COLWHOIS].color5,Colors[COLOFF],
1175                                        who,message);
1176 #else  /* CELECOSM */
1177                                 put_it("%s%sSetAway%s   : (%s) %s",
1178                                        numeric_banner(),
1179                                        CmdsColors[COLWHOIS].color5,Colors[COLOFF],
1180                                        who,message);
1181 #endif /* GENX */
1182 #else  /* WANTANSI */
1183                                 put_it("%sSetAway   : (%s) %s",
1184                                        numeric_banner(),who,message);
1185 #endif /* WANTANSI */
1186 /***************************************************************************/
1187 		}
1188 		eat_away = 0;
1189 	}
1190 }
1191 
1192 /*
1193  * The stuff below this point are all routines suitable for use in the
1194  * add_to_whois_queue() call as the func parameter
1195  */
1196 
1197 /*
1198  * whois_ignore_msgs: This is used when you are ignoring MSGs using the
1199  * user@hostname format
1200  */
1201 void
whois_ignore_msgs(stuff,nick,text)1202 whois_ignore_msgs(stuff, nick, text)
1203 	WhoisStuff *stuff;
1204 	char	*nick;
1205 	char	*text;
1206 {
1207 	char	*ptr;
1208 	int	level;
1209 
1210 	if (stuff)
1211 	{
1212 		ptr = (char *) new_malloc(strlen(stuff->user) +
1213 			strlen(stuff->host) + 2);
1214 		strcpy(ptr, stuff->user);
1215 		strcat(ptr, "@");
1216 		strcat(ptr, stuff->host);
1217 		if (is_ignored(ptr, IGNORE_MSGS) != IGNORED)
1218 		{
1219  			save_message_from();
1220 			level = set_lastlog_msg_level(LOG_MSG);
1221 			message_from(stuff->nick, LOG_MSG);
1222 			if (sed == 1 && !do_hook(ENCRYPTED_PRIVMSG_LIST,"%s %s", stuff->nick,text))
1223 			{
1224 				set_lastlog_msg_level(level);
1225  				restore_message_from();
1226 				return;
1227 			}
1228 			if (do_hook(MSG_LIST, "%s %s", stuff->nick, text))
1229 			{
1230 				if (away_set)
1231 				{
1232 					time_t	t;
1233 					char	*msg = (char *) 0;
1234 					size_t len = strlen(text) + 20;
1235 
1236 					t = time(0);
1237 					msg = (char *) new_malloc(len);
1238 					snprintf(msg, len, "%s <%.16s>", text,
1239 						ctime(&t));
1240 					put_it("*%s* %s", stuff->nick, msg);
1241 					new_free(&msg);
1242 					beep_em(get_int_var(BEEP_WHEN_AWAY_VAR));
1243 				}
1244 				else
1245 				{
1246 					put_it("*%s* %s", stuff->nick, text);
1247 					beep_em(get_int_var(BEEP_ON_MSG_VAR));
1248 				}
1249 			}
1250 			if (beep_on_level & LOG_MSG)
1251 				beep_em(1);
1252 			set_lastlog_msg_level(level);
1253 			message_from((char *) 0, LOG_CURRENT);
1254 			notify_mark(nick, 1, 0);
1255 		}
1256 		else
1257 			send_to_server("NOTICE %s :%s is ignoring you.",
1258 				nick, get_server_nickname(parsing_server_index));
1259 		new_free(&ptr);
1260 	}
1261  	restore_message_from();
1262 }
1263 
1264 /*ARGSUSED*/
1265 void
whois_nickname(stuff,nick,text)1266 whois_nickname(stuff,nick,text)
1267 	WhoisStuff *stuff;
1268 	char	*nick;
1269 	char	*text;
1270 {
1271 	if (stuff)
1272 	{
1273 		if (!(my_stricmp(stuff->user,username)) &&
1274 				(!my_stricmp(stuff->host,hostname)))
1275 			set_server_nickname(parsing_server_index,nick);
1276 	}
1277 }
1278 
1279 /*
1280  * whois_ignore_notices: This is used when you are ignoring NOTICEs using the
1281  * user@hostname format
1282  */
1283 /*ARGSUSED*/
1284 void
whois_ignore_notices(stuff,nick,text)1285 whois_ignore_notices(stuff, nick, text)
1286 	WhoisStuff *stuff;
1287 	char	*nick;
1288 	char	*text;
1289 {
1290 	char	*ptr;
1291 	int	level;
1292 
1293 	if (stuff)
1294 	{
1295 		ptr = (char *) new_malloc(strlen(stuff->user) +
1296 			strlen(stuff->host) + 2);
1297 		strcpy(ptr, stuff->user);
1298 		strcat(ptr, "@");
1299 		strcat(ptr, stuff->host);
1300 		if (is_ignored(ptr, IGNORE_NOTICES) != IGNORED)
1301 		{
1302 			level = set_lastlog_msg_level(LOG_NOTICE);
1303  			save_message_from();
1304 			message_from(stuff->nick, LOG_NOTICE);
1305 			if (sed == 0 && !do_hook(ENCRYPTED_NOTICE_LIST,"%s %s", stuff->nick, text))
1306 			{
1307  				restore_message_from();
1308 				return;
1309 			}
1310 			if (do_hook(NOTICE_LIST, "%s %s", stuff->nick, text))
1311 				put_it("-%s- %s", stuff->nick, text);
1312 			set_lastlog_msg_level(level);
1313  			restore_message_from();
1314 		}
1315 		new_free(&ptr);
1316 	}
1317 }
1318 
1319 /*
1320  * whois_ignore_invites: This is used when you are ignoring INVITES using the
1321  * user@hostname format
1322  */
1323 void
whois_ignore_invites(stuff,nick,text)1324 whois_ignore_invites(stuff, nick, text)
1325 	WhoisStuff *stuff;
1326 	char	*nick;
1327 	char	*text;
1328 {
1329 	char	*ptr;
1330 
1331 	if (stuff)
1332 	{
1333 		ptr = (char *) new_malloc(strlen(stuff->user) +
1334 			strlen(stuff->host) + 2);
1335 		strcpy(ptr, stuff->user);
1336 		strcat(ptr, "@");
1337 		strcat(ptr, stuff->host);
1338 		if (is_ignored(ptr, IGNORE_INVITES) != IGNORED)
1339 		{
1340 			if (do_hook(INVITE_LIST, "%s %s", stuff->nick, text))
1341 				say("%s invites you to channel %s",
1342 					stuff->nick, text);
1343 			malloc_strcpy(&invite_channel, text);
1344 		}
1345 		else
1346 			send_to_server("NOTICE %s :%s is ignoring you.",
1347 				nick, get_server_nickname(parsing_server_index));
1348 		new_free(&ptr);
1349 	}
1350 }
1351 
1352 /*
1353  * whois_ignore_walls: This is used when you are ignoring WALLS using the
1354  * user@hostname format
1355  */
1356 /*ARGSUSED*/
1357 void
whois_ignore_walls(stuff,nick,text)1358 whois_ignore_walls(stuff, nick, text)
1359 	WhoisStuff *stuff;
1360 	char	*nick;
1361 	char	*text;
1362 {
1363 	char	*ptr;
1364 	int	level;
1365 
1366 	level = set_lastlog_msg_level(LOG_WALL);
1367  	save_message_from();
1368 	message_from(stuff->nick, LOG_WALL);
1369 	if (stuff)
1370 	{
1371 		ptr = (char *) new_malloc(strlen(stuff->user) +
1372 			strlen(stuff->host) + 2);
1373 		strcpy(ptr, stuff->user);
1374 		strcat(ptr, "@");
1375 		strcat(ptr, stuff->host);
1376 		if (is_ignored(ptr, IGNORE_WALLS) != IGNORED)
1377 		{
1378 			if (do_hook(WALL_LIST, "%s %s", stuff->nick, text))
1379 				put_it("#%s# %s", stuff->nick, text);
1380 			if (beep_on_level & LOG_WALL)
1381 				beep_em(1);
1382 		}
1383 		new_free(&ptr);
1384 	}
1385 /**************************** PATCHED by Flier ******************************/
1386 	/*set_lastlog_msg_level(level);
1387  	save_message_from();*/
1388  	restore_message_from();
1389 	set_lastlog_msg_level(level);
1390 /****************************************************************************/
1391 }
1392 
1393 void
convert_to_whois()1394 convert_to_whois()
1395 {
1396 	char	*NextAsked;
1397 	char	*Names;
1398 	WhoisQueue *thing;
1399 	void	(*func) _((WhoisStuff *, char *, char *));
1400 
1401 	if (!(whois_type_head(parsing_server_index) & (WHOIS_USERHOST|WHOIS_WHOIS|WHOIS_ISON2)))
1402 	{
1403 		say("Server does not support USERHOST");
1404 		return; /* USERHOST sent interactively. */
1405 	}
1406 	thing = remove_from_whois_queue(parsing_server_index);
1407 	switch(thing->type)
1408 	{
1409 	case WHOIS_ISON:
1410 		Names = thing->nick;
1411 		while ( (NextAsked = next_arg(Names, &Names)))
1412 		{
1413 			if (thing->func == ison_notify)
1414 			{
1415 				func = (void (*) _((WhoisStuff *, char *, char *))) whois_notify;
1416 				add_to_whois_queue(NextAsked, func, "%s", NextAsked);
1417 			}
1418 			else
1419 				say("Server does not support ISON");
1420 		}
1421 		break;
1422 	case WHOIS_USERHOST:
1423 		add_to_whois_queue(thing->nick, thing->func, "%s", thing->text);
1424 		break;
1425 	}
1426 	new_free(&thing->nick);
1427 	new_free(&thing->text);
1428 	new_free(&thing);
1429 }
1430 
1431 void
ison_notify(unused,AskedFor,AreOn)1432 ison_notify(unused, AskedFor, AreOn)
1433 	WhoisStuff *unused;
1434 	char	*AskedFor;
1435 	char	*AreOn;
1436 {
1437 	char	*NextAsked;
1438 	char	*NextGot;
1439 
1440 	NextGot = next_arg(AreOn, &AreOn);
1441 	while ((NextAsked = next_arg(AskedFor, &AskedFor)) != NULL)
1442 	{
1443 		if (NextGot && !my_stricmp(NextAsked, NextGot))
1444 		{
1445 			notify_mark(NextAsked, 1, 1);
1446 			NextGot = next_arg(AreOn, &AreOn);
1447 		}
1448 		else
1449 			notify_mark(NextAsked, 0, 1);
1450 	}
1451 }
1452 
1453 /*
1454  * whois_notify: used by the routines in notify.c to tell when someone has
1455  * signed on or off irc
1456  */
1457 /*ARGSUSED*/
1458 void
whois_notify(stuff,nick,text)1459 whois_notify(stuff, nick, text)
1460 	WhoisStuff *stuff;
1461 	char	*nick;
1462 	char	*text;
1463 {
1464 	int	level;
1465 
1466 	level = set_lastlog_msg_level(LOG_CRAP);
1467 	if (stuff)
1468 		notify_mark(stuff->nick, 1, 1);
1469 	else
1470 		notify_mark(nick, 0, 1);
1471 	set_lastlog_msg_level(level);
1472 }
1473 
1474 void
whois_new_wallops(stuff,nick,text)1475 whois_new_wallops(stuff, nick, text)
1476 	WhoisStuff *stuff;
1477 	char	*nick;
1478 	char	*text;
1479 {
1480 	int	flag,
1481 	level;
1482 	char	*high;
1483 
1484 	flag = is_ignored(nick, IGNORE_WALLOPS);
1485 	if (flag != IGNORED)
1486 	{
1487 		if (flag == HIGHLIGHTED)
1488 			high = &highlight_char;
1489 		else
1490 			high = empty_string;
1491 		if (stuff && (ignore_usernames & IGNORE_WALLOPS))
1492 		{
1493 			char	*ptr;
1494 
1495 			ptr = (char *) new_malloc(strlen(stuff->user) +
1496 				strlen(stuff->host) + 2);
1497 			strcpy(ptr, stuff->user);
1498 			strcat(ptr, "@");
1499 			strcat(ptr, stuff->host);
1500 			if (is_ignored(ptr, IGNORE_WALLOPS) == IGNORED)
1501 			{
1502 				new_free(&ptr);
1503 				return;
1504 			}
1505 			new_free(&ptr);
1506 		}
1507  		save_message_from();
1508 		message_from(nick, LOG_WALLOP);
1509 		level = set_lastlog_msg_level(LOG_WALLOP);
1510 		if (stuff)
1511 		{
1512 			if (do_hook(WALLOP_LIST, "%s %s %s", nick,
1513 					(stuff->oper ? "+" : "-"), text))
1514 				put_it("%s!%s%s!%s %s", high, nick,
1515 					stuff->oper ? "*" : empty_string,
1516 					high, text);
1517 		}
1518 		else
1519 		{
1520 			if (do_hook(WALLOP_LIST, "%s - %s", nick, text))
1521 				put_it("%s!%s!%s %s", high, nick, high, text);
1522 		}
1523 		if (beep_on_level & LOG_WALLOP)
1524 			beep_em(1);
1525 		set_lastlog_msg_level(level);
1526  		restore_message_from();
1527 	}
1528 }
1529 
1530 /* I put the next routine down here to keep my compile quiet */
1531 
1532 /*
1533  * add_to_whois_queue: This routine is called whenever you want to do a WHOIS
1534  * or WHOWAS.  What happens is this... each time this function is called it
1535  * adds a new element to the whois queue using the nick and func as in
1536  * WhoisQueue, and creating the text element using the format and args.  It
1537  * then issues the WHOIS or WHOWAS.
1538  */
1539 void
1540 #ifdef HAVE_STDARG_H
add_to_whois_queue(char * nick,void (* func)_ ((WhoisStuff *,char *,char *)),char * format,...)1541 add_to_whois_queue(char *nick, void (*func) _((WhoisStuff *, char *, char *)), char *format, ...)
1542 #else
1543 add_to_whois_queue(nick, func, format, arg1, arg2,
1544 		arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
1545 	void	(*func) _((WhoisStuff *, char *, char *));
1546 	char	*format,
1547 		*nick;
1548 	char	*arg1,
1549 		*arg2,
1550 		*arg3,
1551 		*arg4,
1552 		*arg5,
1553 		*arg6,
1554 		*arg7,
1555 		*arg8,
1556 		*arg9,
1557 		*arg10;
1558 #endif
1559 {
1560 	int	Type;
1561 #ifdef HAVE_STDARG_H
1562 	va_list	vlist;
1563 
1564 	va_start(vlist, format);
1565 #endif
1566 
1567 	if (func == USERHOST_USERHOST || func == userhost_cmd_returned)
1568 		Type = WHOIS_USERHOST;
1569 	else if (func == whois_notify)
1570 		Type = WHOIS_ISON2;
1571 	else
1572 		Type = WHOIS_WHOIS;
1573 #ifdef HAVE_STDARG_H
1574 	typed_add_to_whois_queue(Type, nick, func, format, vlist);
1575 	va_end(vlist);
1576 #else
1577 	typed_add_to_whois_queue(Type, nick, func, format, arg1, arg2,
1578 	    arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
1579 #endif
1580 }
1581 
1582 /*
1583  * note that typed_add_to_whois_queue() ignores the final (fifth and
1584  * beyond) parameter if the 4th is NULL.  we use the va_list variable
1585  * here instead of 0 to work around picky compilers.
1586  */
1587 void
1588 add_ison_to_whois(nick, func)
1589 	void	(*func) _((WhoisStuff *, char *, char *));
1590 	char	*nick;
1591 {
1592 #ifdef HAVE_STDARG_H
1593 	va_list vlist;
1594 
1595 	typed_add_to_whois_queue(WHOIS_ISON, nick, func, (char *) 0, vlist);
1596 #else
1597 	typed_add_to_whois_queue(WHOIS_ISON, nick, func, (char *) 0, 0);
1598 #endif /* HAVE_STDARG_H */
1599 }
1600 
1601 /**************************** PATCHED by Flier ******************************/
1602 void
add_userhost_to_whois(nick,func)1603 add_userhost_to_whois(nick, func)
1604 	char	*nick;
1605 	void	(*func)();
1606 {
1607 #ifdef HAVE_STDARG_H
1608 	va_list vlist;
1609 
1610 	typed_add_to_whois_queue(WHOIS_USERHOST, nick, func, (char *) 0, vlist);
1611 #else
1612 	typed_add_to_whois_queue(WHOIS_USERHOST, nick, func, (char *) 0, 0);
1613 #endif /* HAVE_STDARG_H */
1614 }
1615 /****************************************************************************/
1616 
1617 static void
1618 #ifdef HAVE_STDARG_H
typed_add_to_whois_queue(int type,char * nick,void (* func)_ ((WhoisStuff *,char *,char *)),char * format,va_list vlist)1619 typed_add_to_whois_queue(int type, char *nick, void (*func) _((WhoisStuff *, char *, char *)), char *format, va_list vlist)
1620 #else
1621 typed_add_to_whois_queue(type, nick, func, format,
1622 		arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
1623 	void	(*func) _((WhoisStuff *, char *, char *));
1624 	char	*format,
1625 		*nick;
1626 	int	type;
1627 	char	*arg1,
1628 		*arg2,
1629 		*arg3,
1630 		*arg4,
1631 		*arg5,
1632 		*arg6,
1633 		*arg7,
1634 		*arg8,
1635 		*arg9,
1636 		*arg10;
1637 #endif
1638 {
1639  	char	lbuf[BIG_BUFFER_SIZE + 1];
1640 	WhoisQueue *new;
1641 	char	*p = nick;
1642 
1643 	if ((nick == (char *) 0) || ! is_server_connected(from_server) ||
1644 	    (server_list[from_server].write == -1)) /* XXX STOP-GAP -Sol */
1645 		return;
1646 
1647 	for (; *p == ' ' || *p == '\t'; p++);
1648 	if (!*p)
1649 		return;	/* nick should always be a non-blank string, but
1650 			   I'd rather check because of a "ISON not enough
1651 			   parameters" coming from the server -Sol */
1652 
1653 	if (index(nick, '*') == (char *) 0)
1654 	{
1655 		new = (WhoisQueue *) new_malloc(sizeof(WhoisQueue));
1656 		new->text = (char *) 0;
1657 		new->nick = (char *) 0;
1658 		new->func = func;
1659 		new->next = (WhoisQueue *) 0;
1660 		new->type = type;
1661 		if (format)
1662 		{
1663 #ifdef HAVE_STDARG_H
1664 			vsnprintf(lbuf, sizeof lbuf, format, vlist);
1665 #else
1666 			snprintf(lbuf, sizeof lbuf, format, arg1, arg2,
1667 			    arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
1668 #endif
1669 			malloc_strcpy(&(new->text), lbuf);
1670 		}
1671 		malloc_strcpy(&(new->nick), nick);
1672 		if ((void *) get_server_qhead(from_server) == (void *) 0)
1673 			set_server_qhead(from_server, new);
1674 		if (get_server_qtail(from_server))
1675 			((WhoisQueue *) get_server_qtail(from_server))->next = new;
1676 		set_server_qtail(from_server, new);
1677 		switch(type)
1678 		{
1679 		case WHOIS_ISON:
1680 #ifdef MONITOR_Q
1681 			put_it("+++ ISON %s", nick);
1682 #endif
1683 			send_to_server("ISON %s", nick);
1684 			break;
1685 		case WHOIS_USERHOST:
1686 #ifdef MONITOR_Q
1687 			put_it("+++ USERHOST %s", nick);
1688 #endif
1689 			send_to_server("USERHOST %s", nick);
1690 			break;
1691 		case WHOIS_WHOIS:
1692 		case WHOIS_ISON2:
1693 #ifdef MONITOR_Q
1694 			put_it("+++ WHOIS %s", nick);
1695 #endif
1696 			send_to_server("WHOIS %s", nick);
1697 			if (!get_server_whois(from_server))
1698 				send_to_server("WHOIS !%s", nick);
1699 				/* postfix with nick so we know who we're
1700 				   talking about -Sol */
1701 				/* send "WHOIS !nick" and expect
1702 				   "!nick: No such nick/channel" :
1703 				   it means the real query was completed
1704 				   and the dummy query is to be ignored
1705 				   in no_such_nickname() -Sol */
1706 			break;
1707 		}
1708 	}
1709 }
1710 
1711 extern	void
1712 userhost_cmd_returned(stuff, nick, text)
1713 	WhoisStuff	*stuff;
1714 	char 	*nick;
1715 	char 	*text;
1716 {
1717 	char	args[BIG_BUFFER_SIZE + 1];
1718 
1719 	strcpy(args, stuff->nick ? stuff->nick : empty_string);
1720 	strcat(args, stuff->oper ? " + " : " - ");
1721 	strcat(args, stuff->away ? "+ " : "- ");
1722 	strcat(args, stuff->user ? stuff->user : empty_string);
1723 	strcat(args, " ");
1724 	strcat(args, stuff->host ? stuff->host : empty_string);
1725 	parse_line((char *) 0, text, args, 0, 0, 1);
1726 }
1727