tmenustats.c - mixmaster - mixmaster 3.0 patched for libressl
HTML git clone git://parazyd.org/mixmaster.git
DIR Log
DIR Files
DIR Refs
DIR README
---
tmenustats.c (9696B)
---
1 /* Mixmaster version 3.0 -- (C) 1999 - 2006 Anonymizer Inc. and others.
2
3 Mixmaster may be redistributed and modified under certain conditions.
4 This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
5 ANY KIND, either express or implied. See the file COPYRIGHT for
6 details.
7
8 Menu-based user interface
9 $Id: menustats.c 934 2006-06-24 13:40:39Z rabbi $ */
10
11
12 #if 0
13 void errlog(int type, char *format, ...) { };
14 char MIXDIR[512];
15 #include "util.c"
16 #include "buffers.c"
17 int menu_getuserpass(BUFFER *p, int mode) { return 0; };
18 #endif
19
20 #include <string.h>
21 #include <assert.h>
22 #include <stdlib.h>
23
24 #include "menu.h"
25 #ifdef WIN32
26 #include <urlmon.h>
27 #pragma comment(lib,"urlmon.lib")
28 #else
29 #include <sys/wait.h>
30 #endif /* WIN32 */
31
32
33 int url_download(char *url, char *dest) {
34 int err;
35 #ifdef WIN32
36 err = URLDownloadToFile(NULL, url, dest, BINDF_GETNEWESTVERSION, NULL);
37
38 if (err != S_OK)
39 return -1;
40 else
41 return 0;
42 #else
43 char s[PATHMAX];
44 snprintf(s, PATHMAX, "%s -q %s -O %s", WGET, url, dest);
45 err = system(s);
46
47 if (err != -1) {
48 if (WIFEXITED(err) == 0)
49 return -1; /* abnormal child exit */
50 else
51 return 0;
52 }
53 else
54 return -1;
55 #endif /* WIN32 */
56 }
57
58 /** read the allpingers file into the buffer */
59 void read_allpingers(BUFFER *allpingers) {
60 FILE *f;
61
62 f = mix_openfile(ALLPINGERSFILE, "r");
63 if (f != NULL) {
64 buf_clear(allpingers);
65 buf_read(allpingers, f);
66 fclose(f);
67 }
68 }
69
70 /* Get all sections from inifile.
71 *
72 * They are put into the sections buffer, separated by newlines
73 */
74 void get_sections(BUFFER *inifile, BUFFER *sections) {
75 BUFFER *line;
76 int err;
77
78 line = buf_new();
79
80 buf_rewind(inifile);
81 buf_reset(sections);
82
83 while ((err = buf_getline(inifile, line)) != -1) {
84 if (bufileft (line, "[") &&
85 bufiright(line, "]")) {
86 line->data[line->length-1] = '\0';
87 buf_appends(sections, line->data+1);
88 buf_nl(sections);
89 };
90 }
91 buf_free (line);
92 }
93
94 /* Get value of an attribute
95 *
96 * returns -1 if it isn't found.
97 */
98 int get_attribute(BUFFER *inifile, char *section, char *attribute, BUFFER *value) {
99 BUFFER *line;
100 int err = -1;
101 int insection = 0;
102
103 line = buf_new();
104
105 buf_rewind(inifile);
106 buf_reset(value);
107
108 while (buf_getline(inifile, line) != -1) {
109 if (bufileft (line, "[") &&
110 bufiright(line, "]")) {
111 if (insection)
112 break;
113
114 line->data[line->length-1] = '\0';
115 if (strcasecmp(section, line->data+1) == 0) {
116 insection = 1;
117 }
118 } else if (insection && bufileft(line, attribute)) {
119 /* we are in the right section and this attribute name
120 * at least starts with what we want */
121 char *ptr = line->data + strlen(attribute);
122 /* eat up whitespace */
123 while ((*ptr == ' ') || (*ptr == '\t'))
124 ptr++;
125 if (*ptr != '=')
126 continue;
127 ptr++;
128 while ((*ptr == ' ') || (*ptr == '\t'))
129 ptr++;
130 buf_appends(value, ptr);
131 err = 0;
132 break;
133 }
134 }
135 buf_free (line);
136 return (err);
137 }
138
139
140
141
142
143 static char *files[] = { "mlist", "rlist", "mixring", "pgpring"};
144 #define NUMFILES sizeof(files)/sizeof(*files)
145
146 /* Download all the needed files from the specified source */
147 /* returns -1 on error */
148 int stats_download(BUFFER *allpingers, char *sourcename, int curses) {
149 char *localfiles[] = { TYPE2REL, TYPE1LIST, PUBRING, PGPREMPUBASC };
150 char path[PATHMAX];
151 char path_t[PATHMAX];
152 BUFFER *value;
153 int ret = 0;
154 int err;
155 int i;
156
157 value = buf_new();
158
159 if (curses) {
160 clear();
161 }
162
163 err = get_attribute(allpingers, sourcename, "base", value);
164 if (err == 0) {
165 if (curses) {
166 standout();
167 printw("%s", value->data);
168 standend();
169 }
170 else
171 printf("%s\n\r", value->data);
172 }
173
174 /* Loop to get each file in turn to a temp file */
175
176 for (i=0; i<NUMFILES; i++) {
177 err = get_attribute(allpingers, sourcename, files[i], value);
178 if (err < 0) {
179 /* the attribute vanished under us */
180 ret = -1;
181 break;
182 }
183 mixfile(path, localfiles[i]);
184 if (curses) {
185 mvprintw(i+3, 0, "downloading %s from %s...", localfiles[i], value->data);
186 refresh();
187 }
188 else
189 printf("downloading %s from %s...", localfiles[i], value->data);
190 err = url_download(value->data, strcat(path, ".t"));
191 if (err < 0) {
192 if (curses)
193 printw("failed to download.\n\rTry using another stats source.");
194 else
195 printf("failed to download.\n\rTry using another stats source.\n\r");
196 ret = -1;
197 break;
198 }
199 if (curses)
200 printw("done");
201 else
202 printf("done\n\r");
203 }
204
205 /* We got them all ok - so rename them to their correct names */
206
207 for (i=0; i<NUMFILES; i++) {
208 mixfile(path, localfiles[i]);
209 mixfile(path_t, localfiles[i]);
210 strcat(path_t, ".t");
211 rename(path_t, path);
212 }
213
214 if (curses) {
215 printw("\n\n\n\n\rPress any key to continue");
216 getch();
217 clear();
218 }
219 buf_free(value);
220 return ret;
221 }
222 /* Checks whether the stats source has all the required files.
223 *
224 * 1 if it has,
225 * 0 otherwise
226 */
227 int good_stats_source (BUFFER *allpingers, char *sourcename) {
228 BUFFER *value;
229 int i;
230 int res = 1;
231 int err;
232
233 value = buf_new();
234
235 for (i = 0; i < NUMFILES; i++) {
236 err = get_attribute(allpingers, sourcename, files[i], value);
237 if (err < 0) {
238 res = 0;
239 break;
240 }
241 }
242
243 buf_free (value);
244 return (res);
245 }
246
247 /* Do a stats download update and report status */
248 /* 0 on success */
249 /* -1 File download failed */
250 /* -2 Error writing file */
251 /* -3 Stats source incomplete */
252
253 int download_stats(char *sourcename) {
254 BUFFER *inifile;
255 FILE *f;
256 int ret;
257 inifile = buf_new();
258 read_allpingers(inifile);
259 if (good_stats_source(inifile, sourcename) == 1) {
260 if (stats_download(inifile, sourcename, 0) == 0) {
261 f = mix_openfile(STATSSRC, "w+");
262 if (f != NULL) {
263 fprintf(f, "%s", sourcename);
264 fclose(f);
265 ret = 0;
266 } else {
267 ret = -2;
268 errlog(ERRORMSG, "Could not open stats source file for writing.\n");
269 }
270 } else {
271 ret = -1;
272 errlog(ERRORMSG, "Stats source download failed.\n");
273 }
274 } else {
275 ret = -3;
276 errlog(ERRORMSG, "Stats source does not include all required files.\n");
277 }
278
279 buf_free(inifile);
280 return (ret);
281 }
282
283
284 /* Download allpingers.txt */
285 /* -1 on error */
286 static int download_list() {
287 char path[PATHMAX];
288
289 mixfile(path, ALLPINGERSFILE);
290
291 clear();
292 standout();
293 printw(ALLPINGERSURL);
294 standend();
295
296 mvprintw(3,0,"downloading %s...", ALLPINGERSURL);
297 refresh();
298 if (url_download(ALLPINGERSURL, path) < 0) {
299 printw("failed to download.\n\rTry again later.");
300 printw("\n\n\rPress any key to continue");
301 getch();
302 return -1;
303 }
304 return 0;
305 }
306
307 /* Displays the choice of stats sources */
308 #define MAXPING (26 * 2)
309 void update_stats() {
310 char c;
311 BUFFER *inifile;
312 BUFFER *pingernames;
313 BUFFER *goodpingers;
314 BUFFER *line;
315 BUFFER *statssrc;
316 FILE *f;
317 int num;
318 int err;
319 int x, y;
320 int i;
321
322 inifile = buf_new();
323 pingernames = buf_new();
324 goodpingers = buf_new();
325 line = buf_new();
326 statssrc = buf_new();
327
328 while (1) {
329 clear();
330 standout();
331 buf_clear(statssrc);
332 f = mix_openfile(STATSSRC, "r");
333 if (f != NULL) {
334 buf_read(statssrc, f);
335 fclose(f);
336 }
337 printw("Select stats source:");
338 standend();
339 if (statssrc->length > 0)
340 printw(" Current: %s (Enter to download)", statssrc->data);
341 printw("\n\n");
342
343 read_allpingers(inifile);
344 get_sections (inifile, pingernames);
345
346 num = 0;
347 buf_reset(goodpingers);
348 buf_rewind(pingernames);
349 while ((buf_getline(pingernames, line) != -1) && num < MAXPING) {
350 if (good_stats_source (inifile, line->data)) {
351 buf_cat(goodpingers, line);
352 buf_nl(goodpingers);
353 num++;
354 }
355 }
356
357 x = 0;
358 buf_rewind(goodpingers);
359 for (i=0; i<num; i++) {
360 err = buf_getline(goodpingers, line);
361 assert (err != -1);
362 y = i;
363 if (y >= LINES - 6)
364 y -= LINES - 6, x = 40;
365 mvprintw(y + 2, x, "%c", i < 26 ? i + 'a' : i - 26 + 'A');
366 mvprintw(y + 2, x + 2, "%s", line->data);
367 }
368 y = i + 3;
369 if (y > LINES - 4)
370 y = LINES - 4;
371 mvprintw(y, 0, "* update list of pingers from web = edit list <space> to exit");
372 c = getch();
373 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
374 if (c >= 'a')
375 c -= 'a';
376 else
377 c = c - 'A' + 26;
378 if (c < num) {
379 buf_rewind(goodpingers);
380 while (c >= 0) {
381 err = buf_getline(goodpingers, line);
382 assert (err != -1);
383 c--;
384 }
385 if (stats_download(inifile, line->data, 1) == 0) {
386 f = mix_openfile(STATSSRC, "w+");
387 if (f != NULL) {
388 fprintf(f, "%s", line->data);
389 fclose(f);
390 } else
391 fprintf(stderr, "Could not open stats source file for writing\n");
392 break;
393 }
394 }
395 }
396 else if (c == '*') {
397 download_list();
398 }
399 else if (c == '=') {
400 char path[PATHMAX];
401 mixfile(path, ALLPINGERSFILE);
402 menu_spawn_editor(path, 0);
403 }
404 else if ((c == '\r') && statssrc->length) {
405 stats_download(inifile, statssrc->data, 1);
406 break;
407 }
408 else if (c == ' ') {
409 break;
410 }
411 }
412 clear();
413
414 buf_free(statssrc);
415 buf_free(inifile);
416 buf_free(line);
417 buf_free(pingernames);
418 buf_free(goodpingers);
419 }
420
421 #if 0
422 int main() {
423 strcpy(MIXDIR,"./");
424
425 BUFFER *allpingers;
426 BUFFER *pingernames;
427 BUFFER *value;
428
429 allpingers = buf_new();
430 pingernames = buf_new();
431 value = buf_new();
432
433 read_allpingers (allpingers);
434 get_sections (allpingers, pingernames);
435
436 printf("%s", pingernames->data);
437
438 get_attribute (allpingers, "noreply", "rlist", value);
439 printf("%s\n", value->data);
440
441
442 exit(0);
443 }
444
445 #endif