NeoMutt  2025-12-11-949-g4870ee
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
sort_gpgme.c
Go to the documentation of this file.
1
23
29
30#include "config.h"
31#include <gpgme.h>
32#include <locale.h>
33#include <stdbool.h>
34#include "mutt/lib.h"
35#include "config/lib.h"
36#include "core/lib.h"
37#include "lib.h"
38#include "crypt_gpgme.h"
39#include "sort.h"
40
44static int crypt_sort_address(const void *a, const void *b, void *sdata)
45{
46 struct CryptKeyInfo *s = *(struct CryptKeyInfo **) a;
47 struct CryptKeyInfo *t = *(struct CryptKeyInfo **) b;
48 const bool sort_reverse = *(bool *) sdata;
49
50 int rc = mutt_istr_cmp(s->uid, t->uid);
51 if (rc != 0)
52 goto done;
53
55
56done:
57 return sort_reverse ? -rc : rc;
58}
59
63static int crypt_sort_keyid(const void *a, const void *b, void *sdata)
64{
65 struct CryptKeyInfo *s = *(struct CryptKeyInfo **) a;
66 struct CryptKeyInfo *t = *(struct CryptKeyInfo **) b;
67 const bool sort_reverse = *(bool *) sdata;
68
70 if (rc != 0)
71 goto done;
72
73 rc = mutt_istr_cmp(s->uid, t->uid);
74
75done:
76 return sort_reverse ? -rc : rc;
77}
78
82static int crypt_sort_date(const void *a, const void *b, void *sdata)
83{
84 struct CryptKeyInfo *s = *(struct CryptKeyInfo **) a;
85 struct CryptKeyInfo *t = *(struct CryptKeyInfo **) b;
86 const bool sort_reverse = *(bool *) sdata;
87
88 unsigned long ts = 0;
89 unsigned long tt = 0;
90 int rc = 0;
91
92 if (s->kobj->subkeys && (s->kobj->subkeys->timestamp > 0))
93 ts = s->kobj->subkeys->timestamp;
94 if (t->kobj->subkeys && (t->kobj->subkeys->timestamp > 0))
95 tt = t->kobj->subkeys->timestamp;
96
97 if (ts > tt)
98 {
99 rc = 1;
100 goto done;
101 }
102
103 if (ts < tt)
104 {
105 rc = -1;
106 goto done;
107 }
108
109 rc = mutt_istr_cmp(s->uid, t->uid);
110
111done:
112 return sort_reverse ? -rc : rc;
113}
114
118static int crypt_sort_trust(const void *a, const void *b, void *sdata)
119{
120 struct CryptKeyInfo *s = *(struct CryptKeyInfo **) a;
121 struct CryptKeyInfo *t = *(struct CryptKeyInfo **) b;
122 const bool sort_reverse = *(bool *) sdata;
123
124 unsigned long ts = 0;
125 unsigned long tt = 0;
126
128 if (rc != 0)
129 goto done;
130
131 // Note: reversed
133 if (rc != 0)
134 return rc;
135
136 ts = 0;
137 tt = 0;
138 if (s->kobj->subkeys)
139 ts = s->kobj->subkeys->length;
140 if (t->kobj->subkeys)
141 tt = t->kobj->subkeys->length;
142
143 // Note: reversed
144 rc = mutt_numeric_cmp(tt, ts);
145 if (rc != 0)
146 goto done;
147
148 ts = 0;
149 tt = 0;
150 if (s->kobj->subkeys && (s->kobj->subkeys->timestamp > 0))
151 ts = s->kobj->subkeys->timestamp;
152 if (t->kobj->subkeys && (t->kobj->subkeys->timestamp > 0))
153 tt = t->kobj->subkeys->timestamp;
154
155 // Note: reversed
156 rc = mutt_numeric_cmp(tt, ts);
157 if (rc != 0)
158 goto done;
159
160 rc = mutt_istr_cmp(s->uid, t->uid);
161 if (rc != 0)
162 goto done;
163
165
166done:
167 return sort_reverse ? -rc : rc;
168}
169
176void gpgme_sort_keys(struct CryptKeyInfoArray *ckia)
177{
178 const short c_pgp_sort_keys = cs_subset_sort(NeoMutt->sub, "pgp_key_sort");
179 sort_t fn = NULL;
180 switch (c_pgp_sort_keys & SORT_MASK)
181 {
182 case KEY_SORT_ADDRESS:
184 break;
185 case KEY_SORT_DATE:
186 fn = crypt_sort_date;
187 break;
188 case KEY_SORT_KEYID:
189 fn = crypt_sort_keyid;
190 break;
191 case KEY_SORT_TRUST:
192 default:
193 fn = crypt_sort_trust;
194 break;
195 }
196
197 if (ARRAY_SIZE(ckia) > 1)
198 {
199 bool sort_reverse = c_pgp_sort_keys & SORT_REVERSE;
200 ARRAY_SORT(ckia, fn, &sort_reverse);
201 }
202}
#define ARRAY_SORT(head, fn, sdata)
Sort an array.
Definition array.h:373
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition helpers.c:266
Convenience wrapper for the config headers.
#define SORT_MASK
Mask for the sort id.
Definition sort.h:39
#define mutt_numeric_cmp(a, b)
Compare two numbers, return -1, 0, or 1.
Definition sort.h:27
#define SORT_REVERSE
Reverse the order of the sort.
Definition sort.h:40
Convenience wrapper for the core headers.
const char * crypt_fpr_or_lkeyid(struct CryptKeyInfo *k)
Find the fingerprint of a key.
Wrapper for PGP/SMIME calls to GPGME.
static int crypt_sort_trust(const void *a, const void *b, void *sdata)
Compare two keys by their trust levels - Implements sort_t -.
Definition sort_gpgme.c:118
static int crypt_sort_address(const void *a, const void *b, void *sdata)
Compare two keys by their addresses - Implements sort_t -.
Definition sort_gpgme.c:44
static int crypt_sort_date(const void *a, const void *b, void *sdata)
Compare two keys by their dates - Implements sort_t -.
Definition sort_gpgme.c:82
static int crypt_sort_keyid(const void *a, const void *b, void *sdata)
Compare two keys by their IDs - Implements sort_t -.
Definition sort_gpgme.c:63
Convenience wrapper for the library headers.
int mutt_istr_cmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition string.c:416
API for encryption/signing of emails.
#define KEYFLAG_RESTRICTIONS
Definition lib.h:162
Crypto Key sorting functions.
@ KEY_SORT_ADDRESS
Sort by address.
Definition sort.h:34
@ KEY_SORT_DATE
Sort by date.
Definition sort.h:35
@ KEY_SORT_TRUST
Sort by trust level.
Definition sort.h:37
@ KEY_SORT_KEYID
Sort by key id.
Definition sort.h:36
int(* sort_t)(const void *a, const void *b, void *sdata)
Definition qsort_r.h:41
void gpgme_sort_keys(struct CryptKeyInfoArray *ckia)
Sort an array of GPGME keys.
Definition sort_gpgme.c:176
A stored PGP key.
Definition crypt_gpgme.h:45
gpgme_validity_t validity
uid validity (cached for convenience)
Definition crypt_gpgme.h:51
KeyFlags flags
global and per uid flags (for convenience)
Definition crypt_gpgme.h:50
const char * uid
and for convenience point to this user ID
Definition crypt_gpgme.h:49
gpgme_key_t kobj
GPGME key object.
Definition crypt_gpgme.h:47
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49