2
* Copyright (C) 2007 Colin DIDIER
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License version 2 as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License along
14
* with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
#define _POSIX_SOURCE 1
20
#define _SVID_SOURCE 1
29
#include "xmpp-servers.h"
31
#define XMPP_PRIORITY_MIN -128
32
#define XMPP_PRIORITY_MAX 127
34
static const char *utf8_charset = "UTF-8";
36
char *call_gpg(char *switches, char *input, char *input2, \
37
int get_stderr, int snip_data) {
38
int pipefd[2], tmp_fd, tmp2_fd = 0, in_data = !snip_data;
40
char *cmd, *tmp_path, *tmp2_path = NULL, *output = NULL;
41
size_t output_size = 0;
42
char buf[100], buf2[100] = "";
43
const char *keyid = settings_get_str("xmpp_pgp");
45
if(keyid) { /* If no keyID, then we don't need a password */
46
if(pipe(pipefd)) goto pgp_error;
47
if(!pgp_passwd) pgp_passwd = get_password("OpenPGP Password:");
49
if(write(pipefd[1], pgp_passwd, strlen(pgp_passwd)) < 1) goto pgp_error;
50
if(close(pipefd[1])) goto pgp_error;
53
if(!(tmp_path = tempnam(NULL, "irssi-xmpp-gpg"))) goto pgp_error;
54
if((tmp_fd = open(tmp_path, O_WRONLY|O_CREAT|O_EXCL, \
55
S_IRUSR|S_IWUSR)) < 0)
58
if(write(tmp_fd, input, strlen(input)) < 0) goto pgp_error;
61
if(!(tmp2_path = tempnam(NULL, "irssi-xmpp-gpg"))) goto pgp_error;
62
if((tmp2_fd = open(tmp2_path, O_WRONLY|O_CREAT|O_EXCL, \
63
S_IRUSR|S_IWUSR)) < 0)
66
if(write(tmp2_fd, input2, strlen(input2)) < 0) goto pgp_error;
69
cmd = malloc(sizeof("gpg -u '' --passphrase-fd '' --trust-model always" \
70
" -qo - --batch --no-tty '' '' 2>/dev/null") \
71
+strlen(switches)+8+strlen(tmp_path)+ \
72
(tmp2_path ? strlen(tmp2_path) : 0));
74
sprintf(cmd, "gpg -u '%s' --passphrase-fd '%d' ", keyid, pipefd[0]);
78
strcat(cmd, switches);
79
strcat(cmd, " --trust-model always -qo - --batch --no-tty '");
80
strcat(cmd, tmp_path);
85
strcat(cmd, tmp2_path);
92
strcat(cmd, " 2>/dev/null");
96
cstream = popen(cmd, "r");
98
while(fgets(buf, sizeof(buf)-1, cstream)) {
99
if(strlen(buf2) > 0) {
100
output = realloc(output, output_size+strlen(buf2)+1);
101
if(!output) goto pgp_error;
102
if(output_size < 1) output[0] = '\0';
103
output_size += strlen(buf2);
104
strcat(output, buf2);
107
if(!in_data && buf[0] == '\n') {
115
/* Get last line if not snipping */
116
if(!snip_data && strlen(buf2) > 0) {
117
output = realloc(output, output_size+strlen(buf2)+1);
118
if(!output) goto pgp_error;
119
if(output_size < 1) output[0] = '\0';
120
output_size += strlen(buf2);
121
strcat(output, buf2);
124
if(pclose(cstream) == 512) { /* TODO: more check exit code */
127
output = call_gpg(switches, input, input2, get_stderr, snip_data);
132
if(tmp2_fd) close(tmp2_fd);
133
if(tmp2_path) free(tmp2_path);
134
if(keyid) close(pipefd[0]);
145
xmpp_get_local_charset(G_CONST_RETURN char **charset)
147
*charset = settings_get_str("term_charset");
148
if (is_valid_charset(*charset))
149
return (g_ascii_strcasecmp(*charset, utf8_charset) == 0);
150
return g_get_charset(charset);
154
xmpp_recode_out(const char *str)
156
G_CONST_RETURN char *charset;
157
char *recoded, *stripped;
159
if (str == NULL || *str == '\0')
161
recoded = stripped = NULL;
162
signal_emit("xmpp formats strip codes", 2, str, &stripped);
163
if (stripped != NULL)
165
if (!xmpp_get_local_charset(&charset) && charset != NULL)
166
recoded = g_convert_with_fallback(str, -1, utf8_charset,
167
charset, NULL, NULL, NULL, NULL);
168
recoded = recoded != NULL ? recoded : g_strdup(str);
174
xmpp_recode_in(const char *str)
176
G_CONST_RETURN char *charset;
177
char *recoded, *to = NULL;
179
if (str == NULL || *str == '\0')
181
if (xmpp_get_local_charset(&charset) || charset == NULL)
182
return g_strdup(str);
183
if (settings_get_bool("recode_transliterate") &&
184
g_ascii_strcasecmp(charset, "//TRANSLIT") != 0)
185
charset = to = g_strconcat(charset ,"//TRANSLIT", (void *)NULL);
186
recoded = g_convert_with_fallback(str, -1, charset, utf8_charset, NULL,
189
return (recoded != NULL) ? recoded : g_strdup(str);
193
xmpp_find_resource_sep(const char *jid)
195
return jid == NULL ? NULL : g_utf8_strchr(jid, -1, '/');
199
xmpp_extract_resource(const char *jid)
203
g_return_val_if_fail(jid != NULL, NULL);
204
pos = xmpp_find_resource_sep(jid);
205
return (pos != NULL) ? g_strdup(pos + 1) : NULL;
209
xmpp_strip_resource(const char *jid)
213
g_return_val_if_fail(jid != NULL, NULL);
214
pos = xmpp_find_resource_sep(jid);
215
return (pos != NULL) ? g_strndup(jid, pos - jid) : g_strdup(jid);
219
xmpp_extract_user(const char *jid)
223
g_return_val_if_fail(jid != NULL, NULL);
224
pos = g_utf8_strchr(jid, -1, '@');
225
return (pos != NULL) ? g_strndup(jid, pos - jid) :
226
xmpp_strip_resource(jid);
230
xmpp_extract_domain(const char *jid)
234
pos1 = g_utf8_strchr(jid, -1, '@');
235
pos2 = xmpp_find_resource_sep(jid);
238
if (pos2 != NULL && pos2 < pos1)
239
return g_strdup(pos1 + 1);
240
return (pos2 != NULL) ?
241
g_strndup(pos1 + 1, pos2 - pos1 - 1) : g_strdup(pos1 + 1);
245
xmpp_have_domain(const char *jid)
249
g_return_val_if_fail(jid != NULL, FALSE);
250
pos = g_utf8_strchr(jid, -1, '@');
251
return (pos != NULL && *(pos+1) != '\0');
255
xmpp_have_resource(const char *jid)
259
g_return_val_if_fail(jid != NULL, FALSE);
260
pos = xmpp_find_resource_sep(jid);
261
return (pos != NULL && *(pos+1) != '\0');
265
xmpp_priority_out_of_bound(const int priority)
267
return (XMPP_PRIORITY_MIN <= priority
268
&& priority <= XMPP_PRIORITY_MAX) ? FALSE : TRUE;
272
xmpp_presence_changed(const int show, const int old_show, const char *status,
273
const char *old_status, const int priority, const int old_priority)
275
return (show != old_show)
276
|| (status == NULL && old_status != NULL)
277
|| (status != NULL && old_status == NULL)
278
|| (status != NULL && old_status != NULL
279
&& strcmp(status, old_status) != 0)
280
|| (priority != old_priority);