/*
* Copyright (C) 1996,1997 Michael R. Elkins <me@cs.hmc.edu>
* Copyright (c) 1998,1999 Thomas Roessler <roessler@guug.de>
*
* 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., 675 Mass Ave, Cambridge, MA
* 02139, USA.
*/
#include "mutt.h"
#include "mutt_curses.h"
#include "mutt_menu.h"
#include "mime.h"
#include "pgp.h"
#include "pager.h"
#include "sort.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <locale.h>
#ifdef _PGPPATH
struct pgp_cache
{
char *what;
char *dflt;
struct pgp_cache *next;
};
static struct pgp_cache *id_defaults = NULL;
static char trust_flags[] = "?- +";
static char *pgp_key_abilities (int flags)
{
static char buff[3];
if (!(flags & KEYFLAG_CANENCRYPT))
buff[0] = '-';
else if (flags & KEYFLAG_PREFER_SIGNING)
buff[0] = '.';
else
buff[0] = 'e';
if (!(flags & KEYFLAG_CANSIGN))
buff[1] = '-';
else if (flags & KEYFLAG_PREFER_ENCRYPTION)
buff[1] = '.';
else
buff[1] = 's';
buff[2] = '\0';
return buff;
}
static char pgp_flags (int flags)
{
if (flags & KEYFLAG_REVOKED)
return 'R';
else if (flags & KEYFLAG_EXPIRED)
return 'X';
else if (flags & KEYFLAG_DISABLED)
return 'd';
else if (flags & KEYFLAG_CRITICAL)
return 'c';
else
return ' ';
}
static pgp_key_t *pgp_principal_key (pgp_key_t *key)
{
if (key->flags & KEYFLAG_SUBKEY && key->parent)
return key->parent;
else
return key;
}
/*
* Format an entry on the PGP key selection menu.
*
* %n number
* %k key id %K key id of the principal key
* %u user id
* %a algorithm %A algorithm of the princ. key
* %l length %L length of the princ. key
* %f flags %F flags of the princ. key
* %c capabilities %C capabilities of the princ. key
* %t trust/validity of the key-uid association
* %[...] date of key using strftime(3)
*/
typedef struct pgp_entry
{
size_t num;
pgp_uid_t *uid;
} pgp_entry_t;
static const char *pgp_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];
pgp_entry_t *entry;
pgp_uid_t *uid;
pgp_key_t *key, *pkey;
int kflags;
int optional = (flags & M_FORMAT_OPTIONAL);
entry = (pgp_entry_t *) data;
uid = entry->uid;
key = uid->parent;
pkey = pgp_principal_key (key);
if (isupper (op))
{
key = pkey;
kflags = pkey->flags;
}
else
/* a subkey inherits the principal key's usage restrictions. */
kflags = key->flags | (pkey->flags & KEYFLAG_RESTRICTIONS);
switch (tolower (op))
{
case '[':
{
const char *cp;
char buf2[SHORT_STRING], *p;
int do_locales;
struct tm *tm;
size_t len;
p = dest;
cp = src;
if (*cp == '!')
{
do_locales = 0;
cp++;
}
else
do_locales = 1;
len = destlen - 1;
while (len > 0 && *cp != ']')
{
if (*cp == '%')
{
cp++;
if (len >= 2)
{
*p++ = '%';
*p++ = *cp;
len -= 2;
}
else
break; /* not enough space */
cp++;
}
else
{
*p++ = *cp++;
len--;
}
}
*p = 0;
if (do_locales && Locale)
setlocale