1 /*
2  * tabkey.c: Ninja IRC tab completion
3  *
4  * written by Joshua J. Drake and Kraig Amador
5  */
6 
7 #include "irc.h"
8 #include "dma.h"
9 
10 #include "tabkey.h"
11 
12 #include "input.h"
13 #include "ircaux.h"
14 #include "list.h"
15 #include "vars.h"
16 
17 static Reply *tabkey_array = (Reply *) 0;
18 
19 /*
20  * tab reply!
21  */
22 void
tab_reply(u_int dumb,u_char * dumber)23 tab_reply(u_int dumb, u_char *dumber)
24 {
25    u_char *tmp = NULL;
26    u_char *cmdchar = NULL;
27 
28    tmp = get_tab_key(1);
29    if (tmp && *tmp)
30      {
31 	u_char tmp1[1024], *p;
32 
33 	if (!(cmdchar = get_string_var(CMDCHARS_VAR)))
34 	   cmdchar = "/";
35 	input_clear_line('\0', NULL);
36 	snprintf(tmp1, sizeof(tmp1)-1, "%s%s ", cmdchar, tmp);
37 	p = tmp1;
38 	while (p && *p)
39 	  input_add_character(*p++, NULL);
40      }
41 }
42 
43 void
add_tab_key(int times,u_char * prompt,u_char * targ)44 add_tab_key(int times, u_char *prompt, u_char *targ)
45 {
46    Reply *new, *tmp;
47    u_char tb[128];
48 
49    if (!prompt || !targ)
50      return;
51    my_strmcpy(tb, prompt, sizeof(tb)-1);
52    my_strmcat(tb, targ, sizeof(tb)-1);
53 
54    tmp = tabkey_array;
55    if (!tmp ||
56        !(new = (Reply *) remove_from_list((List **) & tmp, tb)))
57      {
58 	new = (Reply *) dma_Malloc(sizeof(Reply));
59 	dma_strcpy(&(new->nick), tb);
60 	new->times = times;
61      }
62    new->last_used = time(NULL);
63    new->next = tmp;
64    tabkey_array = new;
65 }
66 
67 u_char *
get_tab_key(int direction)68 get_tab_key(int direction)
69 {
70    Reply *tmp, *new;
71    static u_char tb[128];
72 
73    tmp = new = tabkey_array;
74    if (!tmp)
75      return NULL;
76    if (new->next)
77      {
78 	tabkey_array = new->next;
79 	new->next = NULL;
80 	tmp = tabkey_array;
81 	while (tmp)
82 	  {
83 	     if (tmp->next)
84 	       tmp = tmp->next;
85 	     else
86 	       break;
87 	  }
88 	tmp->next = new;
89      }
90    if (new->times)
91      {
92 	tmp = (Reply *) remove_from_list((List **) & tabkey_array, new->nick);
93 	my_strmcpy(tb, tmp->nick, sizeof(tb)-1);
94 	dma_Free(&tmp->nick);
95 	dma_Free(&tmp);
96 	return tb;
97      }
98    if (new && new->nick)
99      return new->nick;
100    return NULL;
101 }
102 
103 #ifndef NFREQ_TAB_KEY_EXPIRE
104 # define NFREQ_TAB_KEY_EXPIRE	3600 /* default, 1 hour */
105 #endif
106 /*
107  * expire tab reply entries...
108  */
109 void
nchk_tabkeys(current)110 nchk_tabkeys(current)
111    time_t current;
112 {
113    Reply *tmp, *tmp2;
114 
115    tmp = tabkey_array;
116    while (tmp)
117      {
118 	if ((current - tmp->last_used) > NFREQ_TAB_KEY_EXPIRE)
119 	  {
120 	     if ((tmp2 = (Reply *) remove_from_list((List **) & tabkey_array, tmp->nick)) != NULL)
121 	       {
122 		  tmp = tmp2->next;
123 		  dma_Free(&tmp2->nick);
124 		  dma_Free(&tmp2);
125 	       }
126 	  }
127 	else
128 	  tmp = tmp->next;
129      }
130 }
131