]> jfr.im git - irc/quakenet/newserv.git/blame - helpmod2/helpmod_entries.c
GLINES: fix null pointer deref in trustgline / trustungline
[irc/quakenet/newserv.git] / helpmod2 / helpmod_entries.c
CommitLineData
c86edd1d
Q
1#include "helpmod_entries.h"
2#include "helpmod_alias.h"
c224fac3 3#include "../core/error.h"
c86edd1d
Q
4#include "helpmod.h"
5
6struct helpmod_parsed_line_struct helpmod_parsed_line;
7
8int helpmod_valid_selection(helpmod_entry state, int selection)
9{
10 if (selection == -1)
c3db6f7e 11 return ((int)((long)state->parent));
c86edd1d
Q
12 return (selection >= 0 && selection < state->option_count);
13}
14
15helpmod_entry helpmod_make_selection(helpmod_entry state, int selection)
16{
17 if (selection == -1)
18 return state->parent;
19 return state->options[selection];
20}
21
22void helpmod_init_entry(helpmod_entry * entry)
23{
24 *entry = (helpmod_entry)malloc(sizeof(**entry));
25 (*entry)->option_count = (*entry)->text_lines = 0;
26 (*entry)->text = NULL;
27 (*entry)->options = NULL;
28 (*entry)->parent = NULL;
29 (*entry)->description = NULL;
30}
31
32void helpmod_clear_entries(helpmod_entry state)
33{
34 int i;
35 if (state == NULL)
36 return;
37 if (state->description != NULL)
38 freesstring(state->description);
39 for (i=0;i<state->text_lines;i++)
40 freesstring(state->text[i]);
41 if (state->text_lines)
42 free(state->text);
43 for (i=0;i<state->option_count;i++)
44 {
45 helpmod_clear_entries(state->options[i]);
46 free(state->options[i]);
47 }
48 if (state->option_count)
49 free(state->options);
50}
51
52void helpmod_parse_line(FILE* input)
53{
54 int i, slen;
55 char str[512] = "";
56 fgets(str,511,input);
57 helpmod_parsed_line.line_type = HM_LINE_NORMAL;
58 if (*str >= '0' && *str <= '0')
59 {
60 sscanf(str, "%2d", &helpmod_parsed_line.depth);
61 if (str[2] == '*')
62 {
63 helpmod_parsed_line.line_type = HM_LINE_TEXT;
64 strcpy(helpmod_parsed_line.text, str + 3);
65 }
66 else if (str[2] == '$')
67 {
68 helpmod_parsed_line.line_type = HM_LINE_ALIAS;
69 strcpy(helpmod_parsed_line.text, str + 3);
70 }
71 else
72 strcpy(helpmod_parsed_line.text, str + 2);
73 return;
74 }
75 for(i=0,slen=strlen(str);i<slen;i++)
76 if (str[i] == '*')
77 {
78 helpmod_parsed_line.line_type = HM_LINE_TEXT;
79 i++;
80 break;
81 }
82 else if (str[i] == '$')
83 {
84 helpmod_parsed_line.line_type = HM_LINE_ALIAS;
85 i++;
86 break;
87 }
88 else if (str[i] != ' ')
89 break;
90
91 helpmod_parsed_line.depth = i;
92 strcpy(helpmod_parsed_line.text, str + i);
93}
94
95void helpmod_clear_all_entries(void)
96{
97 helpmod_clear_entries(helpmod_base);
98 free(helpmod_base);
99 helpmod_base = NULL;
100}
101
102void helpmod_load_entries(char* setting_file)
103{
104 FILE *main_input;
105 FILE *tmp_input;
106 char buffer[512];
107 int i;
108 if (NULL == setting_file)
109 setting_file = HELPMOD_HELP_DEFAULT_DB;
110 if (NULL == (main_input = fopen(setting_file, "rt")))
111 {
112 Error("helpmod", ERR_WARNING, "Default database not found, service will be unavailable until a valid database is loaded");
113 return;
114 }
115 while (!feof(main_input))
116 {
117 fgets(buffer,511,main_input);
118 if (feof(main_input))
119 return;
120 if (*buffer == '$')
121 {
c86edd1d
Q
122 /* remove the \n, it's not wanted */
123 for (i=0;i<strlen(buffer+1);i++)
124 if ((buffer+1)[i] == '\n')
125 {
126 (buffer+1)[i] = '\0';
127 break;
128 }
129 tmp_input = fopen(buffer+1, "r");
130 if (tmp_input == NULL)
131 {
132 Error("helpmod", ERR_ERROR, "File %s specified in %s not found",buffer+1, setting_file);
133 return;
134 }
9af95c3d 135 helpmod_base->options = (helpmod_entry*)realloc(helpmod_base->options, sizeof(helpmod_entry) * ++helpmod_base->option_count);
136 helpmod_base->options[helpmod_base->option_count-1] = NULL;
137
c86edd1d
Q
138 helpmod_parse_line(tmp_input);
139 helpmod_load_entry(&helpmod_base->options[helpmod_base->option_count-1], tmp_input, 0, helpmod_base);
140 fclose(tmp_input);
141 }
142 else
143 {
144 helpmod_base->text = (sstring**)realloc(helpmod_base->text, sizeof(sstring*) * ++helpmod_base->text_lines);
145 helpmod_base->text[helpmod_base->text_lines-1] = getsstring(buffer, strlen(buffer));
146 }
147 }
148 fclose(main_input);
149}
150
151void helpmod_load_entry(helpmod_entry* base, FILE* input, int depth, helpmod_entry parent)
152{
153 if (feof(input))
154 {
155 *base = NULL;
156 helpmod_parsed_line.depth = 0;
157 return;
158 }
159
160 if (helpmod_parsed_line.depth < depth)
161 {
162 *base = NULL;
163 return;
164 }
165
166 helpmod_init_entry(base);
167 (*base)->parent = parent;
168 (*base)->description = getsstring(helpmod_parsed_line.text, strlen(helpmod_parsed_line.text));
169 depth++;
170
171 helpmod_parse_line(input);
172 while (helpmod_parsed_line.line_type == HM_LINE_ALIAS)
173 {
174 helpmod_add_alias(helpmod_parsed_line.text, *base); /* create an alias */
175 helpmod_parse_line(input);
176 }
177 while (helpmod_parsed_line.line_type == HM_LINE_TEXT)
178 {
179 if (feof(input))
180 return;
181 (*base)->text = (sstring**)realloc((*base)->text, sizeof(sstring*) * ++(*base)->text_lines);
182 (*base)->text[(*base)->text_lines - 1] = getsstring(helpmod_parsed_line.text, strlen(helpmod_parsed_line.text));
183 helpmod_parse_line(input);
184 }
185 while (helpmod_parsed_line.depth == depth)
186 {
187
188 (*base)->options = (helpmod_entry*)realloc((*base)->options, sizeof(helpmod_entry) * ++(*base)->option_count);
189 helpmod_load_entry(&(*base)->options[(*base)->option_count-1],input,depth, *base);
190 }
191 return;
192}
193
194long helpmod_entry_count(helpmod_entry base)
195{
196 int i;
197 long counter = 0;
198 if (base == NULL)
199 return 0;
200 if (base->options == NULL)
201 return 0;
202 for (i=0;i<base->option_count;i++)
203 counter+=helpmod_entry_count(base->options[i]);
204 return i+counter;
205}