80 |
pr_send_text (contact_t *contact, const char *txt) |
pr_send_text (contact_t *contact, const char *txt) |
81 |
{ |
{ |
82 |
size_t len = strlen (txt); |
size_t len = strlen (txt); |
83 |
|
char *utf8str; |
84 |
|
|
85 |
header.type = MSG_TEXT; |
header.type = MSG_TEXT; |
86 |
hton_header (); |
hton_header (); |
|
tr_send_msg (contact, (BYTE *)&header, HEADER_SIZE(text), |
|
|
(BYTE *)txt, len); |
|
87 |
|
|
88 |
|
/* TODO should we use UTF-8 here? */ |
89 |
if (cfg.logging) { |
if (cfg.logging) { |
90 |
lg_log_text (cfg.nick, contact, txt, len); |
lg_log_text (cfg.nick, contact, txt, len); |
91 |
|
} |
92 |
|
|
93 |
|
/* This is not optimal... */ |
94 |
|
if ((utf8str = malloc (len*4)) == NULL) { |
95 |
|
dmx_stop (); |
96 |
|
return; |
97 |
} |
} |
98 |
|
len = utf8_encode ((char*) txt, len, utf8str, len*4); |
99 |
|
|
100 |
|
tr_send_msg (contact, (BYTE *)&header, HEADER_SIZE(text), |
101 |
|
(BYTE *)utf8str, len); |
102 |
|
|
103 |
|
free (utf8str); |
104 |
} |
} |
105 |
|
|
106 |
void |
void |
107 |
pr_send_hello (contact_t *contact) |
pr_send_hello (contact_t *contact) |
108 |
{ |
{ |
109 |
|
char *utf8str; |
110 |
|
size_t len = strlen (cfg.nick); |
111 |
|
|
112 |
|
if ((utf8str = malloc (len*4)) == NULL) { |
113 |
|
dmx_stop(); |
114 |
|
return; |
115 |
|
} |
116 |
|
len = utf8_encode (cfg.nick, len, utf8str, len*4); |
117 |
|
|
118 |
header.type = MSG_HELLO; |
header.type = MSG_HELLO; |
119 |
header.c.hello.version = PROTOCOL_VERSION; |
header.c.hello.version = PROTOCOL_VERSION; |
120 |
header.c.hello.port = cfg.listen_port; |
header.c.hello.port = cfg.listen_port; |
121 |
hton_header (); |
hton_header (); |
122 |
tr_send_msg (contact, (BYTE *)&header, HEADER_SIZE(hello), |
tr_send_msg (contact, (BYTE *)&header, HEADER_SIZE(hello), |
123 |
(BYTE *)cfg.nick, strlen (cfg.nick)); |
(BYTE *)utf8str, len); |
124 |
|
|
125 |
|
free (utf8str); |
126 |
} |
} |
127 |
|
|
128 |
void |
void |
202 |
int nick_len) |
int nick_len) |
203 |
{ |
{ |
204 |
BOOL modif, modif_nick, hello_was_pending; |
BOOL modif, modif_nick, hello_was_pending; |
205 |
|
char *str; |
206 |
|
|
207 |
if (hdr->version < PROTOCOL_VERSION) { |
if (hdr->version < PROTOCOL_VERSION) { |
208 |
ui_output_err ("Connection from outdated client! (from %s)", |
ui_output_err ("Connection from outdated client! (from %s)", |
217 |
return ERR; |
return ERR; |
218 |
} |
} |
219 |
|
|
220 |
|
if ((str = malloc (nick_len)) == NULL) { |
221 |
|
dmx_stop (); |
222 |
|
return ERR; |
223 |
|
} |
224 |
|
|
225 |
|
nick_len = utf8_decode ((char*) nick, nick_len, str, nick_len); |
226 |
|
|
227 |
if (nick_len > (MAX_NICK - 1)) { |
if (nick_len > (MAX_NICK - 1)) { |
228 |
ui_output_err ("Contact's nick is too long (from %s).", |
ui_output_err ("Contact's nick is too long (from %s).", |
229 |
ipv4_to_string (contact->state.ip)); |
ipv4_to_string (contact->state.ip)); |
230 |
|
free (str); |
231 |
return ERR; |
return ERR; |
232 |
} |
} |
233 |
|
|
234 |
/* TODO We should check there are no control characters on the |
/* TODO We should check there are no control characters on the |
235 |
nick, or some jokes can be done. For example, let /nick only |
nick, or some jokes can be done. For example, let /nick only |
236 |
accept printable chars, and accept the same here. */ |
accept printable chars, and accept the same here. */ |
237 |
if (nick_len == 0 || nick[0] == '\0') { |
if (nick_len == 0 || str[0] == '\0') { |
238 |
ui_output_err ("Bad nick in incomming HELLO (from %s).", |
ui_output_err ("Bad nick in incomming HELLO (from %s).", |
239 |
ipv4_to_string (contact->state.ip)); |
ipv4_to_string (contact->state.ip)); |
240 |
|
free (str); |
241 |
return ERR; |
return ERR; |
242 |
} |
} |
243 |
|
|
253 |
} |
} |
254 |
|
|
255 |
if (strlen (contact->nick) != nick_len || |
if (strlen (contact->nick) != nick_len || |
256 |
strncmp (contact->nick, nick, nick_len) != 0) { |
strncmp (contact->nick, str, nick_len) != 0) { |
257 |
char new_nick[MAX_NICK]; |
char new_nick[MAX_NICK]; |
258 |
memcpy (new_nick, nick, nick_len); |
memcpy (new_nick, str, nick_len); |
259 |
new_nick[nick_len] = '\0'; |
new_nick[nick_len] = '\0'; |
260 |
if (contact->nick[0] != '\0') { |
if (contact->nick[0] != '\0') { |
261 |
ui_output_info ("Contact %s is now known as %s.", |
ui_output_info ("Contact %s is now known as %s.", |
282 |
ui_redraw_contacts (); |
ui_redraw_contacts (); |
283 |
} |
} |
284 |
|
|
285 |
|
free (str); |
286 |
|
|
287 |
return OK; |
return OK; |
288 |
} |
} |
289 |
|
|
290 |
static int |
static int |
291 |
received_text (contact_t *contact, const char *text, int len) |
received_text (contact_t *contact, const char *text, int len) |
292 |
{ |
{ |
293 |
|
char *str; |
294 |
|
|
295 |
|
if ((str = malloc (len)) == NULL) { |
296 |
|
dmx_stop (); |
297 |
|
return ERR; |
298 |
|
} |
299 |
|
|
300 |
/* TODO Check there are only printable characters and no '\n', etc. |
/* TODO Check there are only printable characters and no '\n', etc. |
301 |
Should we check for a maximum length? */ |
Should we check for a maximum length? */ |
302 |
|
|
303 |
ui_output_msg (contact, text, len); |
len = utf8_decode ((char*) text, len, str, len); |
304 |
|
|
305 |
|
ui_output_msg (contact, str, len); |
306 |
|
|
307 |
if (cfg.logging) { |
if (cfg.logging) { |
308 |
lg_log_text (contact->nick, contact, text, len); |
lg_log_text (contact->nick, contact, text, len); |
309 |
} |
} |
310 |
|
|
311 |
|
free (str); |
312 |
|
|
313 |
return OK; |
return OK; |
314 |
} |
} |
315 |
|
|