menustats.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