1 /*
2  * stack.c - does the handling of stack functions
3  *
4  * written by matthew green
5  * finished by Jeremy Nelson (ESL)
6  * modified Colten Edwards 1996 for BitchX
7  * copyright (C) 1993.
8  */
9 
10 #include "irc.h"
11 static char cvsrevision[] = "$Id: stack.c 3 2008-02-25 09:49:14Z keaston $";
12 CVS_REVISION(stack_c)
13 #include "struct.h"
14 
15 #include "vars.h"
16 #include "stack.h"
17 #include "window.h"
18 #include "hook.h"
19 #include "ircaux.h"
20 #include "output.h"
21 #include "list.h"
22 #include "misc.h"
23 #define MAIN_SOURCE
24 #include "modval.h"
25 
26 	AliasStack1	*set_stack = NULL;
27 extern void do_stack_set (int, char *);
28 
29 #ifdef OLD_HOOK
30 static	OnStack		*on_stack = NULL;
31 
32 extern void do_stack_on (int, char *);
33 
34 extern int Add_Remove_Check (Hook *, char *);
35 
do_stack_on(int type,char * args)36 static	void	do_stack_on (int type, char *args)
37 {
38 	int	len, cnt, i, which = 0;
39 	Hook	*list = NULL;
40 	NumberMsg *nhook = NULL;
41 	char foo[10];
42 
43 	if (!on_stack && (type == STACK_POP || type == STACK_LIST))
44 	{
45 		say("ON stack is empty!");
46 		return;
47 	}
48 	if (!args || !*args)
49 	{
50 		say("Missing event type for STACK ON");
51 		return;
52 	}
53 	len = strlen(args);
54 	for (cnt = 0, i = 0; i < NUMBER_OF_LISTS; i++)
55 	{
56 		if (!my_strnicmp(args, hook_functions[i].name, len))
57 		{
58 			if (strlen(hook_functions[i].name) == len)
59 			{
60 				cnt = 1;
61 				which = i;
62 				break;
63 			}
64 			else
65 			{
66 				cnt++;
67 				which = i;
68 			}
69 		}
70 		else if (cnt)
71 			break;
72 	}
73 	if (!cnt)
74 	{
75 		if (is_number(args))
76 		{
77 			which = my_atol(args);
78 			if (which < 1 || which > 999)
79 			{
80 				say("Numerics must be between 001 and 999");
81 				return;
82 			}
83 			which = -which;
84 		}
85 		else
86 		{
87 			say("No such ON function: %s", args);
88 			return;
89 		}
90 	}
91 	if (which < 0)
92 	{
93 		sprintf(foo, "%3.3u", -which);
94 		if ((nhook = find_name_in_hooklist(foo, numeric_list, 0, HOOKTABLE_SIZE)))
95 			list = nhook->list;
96 	}
97 	else
98 		list = hook_functions[which].list;
99 
100 	if (type == STACK_PUSH)
101 	{
102 		OnStack	*new;
103 
104 		new = (OnStack *) new_malloc(sizeof(OnStack));
105 		new->next = on_stack;
106 		on_stack = new;
107 		new->which = which;
108 		new->list = list;
109 		if (which < 0)
110 		{
111 
112 			if (!nhook)
113 				return;
114 			nhook = find_name_in_hooklist(foo, numeric_list, 1, HOOKTABLE_SIZE);
115 			new_free(&nhook->name);
116 			new_free(&nhook);
117 		}
118 		else
119 			hook_functions[which].list = NULL;
120 		return;
121 	}
122 	else if (type == STACK_POP)
123 	{
124 		OnStack	*p, *tmp = NULL;
125 
126 		for (p = on_stack; p; tmp = p, p = p->next)
127 		{
128 			if (p->which == which)
129 			{
130 				if (p == on_stack)
131 					on_stack = p->next;
132 				else
133 					tmp->next = p->next;
134 				break;
135 			}
136 		}
137 		if (!p)
138 		{
139 			say("No %s on the stack", args);
140 			return;
141 		}
142 		if (which >= 0 && hook_functions[which].list)
143 			remove_hook(which, NULL, 0, 0, 1);	/* free hooks */
144 		else if (which < 0 && nhook)
145 		{
146 			Hook *tmp, *next;
147 			if ((nhook = find_name_in_hooklist(foo, numeric_list, 1, HOOKTABLE_SIZE)))
148 			{
149 				new_free(&nhook->name);
150 				for (tmp = nhook->list; tmp; tmp = next)
151 				{
152 					next = tmp->next;
153 					tmp->not = 1;
154 					new_free(&(tmp->nick));
155 					new_free(&(tmp->stuff));
156 					new_free((char **)&tmp);
157 				}
158 				new_free(&nhook);
159 			}
160 		}
161 		if (which < 0)
162 		{
163 			/* look -- do we have any hooks already for this numeric? */
164 			if (p->list)
165 			{
166 				sprintf(foo, "%3.3u", -which);
167 				nhook = add_name_to_hooklist(foo, NULL, numeric_list, HOOKTABLE_SIZE);
168 				add_to_list_ext((List **)&nhook->list, (List *)p->list, (int (*)(List *, List *))Add_Remove_Check);
169 			}
170 		}
171 		else
172 			hook_functions[which].list = p->list;
173 		new_free((char **)&p);
174 		return;
175 	}
176 	else if (type == STACK_LIST)
177 	{
178 		int	slevel = 0;
179 		OnStack	*osptr;
180 
181 		for (osptr = on_stack; osptr; osptr = osptr->next)
182 		{
183 			if (osptr->which == which)
184 			{
185 				Hook	*hptr;
186 
187 				slevel++;
188 				say("Level %d stack", slevel);
189 				for (hptr = osptr->list; hptr; hptr = hptr->next)
190 					show_hook(hptr, args);
191 			}
192 		}
193 
194 		if (!slevel)
195 			say("The STACK ON %s list is empty", args);
196 		return;
197 	}
198 	say("Unknown STACK ON type ??");
199 }
200 #endif
201 
BUILT_IN_COMMAND(stackcmd)202 BUILT_IN_COMMAND(stackcmd)
203 {
204 	char	*arg;
205 	int	len, type;
206 
207 	if ((arg = next_arg(args, &args)) != NULL)
208 	{
209 		len = strlen(arg);
210 		if (!my_strnicmp(arg, "PUSH", len))
211 			type = STACK_PUSH;
212 		else if (!my_strnicmp(arg, "POP", len))
213 			type = STACK_POP;
214 		else if (!my_strnicmp(arg, "LIST", len))
215 			type = STACK_LIST;
216 		else
217 		{
218 			say("%s is unknown stack verb", arg);
219 			return;
220 		}
221 	}
222 	else
223 		return;
224 	if ((arg = next_arg(args, &args)) != NULL)
225 	{
226 		len = strlen(arg);
227 		if (!my_strnicmp(arg, "ON", len))
228 			do_stack_on(type, args);
229 		else if (!my_strnicmp(arg, "ALIAS", len))
230 			do_stack_alias(type, args, STACK_DO_ALIAS);
231 		else if (!my_strnicmp(arg, "ASSIGN", len))
232 			do_stack_alias(type, args, STACK_DO_ASSIGN);
233 		else if (!my_strnicmp(arg, "SET", len))
234 			do_stack_set(type, args);
235 		else
236 		{
237 			say("%s is not a valid STACK type", arg);
238 			return;
239 		}
240 	}
241 }
242