Mercurial > pidgin
annotate src/protocols/jabber/pool.c @ 4102:c5ce82228a2f
[gaim-migrate @ 4317]
Cooley enough, @mac.com screen names can sign on without any additional
changes. There are a few problems, though. This fixes one of them:
-SNAC error saying "Not supported by host" or something similar at
signon, because gaim requests a redirect to the email notification
server, but this is not supported for ICQ and @mac.com accounts (I
don't know why ICQ accounts don't give the error). Anyway, so this
fixes the problem by only requesting the redirect if the screen name
has an email address associated with it. I made it so the auth
reply info is stored in the oscar session struct. There are some
other useful variables there, and I think it's just cleaner to
store the whole thing than the little bits and pieces.
I heard someone complain about your_uin@pager.icq.com spam, so I'm
thinking it'd be good if there were a way to disable those types of
messages. WinICQ has a nice little preferences thingy, I think.
I dunno, maybe I could add a checkbox to the account window?
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 19 Dec 2002 20:38:12 +0000 |
parents | 988485669631 |
children |
rev | line source |
---|---|
3127 | 1 /* -------------------------------------------------------------------------- |
2 * | |
3 * License | |
4 * | |
5 * The contents of this file are subject to the Jabber Open Source License | |
6 * Version 1.0 (the "JOSL"). You may not copy or use this file, in either | |
7 * source code or executable form, except in compliance with the JOSL. You | |
8 * may obtain a copy of the JOSL at http://www.jabber.org/ or at | |
9 * http://www.opensource.org/. | |
2086 | 10 * |
3127 | 11 * Software distributed under the JOSL is distributed on an "AS IS" basis, |
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the JOSL | |
13 * for the specific language governing rights and limitations under the | |
14 * JOSL. | |
2086 | 15 * |
3127 | 16 * Copyrights |
17 * | |
18 * Portions created by or assigned to Jabber.com, Inc. are | |
19 * Copyright (c) 1999-2002 Jabber.com, Inc. All Rights Reserved. Contact | |
20 * information for Jabber.com, Inc. is available at http://www.jabber.com/. | |
2086 | 21 * |
3127 | 22 * Portions Copyright (c) 1998-1999 Jeremie Miller. |
23 * | |
24 * Acknowledgements | |
25 * | |
26 * Special thanks to the Jabber Open Source Contributors for their | |
27 * suggestions and support of Jabber. | |
28 * | |
29 * Alternatively, the contents of this file may be used under the terms of the | |
30 * GNU General Public License Version 2 or later (the "GPL"), in which case | |
31 * the provisions of the GPL are applicable instead of those above. If you | |
32 * wish to allow use of your version of this file only under the terms of the | |
33 * GPL and not to allow others to use your version of this file under the JOSL, | |
34 * indicate your decision by deleting the provisions above and replace them | |
35 * with the notice and other provisions required by the GPL. If you do not | |
36 * delete the provisions above, a recipient may use your version of this file | |
37 * under either the JOSL or the GPL. | |
38 * | |
39 * | |
40 * --------------------------------------------------------------------------*/ | |
2086 | 41 |
3127 | 42 #include "lib.h" |
2086 | 43 |
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3127
diff
changeset
|
44 #ifdef _WIN32 |
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3127
diff
changeset
|
45 #include "win32dep.h" |
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3127
diff
changeset
|
46 #endif |
2086 | 47 |
48 #ifdef POOL_DEBUG | |
49 int pool__total = 0; | |
50 int pool__ltotal = 0; | |
51 HASHTABLE pool__disturbed = NULL; | |
52 void *_pool__malloc(size_t size) | |
53 { | |
54 pool__total++; | |
55 return malloc(size); | |
56 } | |
57 void _pool__free(void *block) | |
58 { | |
59 pool__total--; | |
60 free(block); | |
61 } | |
62 #else | |
63 #define _pool__malloc malloc | |
64 #define _pool__free free | |
65 #endif | |
66 | |
67 | |
68 /* make an empty pool */ | |
69 pool _pool_new(char *zone) | |
70 { | |
71 pool p; | |
72 while((p = _pool__malloc(sizeof(_pool))) == NULL) sleep(1); | |
73 p->cleanup = NULL; | |
74 p->heap = NULL; | |
75 p->size = 0; | |
76 | |
77 #ifdef POOL_DEBUG | |
78 p->lsize = -1; | |
79 p->zone[0] = '\0'; | |
80 strcat(p->zone,zone); | |
81 sprintf(p->name,"%X",p); | |
82 | |
83 if(pool__disturbed == NULL) | |
3127 | 84 { |
85 pool__disturbed = 1; /* reentrancy flag! */ | |
2086 | 86 pool__disturbed = ghash_create(POOL_DEBUG,(KEYHASHFUNC)str_hash_code,(KEYCOMPAREFUNC)j_strcmp); |
3127 | 87 } |
88 if(pool__disturbed != 1) | |
89 ghash_put(pool__disturbed,p->name,p); | |
2086 | 90 #endif |
91 | |
92 return p; | |
93 } | |
94 | |
95 /* free a heap */ | |
96 void _pool_heap_free(void *arg) | |
97 { | |
98 struct pheap *h = (struct pheap *)arg; | |
99 | |
100 _pool__free(h->block); | |
101 _pool__free(h); | |
102 } | |
103 | |
104 /* mem should always be freed last */ | |
105 void _pool_cleanup_append(pool p, struct pfree *pf) | |
106 { | |
107 struct pfree *cur; | |
108 | |
109 if(p->cleanup == NULL) | |
110 { | |
111 p->cleanup = pf; | |
112 return; | |
113 } | |
114 | |
115 /* fast forward to end of list */ | |
116 for(cur = p->cleanup; cur->next != NULL; cur = cur->next); | |
117 | |
118 cur->next = pf; | |
119 } | |
120 | |
121 /* create a cleanup tracker */ | |
122 struct pfree *_pool_free(pool p, pool_cleaner f, void *arg) | |
123 { | |
124 struct pfree *ret; | |
125 | |
126 /* make the storage for the tracker */ | |
127 while((ret = _pool__malloc(sizeof(struct pfree))) == NULL) sleep(1); | |
128 ret->f = f; | |
129 ret->arg = arg; | |
130 ret->next = NULL; | |
131 | |
132 return ret; | |
133 } | |
134 | |
135 /* create a heap and make sure it get's cleaned up */ | |
136 struct pheap *_pool_heap(pool p, int size) | |
137 { | |
138 struct pheap *ret; | |
139 struct pfree *clean; | |
140 | |
141 /* make the return heap */ | |
142 while((ret = _pool__malloc(sizeof(struct pheap))) == NULL) sleep(1); | |
143 while((ret->block = _pool__malloc(size)) == NULL) sleep(1); | |
144 ret->size = size; | |
145 p->size += size; | |
146 ret->used = 0; | |
147 | |
148 /* append to the cleanup list */ | |
149 clean = _pool_free(p, _pool_heap_free, (void *)ret); | |
150 clean->heap = ret; /* for future use in finding used mem for pstrdup */ | |
151 _pool_cleanup_append(p, clean); | |
152 | |
153 return ret; | |
154 } | |
155 | |
156 pool _pool_new_heap(int size, char *zone) | |
157 { | |
158 pool p; | |
159 p = _pool_new(zone); | |
160 p->heap = _pool_heap(p,size); | |
161 return p; | |
162 } | |
163 | |
164 void *pmalloc(pool p, int size) | |
165 { | |
166 void *block; | |
167 | |
168 if(p == NULL) | |
169 { | |
170 fprintf(stderr,"Memory Leak! [pmalloc received NULL pool, unable to track allocation, exiting]\n"); | |
171 abort(); | |
172 } | |
173 | |
174 /* if there is no heap for this pool or it's a big request, just raw, I like how we clean this :) */ | |
175 if(p->heap == NULL || size > (p->heap->size / 2)) | |
176 { | |
177 while((block = _pool__malloc(size)) == NULL) sleep(1); | |
178 p->size += size; | |
179 _pool_cleanup_append(p, _pool_free(p, _pool__free, block)); | |
180 return block; | |
181 } | |
182 | |
183 /* we have to preserve boundaries, long story :) */ | |
184 if(size >= 4) | |
185 while(p->heap->used&7) p->heap->used++; | |
186 | |
187 /* if we don't fit in the old heap, replace it */ | |
188 if(size > (p->heap->size - p->heap->used)) | |
189 p->heap = _pool_heap(p, p->heap->size); | |
190 | |
191 /* the current heap has room */ | |
192 block = (char *)p->heap->block + p->heap->used; | |
193 p->heap->used += size; | |
194 return block; | |
195 } | |
196 | |
197 void *pmalloc_x(pool p, int size, char c) | |
198 { | |
199 void* result = pmalloc(p, size); | |
200 if (result != NULL) | |
201 memset(result, c, size); | |
202 return result; | |
203 } | |
204 | |
205 /* easy safety utility (for creating blank mem for structs, etc) */ | |
206 void *pmalloco(pool p, int size) | |
207 { | |
208 void *block = pmalloc(p, size); | |
209 memset(block, 0, size); | |
210 return block; | |
211 } | |
212 | |
213 /* XXX efficient: move this to const char * and then loop throug the existing heaps to see if src is within a block in this pool */ | |
214 char *pstrdup(pool p, const char *src) | |
215 { | |
216 char *ret; | |
217 | |
218 if(src == NULL) | |
219 return NULL; | |
220 | |
221 ret = pmalloc(p,strlen(src) + 1); | |
222 strcpy(ret,src); | |
223 | |
224 return ret; | |
225 } | |
226 | |
227 /* when move above, this one would actually return a new block */ | |
228 char *pstrdupx(pool p, const char *src) | |
229 { | |
230 return pstrdup(p, src); | |
231 } | |
232 | |
233 int pool_size(pool p) | |
234 { | |
235 if(p == NULL) return 0; | |
236 | |
237 return p->size; | |
238 } | |
239 | |
240 void pool_free(pool p) | |
241 { | |
242 struct pfree *cur, *stub; | |
243 | |
244 if(p == NULL) return; | |
245 | |
246 cur = p->cleanup; | |
247 while(cur != NULL) | |
248 { | |
249 (*cur->f)(cur->arg); | |
250 stub = cur->next; | |
251 _pool__free(cur); | |
252 cur = stub; | |
253 } | |
254 | |
255 #ifdef POOL_DEBUG | |
256 ghash_remove(pool__disturbed,p->name); | |
257 #endif | |
258 | |
259 _pool__free(p); | |
260 | |
261 } | |
262 | |
263 /* public cleanup utils, insert in a way that they are run FIFO, before mem frees */ | |
264 void pool_cleanup(pool p, pool_cleaner f, void *arg) | |
265 { | |
266 struct pfree *clean; | |
267 | |
268 clean = _pool_free(p, f, arg); | |
269 clean->next = p->cleanup; | |
270 p->cleanup = clean; | |
271 } | |
272 | |
273 #ifdef POOL_DEBUG | |
274 void debug_log(char *zone, const char *msgfmt, ...); | |
275 int _pool_stat(void *arg, const void *key, void *data) | |
276 { | |
277 pool p = (pool)data; | |
278 | |
279 if(p->lsize == -1) | |
280 debug_log("leak","%s: %X is a new pool",p->zone,p->name); | |
281 else if(p->size > p->lsize) | |
282 debug_log("leak","%s: %X grew %d",p->zone,p->name, p->size - p->lsize); | |
283 else if((int)arg) | |
284 debug_log("leak","%s: %X exists %d",p->zone,p->name, p->size); | |
285 p->lsize = p->size; | |
286 return 1; | |
287 } | |
288 | |
289 void pool_stat(int full) | |
290 { | |
291 ghash_walk(pool__disturbed,_pool_stat,(void *)full); | |
292 if(pool__total != pool__ltotal) | |
293 debug_log("leak","%d\ttotal missed mallocs",pool__total); | |
294 pool__ltotal = pool__total; | |
295 return; | |
296 } | |
297 #else | |
298 void pool_stat(int full) | |
299 { | |
300 return; | |
301 } | |
302 #endif |