📄 remailer.c
字号:
/* * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org> * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /* * Mixmaster support for Mutt */#if HAVE_CONFIG_H# include "config.h"#endif#include "mutt.h"#include "mutt_curses.h"#include "mutt_menu.h"#include "mutt_regex.h"#include "mapping.h"#include "remailer.h"#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/file.h>#include <fcntl.h>#ifdef MIXMASTERstruct coord{ short r, c;};static REMAILER **mix_type2_list (size_t *l);static REMAILER *mix_new_remailer (void);static const char *mix_format_caps (REMAILER *r);static int mix_chain_add (MIXCHAIN *chain, const char *s, REMAILER **type2_list);static int mix_get_caps (const char *capstr);static void mix_add_entry (REMAILER ***, REMAILER *, size_t *, size_t *);static void mix_entry (char *b, size_t blen, MUTTMENU *menu, int num);static void mix_free_remailer (REMAILER **r);static void mix_free_type2_list (REMAILER ***ttlp);static void mix_redraw_ce (REMAILER **type2_list, struct coord *coords, MIXCHAIN *chain, int i, short selected);static void mix_redraw_chain (REMAILER **type2_list, struct coord *coords, MIXCHAIN *chain, int cur);static void mix_redraw_head (MIXCHAIN *);static void mix_screen_coordinates (REMAILER **type2_list, struct coord **, MIXCHAIN *, int);static int mix_get_caps (const char *capstr){ int caps = 0; while (*capstr) { switch (*capstr) { case 'C': caps |= MIX_CAP_COMPRESS; break; case 'M': caps |= MIX_CAP_MIDDLEMAN; break; case 'N': { switch (*++capstr) { case 'm': caps |= MIX_CAP_NEWSMAIL; break; case 'p': caps |= MIX_CAP_NEWSPOST; break; } } } if (*capstr) capstr++; } return caps;}static void mix_add_entry (REMAILER ***type2_list, REMAILER *entry, size_t *slots, size_t *used){ if (*used == *slots) { *slots += 5; safe_realloc (type2_list, sizeof (REMAILER *) * (*slots)); } (*type2_list)[(*used)++] = entry; if (entry) entry->num = *used;}static REMAILER *mix_new_remailer (void){ return safe_calloc (1, sizeof (REMAILER));}static void mix_free_remailer (REMAILER **r){ FREE (&(*r)->shortname); FREE (&(*r)->addr); FREE (&(*r)->ver); FREE (r); /* __FREE_CHECKED__ */}/* parse the type2.list as given by mixmaster -T */static REMAILER **mix_type2_list (size_t *l){ FILE *fp; pid_t mm_pid; int devnull; char cmd[HUGE_STRING + _POSIX_PATH_MAX]; char line[HUGE_STRING]; char *t; REMAILER **type2_list = NULL, *p; size_t slots = 0, used = 0; if (!l) return NULL; if ((devnull = open ("/dev/null", O_RDWR)) == -1) return NULL; snprintf (cmd, sizeof (cmd), "%s -T", Mixmaster); if ((mm_pid = mutt_create_filter_fd (cmd, NULL, &fp, NULL, devnull, -1, devnull)) == -1) { close (devnull); return NULL; } /* first, generate the "random" remailer */ p = mix_new_remailer (); p->shortname = safe_strdup ("<random>"); mix_add_entry (&type2_list, p, &slots, &used); while (fgets (line, sizeof (line), fp)) { p = mix_new_remailer (); if (!(t = strtok (line, " \t\n"))) goto problem; p->shortname = safe_strdup (t); if (!(t = strtok (NULL, " \t\n"))) goto problem; p->addr = safe_strdup (t); if (!(t = strtok (NULL, " \t\n"))) goto problem; if (!(t = strtok (NULL, " \t\n"))) goto problem; p->ver = safe_strdup (t); if (!(t = strtok (NULL, " \t\n"))) goto problem; p->caps = mix_get_caps (t); mix_add_entry (&type2_list, p, &slots, &used); continue; problem: mix_free_remailer (&p); } *l = used; mix_add_entry (&type2_list, NULL, &slots, &used); mutt_wait_filter (mm_pid); close (devnull); return type2_list;}static void mix_free_type2_list (REMAILER ***ttlp){ int i; REMAILER **type2_list = *ttlp; for (i = 0; type2_list[i]; i++) mix_free_remailer (&type2_list[i]); FREE (type2_list); /* __FREE_CHECKED__ */}#define MIX_HOFFSET 2#define MIX_VOFFSET (LINES - 6)#define MIX_MAXROW (LINES - 3)static void mix_screen_coordinates (REMAILER **type2_list, struct coord **coordsp, MIXCHAIN *chain, int i){ short c, r, oc; struct coord *coords; if (!chain->cl) return; safe_realloc (coordsp, sizeof (struct coord) * chain->cl); coords = *coordsp; if (i) { c = coords[i-1].c + strlen (type2_list[chain->ch[i-1]]->shortname) + 2; r = coords[i-1].r; } else { r = MIX_VOFFSET; c = MIX_HOFFSET; } for (; i < chain->cl; i++) { oc = c; c += strlen (type2_list[chain->ch[i]]->shortname) + 2; if (c >= COLS) { oc = c = MIX_HOFFSET; r++; } coords[i].c = oc; coords[i].r = r; } }static void mix_redraw_ce (REMAILER **type2_list, struct coord *coords, MIXCHAIN *chain, int i, short selected){ if (!coords || !chain) return; if (coords[i].r < MIX_MAXROW) { if (selected) SETCOLOR (MT_COLOR_INDICATOR); else SETCOLOR (MT_COLOR_NORMAL); mvaddstr (coords[i].r, coords[i].c, type2_list[chain->ch[i]]->shortname); SETCOLOR (MT_COLOR_NORMAL); if (i + 1 < chain->cl) addstr (", "); }}static void mix_redraw_chain (REMAILER **type2_list, struct coord *coords, MIXCHAIN *chain, int cur){ int i; SETCOLOR (MT_COLOR_NORMAL); BKGDSET (MT_COLOR_NORMAL); for (i = MIX_VOFFSET; i < MIX_MAXROW; i++) { move (i, 0); clrtoeol (); } for (i = 0; i < chain->cl; i++) mix_redraw_ce (type2_list, coords, chain, i, i == cur);}static void mix_redraw_head (MIXCHAIN *chain){ SETCOLOR (MT_COLOR_STATUS); mvprintw (MIX_VOFFSET - 1, 0, "-- Remailer chain [Length: %d]", chain ? chain->cl : 0); BKGDSET (MT_COLOR_STATUS); clrtoeol (); BKGDSET (MT_COLOR_NORMAL); SETCOLOR (MT_COLOR_NORMAL);}static const char *mix_format_caps (REMAILER *r){ static char capbuff[10]; char *t = capbuff; if (r->caps & MIX_CAP_COMPRESS) *t++ = 'C'; else *t++ = ' '; if (r->caps & MIX_CAP_MIDDLEMAN) *t++ = 'M'; else *t++ = ' '; if (r->caps & MIX_CAP_NEWSPOST) { *t++ = 'N'; *t++ = 'p'; } else { *t++ = ' '; *t++ = ' '; } if (r->caps & MIX_CAP_NEWSMAIL) { *t++ = 'N'; *t++ = 'm'; } else { *t++ = ' '; *t++ = ' '; } *t = '\0'; return capbuff;}/* * Format an entry for the remailer menu. * * %n number * %c capabilities * %s short name * %a address * */static const char *mix_entry_fmt (char *dest, size_t destlen, char op, const char *src, const char *prefix, const char *ifstring, const char *elsestring, unsigned long data, format_flag flags){ char fmt[16]; REMAILER *remailer = (REMAILER *) data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -