NeoMutt  2020-08-21-74-g346364
Teaching an old dog new tricks
DOXYGEN
address.h File Reference

Representation of an email address. More...

#include <stddef.h>
#include <stdbool.h>
#include "mutt/lib.h"
+ Include dependency graph for address.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Address
 An email address. More...
 

Macros

#define address_error(num)   AddressErrors[num]
 

Typedefs

typedef bool(* addr_predicate_t) (const struct Address *a)
 Test an Address for some condition. More...
 

Enumerations

enum  AddressError {
  ADDR_ERR_MEMORY = 1, ADDR_ERR_MISMATCH_PAREN, ADDR_ERR_MISMATCH_QUOTE, ADDR_ERR_BAD_ROUTE,
  ADDR_ERR_BAD_ROUTE_ADDR, ADDR_ERR_BAD_ADDR_SPEC
}
 possible values for AddressError More...
 

Functions

 TAILQ_HEAD (AddressList, Address)
 
void mutt_addr_cat (char *buf, size_t buflen, const char *value, const char *specials)
 Copy a string and wrap it in quotes if it contains special characters. More...
 
bool mutt_addr_valid_msgid (const char *msgid)
 Is this a valid Message ID? More...
 
bool mutt_addr_cmp (const struct Address *a, const struct Address *b)
 Compare two e-mail addresses. More...
 
struct Addressmutt_addr_copy (const struct Address *addr)
 Copy the real address. More...
 
struct Addressmutt_addr_create (const char *personal, const char *mailbox)
 Create and populate a new Address. More...
 
const char * mutt_addr_for_display (const struct Address *a)
 Convert an Address for display purposes. More...
 
void mutt_addr_free (struct Address **ptr)
 Free a single Address. More...
 
struct Addressmutt_addr_new (void)
 Create a new Address. More...
 
bool mutt_addr_to_intl (struct Address *a)
 Convert an Address to Punycode. More...
 
bool mutt_addr_to_local (struct Address *a)
 Convert an Address from Punycode. More...
 
bool mutt_addr_uses_unicode (const char *str)
 Does this address use Unicode character. More...
 
size_t mutt_addr_write (char *buf, size_t buflen, struct Address *addr, bool display)
 Write a single Address to a buffer. More...
 
void mutt_addrlist_append (struct AddressList *al, struct Address *a)
 Append an Address to an AddressList. More...
 
void mutt_addrlist_clear (struct AddressList *al)
 Unlink and free all Address in an AddressList. More...
 
void mutt_addrlist_copy (struct AddressList *dst, const struct AddressList *src, bool prune)
 Copy a list of addresses into another list. More...
 
int mutt_addrlist_count_recips (const struct AddressList *al)
 Count the number of Addresses with valid recipients. More...
 
void mutt_addrlist_dedupe (struct AddressList *al)
 Remove duplicate addresses. More...
 
bool mutt_addrlist_equal (const struct AddressList *ala, const struct AddressList *alb)
 Compare two Address lists for equality. More...
 
int mutt_addrlist_parse (struct AddressList *al, const char *s)
 Parse a list of email addresses. More...
 
int mutt_addrlist_parse2 (struct AddressList *al, const char *s)
 Parse a list of email addresses. More...
 
void mutt_addrlist_prepend (struct AddressList *al, struct Address *a)
 Prepend an Address to an AddressList. More...
 
void mutt_addrlist_qualify (struct AddressList *al, const char *host)
 Expand local names in an Address list using a hostname. More...
 
int mutt_addrlist_remove (struct AddressList *al, const char *mailbox)
 Remove an Address from a list. More...
 
void mutt_addrlist_remove_xrefs (const struct AddressList *a, struct AddressList *b)
 Remove cross-references. More...
 
bool mutt_addrlist_search (const struct AddressList *haystack, const struct Address *needle)
 Search for an e-mail address in a list. More...
 
int mutt_addrlist_to_intl (struct AddressList *al, char **err)
 Convert an Address list to Punycode. More...
 
int mutt_addrlist_to_local (struct AddressList *al)
 Convert an Address list from Punycode. More...
 
bool mutt_addrlist_uses_unicode (const struct AddressList *al)
 Do any of a list of addresses use Unicode characters. More...
 
size_t mutt_addrlist_write (const struct AddressList *al, char *buf, size_t buflen, bool display)
 Write an Address to a buffer. More...
 
void mutt_addrlist_write_file (const struct AddressList *addr, FILE *fp, int start_col, bool display)
 Wrapper for mutt_write_address() More...
 
size_t mutt_addrlist_write_list (const struct AddressList *al, struct ListHead *list)
 Write Addresses to a List. More...
 

Variables

int AddressError
 An out-of-band error code. More...
 
const char *const AddressErrors []
 Messages for the error codes in AddressError. More...
 
const char AddressSpecials []
 Characters with special meaning for email addresses. More...
 

Detailed Description

Representation of an email address.

Authors
  • Richard Russon
  • Pietro Cerutti

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, see http://www.gnu.org/licenses/.

Definition in file address.h.

Macro Definition Documentation

◆ address_error

#define address_error (   num)    AddressErrors[num]

Definition at line 62 of file address.h.

Typedef Documentation

◆ addr_predicate_t

typedef bool(* addr_predicate_t) (const struct Address *a)

Test an Address for some condition.

Parameters
aAddress to test
Return values
boolTrue if Address matches the test

Definition at line 69 of file address.h.

Enumeration Type Documentation

◆ AddressError

possible values for AddressError

Enumerator
ADDR_ERR_MEMORY 

Out of memory.

ADDR_ERR_MISMATCH_PAREN 

Mismatched parentheses.

