Mercurial > pidgin
annotate src/protocols/zephyr/ZAsyncLocate.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 | 64895571248f |
children |
rev | line source |
---|---|
2086 | 1 /* This file is part of the Project Athena Zephyr Notification System. |
2 * It contains source for asynchronous location functions. | |
3 * | |
4 * Created by: Marc Horowitz | |
5 * | |
6 * Copyright (c) 1990,1991 by the Massachusetts Institute of Technology. | |
7 * For copying and distribution information, see the file | |
8 * "mit-copyright.h". | |
9 */ | |
10 | |
8791
407355e05a0a
[gaim-migrate @ 9553]
Christian Hammond <chipx86@chipx86.com>
parents:
7475
diff
changeset
|
11 #include "internal.h" |
2086 | 12 |
13 Code_t ZRequestLocations(user, zald, kind, auth) | |
7261 | 14 const char *user; |
10867 | 15 ZAsyncLocateData_t *zald; |
2086 | 16 ZNotice_Kind_t kind; /* UNSAFE, UNACKED, or ACKED */ |
17 Z_AuthProc auth; | |
18 { | |
19 int retval; | |
20 ZNotice_t notice; | |
21 | |
22 if (ZGetFD() < 0) | |
7475 | 23 if ((retval = ZOpenPort((unsigned short *)0)) != ZERR_NONE) |
2086 | 24 return (retval); |
25 | |
26 (void) memset((char *)¬ice, 0, sizeof(notice)); | |
27 notice.z_kind = kind; | |
28 notice.z_port = __Zephyr_port; | |
29 notice.z_class = LOCATE_CLASS; | |
30 notice.z_class_inst = user; | |
31 notice.z_opcode = LOCATE_LOCATE; | |
32 notice.z_sender = 0; | |
33 notice.z_recipient = ""; | |
34 notice.z_default_format = ""; | |
35 notice.z_message_len = 0; | |
36 | |
37 if ((retval = ZSendNotice(¬ice, auth)) != ZERR_NONE) | |
38 return(retval); | |
39 | |
40 if ((zald->user = (char *) malloc(strlen(user)+1)) == NULL) { | |
41 return(ENOMEM); | |
42 } | |
43 if ((zald->version = (char *) malloc(strlen(notice.z_version)+1)) == NULL) { | |
44 free(zald->user); | |
45 return(ENOMEM); | |
46 } | |
47 zald->uid = notice.z_multiuid; | |
48 strcpy(zald->user,user); | |
49 strcpy(zald->version,notice.z_version); | |
50 | |
51 return(ZERR_NONE); | |
52 } | |
53 | |
54 Code_t ZParseLocations(notice,zald,nlocs,user) | |
10867 | 55 ZNotice_t *notice; |
56 ZAsyncLocateData_t *zald; | |
2086 | 57 int *nlocs; |
58 char **user; | |
59 { | |
60 char *ptr, *end; | |
61 int i; | |
62 | |
63 ZFlushLocations(); /* This never fails (this function is part of the | |
64 library, so it is allowed to know this). */ | |
65 | |
66 /* non-matching protocol version numbers means the | |
67 server is probably an older version--must punt */ | |
68 | |
69 if (zald && strcmp(notice->z_version, zald->version)) | |
70 return(ZERR_VERS); | |
71 | |
72 if (notice->z_kind == SERVNAK) | |
73 return (ZERR_SERVNAK); | |
74 | |
75 /* flag ACKs as special */ | |
76 if (notice->z_kind == SERVACK && | |
77 !strcmp(notice->z_opcode, LOCATE_LOCATE)) { | |
78 *nlocs = -1; | |
79 return(ZERR_NONE); | |
80 } | |
81 | |
82 if (notice->z_kind != ACKED) | |
83 return (ZERR_INTERNAL); | |
84 | |
85 end = notice->z_message+notice->z_message_len; | |
86 | |
87 __locate_num = 0; | |
88 | |
89 for (ptr=notice->z_message;ptr<end;ptr++) | |
90 if (!*ptr) | |
91 __locate_num++; | |
92 | |
93 __locate_num /= 3; | |
94 | |
95 if (__locate_num) | |
96 { | |
97 __locate_list = (ZLocations_t *)malloc((unsigned)__locate_num* | |
98 sizeof(ZLocations_t)); | |
99 if (!__locate_list) | |
100 return (ENOMEM); | |
101 } else { | |
102 __locate_list = 0; | |
103 } | |
104 | |
105 for (ptr=notice->z_message, i=0; i<__locate_num; i++) { | |
106 unsigned int len; | |
107 | |
108 len = strlen (ptr) + 1; | |
109 __locate_list[i].host = (char *) malloc(len); | |
110 if (!__locate_list[i].host) | |
111 return (ENOMEM); | |
112 (void) strcpy(__locate_list[i].host, ptr); | |
113 ptr += len; | |
114 | |
115 len = strlen (ptr) + 1; | |
116 __locate_list[i].time = (char *) malloc(len); | |
117 if (!__locate_list[i].time) | |
118 return (ENOMEM); | |
119 (void) strcpy(__locate_list[i].time, ptr); | |
120 ptr += len; | |
121 | |
122 len = strlen (ptr) + 1; | |
123 __locate_list[i].tty = (char *) malloc(len); | |
124 if (!__locate_list[i].tty) | |
125 return (ENOMEM); | |
126 (void) strcpy(__locate_list[i].tty, ptr); | |
127 ptr += len; | |
128 } | |
129 | |
130 __locate_next = 0; | |
131 *nlocs = __locate_num; | |
132 if (user) { | |
133 if (zald) { | |
134 if ((*user = (char *) malloc(strlen(zald->user)+1)) == NULL) | |
135 return(ENOMEM); | |
136 strcpy(*user,zald->user); | |
137 } else { | |
138 if ((*user = (char *) malloc(strlen(notice->z_class_inst)+1)) == NULL) | |
139 return(ENOMEM); | |
140 strcpy(*user,notice->z_class_inst); | |
141 } | |
142 } | |
143 return (ZERR_NONE); | |
144 } | |
145 | |
146 int ZCompareALDPred(notice, zald) | |
147 ZNotice_t *notice; | |
148 void *zald; | |
149 { | |
150 return(ZCompareUID(&(notice->z_multiuid), | |
151 &(((ZAsyncLocateData_t *) zald)->uid))); | |
152 } | |
153 | |
154 void ZFreeALD(zald) | |
10867 | 155 ZAsyncLocateData_t *zald; |
2086 | 156 { |
157 if (!zald) return; | |
158 | |
159 if (zald->user) free(zald->user); | |
160 if (zald->version) free(zald->version); | |
161 (void) memset(zald, 0, sizeof(*zald)); | |
162 } |