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