ADDR_ERR_MISMATCH_QUOTE 

Mismatches quotes.

ADDR_ERR_BAD_ROUTE 

Bad route.

ADDR_ERR_BAD_ROUTE_ADDR 

Bad route address.

ADDR_ERR_BAD_ADDR_SPEC 

Bad address specifier.

Definition at line 48 of file address.h.

49 {
50  ADDR_ERR_MEMORY = 1,
56 };
Bad route address.
Definition: address.h:54
Mismatches quotes.
Definition: address.h:52
Bad address specifier.
Definition: address.h:55
Out of memory.
Definition: address.h:50
Mismatched parentheses.
Definition: address.h:51
Bad route.
Definition: address.h:53

Function Documentation

◆ TAILQ_HEAD()

TAILQ_HEAD ( AddressList  ,
Address   
)

◆ mutt_addr_cat()

void mutt_addr_cat ( char *  buf,
size_t  buflen,
const char *  value,
const char *  specials 
)

Copy a string and wrap it in quotes if it contains special characters.

Parameters
bufBuffer for the result
buflenLength of the result buffer
valueString to copy
specialsCharacters to lookup

This function copies the string in the "value" parameter in the buffer pointed to by "buf" parameter. If the input string contains any of the characters specified in the "specials" parameters, the output string is wrapped in double quoted. Additionally, any backslashes or quotes inside the input string are backslash-escaped.

Definition at line 681 of file address.c.

682 {
683  if (!buf || !value || !specials)
684  return;
685 
686  if (strpbrk(value, specials))
687  {
688  char tmp[256];
689  char *pc = tmp;
690  size_t tmplen = sizeof(tmp) - 3;
691 
692  *pc++ = '"';
693  for (; *value && (tmplen > 1); value++)
694  {
695  if ((*value == '\\') || (*value == '"'))
696  {
697  *pc++ = '\\';
698  tmplen--;
699  }
700  *pc++ = *value;
701  tmplen--;
702  }
703  *pc++ = '"';
704  *pc = '\0';
705  mutt_str_copy(buf, tmp, buflen);
706  }
707  else
708  mutt_str_copy(buf, value, buflen);
709 }
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addr_valid_msgid()

bool mutt_addr_valid_msgid ( const char *  msgid)

Is this a valid Message ID?

Parameters
msgidMessage ID
Return values
trueIt is a valid message ID

Incomplete. Only used to thwart the APOP MD5 attack

Definition at line 764 of file address.c.

765 {
766  /* msg-id = "<" addr-spec ">"
767  * addr-spec = local-part "@" domain
768  * local-part = word *("." word)
769  * word = atom / quoted-string
770  * atom = 1*<any CHAR except specials, SPACE and CTLs>
771  * CHAR = ( 0.-127. )
772  * specials = "(" / ")" / "<" / ">" / "@"
773  * / "," / ";" / ":" / "\" / <">
774  * / "." / "[" / "]"
775  * SPACE = ( 32. )
776  * CTLS = ( 0.-31., 127.)
777  * quoted-string = <"> *(qtext/quoted-pair) <">
778  * qtext = <any CHAR except <">, "\" and CR>
779  * CR = ( 13. )
780  * quoted-pair = "\" CHAR
781  * domain = sub-domain *("." sub-domain)
782  * sub-domain = domain-ref / domain-literal
783  * domain-ref = atom
784  * domain-literal = "[" *(dtext / quoted-pair) "]"
785  */
786 
787  if (!msgid || (*msgid == '\0'))
788  return false;
789 
790  size_t l = mutt_str_len(msgid);
791  if (l < 5) /* <atom@atom> */
792  return false;
793  if ((msgid[0] != '<') || (msgid[l - 1] != '>'))
794  return false;
795  if (!(strrchr(msgid, '@')))
796  return false;
797 
798  /* TODO: complete parser */
799  for (size_t i = 0; i < l; i++)
800  if ((unsigned char) msgid[i] > 127)
801  return false;
802 
803  return true;
804 }
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addr_cmp()

bool mutt_addr_cmp ( const struct Address a,
const struct Address b 
)

Compare two e-mail addresses.

Parameters
aAddress 1
bAddress 2
Return values
trueif they are equivalent

Definition at line 864 of file address.c.

865 {
866  if (!a || !b)
867  return false;
868  if (!a->mailbox || !b->mailbox)
869  return false;
870  if (!mutt_istr_equal(a->mailbox, b->mailbox))
871  return false;
872  return true;
873 }
char * mailbox
Mailbox and host address.
Definition: address.h:37
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addr_copy()

struct Address* mutt_addr_copy ( const struct Address addr)

Copy the real address.

Parameters
addrAddress to copy
Return values
ptrNew Address

Definition at line 716 of file address.c.

717 {
718  if (!addr)
719  return NULL;
720 
721  struct Address *p = mutt_addr_new();
722 
723  p->personal = mutt_str_dup(addr->personal);
724  p->mailbox = mutt_str_dup(addr->mailbox);
725  p->group = addr->group;
726  p->is_intl = addr->is_intl;
727  p->intl_checked = addr->intl_checked;
728  return p;
729 }
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
struct Address * mutt_addr_new(void)
Create a new Address.
Definition: address.c:385
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
bool is_intl
International Domain Name.
Definition: address.h:39
bool intl_checked
Checked for IDN?
Definition: address.h:40
char * personal
Real name of address.
Definition: address.h:36
bool group
Group mailbox?
Definition: address.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addr_create()

struct Address* mutt_addr_create ( const char *  personal,
const char *  mailbox 
)

Create and populate a new Address.

