tmenustats.c - mixmaster - mixmaster 3.0 patched for libressl
 (HTM) 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