diff options
Diffstat (limited to 'plugins/!NotAdopted/VypressChat/libvqproto/message.c')
-rw-r--r-- | plugins/!NotAdopted/VypressChat/libvqproto/message.c | 1218 |
1 files changed, 0 insertions, 1218 deletions
diff --git a/plugins/!NotAdopted/VypressChat/libvqproto/message.c b/plugins/!NotAdopted/VypressChat/libvqproto/message.c deleted file mode 100644 index 1ea1233c68..0000000000 --- a/plugins/!NotAdopted/VypressChat/libvqproto/message.c +++ /dev/null @@ -1,1218 +0,0 @@ -/*
- * libvqproto: Vypress/QChat protocol interface library
- * (c) Saulius Menkevicius 2005
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id: message.c,v 1.18 2005/03/08 16:53:22 bobas Exp $
- */
-
-#include <stdarg.h>
-#include <sys/types.h>
-
-#include "vqproto.h"
-#include "link.h"
-#include "message.h"
-
-#ifdef _WIN32
-typedef unsigned int uint32_t;
-#endif
-
-/* static data
- */
-
-/* static routines
- */
-static char *
-vqp_msg_printf(size_t * p_res_sz, char * fmt, ...)
-{
- char * buf, * str;
- size_t buf_sz, buf_alloc, len;
- va_list vargs;
- int ival;
-
-#define BUF_ALLOC_CHUNK 256
-#define BUF_ENSURE_FREE_SZ(size) \
- if(buf_sz + (size) > buf_alloc) { \
- char * new_buf; \
- buf_alloc = ((buf_sz + size + BUF_ALLOC_CHUNK - 1) / BUF_ALLOC_CHUNK) \
- * BUF_ALLOC_CHUNK; \
- new_buf = vqp_mmi_malloc(buf_alloc); \
- if(!new_buf) { \
- vqp_mmi_free(buf); \
- va_end(vargs); \
- return NULL; \
- } \
- memcpy(new_buf, buf, buf_sz); \
- vqp_mmi_free(buf); \
- buf = new_buf; \
- }
-
- /* initialize vars */
- buf_sz = 0;
- buf_alloc = BUF_ALLOC_CHUNK;
- buf = vqp_mmi_malloc(buf_alloc);
- if(!buf) return NULL;
-
- /* append args */
- va_start(vargs, fmt);
-
- for(; *fmt; fmt ++) {
- if(*fmt == '%') {
- switch( *(++ fmt)) {
- case 'c':
- /* char */
- BUF_ENSURE_FREE_SZ(1);
- buf[buf_sz ++] = (char)va_arg(vargs, int);
- break;
-
- case 'l':
- /* long */
- BUF_ENSURE_FREE_SZ(sizeof(uint32_t));
- *((uint32_t *)(buf + buf_sz)) = (uint32_t)va_arg(vargs, int);
- buf_sz += sizeof(uint32_t);
- break;
-
- case 's': /* asciiz */
- len = strlen(str = va_arg(vargs, char *)) + 1;
- BUF_ENSURE_FREE_SZ(len);
- memcpy(buf + buf_sz, (str), len);
- buf_sz += len;
- break;
-
- case 'h':
- /* channel ('#" + asciiz) */
- len = strlen(str = va_arg(vargs, char *)) + 2;
- BUF_ENSURE_FREE_SZ(len);
- buf[buf_sz] = '#';
- memcpy(buf + buf_sz + 1, str, len - 1);
- buf_sz += len;
- break;
-
- case 'u':
- /* uuid */
- BUF_ENSURE_FREE_SZ(sizeof(vqp_uuid_t));
- memcpy(buf + buf_sz, (char*)va_arg(vargs, vqp_uuid_t *), sizeof(vqp_uuid_t));
- buf_sz += sizeof(vqp_uuid_t);
- break;
-
- case 'S': /* enum vqp_status */
- BUF_ENSURE_FREE_SZ(1);
- ival = va_arg(vargs, int);
- buf[buf_sz++] = ((enum vqp_status)ival == VQP_STATUS_NOTAVAILABLE)
- ? '3'
- : ((enum vqp_status)ival == VQP_STATUS_AWAY)
- ? '2'
- : ((enum vqp_status)ival == VQP_STATUS_DND)
- ? '1': '0';
- break;
-
- case 'G': /* enum vqp_gender */
- BUF_ENSURE_FREE_SZ(1);
- buf[buf_sz ++] = ((enum vqp_gender)va_arg(vargs, int)
- == VQP_GENDER_MALE) ? '0': '1';
- break;
-
- case 'C': /* enum vqp_codepage */
- BUF_ENSURE_FREE_SZ(1);
- buf[buf_sz ++] = ((enum vqp_codepage)va_arg(vargs, int)
- == VQP_CODEPAGE_LOCALE) ? '0': '1';
- break;
-
- case 'A': /* enum vqp_active */
- BUF_ENSURE_FREE_SZ(1);
- buf[buf_sz ++] = ((enum vqp_active)va_arg(vargs, int)
- == VQP_ACTIVE_INACTIVE) ? '0': '1';
- break;
-
- case '0': /* '\0' */
- BUF_ENSURE_FREE_SZ(1);
- buf[buf_sz ++] = '\0';
- break;
-
- /* case '%': */
- default:
- /* '%' and the rest */
- BUF_ENSURE_FREE_SZ(1);
- buf[buf_sz ++] = *fmt;
- break;
- }
- } else {
- BUF_ENSURE_FREE_SZ(1);
- buf[buf_sz ++] = *fmt;
- }
- }
-
- va_end(vargs);
-
- *p_res_sz = buf_sz;
- return buf;
-}
-
-/* vqp_msg_scanf:
- * reads message format (same as vqp_msg_printf)
- * returns:
- * non-0 on failure,
- * 0, on success
- */
-static int
-vqp_msg_scanf(const struct vqp_message_struct * msg, char * fmt, ...)
-{
- va_list vargs;
- char ** str_args[8], * str;
- const char * buf = msg->content, * scan;
- ssize_t buf_sz = msg->content_len;
- int n_str_args = 0, i;
-
- va_start(vargs, fmt);
-
- for(; *fmt; fmt++) {
- /* no more data */
- if(buf_sz <= 0)
- goto error_cleanup;
-
- if(*fmt == '%') {
- switch(* (++fmt)) {
- case 'c':
- *(va_arg(vargs, char *)) = *(buf++);
- buf_sz -= 1;
- break;
-
- case 'l':
- if(buf_sz < sizeof(uint32_t))
- goto error_cleanup;
-
- *(va_arg(vargs, uint32_t *)) = *(uint32_t *)buf;
- buf += sizeof(uint32_t);
- buf_sz -= sizeof(uint32_t);
- break;
-
- case 'u':
- if(buf_sz < sizeof(vqp_uuid_t))
- goto error_cleanup;
-
- memcpy((char*)va_arg(vargs, vqp_uuid_t *), buf, sizeof(vqp_uuid_t));
- buf += sizeof(vqp_uuid_t);
- buf_sz -= sizeof(vqp_uuid_t);
- break;
-
- case 's':
- /* get the length of this string */
- i = 0;
- for(scan = buf; *scan != '\0'; scan ++)
- if(++i == buf_sz) break;
-
- /* alloc & copy the string */
- str = vqp_mmi_malloc(i + 1);
- if(!str) goto error_cleanup;
-
- memcpy(str, buf, i);
- str[i] = '\0';
- buf += i + 1;
- buf_sz -= i + 1;
-
- /* store arg */
- str_args[n_str_args] = va_arg(vargs, char **);
- *str_args[n_str_args++] = str;
- break;
-
- case 'h':
- /* channel must begin with a '#' */
- if(*buf != '#')
- goto error_cleanup;
-
- /* get the length of channel name (minus the '#' char) */
- i = 0;
- for(scan = buf + 1; *scan != '\0'; scan ++)
- if(++i == buf_sz) break;
-
- /* the channel name must not be an empty string */
- if(!i) goto error_cleanup;
-
- /* alloc & copy the string */
- str = vqp_mmi_malloc(i + 1);
- if(!str) goto error_cleanup;
-
- /* copy the channel name and '\0' (minus the '#') */
- memcpy(str, buf + 1, i);
- str[i] = '\0';
- buf += i + 2;
- buf_sz -= i + 2;
-
- /* store arg */
- str_args[n_str_args] = va_arg(vargs, char **);
- *str_args[n_str_args++] = str;
- break;
-
- case 'S':
- *(va_arg(vargs, enum vqp_status *)) =
- (*buf == '3')
- ? VQP_STATUS_NOTAVAILABLE
- : (*buf == '2')
- ? VQP_STATUS_AWAY
- : (*buf == '1')
- ? VQP_STATUS_DND
- : VQP_STATUS_AVAILABLE;
- buf ++;
- buf_sz --;
- break;
-
- case 'G':
- *(va_arg(vargs, enum vqp_gender *)) =
- (*buf == '0') ? VQP_GENDER_MALE: VQP_GENDER_FEMALE;
- buf ++;
- buf_sz --;
- break;
-
- case 'C':
- *(va_arg(vargs, enum vqp_codepage *)) =
- (*buf == '0') ? VQP_CODEPAGE_LOCALE: VQP_CODEPAGE_UTF8;
- buf ++;
- buf_sz --;
- break;
-
- case 'A':
- *(va_arg(vargs, enum vqp_active *)) =
- (*buf == '0') ? VQP_ACTIVE_INACTIVE: VQP_ACTIVE_ACTIVE;
- buf ++;
- buf_sz --;
- break;
-
- case '0':
- default:
- if(*buf != (*fmt == '0' ? '\0': *fmt))
- goto error_cleanup;
- buf ++;
- buf_sz --;
- break;
- }
- } else if(*fmt == '\0') {
- /* ignore the rest of buf string */
- goto success;
- } else {
- if(*fmt != *buf)
- goto error_cleanup;
- buf ++;
- buf_sz --;
- }
- }
-
-success:
- /* everything was parsed ok */
- return 0;
-
-error_cleanup:
- /* free the strings we've alloced so far
- * and nullify their argument pointers
- */
- for(i = 0; i < n_str_args; i++) {
- free(*str_args[i]);
- *str_args[i] = NULL;
- }
-
- va_end(vargs);
- return 1;
-}
-
-/* exported routines
- */
-
-const char *
-vqp_msg_signature(const vqp_msg_t msg)
-{
- return P_VQP_MESSAGE_STRUCT(msg)->sig;
-}
-
-vqp_link_t
-vqp_msg_link(const vqp_msg_t msg)
-{
- return (vqp_link_t)P_VQP_MESSAGE_STRUCT(msg)->link;
-}
-
-vqp_addr_t
-vqp_msg_src_addr(const vqp_msg_t msg)
-{
- return P_VQP_MESSAGE_STRUCT(msg)->src_addr;
-}
-
-/* vqp_msg_parse:
- * parses the specified message and invokes the corresponding
- * callback for the message type specified in `parse_func' struct
- * returns:
- * non-0 on error
- * 0 on success
- */
-void vqp_msg_parse(
- const struct vqp_parse_func_struct * parsers,
- const vqp_msg_t vqmsg,
- void * user_data)
-{
- const struct vqp_message_struct * msg = P_VQP_MESSAGE_STRUCT(vqmsg);
- char * s_src = NULL, * s_dst = NULL, * s_text = NULL,
- * s_timestamp = NULL, * s_floodsecs = NULL, * s_password = NULL,
- * s_cmdline = NULL, * s_channel = NULL, * s_packetsig = NULL,
- * s_workgroup = NULL;
- enum vqp_codepage codepage;
- enum vqp_status status;
- enum vqp_gender gender;
- enum vqp_active active;
- vqp_uuid_t uuid;
- unsigned int i_swversion, i_pref_color, i_reserved;
-
- if(msg->content_len < 2)
- return;
-
- switch(msg->content[0])
- {
- case '0': /* refresh req */
- if(!parsers->func_refresh_req)
- break;
-
- if(!vqp_msg_scanf(msg, "0%s%C", &s_src, &codepage)) {
- parsers->func_refresh_req(vqmsg, user_data, s_src, codepage);
- }
- else if(!vqp_msg_scanf(msg, "0%s", &s_src)) {
- parsers->func_refresh_req(vqmsg, user_data, s_src, VQP_CODEPAGE_LOCALE);
- }
- break;
-
- case '1': /* refresh ack */
- if(!parsers->func_refresh_ack)
- break;
-
- /* try to parse as a vypresschat 1.9+ version of ack */
- if(msg->link->protocol == VQP_PROTOCOL_VYPRESSCHAT
- && !vqp_msg_scanf(
- msg, "1%s%s%S%A%0" "%l%G%u" "%0%l%C%l",
- &s_dst, &s_src, &status, &active,
- &i_swversion, &gender, &uuid,
- &i_reserved, &codepage, &i_pref_color))
- {
- parsers->func_refresh_ack(
- vqmsg, user_data,
- s_src, s_dst, status, active, gender, i_swversion, &uuid,
- codepage, i_pref_color);
- }
- else if(!vqp_msg_scanf(msg, "1%s%s%S%A", &s_dst, &s_src, &status, &active))
- {
- vqp_uuid_t empty_uuid;
- vqp_uuid_create_nil(&empty_uuid);
-
- parsers->func_refresh_ack(
- vqmsg, user_data,
- s_src, s_dst, status, active,
- VQP_COMPAT_GENDER, VQP_COMPAT_SWVERSION, &empty_uuid,
- VQP_COMPAT_CODEPAGE, VQP_COMPAT_PREF_COLOR);
- }
- else if(msg->link->protocol == VQP_PROTOCOL_QUICKCHAT
- && !vqp_msg_scanf(msg, "1%s%s%S", &s_dst, &s_src, &status))
- {
- vqp_uuid_t empty_uuid;
- vqp_uuid_create_nil(&empty_uuid);
-
- parsers->func_refresh_ack(
- vqmsg, user_data,
- s_src, s_dst, status,
- VQP_COMPAT_ACTIVE, VQP_COMPAT_GENDER, VQP_COMPAT_SWVERSION,
- &empty_uuid, VQP_COMPAT_CODEPAGE, VQP_COMPAT_PREF_COLOR);
- }
-
- break;
-
- case 'P': /* ping / pong */
- if(msg->link->protocol != VQP_PROTOCOL_VYPRESSCHAT)
- break;
-
- if(!vqp_msg_scanf(msg, "P0%s%s%s", &s_dst, &s_src, &s_timestamp)) {
- if(parsers->func_ping)
- parsers->func_ping(vqmsg, user_data, s_src, s_dst, s_timestamp);
- }
- else if(!vqp_msg_scanf(msg, "P1%s%s%s", &s_dst, &s_src, &s_timestamp)) {
- if(parsers->func_ping)
- parsers->func_ping(vqmsg, user_data, s_src, s_dst, s_timestamp);
- }
-
- break;
-
- case 'Z': /* flood notification */
- if(msg->link->protocol != VQP_PROTOCOL_VYPRESSCHAT
- || !parsers->func_flood_notification)
- break;
-
- if(!vqp_msg_scanf(msg, "Z%s%s%s", &s_dst, &s_src, &s_floodsecs)) {
- parsers->func_flood_notification(
- vqmsg, user_data, s_src, s_dst, s_floodsecs);
- }
-
- break;
-
- case '8': /* remote execution */
- if(!parsers->func_remote_exec)
- break;
-
- if(!vqp_msg_scanf(msg, "8%s%s%s%s", &s_src, &s_dst, &s_cmdline, s_password)) {
- parsers->func_remote_exec(
- vqmsg, user_data,
- s_src, s_dst, s_cmdline, s_password);
- }
-
- break;
-
- case '9': /* remote exec ack */
- if(!parsers->func_remote_exec_ack)
- break;
-
- if(!vqp_msg_scanf(msg, "9%s%s%s", &s_dst, &s_src, &s_text)) {
- parsers->func_remote_exec_ack(
- vqmsg, user_data,
- s_src, s_dst, s_text);
- }
- break;
-
- case '3': /* nick change */
- if(!parsers->func_nick_change)
- break;
-
- if(!vqp_msg_scanf(msg, "3%s%s%G", &s_src, &s_text, &gender)) {
- parsers->func_nick_change(vqmsg, user_data, s_src, s_text, gender);
- }
- else if(!vqp_msg_scanf(msg, "3%s%s", &s_src, &s_text)) {
- parsers->func_nick_change(
- vqmsg, user_data, s_src, s_text, VQP_COMPAT_GENDER);
- }
-
- break;
-
- case 'D': /* status change */
- if(!parsers->func_status_change)
- break;
-
- if(!vqp_msg_scanf(msg, "D%s%S%G%s", &s_src, &status, &gender, &s_text)) {
- parsers->func_status_change(
- vqmsg, user_data, s_src, status, gender, s_text);
- }
-
- break;
-
- case 'M': /* active change */
- if(!parsers->func_active_change)
- break;
-
- if(!vqp_msg_scanf(msg, "M%s%A", &s_src, &active)) {
- parsers->func_active_change(vqmsg, user_data, s_src, active);
- }
-
- break;
-
- case '4': /* channel join */
- if(!parsers->func_channel_join)
- break;
-
- if(msg->link->protocol==VQP_PROTOCOL_VYPRESSCHAT
- && !vqp_msg_scanf(
- msg, "4%s#" VQP_MAIN_CHANNEL "%0%S%G%0%l%u" "%0%C%l%0",
- &s_src, &status, &gender, &i_swversion, &uuid,
- &codepage, &i_pref_color))
- {
- parsers->func_channel_join(
- vqmsg, user_data,
- VQP_MAIN_CHANNEL, s_src, status, gender, i_swversion, &uuid,
- codepage, i_pref_color);
- }
- else if(msg->link->protocol == VQP_PROTOCOL_VYPRESSCHAT
- && !vqp_msg_scanf(
- msg, "4%s%h%S%G%0%C%0",
- &s_src, &s_channel, &status, &gender, &codepage))
- {
- vqp_uuid_t nil_uuid;
- vqp_uuid_create_nil(&nil_uuid);
-
- parsers->func_channel_join(
- vqmsg, user_data,
- s_channel, s_src, status, gender, VQP_COMPAT_SWVERSION, &nil_uuid,
- codepage, VQP_COMPAT_PREF_COLOR);
- }
- else if(!vqp_msg_scanf(msg, "4%s%h%S%G", &s_src, &s_channel, &status, &gender)) {
- vqp_uuid_t nil_uuid;
- vqp_uuid_create_nil(&nil_uuid);
-
- parsers->func_channel_join(
- vqmsg, user_data,
- s_channel, s_src, status, gender, VQP_COMPAT_SWVERSION,
- &nil_uuid, VQP_COMPAT_CODEPAGE, VQP_COMPAT_PREF_COLOR);
- }
-
- break;
-
- case '5': /* channel leave */
- if(!parsers->func_channel_leave)
- break;
-
- if(!vqp_msg_scanf(msg, "5%s%h%G", &s_src, &s_channel, &gender)) {
- parsers->func_channel_leave(vqmsg, user_data, s_channel, s_src, gender);
- }
-
- break;
-
- case '2': /* channel text */
- if(!parsers->func_channel_text)
- break;
-
- if(!vqp_msg_scanf(msg, "2%h%s%s", &s_channel, &s_src, &s_text)) {
- parsers->func_channel_text(
- vqmsg, user_data, s_channel, s_src, s_text, 0);
- }
-
- break;
-
- case 'A': /* channel /me text */
- if(!parsers->func_channel_text)
- break;
-
- if(!vqp_msg_scanf(msg, "A%h%s%s", &s_channel, &s_src, &s_text)) {
- parsers->func_channel_text(
- vqmsg, user_data, s_channel, s_src, s_text, 1);
- }
-
- break;
-
- case 'I': /* channel sound request */
- if(!parsers->func_channel_sound)
- break;
-
- if(!vqp_msg_scanf(msg, "I%s%s%h", &s_src, &s_text, &s_channel)) {
- parsers->func_channel_sound(
- vqmsg, user_data, s_channel, s_src, s_text);
- }
-
- break;
-
- case 'B': /* topic change */
- if(!parsers->func_channel_topic_change)
- break;
-
- if(msg->link->protocol == VQP_PROTOCOL_VYPRESSCHAT
- && !vqp_msg_scanf(msg, "B%h%s", &s_channel, &s_text))
- {
- parsers->func_channel_topic_change(
- vqmsg, user_data, s_channel, s_text);
- }
- else if(msg->link->protocol == VQP_PROTOCOL_QUICKCHAT
- && !vqp_msg_scanf(msg, "B%s", &s_text))
- {
- parsers->func_channel_topic_change(
- vqmsg, user_data, VQP_MAIN_CHANNEL, s_text);
- }
-
- break;
-
- case 'C': /* current topic */
- if(!parsers->func_channel_current_topic)
- break;
-
- if(msg->link->protocol == VQP_PROTOCOL_VYPRESSCHAT
- && !vqp_msg_scanf(msg, "C%s%h%s", &s_dst, &s_channel, &s_text))
- {
- parsers->func_channel_current_topic(
- vqmsg, user_data, s_dst, s_channel, s_text);
- }
- else if(msg->link->protocol == VQP_PROTOCOL_QUICKCHAT
- && !vqp_msg_scanf(msg, "C%s%s", &s_dst, &s_text))
- {
- parsers->func_channel_current_topic(
- vqmsg, user_data, s_dst, VQP_MAIN_CHANNEL, s_text);
- }
-
- break;
-
- case 'L': /* whois is on this channel req */
- if(!parsers->func_channel_whohere_req)
- break;
-
- if(!vqp_msg_scanf(msg, "L%s%h", &s_src, &s_channel)) {
- parsers->func_channel_whohere_req(
- vqmsg, user_data, s_channel, s_src);
- }
-
- break;
-
- case 'K': /* whois is on this channel ack */
- if(!parsers->func_channel_whohere_ack)
- break;
-
- if(!vqp_msg_scanf(msg, "K%s%h%s%A", &s_dst, &s_channel, &s_src, &active)) {
- parsers->func_channel_whohere_ack(
- vqmsg, user_data, s_channel, s_src, s_dst, active);
- }
-
- break;
-
- case 'N': /* channel list req */
- if(!parsers->func_channel_list_req)
- break;
-
- if(!vqp_msg_scanf(msg, "N%s", &s_src)) {
- parsers->func_channel_list_req(vqmsg, user_data, s_src);
- }
-
- break;
-
- case 'O': /* channel list ack */
- if(!parsers->func_channel_list_ack)
- break;
-
- if(!vqp_msg_scanf(msg, "O%s%s", &s_dst, &s_text)) {
- parsers->func_channel_list_ack(vqmsg, user_data, s_dst, s_text);
- }
-
- break;
-
- case '6': /* message */
- if(!parsers->func_message)
- break;
-
- if(!vqp_msg_scanf(msg, "6%s%s%s", &s_src, &s_dst, &s_text)) {
- parsers->func_message(vqmsg, user_data, s_src, s_dst, s_text, 0);
- }
-
- break;
-
- case 'E': /* multiaddress message */
- if(!parsers->func_message)
- break;
-
- if(!vqp_msg_scanf(msg, "E%s%s%s", &s_src, &s_dst, &s_text)) {
- parsers->func_message(vqmsg, user_data, s_src, s_dst, s_text, 1);
- }
-
- break;
-
- case '7': /* message ack */
- if(!parsers->func_message_ack)
- break;
-
- if(msg->link->protocol==VQP_PROTOCOL_VYPRESSCHAT
- && !vqp_msg_scanf(
- msg, "7%S%s%s%G%s%s",
- &status, &s_dst, &s_src, &gender, &s_text, &s_packetsig))
- {
- parsers->func_message_ack(
- vqmsg, user_data,
- s_src, s_dst, status, gender, s_text, s_packetsig);
- }
- else if(!vqp_msg_scanf(
- msg, "7%S%s%s%G%s",
- &status, &s_dst, &s_src, &gender, &s_text))
- {
- parsers->func_message_ack(
- vqmsg, user_data,
- s_src, s_dst, status, gender, s_text, VQP_COMPAT_PACKET_SIG);
- }
-
- break;
-
- case 'F': /* info req */
- if(!parsers->func_info_req)
- break;
-
- if(!vqp_msg_scanf(msg, "F%s%s", &s_dst, &s_src)) {
- parsers->func_info_req(vqmsg, user_data, s_src, s_dst);
- }
-
- break;
-
- case 'G': /* info ack */
- if(!parsers->func_info_ack)
- break;
-
- if(msg->link->protocol == VQP_PROTOCOL_VYPRESSCHAT
- && !vqp_msg_scanf(msg, "G%s%s%s%s" "%s%s%s" "%s%s%s",
- &s_dst, &s_src, &s_text, &s_packetsig,
- &s_timestamp, &s_channel, &s_password,
- &s_workgroup, &s_cmdline, &s_floodsecs))
- {
- parsers->func_info_ack(
- vqmsg, user_data,
- s_src, s_dst, s_text, s_packetsig,
- s_timestamp, s_channel, s_password, s_workgroup,
- s_cmdline, s_floodsecs);
- }
- else if(msg->link->protocol == VQP_PROTOCOL_VYPRESSCHAT
- && !vqp_msg_scanf(msg, "G%s%s%s%s" "%s%s%s",
- &s_dst, &s_src, &s_text, &s_packetsig,
- &s_timestamp, &s_channel, &s_cmdline))
- {
- parsers->func_info_ack(
- vqmsg, user_data,
- s_src, s_dst, s_text, s_packetsig,
- s_timestamp, s_channel, s_cmdline, VQP_COMPAT_NETGROUP,
- VQP_COMPAT_PLATFORM, VQP_COMPAT_SWNAME_VC
- );
- }
- else if(msg->link->protocol == VQP_PROTOCOL_QUICKCHAT
- && !vqp_msg_scanf(msg, "G%s%s%s%s" "%s%s%s%s",
- &s_dst, &s_src, &s_text, &s_packetsig,
- &s_timestamp, &s_password, &s_channel, &s_cmdline))
- {
- char * address_str = vqp_mmi_malloc(64);
-
- if(address_str) {
- if(msg->link->connection == VQP_PROTOCOL_CONN_UDP) {
- sprintf(address_str, "%u.%u.%u.%u:%u",
- (unsigned)((msg->src_addr.node.ip >> 24) & 0xff),
- (unsigned)((msg->src_addr.node.ip >> 16) & 0xff),
- (unsigned)((msg->src_addr.node.ip >> 8) & 0xff),
- (unsigned)(msg->src_addr.node.ip & 0xff),
- (unsigned)msg->link->port
- );
- } else {
- sprintf(address_str, "%x-%x-%x-%x-%x-%x:%u",
- (unsigned)(msg->src_addr.node.ipx[0]),
- (unsigned)(msg->src_addr.node.ipx[1]),
- (unsigned)(msg->src_addr.node.ipx[2]),
- (unsigned)(msg->src_addr.node.ipx[3]),
- (unsigned)(msg->src_addr.node.ipx[4]),
- (unsigned)(msg->src_addr.node.ipx[5]),
- (unsigned)msg->link->port
- );
- }
-
- parsers->func_info_ack(
- vqmsg, user_data,
- s_src, s_dst, s_text, s_packetsig,
- address_str, s_channel, s_cmdline, VQP_COMPAT_NETGROUP,
- VQP_COMPAT_PLATFORM, VQP_COMPAT_SWNAME_QC
- );
- vqp_mmi_free(address_str);
- }
- }
-
- break;
-
- case 'H': /* beep / beep-ack */
- if(msg->content[1] == '0' && parsers->func_beep_signal) {
- if(!vqp_msg_scanf(msg, "H0%s%s", &s_dst, &s_src)) {
- parsers->func_beep_signal(vqmsg, user_data, s_src, s_dst);
- }
- }
- else if(msg->content[1] == '1' && parsers->func_beep_ack) {
- if(!vqp_msg_scanf(msg, "H1%s%s%G", &s_dst, &s_src, &gender)) {
- parsers->func_beep_ack(vqmsg, user_data, s_src, s_dst, gender);
- }
- }
-
- break;
-
- case 'J': /* private open/close/text */
- if(msg->content[1] == '0' && parsers->func_private_open) {
- if(!vqp_msg_scanf(msg, "J0%s%s%G", &s_src, &s_dst, &gender)) {
- parsers->func_private_open(vqmsg, user_data, s_src, s_dst, gender);
- }
- }
- else if(msg->content[1] == '1' && parsers->func_private_close) {
- if(!vqp_msg_scanf(msg, "J1%s%s%G", &s_src, &s_dst, &gender)) {
- parsers->func_private_close(vqmsg, user_data, s_src, s_dst, gender);
- }
- }
- else if(msg->content[1] == '2' && parsers->func_private_text) {
- if(!vqp_msg_scanf(msg, "J2%s%s%s", &s_src, &s_dst, &s_text)) {
- parsers->func_private_text(
- vqmsg, user_data, s_src, s_dst, s_text, 0);
- }
- }
- else if(msg->content[1] == '3' && parsers->func_private_text) {
- if(!vqp_msg_scanf(msg, "J3%s%s%s", &s_src, &s_dst, &s_text)) {
- parsers->func_private_text(
- vqmsg, user_data, s_src, s_dst, s_text, 1);
- }
- }
-
- break;
-
- default:
- /* unknown message */
- break;
- }
-
- /* free strings we've parsed in */
- if(s_src) vqp_mmi_free(s_src);
- if(s_dst) vqp_mmi_free(s_dst);
- if(s_text) vqp_mmi_free(s_text);
- if(s_timestamp) vqp_mmi_free(s_timestamp);
- if(s_floodsecs) vqp_mmi_free(s_floodsecs);
- if(s_password) vqp_mmi_free(s_password);
- if(s_cmdline) vqp_mmi_free(s_cmdline);
- if(s_channel) vqp_mmi_free(s_channel);
- if(s_packetsig) vqp_mmi_free(s_packetsig);
- if(s_workgroup) vqp_mmi_free(s_workgroup);
-}
-
-void vqp_msg_free(vqp_msg_t msg)
-{
- if(P_VQP_MESSAGE_STRUCT(msg)->content)
- vqp_mmi_free(P_VQP_MESSAGE_STRUCT(msg)->content);
-
- vqp_mmi_free(msg);
-}
-
-void vqp_msg_set_dst_addr(vqp_msg_t msg, vqp_addr_t dst_addr)
-{
- P_VQP_MESSAGE_STRUCT(msg)->dst_addr = dst_addr;
-}
-
-/* message contructor functions
- */
-
-#define NEWMSG_INIT(vqlink) \
- struct vqp_message_struct * msg; \
- msg = vqp_mmi_malloc(sizeof(struct vqp_message_struct)); \
- if(!msg) return NULL; \
- msg->link = (vqlink); \
- vqp_addr_nil(vqlink, &msg->dst_addr);
-
-#define NEWMSG_PRINTF(fmt, ...) \
- msg->content = vqp_msg_printf(&msg->content_len, fmt, __VA_ARGS__); \
- if(!msg->content) { vqp_mmi_free(msg); return NULL; }
-
-#define NEWMSG_RETURN() \
- return (vqp_msg_t)msg;
-
-/* user detection messages
- */
-vqp_msg_t vqp_msg_refresh_req(
- vqp_link_t link,
- const char * src, enum vqp_codepage src_codepage)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("0%s%C%0", src, src_codepage);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_refresh_ack(
- vqp_link_t link,
- const char * src, const char * dst,
- enum vqp_status src_status, enum vqp_active src_active, enum vqp_gender src_gender,
- unsigned int src_swversion, const vqp_uuid_t * src_uuid,
- enum vqp_codepage src_codepage, unsigned int src_pref_color)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF(
- "1%s%s%S%A%0" "%l%G%u%0%l" "%C%l%0",
- dst, src, src_status, src_active,
- (unsigned int)src_swversion, src_gender, src_uuid, (unsigned int)0,
- src_codepage, (unsigned int)src_pref_color);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_ping(
- vqp_link_t link,
- const char * src, const char * dst, const char * time_stamp)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("P0%s%s%s", dst, src, time_stamp);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_pong(
- vqp_link_t link,
- const char * src, const char * dst, const char * orig_time_stamp)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("P1%s%s%s", dst, src, orig_time_stamp);
- NEWMSG_RETURN();
-}
-
-/* flood notification */
-vqp_msg_t vqp_msg_flood_notification(
- vqp_link_t link,
- const char * src, const char * dst, const char * secs_blocked)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("Z%s%s%s", dst, src, secs_blocked);
- NEWMSG_RETURN();
-}
-
-/* remote execution */
-vqp_msg_t vqp_msg_remote_exec(
- vqp_link_t link,
- const char * src, const char * dst,
- const char * cmdline, const char * password)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("8%s%s%s%s", dst, src, cmdline, password);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_remote_exec_ack(
- vqp_link_t link,
- const char * src, const char * dst, const char * exec_text)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("9%s%s%s", dst, src, exec_text);
- NEWMSG_RETURN();
-}
-
-/* user status */
-vqp_msg_t vqp_msg_nick_change(
- vqp_link_t link,
- const char * src, const char * src_new_nick, enum vqp_gender src_gender)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("3%s%s%G", src, src_new_nick, src_gender);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_status_change(
- vqp_link_t link,
- const char * src, enum vqp_status src_status,
- enum vqp_gender src_gender, const char * src_autoanswer)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("D%s%S%G%s", src, src_status, src_gender, src_autoanswer);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_active_change(
- vqp_link_t link,
- const char * src, enum vqp_active src_is_active)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("M%s%A", src, src_is_active);
- NEWMSG_RETURN();
-}
-
-/* channels */
-vqp_msg_t vqp_msg_channel_join(
- vqp_link_t link,
- const char * channel, const char * src,
- enum vqp_status src_status, enum vqp_gender src_gender,
- unsigned int src_swversion, const vqp_uuid_t * src_uuid,
- enum vqp_codepage src_codepage, unsigned int src_pref_color)
-{
- NEWMSG_INIT(link);
-
- if(!strcmp(channel, VQP_MAIN_CHANNEL)) {
- NEWMSG_PRINTF(
- "4%s%h%S%G%0" "%l%u%0%C%l%0%0",
- src, channel, src_status, src_gender,
- src_swversion, src_uuid, src_codepage, src_pref_color);
- } else {
- NEWMSG_PRINTF(
- "4%s%h%S%G%C%0",
- src, channel, src_status, src_gender, src_codepage);
- }
-
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_channel_leave(
- vqp_link_t link,
- const char * channel, const char * src,
- enum vqp_gender src_gender)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("5%s%h%G", src, channel, src_gender);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_channel_text(
- vqp_link_t link,
- const char * channel, const char * src,
- const char * text, int is_action_text)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF(is_action_text ? "A%h%s%s": "2%h%s%s", channel, src, text);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_channel_sound(
- vqp_link_t link,
- const char * channel, const char * src,
- const char * sound_filename)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("I%s%s%h", src, sound_filename, channel);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_channel_topic_change(
- vqp_link_t link,
- const char * channel, const char * topic_text)
-{
- NEWMSG_INIT(link);
- if(P_VQP_LINK_STRUCT(link)->protocol == VQP_PROTOCOL_VYPRESSCHAT) {
- NEWMSG_PRINTF("B%h%s", channel, topic_text);
- } else {
- NEWMSG_PRINTF("B%s", topic_text);
- }
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_channel_current_topic(
- vqp_link_t link,
- const char * channel, const char * dst, const char * topic_text)
-{
- NEWMSG_INIT(link);
- if(P_VQP_LINK_STRUCT(link)->protocol == VQP_PROTOCOL_VYPRESSCHAT) {
- NEWMSG_PRINTF("C%s%h%s", dst, channel, topic_text);
- } else {
- NEWMSG_PRINTF("C%s%s", dst, topic_text);
- }
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_channel_whohere_req(
- vqp_link_t link,
- const char * channel, const char * src)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("L%s%h", src, channel);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_channel_whohere_ack(
- vqp_link_t link,
- const char * channel, const char * src, const char * dst,
- enum vqp_active src_is_active)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("K%s%h%s%A", dst, channel, src, src_is_active);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_channel_list_req(
- vqp_link_t link,
- const char * src)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("N%s", src);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_channel_list_ack(
- vqp_link_t link,
- const char * dst, const char * channel_list)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("O%s%s", dst, channel_list);
- NEWMSG_RETURN();
-}
-
-/* message delivery/ack */
-vqp_msg_t vqp_msg_message(
- vqp_link_t link,
- const char * src, const char * dst,
- const char * text, int is_multiaddress_msg)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF(is_multiaddress_msg ? "E%s%s%s": "6%s%s%s", src, dst, text);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_message_ack(
- vqp_link_t link,
- const char * src, const char * dst,
- enum vqp_status src_status, enum vqp_gender src_gender,
- const char * src_autoanswer, const char * orig_packetsig)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("7%S%s%s%G%s%s",
- src_status, dst, src, src_gender, src_autoanswer, orig_packetsig);
- NEWMSG_RETURN();
-}
-
-/* info req-ack */
-vqp_msg_t vqp_msg_info_req(
- vqp_link_t link,
- const char * src, const char * dst)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("F%s%s", dst, src);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_info_ack(
- vqp_link_t link,
- const char * src, const char * dst,
- const char * src_computer_name, const char * src_user_name,
- const char * src_ip_address, const char * src_channel_list,
- const char * src_autoanswer, const char * src_workgroup,
- const char * src_platform, const char * src_software)
-{
- NEWMSG_INIT(link);
-
- if(P_VQP_LINK_STRUCT(link)->protocol == VQP_PROTOCOL_VYPRESSCHAT) {
- NEWMSG_PRINTF("G%s%s%s%s" "%s%s%s" "%s%s%s%0",
- dst, src, src_computer_name, src_user_name,
- src_ip_address, src_channel_list, src_autoanswer,
- src_workgroup, src_platform, src_software);
- } else {
- NEWMSG_PRINTF("G%s%s%s%s0 %%%00 Kb%0%s%s",
- dst, src, src_computer_name, src_user_name,
- src_channel_list, src_autoanswer);
- }
- NEWMSG_RETURN();
-}
-
-/* beep's */
-vqp_msg_t vqp_msg_beep_signal(
- vqp_link_t link,
- const char * src, const char * dst)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("H0%s%s", dst, src);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_beep_ack(
- vqp_link_t link,
- const char * src, const char * dst, enum vqp_gender src_gender)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("H1%s%s%G", dst, src, src_gender);
- NEWMSG_RETURN();
-}
-
-/* privates */
-vqp_msg_t vqp_msg_private_open(
- vqp_link_t link,
- const char * src, const char * dst, enum vqp_gender src_gender)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("J0%s%s%G", src, dst, src_gender);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_private_close(
- vqp_link_t link,
- const char * src, const char * dst, enum vqp_gender src_gender)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF("J1%s%s%G", src, dst, src_gender);
- NEWMSG_RETURN();
-}
-
-vqp_msg_t vqp_msg_private_text(
- vqp_link_t link,
- const char * src, const char * dst,
- const char * text, int is_action_text)
-{
- NEWMSG_INIT(link);
- NEWMSG_PRINTF(
- is_action_text ? "J3%s%s%s": "J2%s%s%s",
- src, dst, text);
- NEWMSG_RETURN();
-}
-
|