Mercurial > pidgin.yaz
comparison src/protocols/jabber/jabber.c @ 3630:9682c0e022c6
[gaim-migrate @ 3753]
Yeah this will probably break a lot of shit knowing my luck. But hey, I really don't care what people thnk.
committer: Tailor Script <tailor@pidgin.im>
author | Rob Flynn <gaim@robflynn.com> |
---|---|
date | Fri, 11 Oct 2002 03:14:01 +0000 |
parents | 95669ff6dc3b |
children | 5e50f6746509 |
comparison
equal
deleted
inserted
replaced
3629:afc5bb164c5a | 3630:9682c0e022c6 |
---|---|
18 * You should have received a copy of the GNU General Public License | 18 * You should have received a copy of the GNU General Public License |
19 * along with this program; if not, write to the Free Software | 19 * along with this program; if not, write to the Free Software |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 * | 21 * |
22 */ | 22 */ |
23 | |
24 #ifdef HAVE_CONFIG_H | 23 #ifdef HAVE_CONFIG_H |
25 #include "config.h" | 24 #include <config.h> |
26 #endif | 25 #endif |
27 | 26 |
28 | 27 #ifndef _WIN32 |
29 #include <netdb.h> | 28 #include <netdb.h> |
30 #include <unistd.h> | |
31 #include <errno.h> | |
32 #include <netinet/in.h> | 29 #include <netinet/in.h> |
33 #include <arpa/inet.h> | 30 #include <arpa/inet.h> |
31 #include <sys/socket.h> | |
32 #include <sys/utsname.h> | |
33 #include <unistd.h> | |
34 #else | |
35 #include <winsock.h> | |
36 #include "utsname.h" | |
37 #endif | |
38 | |
39 #include <errno.h> | |
34 #include <string.h> | 40 #include <string.h> |
35 #include <stdlib.h> | 41 #include <stdlib.h> |
36 #include <stdio.h> | 42 #include <stdio.h> |
37 #include <time.h> | 43 #include <time.h> |
38 #include <sys/socket.h> | |
39 #include <sys/utsname.h> | |
40 #include <sys/stat.h> | 44 #include <sys/stat.h> |
41 #include "multi.h" | 45 #include "multi.h" |
42 #include "prpl.h" | 46 #include "prpl.h" |
43 #include "gaim.h" | 47 #include "gaim.h" |
44 #ifdef MAX | 48 #ifdef MAX |
48 #undef MIN | 52 #undef MIN |
49 #endif | 53 #endif |
50 #include "jabber.h" | 54 #include "jabber.h" |
51 #include "proxy.h" | 55 #include "proxy.h" |
52 | 56 |
57 #ifdef _WIN32 | |
58 #include "win32dep.h" | |
59 #endif | |
60 | |
53 #include "pixmaps/protocols/jabber/available.xpm" | 61 #include "pixmaps/protocols/jabber/available.xpm" |
54 #include "pixmaps/protocols/jabber/available-away.xpm" | 62 #include "pixmaps/protocols/jabber/available-away.xpm" |
55 #include "pixmaps/protocols/jabber/available-chat.xpm" | 63 #include "pixmaps/protocols/jabber/available-chat.xpm" |
56 #include "pixmaps/protocols/jabber/available-xa.xpm" | 64 #include "pixmaps/protocols/jabber/available-xa.xpm" |
57 #include "pixmaps/protocols/jabber/available-dnd.xpm" | 65 #include "pixmaps/protocols/jabber/available-dnd.xpm" |
58 #include "pixmaps/protocols/jabber/available-error.xpm" | 66 #include "pixmaps/protocols/jabber/available-error.xpm" |
67 | |
68 /* for win32 compatability */ | |
69 G_MODULE_IMPORT GSList *connections; | |
59 | 70 |
60 /* The priv member of gjconn's is a gaim_connection for now. */ | 71 /* The priv member of gjconn's is a gaim_connection for now. */ |
61 #define GJ_GC(x) ((struct gaim_connection *)(x)->priv) | 72 #define GJ_GC(x) ((struct gaim_connection *)(x)->priv) |
62 | 73 |
63 #define IQID_AUTH "__AUTH__" | 74 #define IQID_AUTH "__AUTH__" |
138 gboolean did_import; | 149 gboolean did_import; |
139 GSList *chats; | 150 GSList *chats; |
140 time_t idle; | 151 time_t idle; |
141 gboolean die; | 152 gboolean die; |
142 GHashTable *buddies; | 153 GHashTable *buddies; |
154 GSList *file_transfers; | |
143 }; | 155 }; |
144 | 156 |
145 /* | 157 /* |
146 * Used in jabber_buddy_data.invisible, below | 158 * Used in jabber_buddy_data.invisible, below |
147 */ | 159 */ |
226 | 238 |
227 | 239 |
228 #define STATE_EVT(arg) if(gjc->on_state) { (gjc->on_state)(gjc, (arg) ); } | 240 #define STATE_EVT(arg) if(gjc->on_state) { (gjc->on_state)(gjc, (arg) ); } |
229 | 241 |
230 static void jabber_handlevcard(gjconn, xmlnode, char *); | 242 static void jabber_handlevcard(gjconn, xmlnode, char *); |
243 | |
244 static char *jabber_normalize(const char *s); | |
231 | 245 |
232 static char *create_valid_jid(const char *given, char *server, char *resource) | 246 static char *create_valid_jid(const char *given, char *server, char *resource) |
233 { | 247 { |
234 char *valid; | 248 char *valid; |
235 | 249 |
490 return; | 504 return; |
491 | 505 |
492 gjab_send_raw(gjc, "</stream:stream>"); | 506 gjab_send_raw(gjc, "</stream:stream>"); |
493 gjc->state = JCONN_STATE_OFF; | 507 gjc->state = JCONN_STATE_OFF; |
494 gjc->was_connected = 0; | 508 gjc->was_connected = 0; |
509 #ifndef _WIN32 | |
495 close(gjc->fd); | 510 close(gjc->fd); |
511 #else | |
512 closesocket(gjc->fd); | |
513 #endif | |
496 gjc->fd = -1; | 514 gjc->fd = -1; |
497 XML_ParserFree(gjc->parser); | 515 XML_ParserFree(gjc->parser); |
498 gjc->parser = NULL; | 516 gjc->parser = NULL; |
499 } | 517 } |
500 | 518 |
533 static void gjab_send(gjconn gjc, xmlnode x) | 551 static void gjab_send(gjconn gjc, xmlnode x) |
534 { | 552 { |
535 if (gjc && gjc->state != JCONN_STATE_OFF) { | 553 if (gjc && gjc->state != JCONN_STATE_OFF) { |
536 char *buf = xmlnode2str(x); | 554 char *buf = xmlnode2str(x); |
537 if (buf) | 555 if (buf) |
556 #ifndef _WIN32 | |
538 write(gjc->fd, buf, strlen(buf)); | 557 write(gjc->fd, buf, strlen(buf)); |
558 #else | |
559 send(gjc->fd, buf, strlen(buf), 0); | |
560 #endif | |
539 debug_printf("gjab_send: %s\n", buf); | 561 debug_printf("gjab_send: %s\n", buf); |
540 } | 562 } |
541 } | 563 } |
542 | 564 |
543 static void gjab_send_raw(gjconn gjc, const char *str) | 565 static void gjab_send_raw(gjconn gjc, const char *str) |
544 { | 566 { |
545 if (gjc && gjc->state != JCONN_STATE_OFF) { | 567 if (gjc && gjc->state != JCONN_STATE_OFF) { |
546 /* | 568 /* |
547 * JFIXME: No error detection?!?! | 569 * JFIXME: No error detection?!?! |
548 */ | 570 */ |
571 #ifndef _WIN32 | |
549 if(write(gjc->fd, str, strlen(str)) < 0) { | 572 if(write(gjc->fd, str, strlen(str)) < 0) { |
573 #else | |
574 if(send(gjc->fd, str, strlen(str), 0) < 0) { | |
575 #endif | |
550 fprintf(stderr, "DBG: Problem sending. Error: %d\n", errno); | 576 fprintf(stderr, "DBG: Problem sending. Error: %d\n", errno); |
551 fflush(stderr); | 577 fflush(stderr); |
552 } | 578 } |
553 debug_printf("gjab_send_raw: %s\n", str); | 579 debug_printf("gjab_send_raw: %s\n", str); |
554 } | 580 } |
634 static char buf[4096]; | 660 static char buf[4096]; |
635 int len; | 661 int len; |
636 | 662 |
637 if (!gjc || gjc->state == JCONN_STATE_OFF) | 663 if (!gjc || gjc->state == JCONN_STATE_OFF) |
638 return; | 664 return; |
639 | 665 #ifndef _WIN32 |
640 if ((len = read(gjc->fd, buf, sizeof(buf) - 1)) > 0) { | 666 if ((len = read(gjc->fd, buf, sizeof(buf) - 1)) > 0) { |
667 #else | |
668 if ((len = recv(gjc->fd, buf, sizeof(buf) - 1, 0)) > 0) { | |
669 #endif | |
641 struct jabber_data *jd = GJ_GC(gjc)->proto_data; | 670 struct jabber_data *jd = GJ_GC(gjc)->proto_data; |
642 buf[len] = '\0'; | 671 buf[len] = '\0'; |
643 debug_printf("input (len %d): %s\n", len, buf); | 672 debug_printf("input (len %d): %s\n", len, buf); |
644 XML_Parse(gjc->parser, buf, len, 0); | 673 XML_Parse(gjc->parser, buf, len, 0); |
645 if (jd->die) | 674 if (jd->die) |
725 struct gaim_connection *gc = data; | 754 struct gaim_connection *gc = data; |
726 struct jabber_data *jd; | 755 struct jabber_data *jd; |
727 gjconn gjc; | 756 gjconn gjc; |
728 | 757 |
729 if (!g_slist_find(connections, gc)) { | 758 if (!g_slist_find(connections, gc)) { |
759 #ifndef _WIN32 | |
730 close(source); | 760 close(source); |
761 #else | |
762 closesocket(source); | |
763 #endif | |
731 return; | 764 return; |
732 } | 765 } |
733 | 766 |
734 jd = gc->proto_data; | 767 jd = gc->proto_data; |
735 gjc = jd->gjc; | 768 gjc = jd->gjc; |
1899 gjab_send(gjc, x); | 1932 gjab_send(gjc, x); |
1900 | 1933 |
1901 xmlnode_free(x); | 1934 xmlnode_free(x); |
1902 } | 1935 } |
1903 | 1936 |
1937 struct jabber_file_transfer { | |
1938 enum { JFT_SENDFILE_IN, JFT_SENDFILE_OUT } type; | |
1939 struct file_transfer *xfer; | |
1940 char *from; | |
1941 struct g_url *url; | |
1942 char *name; | |
1943 GString *headers; | |
1944 | |
1945 int len; | |
1946 int fd; | |
1947 int watcher; | |
1948 | |
1949 gboolean sentreq; | |
1950 gboolean newline; | |
1951 gboolean startsaving; | |
1952 | |
1953 struct gaim_connection *gc; | |
1954 }; | |
1955 | |
1956 static struct jabber_file_transfer *find_jft_by_xfer(struct gaim_connection *gc, | |
1957 struct file_transfer *xfer) { | |
1958 GSList *g = ((struct jabber_data *)gc->proto_data)->file_transfers; | |
1959 struct jabber_file_transfer *f = NULL; | |
1960 | |
1961 while(g) { | |
1962 f = (struct jabber_file_transfer *)g->data; | |
1963 if(f->xfer == xfer) | |
1964 break; | |
1965 g = g->next; | |
1966 f = NULL; | |
1967 } | |
1968 | |
1969 return f; | |
1970 } | |
1971 | |
1972 static void jabber_http_recv_callback(gpointer data, gint source, GaimInputCondition condition) { | |
1973 struct jabber_file_transfer *jft = data; | |
1974 char test; | |
1975 | |
1976 jft->fd = source; | |
1977 if(!jft->sentreq) { | |
1978 char buf[1024]; | |
1979 g_snprintf(buf, sizeof(buf), "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", jft->url->page, jft->url->address); | |
1980 write(source, buf, strlen(buf)); | |
1981 fcntl(source, F_SETFL, O_NONBLOCK); | |
1982 jft->sentreq = TRUE; | |
1983 jft->watcher = gaim_input_add(source, GAIM_INPUT_READ, jabber_http_recv_callback,data); | |
1984 return; | |
1985 } | |
1986 | |
1987 if(!jft->startsaving) { | |
1988 if(read(source, &test, sizeof(test)) > 0 || errno == EWOULDBLOCK) { | |
1989 if(errno == EWOULDBLOCK) { | |
1990 errno = 0; | |
1991 return; | |
1992 } | |
1993 | |
1994 jft->headers = g_string_append_c(jft->headers, test); | |
1995 if(test == '\r') | |
1996 return; | |
1997 if(test == '\n') { | |
1998 if(jft->newline) { | |
1999 gchar *lenstr = strstr(jft->headers->str, "Content-Length: "); | |
2000 if(lenstr) { | |
2001 sscanf(lenstr, "Content-Length: %d", &jft->len); | |
2002 } | |
2003 jft->startsaving = TRUE; | |
2004 } else | |
2005 jft->newline = TRUE; | |
2006 return; | |
2007 } | |
2008 jft->newline = FALSE; | |
2009 return; | |
2010 } else { | |
2011 gaim_input_remove(jft->watcher); | |
2012 close(source); | |
2013 //FIXME: ft_cancel(NULL, jft->xfer); | |
2014 } | |
2015 return; | |
2016 } | |
2017 | |
2018 /* we've parsed the headers, gotten the size, all is good. now we pass the reception of | |
2019 * the file off to the core, and leave it in it's capable...err...hands?? */ | |
2020 gaim_input_remove(jft->watcher); | |
2021 jft->watcher = 0; | |
2022 transfer_in_do(jft->xfer, jft->fd, jft->name, jft->len); | |
2023 } | |
2024 | |
2025 static void jabber_file_transfer_cancel(struct gaim_connection *gc, struct file_transfer *xfer) { | |
2026 struct jabber_data *jd = gc->proto_data; | |
2027 struct jabber_file_transfer *jft = find_jft_by_xfer(gc, xfer);\ | |
2028 xmlnode x,y; | |
2029 | |
2030 jd->file_transfers = g_slist_remove(jd->file_transfers, jft); | |
2031 | |
2032 gaim_input_remove(jft->watcher); | |
2033 close(jft->fd); | |
2034 | |
2035 x = xmlnode_new_tag("iq"); | |
2036 xmlnode_put_attrib(x, "type", "error"); | |
2037 xmlnode_put_attrib(x, "to", jft->from); | |
2038 y = xmlnode_insert_tag(x, "error"); | |
2039 /* FIXME: need to handle other kinds of errors here */ | |
2040 xmlnode_put_attrib(y, "code", "406"); | |
2041 xmlnode_insert_cdata(y, "File Transfer Refused", -1); | |
2042 | |
2043 gjab_send(jd->gjc, x); | |
2044 | |
2045 xmlnode_free(x); | |
2046 | |
2047 g_string_free(jft->headers, TRUE); | |
2048 g_free(jft->from); | |
2049 g_free(jft->url); | |
2050 g_free(jft->name); | |
2051 | |
2052 g_free(jft); | |
2053 } | |
2054 | |
2055 static void jabber_file_transfer_done(struct gaim_connection *gc, struct file_transfer *xfer) { | |
2056 struct jabber_data *jd = gc->proto_data; | |
2057 struct jabber_file_transfer *jft = find_jft_by_xfer(gc, xfer); | |
2058 xmlnode x; | |
2059 | |
2060 jd->file_transfers = g_slist_remove(jd->file_transfers, jft); | |
2061 | |
2062 gaim_input_remove(jft->watcher); | |
2063 close(jft->fd); | |
2064 | |
2065 x = xmlnode_new_tag("iq"); | |
2066 xmlnode_put_attrib(x, "type", "result"); | |
2067 xmlnode_put_attrib(x, "to", jft->from); | |
2068 | |
2069 gjab_send(jd->gjc, x); | |
2070 | |
2071 xmlnode_free(x); | |
2072 | |
2073 g_string_free(jft->headers, TRUE); | |
2074 g_free(jft->from); | |
2075 g_free(jft->url); | |
2076 g_free(jft->name); | |
2077 | |
2078 g_free(jft); | |
2079 } | |
2080 | |
2081 static void jabber_file_transfer_in(struct gaim_connection *gc, struct file_transfer *xfer, int offset) { | |
2082 struct jabber_file_transfer *jft = find_jft_by_xfer(gc, xfer); | |
2083 | |
2084 proxy_connect(jft->url->address, jft->url->port, jabber_http_recv_callback, jft); | |
2085 } | |
2086 | |
2087 static void jabber_handleoob(gjconn gjc, xmlnode iqnode) { | |
2088 struct jabber_file_transfer *jft; | |
2089 struct jabber_data *jd = GJ_GC(gjc)->proto_data; | |
2090 char *msg = NULL; | |
2091 xmlnode querynode = xmlnode_get_tag(iqnode, "query"); | |
2092 xmlnode urlnode,descnode; | |
2093 | |
2094 if(!querynode) | |
2095 return; | |
2096 urlnode = xmlnode_get_tag(querynode, "url"); | |
2097 if(!urlnode) | |
2098 return; | |
2099 descnode = xmlnode_get_tag(querynode, "desc"); | |
2100 if(descnode) | |
2101 msg = xmlnode_get_data(descnode); | |
2102 | |
2103 jft = g_new0(struct jabber_file_transfer, 1); | |
2104 jft->type = JFT_SENDFILE_IN; | |
2105 jft->gc = GJ_GC(gjc); | |
2106 jft->url = parse_url(xmlnode_get_data(urlnode)); | |
2107 jft->from = g_strdup(xmlnode_get_attrib(iqnode, "from")); | |
2108 jft->name = g_strdup(g_strrstr(jft->url->page,"/")); | |
2109 if (!jft->name) | |
2110 jft->name = g_strdup(jft->url->page); | |
2111 jft->headers = g_string_new(""); | |
2112 jft->len = -1; | |
2113 | |
2114 jd->file_transfers = g_slist_append(jd->file_transfers, jft); | |
2115 | |
2116 jft->xfer = transfer_in_add(GJ_GC(gjc), jft->from, jft->name, jft->len, 1, msg); | |
2117 } | |
2118 | |
1904 static void jabber_handlelast(gjconn gjc, xmlnode iqnode) { | 2119 static void jabber_handlelast(gjconn gjc, xmlnode iqnode) { |
1905 xmlnode x, querytag; | 2120 xmlnode x, querytag; |
1906 char *id, *from; | 2121 char *id, *from; |
1907 struct jabber_data *jd = GJ_GC(gjc)->proto_data; | 2122 struct jabber_data *jd = GJ_GC(gjc)->proto_data; |
1908 char idle_time[32]; | 2123 char idle_time[32]; |
1909 | 2124 |
1910 id = xmlnode_get_attrib(iqnode, "id"); | 2125 id = xmlnode_get_attrib(iqnode, "id"); |
1911 from = xmlnode_get_attrib(iqnode, "from"); | 2126 from = xmlnode_get_attrib(iqnode, "from"); |
1912 | 2127 |
1913 x = jutil_iqnew(JPACKET__RESULT, "jabber:iq:last"); | 2128 x = jutil_iqnew(JPACKET__RESULT, "jabber:iq:last"); |
1914 | 2129 |
1977 if (jpacket_subtype(p) == JPACKET__SET) { | 2192 if (jpacket_subtype(p) == JPACKET__SET) { |
1978 xmlnode querynode; | 2193 xmlnode querynode; |
1979 querynode = xmlnode_get_tag(p->x, "query"); | 2194 querynode = xmlnode_get_tag(p->x, "query"); |
1980 if (NSCHECK(querynode, "jabber:iq:roster")) { | 2195 if (NSCHECK(querynode, "jabber:iq:roster")) { |
1981 jabber_handlebuddy(gjc, xmlnode_get_firstchild(querynode)); | 2196 jabber_handlebuddy(gjc, xmlnode_get_firstchild(querynode)); |
2197 } else if(NSCHECK(querynode, "jabber:iq:oob")) { | |
2198 jabber_handleoob(gjc, p->x); | |
1982 } | 2199 } |
1983 } else if (jpacket_subtype(p) == JPACKET__GET) { | 2200 } else if (jpacket_subtype(p) == JPACKET__GET) { |
1984 xmlnode querynode; | 2201 xmlnode querynode; |
1985 querynode = xmlnode_get_tag(p->x, "query"); | 2202 querynode = xmlnode_get_tag(p->x, "query"); |
1986 if (NSCHECK(querynode, NS_VERSION)) { | 2203 if (NSCHECK(querynode, NS_VERSION)) { |
2259 y = xmlnode_insert_tag(x, "x"); | 2476 y = xmlnode_insert_tag(x, "x"); |
2260 xmlnode_put_attrib(y, "xmlns", "jabber:x:event"); | 2477 xmlnode_put_attrib(y, "xmlns", "jabber:x:event"); |
2261 xmlnode_insert_tag(y, "composing"); | 2478 xmlnode_insert_tag(y, "composing"); |
2262 | 2479 |
2263 if (message && strlen(message)) { | 2480 if (message && strlen(message)) { |
2264 char *utf8 = str_to_utf8(message); | 2481 char *utf8 = str_to_utf8((char*)message); |
2265 y = xmlnode_insert_tag(x, "body"); | 2482 y = xmlnode_insert_tag(x, "body"); |
2266 xmlnode_insert_cdata(y, utf8, -1); | 2483 xmlnode_insert_cdata(y, utf8, -1); |
2267 g_free(utf8); | 2484 g_free(utf8); |
2268 } | 2485 } |
2269 | 2486 |
2746 subject = g_strdup_printf("%s@%s", jc->gjid->user, jc->gjid->server); | 2963 subject = g_strdup_printf("%s@%s", jc->gjid->user, jc->gjid->server); |
2747 xmlnode_put_attrib(y, "jid", subject); | 2964 xmlnode_put_attrib(y, "jid", subject); |
2748 g_free(subject); | 2965 g_free(subject); |
2749 | 2966 |
2750 if (message && strlen(message)) { | 2967 if (message && strlen(message)) { |
2751 char *utf8 = str_to_utf8(message); | 2968 char *utf8 = str_to_utf8((char*)message); |
2752 y = xmlnode_insert_tag(x, "body"); | 2969 y = xmlnode_insert_tag(x, "body"); |
2753 xmlnode_insert_cdata(y, utf8, -1); | 2970 xmlnode_insert_cdata(y, utf8, -1); |
2754 g_free(utf8); | 2971 g_free(utf8); |
2755 } | 2972 } |
2756 | 2973 |
3958 return m; | 4175 return m; |
3959 } | 4176 } |
3960 | 4177 |
3961 static struct prpl *my_protocol = NULL; | 4178 static struct prpl *my_protocol = NULL; |
3962 | 4179 |
3963 void jabber_init(struct prpl *ret) | 4180 G_MODULE_EXPORT void jabber_init(struct prpl *ret) |
3964 { | 4181 { |
3965 /* the NULL's aren't required but they're nice to have */ | 4182 /* the NULL's aren't required but they're nice to have */ |
3966 struct proto_user_opt *puo; | 4183 struct proto_user_opt *puo; |
3967 ret->protocol = PROTO_JABBER; | 4184 ret->protocol = PROTO_JABBER; |
3968 ret->options = OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_CHAT_TOPIC; | 4185 ret->options = OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_CHAT_TOPIC; |
4007 ret->alias_buddy = jabber_alias_buddy; | 4224 ret->alias_buddy = jabber_alias_buddy; |
4008 ret->group_buddy = jabber_group_change; | 4225 ret->group_buddy = jabber_group_change; |
4009 ret->send_typing = jabber_send_typing; | 4226 ret->send_typing = jabber_send_typing; |
4010 ret->convo_closed = jabber_convo_closed; | 4227 ret->convo_closed = jabber_convo_closed; |
4011 ret->rename_group = jabber_rename_group; | 4228 ret->rename_group = jabber_rename_group; |
4012 | 4229 ret->file_transfer_out = NULL; /* TODO */ |
4230 ret->file_transfer_in = jabber_file_transfer_in; | |
4231 ret->file_transfer_data_chunk = NULL; /* TODO */ | |
4232 ret->file_transfer_done = jabber_file_transfer_done; | |
4233 ret->file_transfer_cancel = jabber_file_transfer_cancel; | |
4234 | |
4013 puo = g_new0(struct proto_user_opt, 1); | 4235 puo = g_new0(struct proto_user_opt, 1); |
4014 puo->label = g_strdup("Port:"); | 4236 puo->label = g_strdup("Port:"); |
4015 puo->def = g_strdup("5222"); | 4237 puo->def = g_strdup("5222"); |
4016 puo->pos = USEROPT_PORT; | 4238 puo->pos = USEROPT_PORT; |
4017 ret->user_opts = g_list_append(ret->user_opts, puo); | 4239 ret->user_opts = g_list_append(ret->user_opts, puo); |
4019 my_protocol = ret; | 4241 my_protocol = ret; |
4020 } | 4242 } |
4021 | 4243 |
4022 #ifndef STATIC | 4244 #ifndef STATIC |
4023 | 4245 |
4024 void *gaim_prpl_init(struct prpl *prpl) | 4246 G_MODULE_EXPORT void gaim_prpl_init(struct prpl *prpl) |
4025 { | 4247 { |
4026 jabber_init(prpl); | 4248 jabber_init(prpl); |
4027 prpl->plug->desc.api_version = PLUGIN_API_VERSION; | 4249 prpl->plug->desc.api_version = PLUGIN_API_VERSION; |
4028 } | 4250 } |
4029 | 4251 |