libpurple/protocols/gg/lib/libgadu.c

changeset 35630
8e5d0d726b09
parent 35620
fb20cfee648a
parent 35627
fd11790cc4d6
child 36119
b2ad25dfbd57
equal deleted inserted replaced
35629:5aecb81f23ab 35630:8e5d0d726b09
1 /* $Id$ */ 1 /* $Id$ */
2 2
3 /* 3 /*
4 * (C) Copyright 2001-2010 Wojtek Kaniewski <wojtekka@irc.pl> 4 * (C) Copyright 2001-2010 Wojtek Kaniewski <wojtekka@irc.pl>
5 * Robert J. Woźny <speedy@ziew.org> 5 * Robert J. Woźny <speedy@ziew.org>
6 * Arkadiusz Miśkiewicz <arekm@pld-linux.org> 6 * Arkadiusz Miśkiewicz <arekm@pld-linux.org>
7 * Tomasz Chiliński <chilek@chilan.com> 7 * Tomasz Chiliński <chilek@chilan.com>
8 * Adam Wysocki <gophi@ekg.chmurka.net> 8 * Adam Wysocki <gophi@ekg.chmurka.net>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License Version 11 * it under the terms of the GNU Lesser General Public License Version
12 * 2.1 as published by the Free Software Foundation. 12 * 2.1 as published by the Free Software Foundation.
13 * 13 *
28 * \brief Główny moduł biblioteki 28 * \brief Główny moduł biblioteki
29 */ 29 */
30 30
31 #include "strman.h" 31 #include "strman.h"
32 #include "network.h" 32 #include "network.h"
33 #ifdef sun 33 #include "fileio.h"
34 # include <sys/filio.h>
35 #endif
36 34
37 #include "libgadu.h" 35 #include "libgadu.h"
38 #include "protocol.h" 36 #include "protocol.h"
39 #include "resolver.h" 37 #include "resolver.h"
40 #include "internal.h" 38 #include "internal.h"
60 # include <openssl/rand.h> 58 # include <openssl/rand.h>
61 #endif 59 #endif
62 60
63 /** 61 /**
64 * Port gniazda nasłuchującego dla połączeń bezpośrednich. 62 * Port gniazda nasłuchującego dla połączeń bezpośrednich.
65 * 63 *
66 * \ingroup ip 64 * \ingroup ip
67 */ 65 */
68 int gg_dcc_port = 0; 66 int gg_dcc_port = 0;
69 67
70 /** 68 /**
124 char *gg_proxy_password = NULL; 122 char *gg_proxy_password = NULL;
125 123
126 #ifndef DOXYGEN 124 #ifndef DOXYGEN
127 125
128 #ifndef lint 126 #ifndef lint
129 static char rcsid[] 127 static char rcsid[] GG_UNUSED = "$Id$";
130 #ifdef __GNUC__
131 __attribute__ ((unused))
132 #endif
133 = "$Id$";
134 #endif 128 #endif
135 129
136 #endif /* DOXYGEN */ 130 #endif /* DOXYGEN */
137 131
138 static void gg_compat_message_sent(struct gg_session *sess, int seq, size_t recipients_count, uin_t *recipients); 132 static void gg_compat_message_sent(struct gg_session *sess, int seq, size_t recipients_count, uin_t *recipients);
173 void *ptr; 167 void *ptr;
174 168
175 ptr = malloc(size); 169 ptr = malloc(size);
176 if (ptr == NULL) { 170 if (ptr == NULL) {
177 gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR, 171 gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR,
178 "//gg_new0(%zd) not enough memory\n", size); 172 "//gg_new0(%" GG_SIZE_FMT
173 ") not enough memory\n", size);
179 return NULL; 174 return NULL;
180 } 175 }
181 176
182 memset(ptr, 0, size); 177 memset(ptr, 0, size);
183 return ptr; 178 return ptr;
448 443
449 return res; 444 return res;
450 } 445 }
451 } 446 }
452 447
453
454
455 /** 448 /**
456 * \internal Wysyła do serwera dane binarne. 449 * \internal Wysyła do serwera dane binarne.
457 * 450 *
458 * Funkcja wysyła dane do serwera zajmując się TLS w razie konieczności. 451 * Funkcja wysyła dane do serwera zajmując się TLS w razie konieczności.
459 * 452 *
566 { 559 {
567 struct gg_header *gh; 560 struct gg_header *gh;
568 char *packet; 561 char *packet;
569 int res; 562 int res;
570 size_t len; 563 size_t len;
564 uint32_t ghlen = 0;
571 565
572 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_recv_packet(%p);\n", sess); 566 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_recv_packet(%p);\n", sess);
573 567
574 if (sess == NULL) { 568 if (sess == NULL) {
575 errno = EFAULT; 569 errno = EFAULT;
588 582
589 gh = (struct gg_header*) sess->recv_buf; 583 gh = (struct gg_header*) sess->recv_buf;
590 584
591 if ((size_t) sess->recv_done < sizeof(struct gg_header)) { 585 if ((size_t) sess->recv_done < sizeof(struct gg_header)) {
592 len = sizeof(struct gg_header) - sess->recv_done; 586 len = sizeof(struct gg_header) - sess->recv_done;
593 gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() header: %d done, %d to go\n", sess->recv_done, len); 587 gg_debug_session(sess, GG_DEBUG_NET,
588 "// gg_recv_packet() header: %d done, "
589 "%" GG_SIZE_FMT " to go\n",
590 sess->recv_done, len);
594 } else { 591 } else {
595 uint32_t ghlen = gh ? gg_fix32(gh->length) : 0; 592 ghlen = gh ? gg_fix32(gh->length) : 0;
593
594 if (ghlen > 65535) {
595 gg_debug_session(sess, GG_DEBUG_ERROR,
596 "// gg_recv_packet() invalid packet "
597 "length (%d)\n", ghlen);
598 errno = ERANGE;
599 goto fail;
600 }
601
596 if ((size_t) sess->recv_done >= sizeof(struct gg_header) + ghlen) { 602 if ((size_t) sess->recv_done >= sizeof(struct gg_header) + ghlen) {
597 gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() and that's it\n"); 603 gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() and that's it\n");
598 break; 604 break;
599 } 605 }
600 606
601 len = sizeof(struct gg_header) + ghlen - sess->recv_done; 607 len = sizeof(struct gg_header) + ghlen - sess->recv_done;
602 608
603 gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() payload: %d done, %d length, %d to go\n", sess->recv_done, ghlen, len); 609 gg_debug_session(sess, GG_DEBUG_NET,
610 "// gg_recv_packet() payload: %d done, "
611 "%u length, %" GG_SIZE_FMT " to go\n",
612 sess->recv_done, ghlen, len);
604 } 613 }
605 614
606 res = gg_read(sess, sess->recv_buf + sess->recv_done, len); 615 res = gg_read(sess, sess->recv_buf + sess->recv_done, len);
607 616
608 if (res == 0) { 617 if (res == 0) {
615 gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() resource temporarily unavailable\n"); 624 gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() resource temporarily unavailable\n");
616 goto eagain; 625 goto eagain;
617 } 626 }
618 627
619 if (res == -1) { 628 if (res == -1) {
620 gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_recv_packet() read failed: errno=%d, %s\n", errno, strerror(errno)); 629 gg_debug_session(sess, GG_DEBUG_ERROR,
630 "// gg_recv_packet() read failed: errno=%d, "
631 "%s\n", errno, strerror(errno));
621 goto fail; 632 goto fail;
622 } 633 }
623 634
624 gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() read %d bytes\n", res); 635 gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() read %d bytes\n", res);
625 636
626 if (sess->recv_done + res == sizeof(struct gg_header)) { 637 if (sess->recv_done + res == sizeof(struct gg_header)) {
627 char *tmp; 638 char *tmp;
628 uint32_t ghlen = gh ? gg_fix32(gh->length) : 0; 639 ghlen = gh ? gg_fix32(gh->length) : 0;
629 640
630 gg_debug_session(sess, GG_DEBUG_NET, "// gg_recv_packet() header complete, payload %d bytes\n", ghlen); 641 gg_debug_session(sess, GG_DEBUG_NET,
642 "// gg_recv_packet() header complete, "
643 "payload %d bytes\n", ghlen);
631 644
632 if (ghlen == 0) 645 if (ghlen == 0)
633 break; 646 break;
634 647
635 if (ghlen > 65535) { 648 if (ghlen > 65535) {
636 gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_recv_packet() invalid packet length (%d)\n", ghlen); 649 gg_debug_session(sess, GG_DEBUG_ERROR,
650 "// gg_recv_packet() invalid packet "
651 "length (%d)\n", ghlen);
637 errno = ERANGE; 652 errno = ERANGE;
638 goto fail; 653 goto fail;
639 } 654 }
640 655
641 tmp = realloc(sess->recv_buf, sizeof(struct gg_header) + ghlen + 1); 656 tmp = realloc(sess->recv_buf, sizeof(struct gg_header) + ghlen + 1);
657 672
658 if (gh == NULL) 673 if (gh == NULL)
659 goto fail; 674 goto fail;
660 675
661 /* Czasami zakładamy, że teksty w pakietach są zakończone zerem */ 676 /* Czasami zakładamy, że teksty w pakietach są zakończone zerem */
662 packet[sizeof(struct gg_header) + gg_fix32(gh->length)] = 0; 677 packet[sizeof(struct gg_header) + ghlen] = 0;
663 678
664 gg_debug_session(sess, GG_DEBUG_MISC, "// gg_recv_packet(type=0x%.2x, length=%d)\n", gg_fix32(gh->type), gg_fix32(gh->length)); 679 gg_debug_session(sess, GG_DEBUG_MISC, "// gg_recv_packet(type=0x%.2x, "
665 gg_debug_dump(sess, GG_DEBUG_DUMP, packet, sizeof(struct gg_header) + gg_fix32(gh->length)); 680 "length=%d)\n", gg_fix32(gh->type), ghlen);
681 gg_debug_dump(sess, GG_DEBUG_DUMP, packet, sizeof(struct gg_header) + ghlen);
666 682
667 gh->type = gg_fix32(gh->type); 683 gh->type = gg_fix32(gh->type);
668 gh->length = gg_fix32(gh->length); 684 gh->length = ghlen;
669 685
670 return packet; 686 return packet;
671 687
672 fail: 688 fail:
673 free(sess->recv_buf); 689 free(sess->recv_buf);
686 * część zostanie zakolejkowana i wysłana, gdy będzie to możliwe. 702 * część zostanie zakolejkowana i wysłana, gdy będzie to możliwe.
687 * 703 *
688 * \param sess Struktura sesji 704 * \param sess Struktura sesji
689 * \param type Rodzaj pakietu 705 * \param type Rodzaj pakietu
690 * \param ... Lista kolejnych części pakietu (wskaźnik na bufor i długość 706 * \param ... Lista kolejnych części pakietu (wskaźnik na bufor i długość
691 * typu \c int) zakończona \c NULL 707 * typu \c int) zakończona \c NULL
692 * 708 *
693 * \return 0 jeśli się powiodło, -1 w przypadku błędu 709 * \return 0 jeśli się powiodło, -1 w przypadku błędu
694 */ 710 */
695 int gg_send_packet(struct gg_session *sess, int type, ...) 711 int gg_send_packet(struct gg_session *sess, int type, ...)
696 { 712 {
739 755
740 h = (struct gg_header*) tmp; 756 h = (struct gg_header*) tmp;
741 h->type = gg_fix32(type); 757 h->type = gg_fix32(type);
742 h->length = gg_fix32(tmp_length - sizeof(struct gg_header)); 758 h->length = gg_fix32(tmp_length - sizeof(struct gg_header));
743 759
744 gg_debug_session(sess, GG_DEBUG_MISC, "// gg_send_packet(type=0x%.2x, length=%d)\n", gg_fix32(h->type), gg_fix32(h->length)); 760 gg_debug_session(sess, GG_DEBUG_MISC, "// gg_send_packet(type=0x%.2x, "
761 "length=%d)\n", gg_fix32(h->type), gg_fix32(h->length));
745 gg_debug_dump(sess, GG_DEBUG_DUMP, tmp, tmp_length); 762 gg_debug_dump(sess, GG_DEBUG_DUMP, tmp, tmp_length);
746 763
747 res = gg_write(sess, tmp, tmp_length); 764 res = gg_write(sess, tmp, tmp_length);
748 765
749 free(tmp); 766 free(tmp);
750 767
751 if (res == -1) { 768 if (res == -1) {
752 gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_send_packet() write() failed. res = %d, errno = %d (%s)\n", res, errno, strerror(errno)); 769 gg_debug_session(sess, GG_DEBUG_ERROR, "// gg_send_packet() "
753 return -1; 770 "write() failed. res = %d, errno = %d (%s)\n",
754 } 771 res, errno, strerror(errno));
755 772 return -1;
756 if (sess->async) 773 }
757 gg_debug_session(sess, GG_DEBUG_NET, "// gg_send_packet() partial write(), %d sent, %d left, %d total left\n", res, tmp_length - res, sess->send_left); 774
775 if (sess->async) {
776 gg_debug_session(sess, GG_DEBUG_NET, "// gg_send_packet() "
777 "partial write(), %d sent, %d left, %d total left\n",
778 res, tmp_length - res, sess->send_left);
779 }
758 780
759 if (sess->send_buf) 781 if (sess->send_buf)
760 sess->check |= GG_CHECK_WRITE; 782 sess->check |= GG_CHECK_WRITE;
761 783
762 return 0; 784 return 0;
808 * 830 *
809 * \note Funkcja zwróci błąd ENOSYS jeśli połączenie SSL było wymagane, ale 831 * \note Funkcja zwróci błąd ENOSYS jeśli połączenie SSL było wymagane, ale
810 * obsługa SSL nie jest wkompilowana. 832 * obsługa SSL nie jest wkompilowana.
811 * 833 *
812 * \param p Struktura opisująca parametry połączenia. Wymagane pola: uin, 834 * \param p Struktura opisująca parametry połączenia. Wymagane pola: uin,
813 * password, async. 835 * password, async.
814 * 836 *
815 * \return Wskaźnik do zaalokowanej struktury sesji \c gg_session lub NULL 837 * \return Wskaźnik do zaalokowanej struktury sesji \c gg_session lub NULL
816 * w przypadku błędu. 838 * w przypadku błędu.
817 * 839 *
818 * \ingroup login 840 * \ingroup login
819 */ 841 */
820 struct gg_session *gg_login(const struct gg_login_params *p) 842 struct gg_session *gg_login(const struct gg_login_params *p)
821 { 843 {
926 sess_private->socket_manager_type = 948 sess_private->socket_manager_type =
927 GG_SOCKET_MANAGER_TYPE_INTERNAL; 949 GG_SOCKET_MANAGER_TYPE_INTERNAL;
928 } 950 }
929 951
930 if (GG_LOGIN_PARAMS_HAS_FIELD(p, host_white_list) && 952 if (GG_LOGIN_PARAMS_HAS_FIELD(p, host_white_list) &&
931 p->host_white_list != NULL) { 953 p->host_white_list != NULL)
954 {
932 sess_private->host_white_list = 955 sess_private->host_white_list =
933 gg_strarr_dup(p->host_white_list); 956 gg_strarr_dup(p->host_white_list);
934 if (sess_private->host_white_list == NULL) 957 if (sess_private->host_white_list == NULL)
935 goto fail; 958 goto fail;
936 } 959 }
937 960
938 if (p->protocol_features == 0) { 961 if (p->protocol_features == 0) {
939 sess->protocol_features = GG_FEATURE_MSG80 | GG_FEATURE_STATUS80 | GG_FEATURE_DND_FFC | GG_FEATURE_IMAGE_DESCR | GG_FEATURE_UNKNOWN_100 | GG_FEATURE_USER_DATA | GG_FEATURE_MSG_ACK | GG_FEATURE_TYPING_NOTIFICATION; 962 sess->protocol_features = GG_FEATURE_MSG80 |
963 GG_FEATURE_STATUS80 | GG_FEATURE_DND_FFC |
964 GG_FEATURE_IMAGE_DESCR | GG_FEATURE_UNKNOWN_100 |
965 GG_FEATURE_USER_DATA | GG_FEATURE_MSG_ACK |
966 GG_FEATURE_TYPING_NOTIFICATION;
940 } else { 967 } else {
941 sess->protocol_features = (p->protocol_features & ~(GG_FEATURE_STATUS77 | GG_FEATURE_MSG77)); 968 sess->protocol_features = (p->protocol_features & ~(GG_FEATURE_STATUS77 | GG_FEATURE_MSG77));
942 969
943 if (!(p->protocol_features & GG_FEATURE_STATUS77)) 970 if (!(p->protocol_features & GG_FEATURE_STATUS77))
944 sess->protocol_features |= GG_FEATURE_STATUS80; 971 sess->protocol_features |= GG_FEATURE_STATUS80;
963 sess->image_size = p->image_size; 990 sess->image_size = p->image_size;
964 sess->pid = -1; 991 sess->pid = -1;
965 sess->encoding = p->encoding; 992 sess->encoding = p->encoding;
966 993
967 if (gg_session_set_resolver(sess, p->resolver) == -1) { 994 if (gg_session_set_resolver(sess, p->resolver) == -1) {
968 gg_debug(GG_DEBUG_MISC, "// gg_login() invalid arguments. unsupported resolver type (%d)\n", p->resolver); 995 gg_debug(GG_DEBUG_MISC, "// gg_login() invalid arguments. "
996 "unsupported resolver type (%d)\n", p->resolver);
969 errno = EFAULT; 997 errno = EFAULT;
970 goto fail; 998 goto fail;
971 } 999 }
972 1000
973 if (p->status_descr) { 1001 if (p->status_descr) {
975 1003
976 if (!sess->initial_descr) { 1004 if (!sess->initial_descr) {
977 gg_debug(GG_DEBUG_MISC, "// gg_login() not enough memory for status\n"); 1005 gg_debug(GG_DEBUG_MISC, "// gg_login() not enough memory for status\n");
978 goto fail; 1006 goto fail;
979 } 1007 }
980 1008
981 /* XXX pamiętać, żeby nie ciąć w środku znaku utf-8 */ 1009 /* XXX pamiętać, żeby nie ciąć w środku znaku utf-8 */
982 1010
983 if (strlen(sess->initial_descr) > GG_STATUS_DESCR_MAXSIZE) 1011 if (strlen(sess->initial_descr) > GG_STATUS_DESCR_MAXSIZE)
984 sess->initial_descr[GG_STATUS_DESCR_MAXSIZE] = 0; 1012 sess->initial_descr[GG_STATUS_DESCR_MAXSIZE] = 0;
985 } 1013 }
986 1014
987 if (p->tls != GG_SSL_DISABLED) { 1015 if (p->tls != GG_SSL_DISABLED) {
1004 1032
1005 if (sess->server_addr == 0 && sess->connect_host == NULL) { 1033 if (sess->server_addr == 0 && sess->connect_host == NULL) {
1006 if (gg_proxy_enabled) { 1034 if (gg_proxy_enabled) {
1007 sess->resolver_host = gg_proxy_host; 1035 sess->resolver_host = gg_proxy_host;
1008 sess->proxy_port = gg_proxy_port; 1036 sess->proxy_port = gg_proxy_port;
1009 sess->state = (sess->async) ? GG_STATE_RESOLVE_PROXY_HUB_ASYNC : GG_STATE_RESOLVE_PROXY_HUB_SYNC; 1037 sess->state = (sess->async) ?
1038 GG_STATE_RESOLVE_PROXY_HUB_ASYNC :
1039 GG_STATE_RESOLVE_PROXY_HUB_SYNC;
1010 } else { 1040 } else {
1011 sess->resolver_host = GG_APPMSG_HOST; 1041 sess->resolver_host = GG_APPMSG_HOST;
1012 sess->proxy_port = 0; 1042 sess->proxy_port = 0;
1013 sess->state = (sess->async) ? GG_STATE_RESOLVE_HUB_ASYNC : GG_STATE_RESOLVE_HUB_SYNC; 1043 sess->state = (sess->async) ? GG_STATE_RESOLVE_HUB_ASYNC : GG_STATE_RESOLVE_HUB_SYNC;
1014 } 1044 }
1015 } else { 1045 } else {
1016 if (sess->connect_host != NULL) 1046 if (sess->connect_host != NULL)
1017 sess->server_addr = 0; 1047 sess->server_addr = 0;
1018 else { 1048 else {
1019 // XXX inet_ntoa i wielowątkowość 1049 /* XXX inet_ntoa i wielowątkowość */
1020 sess->connect_host = strdup(inet_ntoa(*(struct in_addr*) &sess->server_addr)); 1050 sess->connect_host = strdup(inet_ntoa(*(struct in_addr*) &sess->server_addr));
1021 if (sess->connect_host == NULL) 1051 if (sess->connect_host == NULL)
1022 goto fail; 1052 goto fail;
1023 } 1053 }
1024 sess->connect_index = 0; 1054 sess->connect_index = 0;
1048 } 1078 }
1049 sess->state = (sess->async) ? GG_STATE_RESOLVE_GG_ASYNC : GG_STATE_RESOLVE_GG_SYNC; 1079 sess->state = (sess->async) ? GG_STATE_RESOLVE_GG_ASYNC : GG_STATE_RESOLVE_GG_SYNC;
1050 } 1080 }
1051 } 1081 }
1052 1082
1053 // XXX inaczej gg_watch_fd() wyjdzie z timeoutem 1083 /* XXX inaczej gg_watch_fd() wyjdzie z timeoutem */
1054 sess->timeout = GG_DEFAULT_TIMEOUT; 1084 sess->timeout = GG_DEFAULT_TIMEOUT;
1055 1085
1056 if (!sess->async) { 1086 if (!sess->async) {
1057 while (!GG_SESSION_IS_CONNECTED(sess)) { 1087 while (!GG_SESSION_IS_CONNECTED(sess)) {
1058 struct gg_event *ge; 1088 struct gg_event *ge;
1083 goto fail; 1113 goto fail;
1084 } 1114 }
1085 1115
1086 gg_event_free(ge); 1116 gg_event_free(ge);
1087 } 1117 }
1088
1089
1090 1118
1091 return sess; 1119 return sess;
1092 1120
1093 fail: 1121 fail:
1094 gg_free_session(sess); 1122 gg_free_session(sess);
1220 1248
1221 if (sess->ssl_ctx) 1249 if (sess->ssl_ctx)
1222 SSL_CTX_free(sess->ssl_ctx); 1250 SSL_CTX_free(sess->ssl_ctx);
1223 #endif 1251 #endif
1224 1252
1225 sess->resolver_cleanup(&sess->resolver, 1); 1253 if (sess->resolver_cleanup != NULL)
1254 sess->resolver_cleanup(&sess->resolver, 1);
1226 1255
1227 gg_close(sess); 1256 gg_close(sess);
1228 1257
1229 while (sess->images) 1258 while (sess->images) {
1259 struct gg_image_queue *next = sess->images->next;
1260
1230 gg_image_queue_remove(sess, sess->images, 1); 1261 gg_image_queue_remove(sess, sess->images, 1);
1262
1263 /* a fix for false-positive NULL-dereference */
1264 sess->images = next;
1265 }
1231 1266
1232 free(sess->send_buf); 1267 free(sess->send_buf);
1233 1268
1234 for (dcc = sess->dcc7_list; dcc; dcc = dcc->next) 1269 for (dcc = sess->dcc7_list; dcc; dcc = dcc->next)
1235 dcc->sess = NULL; 1270 dcc->sess = NULL;
1324 if (sess->protocol_version >= GG_PROTOCOL_VERSION_110) { 1359 if (sess->protocol_version >= GG_PROTOCOL_VERSION_110) {
1325 p.flags = gg_fix32(0x00000014); 1360 p.flags = gg_fix32(0x00000014);
1326 descr_null_len = 1; 1361 descr_null_len = 1;
1327 } 1362 }
1328 1363
1329 res = gg_send_packet(sess, GG_NEW_STATUS80, 1364 res = gg_send_packet(sess, GG_NEW_STATUS80,
1330 &p, sizeof(p), 1365 &p, sizeof(p), descr, descr_len,
1331 descr, descr_len, 1366 "\x00", descr_null_len, NULL);
1332 "\x00", descr_null_len,
1333 NULL);
1334 1367
1335 free(gen_descr); 1368 free(gen_descr);
1336 1369
1337 if (GG_S_NA(status)) { 1370 if (GG_S_NA(status)) {
1338 sess->state = GG_STATE_DISCONNECTING; 1371 sess->state = GG_STATE_DISCONNECTING;
1354 * 1387 *
1355 * \ingroup status 1388 * \ingroup status
1356 */ 1389 */
1357 int gg_change_status_descr_time(struct gg_session *sess, int status, const char *descr, int ts) 1390 int gg_change_status_descr_time(struct gg_session *sess, int status, const char *descr, int ts)
1358 { 1391 {
1359 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_change_status_descr_time(%p, %d, \"%s\", %d);\n", sess, status, descr, ts); 1392 gg_debug_session(sess, GG_DEBUG_FUNCTION,
1393 "** gg_change_status_descr_time(%p, %d, \"%s\", %d);\n",
1394 sess, status, descr, ts);
1360 1395
1361 return gg_change_status_descr(sess, status, descr); 1396 return gg_change_status_descr(sess, status, descr);
1362 } 1397 }
1363 1398
1364 /** 1399 /**
1400 char *html_message_gen = NULL, *plain_message_gen = NULL; 1435 char *html_message_gen = NULL, *plain_message_gen = NULL;
1401 const char *html_message, *plain_message; 1436 const char *html_message, *plain_message;
1402 int succ = 1; 1437 int succ = 1;
1403 1438
1404 gg_debug_session(sess, GG_DEBUG_FUNCTION, 1439 gg_debug_session(sess, GG_DEBUG_FUNCTION,
1405 "** gg_send_message_110(%p, %u, %llu, %p, %d);\n", 1440 "** gg_send_message_110(%p, %u, %" PRIu64 ", %p, %d);\n",
1406 sess, recipient, chat_id, message, is_html); 1441 sess, recipient, chat_id, message, is_html);
1407 1442
1408 if (message == NULL) 1443 if (message == NULL)
1409 return -1; 1444 return -1;
1410 1445
1436 plain_message, sess->encoding, GG_ENCODING_UTF8, 1471 plain_message, sess->encoding, GG_ENCODING_UTF8,
1437 -1, -1); 1472 -1, -1);
1438 if (plain_message_gen == NULL) 1473 if (plain_message_gen == NULL)
1439 return -1; 1474 return -1;
1440 } 1475 }
1441 1476
1442 html_message = html_message_gen = 1477 html_message = html_message_gen =
1443 gg_message_text_to_html_110(plain_message, -1); 1478 gg_message_text_to_html_110(plain_message, -1);
1444 if (html_message_gen == NULL) { 1479 if (html_message_gen == NULL) {
1445 free(plain_message_gen); 1480 free(plain_message_gen);
1446 return -1; 1481 return -1;
1492 * 1527 *
1493 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu. 1528 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
1494 * 1529 *
1495 * \ingroup messages 1530 * \ingroup messages
1496 */ 1531 */
1497 static int gg_send_message_common(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *message, const unsigned char *format, int formatlen, const unsigned char *html_message) 1532 static int gg_send_message_common(struct gg_session *sess, int msgclass,
1533 int recipients_count, uin_t *recipients, const unsigned char *message,
1534 const unsigned char *format, int formatlen,
1535 const unsigned char *html_message)
1498 { 1536 {
1499 struct gg_send_msg80 s80; 1537 struct gg_send_msg80 s80;
1500 const char *cp_msg = NULL, *utf_html_msg = NULL; 1538 const char *cp_msg = NULL, *utf_html_msg = NULL;
1501 char *recoded_msg = NULL, *recoded_html_msg = NULL; 1539 char *recoded_msg = NULL, *recoded_html_msg = NULL;
1502 unsigned char *generated_format = NULL; 1540 unsigned char *generated_format = NULL;
1503 int seq_no = -1; 1541 int seq_no = -1;
1504 1542
1505 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_common(%p, %d, %d, %p, %p, %p, %d, %p);\n", sess, msgclass, recipients_count, recipients, message, format, formatlen, html_message); 1543 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_common("
1544 "%p, %d, %d, %p, %p, %p, %d, %p);\n", sess, msgclass,
1545 recipients_count, recipients, message, format,
1546 formatlen, html_message);
1506 1547
1507 if (!sess) { 1548 if (!sess) {
1508 errno = EFAULT; 1549 errno = EFAULT;
1509 return -1; 1550 return -1;
1510 } 1551 }
1512 if (sess->state != GG_STATE_CONNECTED) { 1553 if (sess->state != GG_STATE_CONNECTED) {
1513 errno = ENOTCONN; 1554 errno = ENOTCONN;
1514 return -1; 1555 return -1;
1515 } 1556 }
1516 1557
1517 if ((message == NULL && html_message == NULL) || recipients_count <= 0 || recipients_count > 0xffff || recipients == NULL || (format == NULL && formatlen != 0)) { 1558 if ((message == NULL && html_message == NULL) ||
1559 recipients_count <= 0 || recipients_count > 0xffff ||
1560 recipients == NULL || (format == NULL && formatlen != 0))
1561 {
1518 errno = EINVAL; 1562 errno = EINVAL;
1519 return -1; 1563 return -1;
1520 } 1564 }
1521 1565
1522 if (sess->protocol_version >= GG_PROTOCOL_VERSION_110 && recipients_count == 1) 1566 if (sess->protocol_version >= GG_PROTOCOL_VERSION_110 &&
1567 recipients_count == 1)
1523 { 1568 {
1524 int is_html = (html_message != NULL); 1569 int is_html = (html_message != NULL);
1525 seq_no = gg_send_message_110(sess, recipients[0], 0, 1570 seq_no = gg_send_message_110(sess, recipients[0], 0,
1526 (const char*)(is_html ? html_message : message), 1571 (const char*)(is_html ? html_message : message),
1527 is_html); 1572 is_html);
1528 goto cleanup; 1573 goto cleanup;
1529 } 1574 }
1530 1575
1531 if (sess->protocol_version >= GG_PROTOCOL_VERSION_110 && !gg_compat_feature_is_enabled(sess, GG_COMPAT_FEATURE_LEGACY_CONFER)) { 1576 if (sess->protocol_version >= GG_PROTOCOL_VERSION_110 &&
1532 gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_send_message_common() legacy conferences disabled\n"); 1577 !gg_compat_feature_is_enabled(sess, GG_COMPAT_FEATURE_LEGACY_CONFER))
1578 {
1579 gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_ERROR,
1580 "// gg_send_message_common() legacy conferences disabled\n");
1533 errno = EINVAL; 1581 errno = EINVAL;
1534 return -1; 1582 return -1;
1535 } 1583 }
1536 1584
1537 if (message == NULL) { 1585 if (message == NULL) {
1555 } 1603 }
1556 1604
1557 generated_format[0] = '\x02'; 1605 generated_format[0] = '\x02';
1558 fixed_fmt_len = gg_fix16(fmt_len); 1606 fixed_fmt_len = gg_fix16(fmt_len);
1559 memcpy(generated_format + 1, &fixed_fmt_len, sizeof(fixed_fmt_len)); 1607 memcpy(generated_format + 1, &fixed_fmt_len, sizeof(fixed_fmt_len));
1560 gg_message_html_to_text(tmp_msg, generated_format + 3, NULL, (const char*) html_message, sess->encoding); 1608 gg_message_html_to_text(tmp_msg, generated_format + 3,
1609 NULL, (const char*)html_message, sess->encoding);
1561 1610
1562 format = generated_format; 1611 format = generated_format;
1563 formatlen = fmt_len + 3; 1612 formatlen = fmt_len + 3;
1564 } else { 1613 } else {
1565 gg_message_html_to_text(tmp_msg, NULL, NULL, (const char*) html_message, sess->encoding); 1614 gg_message_html_to_text(tmp_msg, NULL, NULL, (const char*) html_message, sess->encoding);
1577 } else { 1626 } else {
1578 cp_msg = recoded_msg = tmp_msg; 1627 cp_msg = recoded_msg = tmp_msg;
1579 } 1628 }
1580 } else { 1629 } else {
1581 if (sess->encoding == GG_ENCODING_UTF8) { 1630 if (sess->encoding == GG_ENCODING_UTF8) {
1582 cp_msg = recoded_msg = gg_encoding_convert((const char*) message, sess->encoding, GG_ENCODING_CP1250, -1, -1); 1631 cp_msg = recoded_msg = gg_encoding_convert(
1632 (const char*)message, sess->encoding,
1633 GG_ENCODING_CP1250, -1, -1);
1583 1634
1584 if (cp_msg == NULL) 1635 if (cp_msg == NULL)
1585 goto cleanup; 1636 goto cleanup;
1586 } else { 1637 } else {
1587 cp_msg = (const char*) message; 1638 cp_msg = (const char*) message;
1596 size_t formatlen_ = 0; 1647 size_t formatlen_ = 0;
1597 1648
1598 if (sess->encoding == GG_ENCODING_UTF8) { 1649 if (sess->encoding == GG_ENCODING_UTF8) {
1599 utf_msg = (const char*) message; 1650 utf_msg = (const char*) message;
1600 } else { 1651 } else {
1601 utf_msg = recoded_msg = gg_encoding_convert((const char*) message, sess->encoding, GG_ENCODING_UTF8, -1, -1); 1652 utf_msg = recoded_msg = gg_encoding_convert(
1653 (const char*)message, sess->encoding,
1654 GG_ENCODING_UTF8, -1, -1);
1602 1655
1603 if (utf_msg == NULL) 1656 if (utf_msg == NULL)
1604 goto cleanup; 1657 goto cleanup;
1605 } 1658 }
1606 1659
1621 utf_html_msg = recoded_html_msg = tmp; 1674 utf_html_msg = recoded_html_msg = tmp;
1622 } else { 1675 } else {
1623 if (sess->encoding == GG_ENCODING_UTF8) { 1676 if (sess->encoding == GG_ENCODING_UTF8) {
1624 utf_html_msg = (const char*) html_message; 1677 utf_html_msg = (const char*) html_message;
1625 } else { 1678 } else {
1626 utf_html_msg = recoded_html_msg = gg_encoding_convert((const char*) html_message, sess->encoding, GG_ENCODING_UTF8, -1, -1); 1679 utf_html_msg = recoded_html_msg = gg_encoding_convert(
1680 (const char*)html_message, sess->encoding,
1681 GG_ENCODING_UTF8, -1, -1);
1627 1682
1628 if (utf_html_msg == NULL) 1683 if (utf_html_msg == NULL)
1629 goto cleanup; 1684 goto cleanup;
1630 } 1685 }
1631 } 1686 }
1670 } 1725 }
1671 } 1726 }
1672 1727
1673 s80.recipient = gg_fix32(recipients[i]); 1728 s80.recipient = gg_fix32(recipients[i]);
1674 1729
1675 if (gg_send_packet(sess, GG_SEND_MSG80, &s80, sizeof(s80), utf_html_msg, strlen(utf_html_msg) + 1, cp_msg, strlen(cp_msg) + 1, &r, sizeof(r), recps, (recipients_count - 1) * sizeof(uin_t), format, formatlen, NULL) == -1) 1730 if (gg_send_packet(sess, GG_SEND_MSG80, &s80,
1731 sizeof(s80), utf_html_msg,
1732 strlen(utf_html_msg) + 1, cp_msg,
1733 strlen(cp_msg) + 1, &r, sizeof(r), recps,
1734 (recipients_count - 1) * sizeof(uin_t), format,
1735 formatlen, NULL) == -1)
1736 {
1676 seq_no = -1; 1737 seq_no = -1;
1738 }
1677 } 1739 }
1678 1740
1679 free(recps); 1741 free(recps);
1680 } else { 1742 } else {
1681 s80.recipient = gg_fix32(recipients[0]); 1743 s80.recipient = gg_fix32(recipients[0]);
1682 1744
1683 if (gg_send_packet(sess, GG_SEND_MSG80, &s80, sizeof(s80), utf_html_msg, strlen(utf_html_msg) + 1, cp_msg, strlen(cp_msg) + 1, format, formatlen, NULL) == -1) 1745 if (gg_send_packet(sess, GG_SEND_MSG80, &s80, sizeof(s80),
1746 utf_html_msg, strlen(utf_html_msg) + 1, cp_msg,
1747 strlen(cp_msg) + 1, format, formatlen, NULL) == -1)
1748 {
1684 seq_no = -1; 1749 seq_no = -1;
1750 }
1685 } 1751 }
1686 1752
1687 cleanup: 1753 cleanup:
1688 free(recoded_msg); 1754 free(recoded_msg);
1689 free(recoded_html_msg); 1755 free(recoded_html_msg);
1712 * 1778 *
1713 * \ingroup messages 1779 * \ingroup messages
1714 */ 1780 */
1715 int gg_send_message(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message) 1781 int gg_send_message(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message)
1716 { 1782 {
1717 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message(%p, %d, %u, %p)\n", sess, msgclass, recipient, message); 1783 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message(%p, %d, "
1718 1784 "%u, %p)\n", sess, msgclass, recipient, message);
1719 return gg_send_message_common(sess, msgclass, 1, &recipient, message, (const unsigned char*) "\x02\x06\x00\x00\x00\x08\x00\x00\x00", 9, NULL); 1785
1786 return gg_send_message_common(sess, msgclass, 1, &recipient, message,
1787 (const unsigned char*)"\x02\x06\x00\x00\x00\x08\x00\x00\x00",
1788 9, NULL);
1720 } 1789 }
1721 1790
1722 /** 1791 /**
1723 * Wysyła wiadomość formatowaną. 1792 * Wysyła wiadomość formatowaną.
1724 * 1793 *
1734 * 1803 *
1735 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu. 1804 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
1736 * 1805 *
1737 * \ingroup messages 1806 * \ingroup messages
1738 */ 1807 */
1739 int gg_send_message_richtext(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message, const unsigned char *format, int formatlen) 1808 int gg_send_message_richtext(struct gg_session *sess, int msgclass,
1740 { 1809 uin_t recipient, const unsigned char *message,
1741 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_richtext(%p, %d, %u, %p, %p, %d);\n", sess, msgclass, recipient, message, format, formatlen); 1810 const unsigned char *format, int formatlen)
1811 {
1812 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_richtext("
1813 "%p, %d, %u, %p, %p, %d);\n", sess, msgclass, recipient,
1814 message, format, formatlen);
1742 1815
1743 return gg_send_message_common(sess, msgclass, 1, &recipient, message, format, formatlen, NULL); 1816 return gg_send_message_common(sess, msgclass, 1, &recipient, message, format, formatlen, NULL);
1744 } 1817 }
1745 1818
1746 /** 1819 /**
1758 * 1831 *
1759 * \ingroup messages 1832 * \ingroup messages
1760 */ 1833 */
1761 int gg_send_message_html(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *html_message) 1834 int gg_send_message_html(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *html_message)
1762 { 1835 {
1763 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_html(%p, %d, %u, %p);\n", sess, msgclass, recipient, html_message); 1836 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_html(%p, "
1837 "%d, %u, %p);\n", sess, msgclass, recipient, html_message);
1764 1838
1765 return gg_send_message_common(sess, msgclass, 1, &recipient, NULL, NULL, 0, html_message); 1839 return gg_send_message_common(sess, msgclass, 1, &recipient, NULL, NULL, 0, html_message);
1766 } 1840 }
1767 1841
1768 /** 1842 /**
1779 * 1853 *
1780 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu. 1854 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
1781 * 1855 *
1782 * \ingroup messages 1856 * \ingroup messages
1783 */ 1857 */
1784 int gg_send_message_confer(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *message) 1858 int gg_send_message_confer(struct gg_session *sess, int msgclass,
1785 { 1859 int recipients_count, uin_t *recipients, const unsigned char *message)
1786 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_confer(%p, %d, %d, %p, %p);\n", sess, msgclass, recipients_count, recipients, message); 1860 {
1787 1861 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_confer("
1788 return gg_send_message_common(sess, msgclass, recipients_count, recipients, message, (const unsigned char*) "\x02\x06\x00\x00\x00\x08\x00\x00\x00", 9, NULL); 1862 "%p, %d, %d, %p, %p);\n", sess, msgclass, recipients_count,
1863 recipients, message);
1864
1865 return gg_send_message_common(sess, msgclass, recipients_count,
1866 recipients, message,
1867 (const unsigned char*)"\x02\x06\x00\x00\x00\x08\x00\x00\x00",
1868 9, NULL);
1789 } 1869 }
1790 1870
1791 /** 1871 /**
1792 * Wysyła wiadomość formatowaną w ramach konferencji. 1872 * Wysyła wiadomość formatowaną w ramach konferencji.
1793 * 1873 *
1804 * 1884 *
1805 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu. 1885 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
1806 * 1886 *
1807 * \ingroup messages 1887 * \ingroup messages
1808 */ 1888 */
1809 int gg_send_message_confer_richtext(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *message, const unsigned char *format, int formatlen) 1889 int gg_send_message_confer_richtext(struct gg_session *sess, int msgclass,
1810 { 1890 int recipients_count, uin_t *recipients, const unsigned char *message,
1811 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_confer_richtext(%p, %d, %d, %p, %p, %p, %d);\n", sess, msgclass, recipients_count, recipients, message, format, formatlen); 1891 const unsigned char *format, int formatlen)
1892 {
1893 gg_debug_session(sess, GG_DEBUG_FUNCTION,
1894 "** gg_send_message_confer_richtext(%p, %d, %d, %p, %p, %p, "
1895 "%d);\n", sess, msgclass, recipients_count, recipients, message,
1896 format, formatlen);
1812 1897
1813 return gg_send_message_common(sess, msgclass, recipients_count, recipients, message, format, formatlen, NULL); 1898 return gg_send_message_common(sess, msgclass, recipients_count, recipients, message, format, formatlen, NULL);
1814 } 1899 }
1815 1900
1816 /** 1901 /**
1827 * 1912 *
1828 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu. 1913 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
1829 * 1914 *
1830 * \ingroup messages 1915 * \ingroup messages
1831 */ 1916 */
1832 int gg_send_message_confer_html(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *html_message) 1917 int gg_send_message_confer_html(struct gg_session *sess, int msgclass,
1833 { 1918 int recipients_count, uin_t *recipients,
1834 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_confer_html(%p, %d, %d, %p, %p);\n", sess, msgclass, recipients_count, recipients, html_message); 1919 const unsigned char *html_message)
1920 {
1921 gg_debug_session(sess, GG_DEBUG_FUNCTION,
1922 "** gg_send_message_confer_html(%p, %d, %d, %p, %p);\n", sess,
1923 msgclass, recipients_count, recipients, html_message);
1835 1924
1836 return gg_send_message_common(sess, msgclass, recipients_count, recipients, NULL, NULL, 0, html_message); 1925 return gg_send_message_common(sess, msgclass, recipients_count, recipients, NULL, NULL, 0, html_message);
1837 } 1926 }
1838 1927
1839 /** 1928 /**
1851 * 1940 *
1852 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu. 1941 * \return Numer sekwencyjny wiadomości lub -1 w przypadku błędu.
1853 * 1942 *
1854 * \ingroup messages 1943 * \ingroup messages
1855 */ 1944 */
1856 int gg_send_message_ctcp(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message, int message_len) 1945 int gg_send_message_ctcp(struct gg_session *sess, int msgclass, uin_t recipient,
1946 const unsigned char *message, int message_len)
1857 { 1947 {
1858 struct gg_send_msg s; 1948 struct gg_send_msg s;
1859 1949
1860 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_ctcp(%p, %d, %u, ...);\n", sess, msgclass, recipient); 1950 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message_ctcp(%p, "
1951 "%d, %u, ...);\n", sess, msgclass, recipient);
1861 1952
1862 if (!sess) { 1953 if (!sess) {
1863 errno = EFAULT; 1954 errno = EFAULT;
1864 return -1; 1955 return -1;
1865 } 1956 }
1898 struct gg_send_msg s; 1989 struct gg_send_msg s;
1899 struct gg_msg_image_request r; 1990 struct gg_msg_image_request r;
1900 char dummy = 0; 1991 char dummy = 0;
1901 int res; 1992 int res;
1902 1993
1903 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_image_request(%p, %d, %u, 0x%.4x);\n", sess, recipient, size, crc32); 1994 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_image_request(%p, %d, "
1995 "%u, 0x%.4x);\n", sess, recipient, size, crc32);
1904 1996
1905 if (!sess) { 1997 if (!sess) {
1906 errno = EFAULT; 1998 errno = EFAULT;
1907 return -1; 1999 return -1;
1908 } 2000 }
1930 if (!res) { 2022 if (!res) {
1931 struct gg_image_queue *q = malloc(sizeof(*q)); 2023 struct gg_image_queue *q = malloc(sizeof(*q));
1932 char *buf; 2024 char *buf;
1933 2025
1934 if (!q) { 2026 if (!q) {
1935 gg_debug_session(sess, GG_DEBUG_MISC, "// gg_image_request() not enough memory for image queue\n"); 2027 gg_debug_session(sess, GG_DEBUG_MISC,
2028 "// gg_image_request() not enough memory for "
2029 "image queue\n");
1936 return -1; 2030 return -1;
1937 } 2031 }
1938 2032
1939 buf = malloc(size); 2033 buf = malloc(size);
1940 if (size && !buf) 2034 if (size && !buf) {
1941 {
1942 gg_debug_session(sess, GG_DEBUG_MISC, "// gg_image_request() not enough memory for image\n"); 2035 gg_debug_session(sess, GG_DEBUG_MISC, "// gg_image_request() not enough memory for image\n");
1943 free(q); 2036 free(q);
1944 return -1; 2037 return -1;
1945 } 2038 }
1946 2039
1954 if (!sess->images) 2047 if (!sess->images)
1955 sess->images = q; 2048 sess->images = q;
1956 else { 2049 else {
1957 struct gg_image_queue *qq; 2050 struct gg_image_queue *qq;
1958 2051
1959 for (qq = sess->images; qq->next; qq = qq->next) 2052 for (qq = sess->images; qq->next; qq = qq->next);
1960 ;
1961 2053
1962 qq->next = q; 2054 qq->next = q;
1963 } 2055 }
1964 } 2056 }
1965 2057
1985 struct gg_send_msg s; 2077 struct gg_send_msg s;
1986 const char *tmp; 2078 const char *tmp;
1987 char buf[1910]; 2079 char buf[1910];
1988 int res = -1; 2080 int res = -1;
1989 2081
1990 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_image_reply(%p, %d, \"%s\", %p, %d);\n", sess, recipient, filename, image, size); 2082 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_image_reply(%p, %d, "
2083 "\"%s\", %p, %d);\n", sess, recipient, filename, image, size);
1991 2084
1992 if (!sess || !filename || !image) { 2085 if (!sess || !filename || !image) {
1993 errno = EFAULT; 2086 errno = EFAULT;
1994 return -1; 2087 return -1;
1995 } 2088 }
2068 size_t prev_size = gg_tvbuilder_get_size(tvb); 2161 size_t prev_size = gg_tvbuilder_get_size(tvb);
2069 gg_tvbuilder_write_uin(tvb, userlist[i]); 2162 gg_tvbuilder_write_uin(tvb, userlist[i]);
2070 gg_tvbuilder_write_uint8(tvb, 2163 gg_tvbuilder_write_uint8(tvb,
2071 (types == NULL) ? GG_USER_NORMAL : types[i]); 2164 (types == NULL) ? GG_USER_NORMAL : types[i]);
2072 2165
2073 /* Oryginalny klient wysyła maksymalnie 2048 bajtów 2166 /* Oryginalny klient wysyła maksymalnie 2048 bajtów
2074 * danych w każdym pakiecie tego typu. 2167 * danych w każdym pakiecie tego typu.
2075 */ 2168 */
2076 if (gg_tvbuilder_get_size(tvb) > 2048) { 2169 if (gg_tvbuilder_get_size(tvb) > 2048) {
2077 gg_tvbuilder_strip(tvb, prev_size); 2170 gg_tvbuilder_strip(tvb, prev_size);
2078 break; 2171 break;
2079 } 2172 }
2080 i++; 2173 i++;
2081 } 2174 }
2082 2175
2083 if (!gg_tvbuilder_send(tvb, (i < count) ? 2176 if (!gg_tvbuilder_send(tvb, (i < count) ?
2084 GG_NOTIFY105_FIRST : GG_NOTIFY105_LAST)) { 2177 GG_NOTIFY105_FIRST : GG_NOTIFY105_LAST))
2178 {
2085 return -1; 2179 return -1;
2086 } 2180 }
2087 } 2181 }
2088 2182
2089 return 0; 2183 return 0;
2110 * \ingroup contacts 2204 * \ingroup contacts
2111 */ 2205 */
2112 int gg_notify_ex(struct gg_session *sess, uin_t *userlist, char *types, int count) 2206 int gg_notify_ex(struct gg_session *sess, uin_t *userlist, char *types, int count)
2113 { 2207 {
2114 struct gg_notify *n; 2208 struct gg_notify *n;
2115 uin_t *u;
2116 char *t;
2117 int i, res = 0; 2209 int i, res = 0;
2118 2210
2119 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_notify_ex(%p, %p, %p, %d);\n", sess, userlist, types, count); 2211 gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_notify_ex(%p, %p, %p, %d);\n", sess, userlist, types, count);
2120 2212
2121 if (!sess) { 2213 if (!sess) {
2146 } 2238 }
2147 2239
2148 if (!(n = (struct gg_notify*) malloc(sizeof(*n) * part_count))) 2240 if (!(n = (struct gg_notify*) malloc(sizeof(*n) * part_count)))
2149 return -1; 2241 return -1;
2150 2242
2151 for (u = userlist, t = types, i = 0; i < part_count; u++, t++, i++) { 2243 for (i = 0; i < part_count; i++) {
2152 n[i].uin = gg_fix32(*u); 2244 n[i].uin = gg_fix32(userlist[i]);
2153 if (types == NULL) 2245 if (types == NULL)
2154 n[i].dunno1 = GG_USER_NORMAL; 2246 n[i].dunno1 = GG_USER_NORMAL;
2155 else 2247 else
2156 n[i].dunno1 = *t; 2248 n[i].dunno1 = types[i];
2157 } 2249 }
2158 2250
2159 if (gg_send_packet(sess, packet_type, n, sizeof(*n) * part_count, NULL) == -1) { 2251 if (gg_send_packet(sess, packet_type, n, sizeof(*n) * part_count, NULL) == -1) {
2160 free(n); 2252 free(n);
2161 res = -1; 2253 res = -1;
2409 * 2501 *
2410 * \return 0 jeśli się powiodło, -1 w przypadku błędu 2502 * \return 0 jeśli się powiodło, -1 w przypadku błędu
2411 * 2503 *
2412 * \ingroup importexport 2504 * \ingroup importexport
2413 */ 2505 */
2414 int gg_userlist100_request(struct gg_session *sess, char type, unsigned int version, char format_type, const char *request) 2506 int gg_userlist100_request(struct gg_session *sess, char type,
2507 unsigned int version, char format_type, const char *request)
2415 { 2508 {
2416 struct gg_userlist100_request pkt; 2509 struct gg_userlist100_request pkt;
2417 unsigned char *zrequest; 2510 unsigned char *zrequest;
2418 size_t zrequest_len; 2511 size_t zrequest_len;
2419 int ret; 2512 int ret;
2565 seq = ++gs->seq; 2658 seq = ++gs->seq;
2566 pkt.id = gg_fix64(id); 2659 pkt.id = gg_fix64(id);
2567 pkt.seq = gg_fix32(seq); 2660 pkt.seq = gg_fix32(seq);
2568 pkt.participants_count = gg_fix32(participants_count); 2661 pkt.participants_count = gg_fix32(participants_count);
2569 2662
2570 for (i = 0; i < participants_count; i++) 2663 for (i = 0; i < participants_count; i++) {
2571 {
2572 participants_list[i].uin = gg_fix32(participants[i]); 2664 participants_list[i].uin = gg_fix32(participants[i]);
2573 participants_list[i].dummy = gg_fix32(0x1e); 2665 participants_list[i].dummy = gg_fix32(0x1e);
2574 } 2666 }
2575 2667
2576 ret = gg_send_packet(gs, GG_CHAT_INVITE, 2668 ret = gg_send_packet(gs, GG_CHAT_INVITE,
2693 2785
2694 p->socket_is_external = 0; 2786 p->socket_is_external = 0;
2695 sess->fd = pipes[1]; 2787 sess->fd = pipes[1];
2696 sess->check = GG_CHECK_READ; 2788 sess->check = GG_CHECK_READ;
2697 sess->state = GG_STATE_ERROR; 2789 sess->state = GG_STATE_ERROR;
2698 send(pipes[0], &dummy, sizeof(dummy), 0); 2790 if (send(pipes[0], &dummy, sizeof(dummy), 0) != sizeof(dummy)) {
2791 gg_debug(GG_DEBUG_MISC, "// gg_socket_manager_error() unable to"
2792 " send via pipe (errno=%d, %s)\n", errno,
2793 strerror(errno));
2794 return;
2795 }
2699 close(pipes[0]); 2796 close(pipes[0]);
2700 } 2797 }
2701 2798
2702 int gg_compat_feature_is_enabled(struct gg_session *sess, gg_compat_feature_t feature) 2799 int gg_compat_feature_is_enabled(struct gg_session *sess, gg_compat_feature_t feature)
2703 { 2800 {

mercurial