Mercurial > pidgin
annotate src/protocols/zephyr/ZRetSubs.c @ 13967:99b9b58b19dd
[gaim-migrate @ 16523]
Fix a crazy MSN crash. Basically it's possible to have more than one
slplink associated with a given switchboard, but our code did not
allow for that. I think it happens when you're in a multi-user
chat and you do stuff with multiple users that involves slplinks.
Like maybe file transfer and buddy icon related stuff.
Tracking this down took an ungodly amount of time, but thanks to
Meebo for letting me do it :-)
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 20 Jul 2006 07:31:15 +0000 |
parents | 7c2e2c4d45a4 |
children |
rev | line source |
---|---|
2086 | 1 /* This file is part of the Project Athena Zephyr Notification System. |
2 * It contains source for the ZRetrieveSubscriptions and | |
3 * ZRetrieveDefaultSubscriptions functions. | |
4 * | |
5 * Created by: Robert French | |
6 * | |
7 * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology. | |
8 * For copying and distribution information, see the file | |
9 * "mit-copyright.h". | |
10 */ | |
11 | |
8792
43d6c08d7e96
[gaim-migrate @ 9554]
Christian Hammond <chipx86@chipx86.com>
parents:
7475
diff
changeset
|
12 #include "internal.h" |
2086 | 13 |
12424
7c2e2c4d45a4
[gaim-migrate @ 14731]
Richard Laager <rlaager@wiktel.com>
parents:
11105
diff
changeset
|
14 static Code_t Z_RetSubs(ZNotice_t *notice, int *nsubs, Z_AuthProc auth_routine); |
2086 | 15 |
16 /* Need STDC definition when possible for unsigned short argument. */ | |
17 #ifdef __STDC__ | |
18 Code_t ZRetrieveSubscriptions(unsigned short port, int *nsubs) | |
19 #else | |
20 Code_t ZRetrieveSubscriptions(port,nsubs) | |
21 unsigned short port; | |
22 int *nsubs; | |
23 #endif | |
24 { | |
25 int retval; | |
26 ZNotice_t notice; | |
27 char asciiport[50]; | |
28 | |
29 if (!port) /* use default port */ | |
30 port = __Zephyr_port; | |
31 | |
32 retval = ZMakeAscii16(asciiport, sizeof(asciiport), ntohs(port)); | |
33 if (retval != ZERR_NONE) | |
34 return (retval); | |
35 | |
36 (void) memset((char *)¬ice, 0, sizeof(notice)); | |
37 notice.z_message = asciiport; | |
38 notice.z_message_len = strlen(asciiport)+1; | |
39 notice.z_opcode = CLIENT_GIMMESUBS; | |
40 | |
41 return(Z_RetSubs(¬ice, nsubs, ZAUTH)); | |
42 } | |
43 | |
12424
7c2e2c4d45a4
[gaim-migrate @ 14731]
Richard Laager <rlaager@wiktel.com>
parents:
11105
diff
changeset
|
44 #if 0 |
2086 | 45 Code_t ZRetrieveDefaultSubscriptions(nsubs) |
46 int *nsubs; | |
47 { | |
48 ZNotice_t notice; | |
49 | |
50 (void) memset((char *)¬ice, 0, sizeof(notice)); | |
51 notice.z_message = (char *) 0; | |
52 notice.z_message_len = 0; | |
53 notice.z_opcode = CLIENT_GIMMEDEFS; | |
54 | |
55 return(Z_RetSubs(¬ice, nsubs, ZNOAUTH)); | |
56 | |
57 } | |
12424
7c2e2c4d45a4
[gaim-migrate @ 14731]
Richard Laager <rlaager@wiktel.com>
parents:
11105
diff
changeset
|
58 #endif |
2086 | 59 |
60 static Code_t Z_RetSubs(notice, nsubs, auth_routine) | |
61 register ZNotice_t *notice; | |
62 int *nsubs; | |
63 Z_AuthProc auth_routine; | |
64 { | |
65 register int i; | |
66 int retval,nrecv,gimmeack; | |
67 ZNotice_t retnotice; | |
68 char *ptr,*end,*ptr2; | |
69 | |
70 retval = ZFlushSubscriptions(); | |
71 | |
72 if (retval != ZERR_NONE && retval != ZERR_NOSUBSCRIPTIONS) | |
73 return (retval); | |
74 | |
75 if (ZGetFD() < 0) | |
7475 | 76 if ((retval = ZOpenPort((unsigned short *)0)) != ZERR_NONE) |
2086 | 77 return (retval); |
78 | |
79 notice->z_kind = ACKED; | |
80 notice->z_port = __Zephyr_port; | |
81 notice->z_class = ZEPHYR_CTL_CLASS; | |
82 notice->z_class_inst = ZEPHYR_CTL_CLIENT; | |
83 notice->z_sender = 0; | |
84 notice->z_recipient = ""; | |
85 notice->z_default_format = ""; | |
86 | |
87 if ((retval = ZSendNotice(notice,auth_routine)) != ZERR_NONE) | |
88 return (retval); | |
89 | |
90 nrecv = 0; | |
91 gimmeack = 0; | |
92 __subscriptions_list = (ZSubscription_t *) 0; | |
93 | |
94 while (!nrecv || !gimmeack) { | |
95 retval = Z_WaitForNotice (&retnotice, ZCompareMultiUIDPred, | |
96 ¬ice->z_multiuid, SRV_TIMEOUT); | |
97 if (retval == ZERR_NONOTICE) | |
98 return ETIMEDOUT; | |
99 else if (retval != ZERR_NONE) | |
100 return retval; | |
101 | |
102 if (retnotice.z_kind == SERVNAK) { | |
103 ZFreeNotice(&retnotice); | |
104 return (ZERR_SERVNAK); | |
105 } | |
106 /* non-matching protocol version numbers means the | |
107 server is probably an older version--must punt */ | |
108 if (strcmp(notice->z_version,retnotice.z_version)) { | |
109 ZFreeNotice(&retnotice); | |
110 return(ZERR_VERS); | |
111 } | |
112 if (retnotice.z_kind == SERVACK && | |
113 !strcmp(retnotice.z_opcode,notice->z_opcode)) { | |
114 ZFreeNotice(&retnotice); | |
115 gimmeack = 1; | |
116 continue; | |
117 } | |
118 | |
119 if (retnotice.z_kind != ACKED) { | |
120 ZFreeNotice(&retnotice); | |
121 return (ZERR_INTERNAL); | |
122 } | |
123 | |
124 nrecv++; | |
125 | |
126 end = retnotice.z_message+retnotice.z_message_len; | |
127 | |
128 __subscriptions_num = 0; | |
129 for (ptr=retnotice.z_message;ptr<end;ptr++) | |
130 if (!*ptr) | |
131 __subscriptions_num++; | |
132 | |
133 __subscriptions_num = __subscriptions_num / 3; | |
134 | |
135 __subscriptions_list = (ZSubscription_t *) | |
136 malloc((unsigned)(__subscriptions_num* | |
137 sizeof(ZSubscription_t))); | |
138 if (__subscriptions_num && !__subscriptions_list) { | |
139 ZFreeNotice(&retnotice); | |
140 return (ENOMEM); | |
141 } | |
142 | |
143 for (ptr=retnotice.z_message,i = 0; i< __subscriptions_num; i++) { | |
144 __subscriptions_list[i].zsub_class = (char *) | |
145 malloc((unsigned)strlen(ptr)+1); | |
146 if (!__subscriptions_list[i].zsub_class) { | |
147 ZFreeNotice(&retnotice); | |
148 return (ENOMEM); | |
149 } | |
150 (void) strcpy(__subscriptions_list[i].zsub_class,ptr); | |
151 ptr += strlen(ptr)+1; | |
152 __subscriptions_list[i].zsub_classinst = (char *) | |
153 malloc((unsigned)strlen(ptr)+1); | |
154 if (!__subscriptions_list[i].zsub_classinst) { | |
155 ZFreeNotice(&retnotice); | |
156 return (ENOMEM); | |
157 } | |
158 (void) strcpy(__subscriptions_list[i].zsub_classinst,ptr); | |
159 ptr += strlen(ptr)+1; | |
160 ptr2 = ptr; | |
161 if (!*ptr2) | |
162 ptr2 = "*"; | |
163 __subscriptions_list[i].zsub_recipient = (char *) | |
164 malloc((unsigned)strlen(ptr2)+1); | |
165 if (!__subscriptions_list[i].zsub_recipient) { | |
166 ZFreeNotice(&retnotice); | |
167 return (ENOMEM); | |
168 } | |
169 (void) strcpy(__subscriptions_list[i].zsub_recipient,ptr2); | |
170 ptr += strlen(ptr)+1; | |
171 } | |
172 ZFreeNotice(&retnotice); | |
173 } | |
174 | |
175 __subscriptions_next = 0; | |
176 *nsubs = __subscriptions_num; | |
177 | |
178 return (ZERR_NONE); | |
179 } |