1 /* GNU Mailutils -- a suite of utilities for electronic mail
2    Copyright (C) 1999-2021 Free Software Foundation, Inc.
3 
4    GNU Mailutils is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8 
9    GNU Mailutils is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
16 
17 #include "mail.h"
18 
19 static mu_list_t retained_headers = NULL;
20 static mu_list_t ignored_headers = NULL;
21 static mu_list_t unfolded_headers = NULL;
22 static mu_list_t sender_headers = NULL;
23 
24 static int
process_list(int argc,char ** argv,mu_list_t * list,void (* fun)(mu_list_t *,char *),char * msg)25 process_list (int argc, char **argv,
26 	      mu_list_t *list,
27 	      void (*fun) (mu_list_t *, char *),
28 	      char *msg)
29 {
30   if (argc == 1)
31     {
32       if (mu_list_is_empty (*list))
33 	mu_printf ("%s", _(msg));
34       else
35 	util_slist_print (*list, 1);
36       return 0;
37     }
38 
39   while (--argc)
40     fun (list, *++argv);
41   return 0;
42 }
43 
44 /*
45  * ret[ain] [heder-field...]
46  */
47 
48 int
mail_retain(int argc,char ** argv)49 mail_retain (int argc, char **argv)
50 {
51   return process_list (argc, argv, &retained_headers,
52 		       util_slist_add,
53 		       N_("No fields are currently being retained\n"));
54 }
55 
56 /*
57  * di[scard] [header-field...]
58  * ig[nore] [header-field...]
59  */
60 
61 int
mail_discard(int argc,char ** argv)62 mail_discard (int argc, char **argv)
63 {
64   return process_list (argc, argv, &ignored_headers,
65 		       util_slist_add,
66 		       N_("No fields are currently being ignored\n"));
67   return 0;
68 }
69 
70 /*
71  * unfold [header-field...]
72  */
73 
74 int
mail_unfold(int argc,char ** argv)75 mail_unfold (int argc, char **argv)
76 {
77   return process_list (argc, argv, &unfolded_headers,
78 		       util_slist_add,
79 		       N_("No fields are currently being unfolded\n"));
80 }
81 
82 /*
83  * nounfold [header-field...]
84  */
85 
86 int
mail_nounfold(int argc,char ** argv)87 mail_nounfold (int argc, char **argv)
88 {
89   return process_list (argc, argv, &unfolded_headers,
90 		       util_slist_remove,
91 		       N_("No fields are currently being unfolded\n"));
92 }
93 
94 int
mail_header_is_unfoldable(const char * str)95 mail_header_is_unfoldable (const char *str)
96 {
97   return util_slist_lookup (unfolded_headers, str);
98 }
99 
100 int
mail_header_is_visible(const char * str)101 mail_header_is_visible (const char *str)
102 {
103   if (retained_headers)
104     return util_slist_lookup (retained_headers, str);
105   else
106     return !util_slist_lookup (ignored_headers, str);
107 }
108 
109 /*
110  * sender [header-field...]
111  */
112 
113 int
mail_sender(int argc,char ** argv)114 mail_sender (int argc, char **argv)
115 {
116   return process_list (argc, argv, &sender_headers,
117 		       util_slist_add,
118 		       N_("Sender address is obtained from the envelope\n"));
119 }
120 
121 int
mail_nosender(int argc,char ** argv)122 mail_nosender (int argc, char **argv)
123 {
124   if (argc == 1)
125     {
126       util_slist_destroy (&sender_headers);
127       mu_printf (
128 			_("Sender address is obtained from the envelope\n"));
129     }
130   else
131     while (--argc)
132       util_slist_remove (&sender_headers, *++argv);
133   return 0;
134 }
135 
136 
137 mu_address_t
get_sender_address(mu_message_t msg)138 get_sender_address (mu_message_t msg)
139 {
140   mu_iterator_t itr;
141   mu_header_t header = NULL;
142   mu_address_t addr = NULL;
143 
144   if (mu_message_get_header (msg, &header))
145     return NULL;
146 
147   if (!sender_headers || mu_list_get_iterator (sender_headers, &itr))
148     return NULL;
149 
150   for (mu_iterator_first (itr); !addr && !mu_iterator_is_done (itr);
151        mu_iterator_next (itr))
152     {
153       char *name;
154       char *buf = NULL;
155 
156       mu_iterator_current (itr, (void **)&name);
157       if (mu_header_aget_value (header, name, &buf) == 0)
158 	mu_address_create (&addr, buf);
159       free (buf);
160     }
161   mu_iterator_destroy (&itr);
162   return addr;
163 }
164 
165