#include "barev_xml.h" #include static int append_str(char *out, size_t out_size, size_t *pos, const char *s) { size_t i; if (!out || !s || !pos || out_size == 0) return 0; for (i = 0; s[i] != '\0'; ++i) { if (*pos + 1 >= out_size) return 0; out[*pos] = s[i]; *pos = *pos + 1; } out[*pos] = '\0'; return 1; } int barev_xml_escape(const char *in, char *out, size_t out_size) { size_t i; size_t pos; const char *rep; if (!in || !out || out_size == 0) return 0; pos = 0; out[0] = '\0'; for (i = 0; in[i] != '\0'; ++i) { rep = 0; if (in[i] == '&') rep = "&"; else if (in[i] == '<') rep = "<"; else if (in[i] == '>') rep = ">"; else if (in[i] == '"') rep = """; else if (in[i] == '\'') rep = "'"; if (rep) { if (!append_str(out, out_size, &pos, rep)) return 0; } else { if (pos + 1 >= out_size) return 0; out[pos++] = in[i]; out[pos] = '\0'; } } return 1; } int barev_build_stream_header(const char *from_jid, const char *to_jid, char *out, size_t out_size) { size_t pos; char from_e[512], to_e[512]; if (!from_jid || !to_jid || !out || out_size == 0) return 0; if (!barev_xml_escape(from_jid, from_e, sizeof(from_e))) return 0; if (!barev_xml_escape(to_jid, to_e, sizeof(to_e))) return 0; pos = 0; out[0] = '\0'; if (!append_str(out, out_size, &pos, "\n")) return 0; if (!append_str(out, out_size, &pos, "")) return 0; return 1; } int barev_build_stream_end(char *out, size_t out_size) { size_t pos; if (!out || out_size == 0) return 0; pos = 0; out[0] = '\0'; return append_str(out, out_size, &pos, ""); } int barev_build_presence(const char *to_jid, int status, const char *status_msg, char *out, size_t out_size) { size_t pos; char to_e[512], msg_e[1024]; const char *show = 0; if (!out || out_size == 0) return 0; pos = 0; out[0] = '\0'; if (!append_str(out, out_size, &pos, "")) return 0; if (status == 2) show = "away"; else if (status == 3) show = "xa"; else if (status == 4) show = "dnd"; else if (status == 0) show = "offline"; if (show) { if (!append_str(out, out_size, &pos, "")) return 0; if (!append_str(out, out_size, &pos, show)) return 0; if (!append_str(out, out_size, &pos, "")) return 0; } if (status_msg && status_msg[0] != '\0') { if (!barev_xml_escape(status_msg, msg_e, sizeof(msg_e))) return 0; if (!append_str(out, out_size, &pos, "")) return 0; if (!append_str(out, out_size, &pos, msg_e)) return 0; if (!append_str(out, out_size, &pos, "")) return 0; } if (!append_str(out, out_size, &pos, "")) return 0; return 1; } int barev_build_message(const char *from_jid, const char *to_jid, const char *body, char *out, size_t out_size) { size_t pos; char from_e[512], to_e[512], body_e[2048]; if (!from_jid || !to_jid || !body || !out || out_size == 0) return 0; if (!barev_xml_escape(from_jid, from_e, sizeof(from_e))) return 0; if (!barev_xml_escape(to_jid, to_e, sizeof(to_e))) return 0; if (!barev_xml_escape(body, body_e, sizeof(body_e))) return 0; pos = 0; out[0] = '\0'; if (!append_str(out, out_size, &pos, "")) return 0; if (!append_str(out, out_size, &pos, body_e)) return 0; if (!append_str(out, out_size, &pos, "")) return 0; return 1; } int barev_build_ping(const char *from_jid, const char *to_jid, const char *ping_id, char *out, size_t out_size) { size_t pos; char from_e[512], to_e[512], id_e[256]; if (!from_jid || !to_jid || !ping_id || !out || out_size == 0) return 0; if (!barev_xml_escape(from_jid, from_e, sizeof(from_e))) return 0; if (!barev_xml_escape(to_jid, to_e, sizeof(to_e))) return 0; if (!barev_xml_escape(ping_id, id_e, sizeof(id_e))) return 0; pos = 0; out[0] = '\0'; if (!append_str(out, out_size, &pos, "")) return 0; return 1; } int barev_build_pong(const char *to_jid, const char *ping_id, char *out, size_t out_size) { size_t pos; char to_e[512], id_e[256]; if (!to_jid || !ping_id || !out || out_size == 0) return 0; if (!barev_xml_escape(to_jid, to_e, sizeof(to_e))) return 0; if (!barev_xml_escape(ping_id, id_e, sizeof(id_e))) return 0; pos = 0; out[0] = '\0'; if (!append_str(out, out_size, &pos, "")) return 0; return 1; } int barev_build_chatstate(const char *to_jid, const char *state_name, char *out, size_t out_size) { size_t pos; char to_e[512], st_e[64]; if (!to_jid || !state_name || !out || out_size == 0) return 0; if (!barev_xml_escape(to_jid, to_e, sizeof(to_e))) return 0; if (!barev_xml_escape(state_name, st_e, sizeof(st_e))) return 0; pos = 0; out[0] = '\0'; if (!append_str(out, out_size, &pos, "<")) return 0; if (!append_str(out, out_size, &pos, st_e)) return 0; if (!append_str(out, out_size, &pos, " xmlns=\"http://jabber.org/protocol/chatstates\"/>")) return 0; return 1; } int barev_build_vcard_get(const char *to_jid, const char *id, char *out, size_t out_size) { size_t pos; char to_e[512], id_e[128]; if (!to_jid || !id || !out || out_size == 0) return 0; if (!barev_xml_escape(to_jid, to_e, sizeof(to_e))) return 0; if (!barev_xml_escape(id, id_e, sizeof(id_e))) return 0; pos = 0; out[0] = '\0'; if (!append_str(out, out_size, &pos, "")) return 0; return 1; } int barev_build_vcard_result(const char *to_jid, const char *id, const char *vcard_inner, char *out, size_t out_size) { size_t pos; char to_e[512], id_e[128]; if (!to_jid || !id || !vcard_inner || !out || out_size == 0) return 0; if (!barev_xml_escape(to_jid, to_e, sizeof(to_e))) return 0; if (!barev_xml_escape(id, id_e, sizeof(id_e))) return 0; pos = 0; out[0] = '\0'; if (!append_str(out, out_size, &pos, "")) return 0; if (!append_str(out, out_size, &pos, vcard_inner)) return 0; if (!append_str(out, out_size, &pos, "")) return 0; return 1; } int barev_extract_attribute(const char *xml, const char *attr_name, char *out, size_t out_size) { const char *p; const char *q; size_t n; char pat[128]; if (!xml || !attr_name || !out || out_size == 0) return 0; out[0] = '\0'; if (strlen(attr_name) + 3 >= sizeof(pat)) return 0; strcpy(pat, attr_name); strcat(pat, "='"); p = strstr(xml, pat); if (!p) { strcpy(pat, attr_name); strcat(pat, "=\""); p = strstr(xml, pat); if (!p) return 0; } p += strlen(pat); q = p; while (*q && *q != '\'' && *q != '"') q++; n = (size_t)(q - p); if (n + 1 > out_size) return 0; memcpy(out, p, n); out[n] = '\0'; return 1; } int barev_extract_element_content(const char *xml, const char *element, char *out, size_t out_size) { char open[128], close[128]; const char *p; const char *q; size_t n; if (!xml || !element || !out || out_size == 0) return 0; out[0] = '\0'; if (strlen(element) + 3 >= sizeof(open)) return 0; strcpy(open, "<"); strcat(open, element); strcat(open, ">"); strcpy(close, ""); p = strstr(xml, open); if (!p) return 0; p += strlen(open); q = strstr(p, close); if (!q) return 0; n = (size_t)(q - p); if (n + 1 > out_size) return 0; memcpy(out, p, n); out[n] = '\0'; return 1; }