Parameters
[in]personalThe personal name for the Address (can be NULL)
[in]mailboxThe mailbox for the Address (can be NULL)
Return values
ptrNewly allocated Address
Note
The personal and mailbox values, if not NULL, are going to be copied into the newly allocated Address.

Definition at line 398 of file address.c.

399 {
400  struct Address *a = mutt_addr_new();
403  return a;
404 }
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
struct Address * mutt_addr_new(void)
Create a new Address.
Definition: address.c:385
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
char * personal
Real name of address.
Definition: address.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addr_for_display()

const char* mutt_addr_for_display ( const struct Address a)

Convert an Address for display purposes.

Parameters
aAddress to convert
Return values
ptrAddress to display
Warning
This function may return a static pointer. It must not be freed by the caller. Later calls may overwrite the returned pointer.

Definition at line 986 of file address.c.

987 {
988  if (!a)
989  return NULL;
990 
991  char *user = NULL, *domain = NULL;
992  static char *buf = NULL;
993 
994  if (!a->mailbox || addr_is_local(a))
995  return a->mailbox;
996 
997  if (addr_mbox_to_udomain(a->mailbox, &user, &domain) == -1)
998  return a->mailbox;
999 
1000  char *local_mailbox = mutt_idna_intl_to_local(user, domain, MI_MAY_BE_IRREVERSIBLE);
1001 
1002  FREE(&user);
1003  FREE(&domain);
1004 
1005  if (!local_mailbox)
1006  return a->mailbox;
1007 
1008  mutt_str_replace(&buf, local_mailbox);
1009  FREE(&local_mailbox);
1010 
1011  return buf;
1012 }
char * mailbox
Mailbox and host address.
Definition: address.h:37
static int addr_mbox_to_udomain(const char *mbox, char **user, char **domain)
Split a mailbox name into user and domain.
Definition: address.c:929
static bool addr_is_local(const struct Address *a)
Does the Address have NO IDN components.
Definition: address.c:912
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
#define FREE(x)
Definition: memory.h:40
#define MI_MAY_BE_IRREVERSIBLE
Definition: idna2.h:32
char * mutt_idna_intl_to_local(const char *user, const char *domain, int flags)
Convert an email&#39;s domain from Punycode.
Definition: idna.c:147
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addr_free()

void mutt_addr_free ( struct Address **  ptr)

Free a single Address.

Parameters
[out]ptrAddress to free

Definition at line 440 of file address.c.

441 {
442  if (!ptr || !*ptr)
443  return;
444 
445  struct Address *a = *ptr;
446 
447  FREE(&a->personal);
448  FREE(&a->mailbox);
449  FREE(ptr);
450 }
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
char * personal
Real name of address.
Definition: address.h:36
#define FREE(x)
Definition: memory.h:40
+ Here is the caller graph for this function:

◆ mutt_addr_new()

struct Address* mutt_addr_new ( void  )

Create a new Address.

Return values
ptrNewly allocated Address

Free the result with mutt_addr_free()

Definition at line 385 of file address.c.

