mixmaster

mixmaster 3.0 patched for libressl
git clone git://parazyd.org/mixmaster.git
Log | Files | Refs | README

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