1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999-2021 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library 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 GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
18 #if HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <sys/types.h>
26 #include <stdio.h>
27 #include <mailutils/types.h>
28 #include <mailutils/address.h>
29 #include <mailutils/mu_auth.h>
30 #include <mailutils/util.h>
31 #include <mailutils/parse822.h>
32 #include <mailutils/errno.h>
33
34 /*
35 * Functions used to convert unix mailbox/user names into RFC822 addr-specs.
36 */
37
38 static char *mu_user_email = 0;
39
40 int
mu_set_user_email(const char * candidate)41 mu_set_user_email (const char *candidate)
42 {
43 int err = 0;
44 mu_address_t addr = NULL;
45 size_t emailno = 0;
46 char *email = NULL;
47 const char *domain = NULL;
48
49 if (!candidate)
50 {
51 free (mu_user_email);
52 mu_user_email = NULL;
53 return 0;
54 }
55
56 if ((err = mu_address_create (&addr, candidate)) != 0)
57 return err;
58
59 if ((err = mu_address_get_email_count (addr, &emailno)) != 0)
60 goto cleanup;
61
62 if (emailno != 1)
63 {
64 errno = EINVAL;
65 goto cleanup;
66 }
67
68 if ((err = mu_address_aget_email (addr, 1, &email)) != 0)
69 goto cleanup;
70 else if (email == NULL)
71 {
72 err = MU_ERR_NOENT;
73 goto cleanup;
74 }
75
76 free (mu_user_email);
77
78 mu_user_email = email;
79
80 if ((err = mu_address_sget_domain (addr, 1, &domain)) != 0)
81 goto cleanup;
82 else if (domain == NULL)
83 {
84 err = MU_ERR_NOENT;
85 goto cleanup;
86 }
87 mu_set_user_email_domain (domain);
88
89 cleanup:
90 mu_address_destroy (&addr);
91
92 return err;
93 }
94
95 static char *mu_user_email_domain = 0;
96
97 int
mu_set_user_email_domain(const char * domain)98 mu_set_user_email_domain (const char *domain)
99 {
100 char *d;
101
102 if (domain)
103 {
104 d = strdup (domain);
105
106 if (!d)
107 return ENOMEM;
108 }
109 else
110 d = NULL;
111
112 if (mu_user_email_domain)
113 free (mu_user_email_domain);
114
115 mu_user_email_domain = d;
116
117 return 0;
118 }
119
120 /* FIXME: must be called _sget_ */
121 int
mu_get_user_email_domain(const char ** domain)122 mu_get_user_email_domain (const char **domain)
123 {
124 int err = 0;
125
126 if (!mu_user_email_domain)
127 {
128 if ((err = mu_get_host_name (&mu_user_email_domain)))
129 return err;
130 }
131
132 *domain = mu_user_email_domain;
133
134 return 0;
135 }
136
137 int
mu_aget_user_email_domain(char ** pdomain)138 mu_aget_user_email_domain (char **pdomain)
139 {
140 const char *domain;
141 int status = mu_get_user_email_domain (&domain);
142 if (status)
143 return status;
144 if (domain == NULL)
145 *pdomain = NULL;
146 else
147 {
148 *pdomain = strdup (domain);
149 if (*pdomain == NULL)
150 return ENOMEM;
151 }
152 return 0;
153 }
154
155 /* Note: allocates memory */
156 char *
mu_get_user_email(const char * name)157 mu_get_user_email (const char *name)
158 {
159 int status = 0;
160 char *localpart = NULL;
161 const char *domainpart = NULL;
162 char *email = NULL;
163 char *tmpname = NULL;
164
165 if (!name && mu_user_email)
166 {
167 email = strdup (mu_user_email);
168 if (!email)
169 errno = ENOMEM;
170 return email;
171 }
172
173 if (!name)
174 {
175 struct mu_auth_data *auth = mu_get_auth_by_uid (geteuid ());
176 if (!auth)
177 {
178 errno = EINVAL;
179 return NULL;
180 }
181 name = tmpname = strdup(auth->name);
182 if (auth)
183 mu_auth_data_free (auth);
184 if (!name)
185 {
186 errno = ENOMEM;
187 return NULL;
188 }
189 }
190
191 status = mu_get_user_email_domain (&domainpart);
192
193 if (status)
194 {
195 free(tmpname);
196 errno = status;
197 return NULL;
198 }
199
200 if ((status = mu_parse822_quote_local_part (&localpart, name)))
201 {
202 free(tmpname);
203 errno = status;
204 return NULL;
205 }
206
207
208 email = malloc (strlen (localpart) + 1
209 + strlen (domainpart) + 1);
210 if (!email)
211 errno = ENOMEM;
212 else
213 sprintf (email, "%s@%s", localpart, domainpart);
214
215 free(tmpname);
216 free (localpart);
217
218 return email;
219 }
220