386 {
387  return mutt_mem_calloc(1, sizeof(struct Address));
388 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
An email address.
Definition: address.h:34
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addr_to_intl()

bool mutt_addr_to_intl ( struct Address a)

Convert an Address to Punycode.

Parameters
aAddress to convert
Return values
boolTrue on success, false otherwise

Definition at line 1275 of file address.c.

1276 {
1277  if (!a || !a->mailbox || addr_is_intl(a))
1278  return true;
1279 
1280  char *user = NULL;
1281  char *domain = NULL;
1282  if (addr_mbox_to_udomain(a->mailbox, &user, &domain) == -1)
1283  return true;
1284 
1285  char *intl_mailbox = mutt_idna_local_to_intl(user, domain);
1286 
1287  FREE(&user);
1288  FREE(&domain);
1289 
1290  if (!intl_mailbox)
1291  return false;
1292 
1293  addr_set_intl(a, intl_mailbox);
1294  return true;
1295 }
static void addr_set_intl(struct Address *a, char *intl_mailbox)
Mark an Address as having IDN components.
Definition: address.c:951
char * mailbox
Mailbox and host address.
Definition: address.h:37
static int addr_mbox_to_udomain(const char *mbox, char **user, char **domain)
Split a mailbox name into user and domain.
Definition: address.c:929
static bool addr_is_intl(const struct Address *a)
Does the Address have IDN components.
Definition: address.c:900
#define FREE(x)
Definition: memory.h:40
char * mutt_idna_local_to_intl(const char *user, const char *domain)
Convert an email&#39;s domain to Punycode.
Definition: idna.c:265
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addr_to_local()

bool mutt_addr_to_local ( struct Address a)

Convert an Address from Punycode.

Parameters
aAddress to convert
Return values
boolTrue on success, false otherwise

Definition at line 1349 of file address.c.

1350 {
1351  if (!a->mailbox)
1352  {
1353  return false;
1354  }
1355 
1356  if (addr_is_local(a))
1357  {
1358  return true;
1359  }
1360 
1361  char *user = NULL;
1362  char *domain = NULL;
1363  if (addr_mbox_to_udomain(a->mailbox, &user, &domain) == -1)
1364  {
1365  return false;
1366  }
1367 
1368  char *local_mailbox = mutt_idna_intl_to_local(user, domain, 0);
1369  FREE(&user);
1370  FREE(&domain);
1371 
1372  if (!local_mailbox)
1373  {
1374  return false;
1375  }
1376 
1377  addr_set_local(a, local_mailbox);
1378  return true;
1379 }
static void addr_set_local(struct Address *a, char *local_mailbox)
Mark an Address as having NO IDN components.
Definition: address.c:967
char * mailbox
Mailbox and host address.
Definition: address.h:37
static int addr_mbox_to_udomain(const char *mbox, char **user, char **domain)
Split a mailbox name into user and domain.
Definition: address.c:929
static bool addr_is_local(const struct Address *a)
Does the Address have NO IDN components.
Definition: address.c:912
#define FREE(x)
Definition: memory.h:40
char * mutt_idna_intl_to_local(const char *user, const char *domain, int flags)
Convert an email&#39;s domain from Punycode.
Definition: idna.c:147
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addr_uses_unicode()

bool mutt_addr_uses_unicode ( const char *  str)

Does this address use Unicode character.

Parameters
strAddress string to check
Return values
trueIf the string uses 8-bit characters

Definition at line 1510 of file address.c.

1511 {
1512  if (!str)
1513  return false;
1514 
1515  while (*str)
1516  {
1517  if ((unsigned char) *str & (1 << 7))
1518  return true;
1519  str++;
1520  }
1521 
1522  return false;
1523 }
+ Here is the caller graph for this function:

◆ mutt_addr_write()

size_t mutt_addr_write ( char *  buf,
size_t  buflen,
struct Address addr,
bool  display 
)

Write a single Address to a buffer.

Parameters
bufBuffer for the Address
buflenLength of the buffer
addrAddress to display
displayThis address will be displayed to the user
Return values
numLength of the string written to buf

If 'display' is set, then it doesn't matter if the transformation isn't reversible.

Definition at line 1025 of file address.c.

1026 {
1027  if (!buf || (buflen == 0) || !addr)
1028  return 0;
1029 
1030  if (!addr->personal && !addr->mailbox)
1031  return 0;
1032 
1033  size_t len;
1034  char *pbuf = buf;
1035  char *pc = NULL;
1036 
1037  buflen--; /* save room for the terminal nul */
1038 
1039  if (addr->personal)
1040  {
1041  if (strpbrk(addr->personal, AddressSpecials))
1042  {
1043  if (buflen == 0)
1044  goto done;
1045  *pbuf++ = '"';
1046  buflen--;
1047  for (pc = addr->personal; *pc && (buflen > 0); pc++)
1048  {
1049  if ((*pc == '"') || (*pc == '\\'))
1050  {
1051  *pbuf++ = '\\';
1052  buflen--;
1053  }
1054  if (buflen == 0)
1055  goto done;
1056  *pbuf++ = *pc;
1057  buflen--;
1058  }
1059  if (buflen == 0)
1060  goto done;
1061  *pbuf++ = '"';
1062  buflen--;
1063  }
1064  else
1065  {
1066  if (buflen == 0)
1067  goto done;
1068  len = mutt_str_copy(pbuf, addr->personal, buflen + 1);
1069  pbuf += len;
1070  buflen -= len;
1071  }
1072 
1073  if (buflen == 0)
1074  goto done;
1075  *pbuf++ = ' ';
1076  buflen--;
1077  }
1078 
1079  if (addr->personal || (addr->mailbox && (*addr->mailbox == '@')))
1080  {
1081  if (buflen == 0)
1082  goto done;
1083  *pbuf++ = '<';
1084  buflen--;
1085  }
1086 
1087  if (addr->mailbox)
1088  {
1089  if (buflen == 0)
1090  goto done;
1091  if (mutt_str_equal(addr->mailbox, "@"))
1092  {
1093  *pbuf = '\0';
1094  }
1095  else
1096  {
1097  const char *a = display ? mutt_addr_for_display(addr) : addr->mailbox;
1098  len = mutt_str_copy(pbuf, a, buflen + 1);
1099  pbuf += len;
1100  buflen -= len;
1101  }
1102 
1103  if (addr->personal || (addr->mailbox && (*addr->mailbox == '@')))
1104  {
1105  if (buflen == 0)
1106  goto done;
1107  *pbuf++ = '>';
1108  buflen--;
1109  }
1110 
1111  if (addr->group)
1112  {
1113  if (buflen == 0)
1114  goto done;
1115  *pbuf++ = ':';
1116  buflen--;
1117  if (buflen == 0)
1118  goto done;
1119  *pbuf++ = ' ';
1120  buflen--;
1121  }
1122  }
1123  else
1124  {
1125  if (buflen == 0)
1126  goto done;
1127  *pbuf++ = ';';
1128  }
1129 done:
1130  /* no need to check for length here since we already save space at the
1131  * beginning of this routine */
1132  *pbuf = '\0';
1133 
1134  return pbuf - buf;
1135 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
const char AddressSpecials[]
Characters with special meaning for email addresses.
Definition: address.c:42
char * mailbox
Mailbox and host address.
Definition: address.h:37
const char * mutt_addr_for_display(const struct Address *a)
Convert an Address for display purposes.
Definition: address.c:986
char * personal
Real name of address.
Definition: address.h:36
bool group
Group mailbox?
Definition: address.h:38
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
static unsigned char * pbuf
Cache PGP data packet.
Definition: pgppacket.c:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_append()

void mutt_addrlist_append ( struct AddressList *  al,
struct Address a 
)

Append an Address to an AddressList.

Parameters
alAddressList
aAddress

Definition at line 1488 of file address.c.

1489 {
1490  if (al && a)
1491  TAILQ_INSERT_TAIL(al, a, entries);
1492 }
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
+ Here is the caller graph for this function:

◆ mutt_addrlist_clear()

void mutt_addrlist_clear ( struct AddressList *  al)

Unlink and free all Address in an AddressList.

Parameters
alAddressList
Note
After this call, the AddressList is reinitialized and ready for reuse.

Definition at line 1468 of file address.c.

1469 {
1470  if (!al)
1471  return;
1472 
1473  struct Address *a = TAILQ_FIRST(al), *next = NULL;
1474  while (a)
1475  {
1476  next = TAILQ_NEXT(a, entries);
1477  mutt_addr_free(&a);
1478  a = next;
1479  }
1480  TAILQ_INIT(al);
1481 }
#define TAILQ_FIRST(head)
Definition: queue.h:716
An email address.
Definition: address.h:34
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
#define TAILQ_INIT(head)
Definition: queue.h:758
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_copy()

void mutt_addrlist_copy ( struct AddressList *  dst,
const struct AddressList *  src,
bool  prune 
)

Copy a list of addresses into another list.

Parameters
dstDestination Address list
srcSource Address list
pruneSkip groups if there are more addresses

Definition at line 737 of file address.c.

738 {
739  if (!dst || !src)
740  return;
741 
742  struct Address *a = NULL;
743  TAILQ_FOREACH(a, src, entries)
744  {
745  struct Address *next = TAILQ_NEXT(a, entries);
746  if (prune && a->group && (!next || !next->mailbox))
747  {
748  /* ignore this element of the list */
749  }
750  else
751  {
753  }
754  }
755 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
struct Address * mutt_addr_copy(const struct Address *addr)
Copy the real address.
Definition: address.c:716
bool group
Group mailbox?
Definition: address.h:38
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1488
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_count_recips()

int mutt_addrlist_count_recips ( const struct AddressList *  al)

Count the number of Addresses with valid recipients.

Parameters
alAddress list
Return values
numNumber of valid Addresses

An Address has a recipient if the mailbox is set and is not a group

Definition at line 844 of file address.c.

845 {
846  if (!al)
847  return 0;
848 
849  int c = 0;
850  struct Address *a = NULL;
851  TAILQ_FOREACH(a, al, entries)
852  {
853  c += (a->mailbox && !a->group);
854  }
855  return c;
856 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
bool group
Group mailbox?
Definition: address.h:38
+ Here is the caller graph for this function:

◆ mutt_addrlist_dedupe()

void mutt_addrlist_dedupe ( struct AddressList *  al)

Remove duplicate addresses.

Parameters
alAddress list to de-dupe

Given a list of addresses, return a list of unique addresses

Definition at line 1405 of file address.c.

1406 {
1407  if (!al)
1408  return;
1409 
1410  struct Address *a = NULL;
1411  TAILQ_FOREACH(a, al, entries)
1412  {
1413  if (a->mailbox)
1414  {
1415  struct Address *a2 = TAILQ_NEXT(a, entries);
1416  struct Address *tmp = NULL;
1417 
1418  if (a2)
1419  {
1420  TAILQ_FOREACH_FROM_SAFE(a2, al, entries, tmp)
1421  {
1422  if (a2->mailbox && mutt_istr_equal(a->mailbox, a2->mailbox))
1423  {
1424  mutt_debug(LL_DEBUG2, "Removing %s\n", a2->mailbox);
1425  TAILQ_REMOVE(al, a2, entries);
1426  mutt_addr_free(&a2);
1427  }
1428  }
1429  }
1430  }
1431  }
1432 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
Log at debug level 2.
Definition: logging.h:41
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)
Definition: queue.h:733
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_equal()

bool mutt_addrlist_equal ( const struct AddressList *  ala,
const struct AddressList *  alb 
)

Compare two Address lists for equality.

Parameters
alaFirst Address
albSecond Address
Return values
trueAddress lists are strictly identical

Definition at line 812 of file address.c.

813 {
814  if (!ala || !alb)
815  {
816  return !(ala || alb);
817  }
818 
819  struct Address *ana = TAILQ_FIRST(ala);
820  struct Address *anb = TAILQ_FIRST(alb);
821 
822  while (ana && anb)
823  {
824  if (!mutt_str_equal(ana->mailbox, anb->mailbox) ||
825  !mutt_str_equal(ana->personal, anb->personal))
826  {
827  break;
828  }
829 
830  ana = TAILQ_NEXT(ana, entries);
831  anb = TAILQ_NEXT(anb, entries);
832  }
833 
834  return !(ana || anb);
835 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
#define TAILQ_FIRST(head)
Definition: queue.h:716
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
char * personal
Real name of address.
Definition: address.h:36
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_parse()

int mutt_addrlist_parse ( struct AddressList *  al,
const char *  s 
)

Parse a list of email addresses.

Parameters
alAddressList to append addresses
sString to parse
Return values
numNumber of parsed addresses

Definition at line 458 of file address.c.

459 {
460  if (!s)
461  return 0;
462 
463  int parsed = 0;
464  char comment[1024], phrase[1024];
465  size_t phraselen = 0, commentlen = 0;
466  AddressError = 0;
467 
468  bool ws_pending = mutt_str_is_email_wsp(*s);
469 
471  while (*s)
472  {
473  switch (*s)
474  {
475  case ';':
476  case ',':
477  if (phraselen != 0)
478  {
479  terminate_buffer(phrase, phraselen);
480  if (add_addrspec(al, phrase, comment, &commentlen, sizeof(comment) - 1))
481  {
482  parsed++;
483  }
484  }
485  else if (commentlen != 0)
486  {
487  struct Address *last = TAILQ_LAST(al, AddressList);
488  if (last && !last->personal && last->mailbox)
489  {
490  terminate_buffer(comment, commentlen);
491  last->personal = mutt_str_dup(comment);
492  }
493  }
494 
495  if (*s == ';')
496  {
497  /* add group terminator */
499  }
500 
501  phraselen = 0;
502  commentlen = 0;
503  s++;
504  break;
505 
506  case '(':
507  if ((commentlen != 0) && (commentlen < (sizeof(comment) - 1)))
508  comment[commentlen++] = ' ';
509  s = next_token(s, comment, &commentlen, sizeof(comment) - 1);
510  if (!s)
511  {
513  return 0;
514  }
515  break;
516 
517  case '"':
518  if ((phraselen != 0) && (phraselen < (sizeof(phrase) - 1)))
519  phrase[phraselen++] = ' ';
520  s = parse_quote(s + 1, phrase, &phraselen, sizeof(phrase) - 1);
521  if (!s)
522  {
524  return 0;
525  }
526  break;
527 
528  case ':':
529  {
530  struct Address *a = mutt_addr_new();
531  terminate_buffer(phrase, phraselen);
532  a->mailbox = mutt_str_dup(phrase);
533  a->group = true;
534  mutt_addrlist_append(al, a);
535  phraselen = 0;
536  commentlen = 0;
537  s++;
538  break;
539  }
540 
541  case '<':
542  {
543  struct Address *a = mutt_addr_new();
544  terminate_buffer(phrase, phraselen);
545  a->personal = mutt_str_dup(phrase);
546  s = parse_route_addr(s + 1, comment, &commentlen, sizeof(comment) - 1, a);
547  if (!s)
548  {
550  mutt_addr_free(&a);
551  return 0;
552  }
553  mutt_addrlist_append(al, a);
554  phraselen = 0;
555  commentlen = 0;
556  parsed++;
557  break;
558  }
559 
560  default:
561  if ((phraselen != 0) && (phraselen < (sizeof(phrase) - 1)) && ws_pending)
562  phrase[phraselen++] = ' ';
563  if (*s == '\\')
564  {
565  s++;
566  if (*s && (phraselen < (sizeof(phrase) - 1)))
567  {
568  phrase[phraselen++] = *s;
569  s++;
570  }
571  }
572  s = next_token(s, phrase, &phraselen, sizeof(phrase) - 1);
573  if (!s)
574  {
576  return 0;
577  }
578  break;
579  } // switch (*s)
580 
581  ws_pending = mutt_str_is_email_wsp(*s);
583  } // while (*s)
584 
585  if (phraselen != 0)
586  {
587  terminate_buffer(phrase, phraselen);
588  terminate_buffer(comment, commentlen);
589  if (add_addrspec(al, phrase, comment, &commentlen, sizeof(comment) - 1))
590  {
591  parsed++;
592  }
593  }
594  else if (commentlen != 0)
595  {
596  struct Address *last = TAILQ_LAST(al, AddressList);
597  if (last && !last->personal && last->mailbox)
598  {
599  terminate_buffer(comment, commentlen);
600  last->personal = mutt_str_dup(comment);
601  }
602  }
603 
604  return parsed;
605 }
#define TAILQ_LAST(head, headname)
Definition: queue.h:812
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
static const char * parse_route_addr(const char *s, char *comment, size_t *commentlen, size_t commentmax, struct Address *addr)
Parse an email addresses.
Definition: address.c:283
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
struct Address * mutt_addr_new(void)
Create a new Address.
Definition: address.c:385
static bool add_addrspec(struct AddressList *al, const char *phrase, char *comment, size_t *commentlen, size_t commentmax)
Parse an email address and add an Address to a list.
Definition: address.c:364
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
static const char * parse_quote(const char *s, char *token, size_t *tokenlen, size_t tokenmax)
Extract a quoted string.
Definition: address.c:120
AddressError
possible values for AddressError
Definition: address.h:48
bool mutt_str_is_email_wsp(char c)
Is this a whitespace character (for an email header)
Definition: string.c:759
#define terminate_buffer(str, strlen)
Definition: string2.h:53
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:743
char * personal
Real name of address.
Definition: address.h:36
bool group
Group mailbox?
Definition: address.h:38
static const char * next_token(const char *s, char *token, size_t *tokenlen, size_t tokenmax)
Find the next word, skipping quoted and parenthesised text.
Definition: address.c:151
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1488
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_parse2()

int mutt_addrlist_parse2 ( struct AddressList *  al,
const char *  s 
)

Parse a list of email addresses.

Parameters
alAdd to this List of Addresses
sString to parse
Return values
numNumber of parsed addresses

Simple email addresses (without any personal name or grouping) can be separated by whitespace or commas.

Definition at line 616 of file address.c.

617 {
618  if (!s || (*s == '\0'))
619  return 0;
620 
621  int parsed = 0;
622 
623  /* check for a simple whitespace separated list of addresses */
624  if (!strpbrk(s, "\"<>():;,\\"))
625  {
626  char *copy = mutt_str_dup(s);
627  char *r = copy;
628  while ((r = strtok(r, " \t")))
629  {
630  parsed += mutt_addrlist_parse(al, r);
631  r = NULL;
632  }
633  FREE(&copy);
634  }
635  else
636  parsed = mutt_addrlist_parse(al, s);
637 
638  return parsed;
639 }
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_prepend()

void mutt_addrlist_prepend ( struct AddressList *  al,
struct Address a 
)

Prepend an Address to an AddressList.

Parameters
alAddressList
aAddress

Definition at line 1499 of file address.c.

1500 {
1501  if (al && a)
1502  TAILQ_INSERT_HEAD(al, a, entries);
1503 }
#define TAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:789
+ Here is the caller graph for this function:

◆ mutt_addrlist_qualify()

void mutt_addrlist_qualify ( struct AddressList *  al,
const char *  host 
)

Expand local names in an Address list using a hostname.

Parameters
alAddress list
hostHostname

Any addresses containing a bare name will be expanded using the hostname. e.g. "john", "example.com" -> 'john@.nosp@m.exam.nosp@m.ple.c.nosp@m.om'. This function has no effect if host is NULL or the empty string.

Definition at line 650 of file address.c.

651 {
652  if (!al || !host || (*host == '\0'))
653  return;
654 
655  struct Address *a = NULL;
656  TAILQ_FOREACH(a, al, entries)
657  {
658  if (!a->group && a->mailbox && !strchr(a->mailbox, '@'))
659  {
660  char *p = mutt_mem_malloc(mutt_str_len(a->mailbox) + mutt_str_len(host) + 2);
661  sprintf(p, "%s@%s", a->mailbox, host);
662  FREE(&a->mailbox);
663  a->mailbox = p;
664  }
665  }
666 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
bool group
Group mailbox?
Definition: address.h:38
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_remove()

int mutt_addrlist_remove ( struct AddressList *  al,
const char *  mailbox 
)

Remove an Address from a list.

Parameters
[in,out]alAddressList
[in]mailboxEmail address to match
Return values
0Success
-1Error, or email not found

Definition at line 413 of file address.c.

414 {
415  if (!al)
416  return -1;
417 
418  if (!mailbox)
419  return 0;
420 
421  int rc = -1;
422  struct Address *a = NULL, *tmp = NULL;
423  TAILQ_FOREACH_SAFE(a, al, entries, tmp)
424  {
426  {
427  TAILQ_REMOVE(al, a, entries);
428  mutt_addr_free(&a);
429  rc = 0;
430  }
431  }
432 
433  return rc;
434 }
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:728
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_remove_xrefs()

void mutt_addrlist_remove_xrefs ( const struct AddressList *  a,
struct AddressList *  b 
)

Remove cross-references.

Parameters
aReference AddressList
bAddressLis to trim

Remove addresses from "b" which are contained in "a"

Definition at line 1441 of file address.c.

1442 {
1443  if (!a || !b)
1444  return;
1445 
1446  struct Address *aa = NULL, *ab = NULL, *tmp = NULL;
1447 
1448  TAILQ_FOREACH_SAFE(ab, b, entries, tmp)
1449  {
1450  TAILQ_FOREACH(aa, a, entries)
1451  {
1452  if (mutt_addr_cmp(aa, ab))
1453  {
1454  TAILQ_REMOVE(b, ab, entries);
1455  mutt_addr_free(&ab);
1456  break;
1457  }
1458  }
1459  }
1460 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:728
An email address.
Definition: address.h:34
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
bool mutt_addr_cmp(const struct Address *a, const struct Address *b)
Compare two e-mail addresses.
Definition: address.c:864
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_search()

bool mutt_addrlist_search ( const struct AddressList *  haystack,
const struct Address needle 
)

Search for an e-mail address in a list.

Parameters
haystackAddress List
needleAddress containing the search email
Return values
trueIf the Address is in the list

Definition at line 881 of file address.c.

882 {
883  if (!needle || !haystack)
884  return false;
885 
886  struct Address *a = NULL;
887  TAILQ_FOREACH(a, haystack, entries)
888  {
889  if (mutt_addr_cmp(needle, a))
890  return true;
891  }
892  return false;
893 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
bool mutt_addr_cmp(const struct Address *a, const struct Address *b)
Compare two e-mail addresses.
Definition: address.c:864
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_to_intl()

int mutt_addrlist_to_intl ( struct AddressList *  al,
char **  err 
)

Convert an Address list to Punycode.

Parameters
[in]alAddress list to modify
[out]errPointer for failed addresses
Return values
0Success, all addresses converted
-1Error, err will be set to the failed address

Definition at line 1304 of file address.c.

1305 {
1306  if (!al)
1307  return 0;
1308 
1309  int rc = 0;
1310 
1311  if (err)
1312  *err = NULL;
1313 
1314  struct Address *a = NULL;
1315  TAILQ_FOREACH(a, al, entries)
1316  {
1317  if (!a->mailbox || addr_is_intl(a))
1318  continue;
1319 
1320  char *user = NULL;
1321  char *domain = NULL;
1322  if (addr_mbox_to_udomain(a->mailbox, &user, &domain) == -1)
1323  continue;
1324 
1325  char *intl_mailbox = mutt_idna_local_to_intl(user, domain);
1326 
1327  FREE(&user);
1328  FREE(&domain);
1329 
1330  if (!intl_mailbox)
1331  {
1332  rc = -1;
1333  if (err && !*err)
1334  *err = mutt_str_dup(a->mailbox);
1335  continue;
1336  }
1337 
1338  addr_set_intl(a, intl_mailbox);
1339  }
1340 
1341  return rc;
1342 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
static void addr_set_intl(struct Address *a, char *intl_mailbox)
Mark an Address as having IDN components.
Definition: address.c:951
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
static int addr_mbox_to_udomain(const char *mbox, char **user, char **domain)
Split a mailbox name into user and domain.
Definition: address.c:929
static bool addr_is_intl(const struct Address *a)
Does the Address have IDN components.
Definition: address.c:900
#define FREE(x)
Definition: memory.h:40
char * mutt_idna_local_to_intl(const char *user, const char *domain)
Convert an email&#39;s domain to Punycode.
Definition: idna.c:265
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_to_local()

int mutt_addrlist_to_local ( struct AddressList *  al)

Convert an Address list from Punycode.

Parameters
alAddress list to modify
Return values
0Always

Definition at line 1386 of file address.c.

1387 {
1388  if (!al)
1389  return 0;
1390 
1391  struct Address *a = NULL;
1392  TAILQ_FOREACH(a, al, entries)
1393  {
1394  mutt_addr_to_local(a);
1395  }
1396  return 0;
1397 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
bool mutt_addr_to_local(struct Address *a)
Convert an Address from Punycode.
Definition: address.c:1349
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_uses_unicode()

bool mutt_addrlist_uses_unicode ( const struct AddressList *  al)

Do any of a list of addresses use Unicode characters.

Parameters
alAddress list to check
Return values
trueIf any use 8-bit characters

Definition at line 1530 of file address.c.

1531 {
1532  if (!al)
1533  {
1534  return false;
1535  }
1536 
1537  struct Address *a = NULL;
1538  TAILQ_FOREACH(a, al, entries)
1539  {
1540  if (a->mailbox && !a->group && mutt_addr_uses_unicode(a->mailbox))
1541  return true;
1542  }
1543  return false;
1544 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
bool mutt_addr_uses_unicode(const char *str)
Does this address use Unicode character.
Definition: address.c:1510
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
bool group
Group mailbox?
Definition: address.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_write()

size_t mutt_addrlist_write ( const struct AddressList *  al,
char *  buf,
size_t  buflen,
bool  display 
)

Write an Address to a buffer.

Parameters
alAddressList to display
bufBuffer for the Address
buflenLength of the buffer
displayThis address will be displayed to the user
Return values
numLength of the string written to buf

If 'display' is set, then it doesn't matter if the transformation isn't reversible.

Note
It is assumed that buf is nul terminated!

Definition at line 1150 of file address.c.

1151 {
1152  if (!buf || (buflen == 0) || !al)
1153  return 0;
1154 
1155  size_t len = mutt_str_len(buf);
1156  if (len >= buflen)
1157  {
1158  return 0;
1159  }
1160 
1161  char *pbuf = buf + len;
1162  buflen -= len;
1163 
1164  struct Address *a = NULL;
1165  TAILQ_FOREACH(a, al, entries)
1166  {
1167  if (len > 0)
1168  {
1169  if (buflen > 1)
1170  {
1171  *pbuf++ = ',';
1172  buflen--;
1173  }
1174  if (buflen > 1)
1175  {
1176  *pbuf++ = ' ';
1177  buflen--;
1178  }
1179  }
1180 
1181  if (buflen == 1)
1182  {
1183  break;
1184  }
1185 
1186  len = mutt_addr_write(pbuf, buflen, a, display);
1187  pbuf += len;
1188  buflen -= len;
1189  }
1190 
1191  *pbuf = '\0';
1192  return pbuf - buf;
1193 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display)
Write a single Address to a buffer.
Definition: address.c:1025
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
static unsigned char * pbuf
Cache PGP data packet.
Definition: pgppacket.c:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_write_file()

void mutt_addrlist_write_file ( const struct AddressList *  al,
FILE *  fp,
int  start_col,
bool  display 
)

Wrapper for mutt_write_address()

Parameters
alAddress list
fpFile to write to
start_colStarting column in the output line
displayTrue if these addresses will be displayed to the user

So we can handle very large recipient lists without needing a huge temporary buffer in memory

Definition at line 1231 of file address.c.

1232 {
1233  char buf[1024];
1234  int count = 0;
1235  int linelen = start_col;
1236 
1237  struct Address *a = NULL;
1238  TAILQ_FOREACH(a, al, entries)
1239  {
1240  buf[0] = '\0';
1241  size_t len = mutt_addr_write(buf, sizeof(buf), a, display);
1242  if (len == 0)
1243  continue;
1244  if (count && (linelen + len > 74))
1245  {
1246  fputs("\n\t", fp);
1247  linelen = len + 8; /* tab is usually about 8 spaces... */
1248  }
1249  else
1250  {
1251  if (count && a->mailbox)
1252  {
1253  fputc(' ', fp);
1254  linelen++;
1255  }
1256  linelen += len;
1257  }
1258  fputs(buf, fp);
1259  struct Address *next = TAILQ_NEXT(a, entries);
1260  if (!a->group && next && next->mailbox)
1261  {
1262  linelen++;
1263  fputc(',', fp);
1264  }
1265  count++;
1266  }
1267  fputc('\n', fp);
1268 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display)
Write a single Address to a buffer.
Definition: address.c:1025
bool group
Group mailbox?
Definition: address.h:38
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addrlist_write_list()

size_t mutt_addrlist_write_list ( const struct AddressList *  al,
struct ListHead *  list 
)

Write Addresses to a List.

Parameters
alAddressList to write
listList for the Addresses
Return values
numNumber of addresses written

Definition at line 1201 of file address.c.

1202 {
1203  if (!al || !list)
1204  return 0;
1205 
1206  char addr[256];
1207  size_t count = 0;
1208  struct Address *a = NULL;
1209  TAILQ_FOREACH(a, al, entries)
1210  {
1211  if (mutt_addr_write(addr, sizeof(addr), a, true) != 0)
1212  {
1213  mutt_list_insert_tail(list, strdup(addr));
1214  count++;
1215  }
1216  }
1217 
1218  return count;
1219 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display)
Write a single Address to a buffer.
Definition: address.c:1025
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ AddressError

An out-of-band error code.

Many of the Address functions set this variable on error. Its values are defined in AddressError. Text for the errors can be looked up using AddressErrors.

Definition at line 57 of file address.c.

◆ AddressErrors

const char* const AddressErrors[]

Messages for the error codes in AddressError.

These must defined in the same order as enum AddressError.

Definition at line 64 of file address.c.

◆ AddressSpecials

const char AddressSpecials[]

Characters with special meaning for email addresses.

Definition at line 42 of file address.c.