]> gb7djk.dxcluster.net Git - spider.git/blob - src/cmsg.c
Fix crash on sending an invalid rcmd
[spider.git] / src / cmsg.c
1 /*
2  * cmsg.c
3  * 
4  * create and free message buffers
5  * 
6  * Copyright 1996 (c) D-J Koopman
7  * 
8  * $Header$
9  */
10
11
12 static char rcsid[] = "$Id$";
13
14 #include <time.h>
15 #include <stdlib.h>
16
17 #include "chain.h"
18 #include "cmsg.h"
19
20 long cmsg_count = 0;
21
22 #ifdef DB_CMSG
23 #include <malloc.h>
24 #include <stdio.h>
25
26
27 #define MAXSORT 20
28 #define INTERVAL 10
29 #define FN "msg_stats"
30
31 static struct {
32         long new;
33         long free;
34 } stats[MAXSORT+1];
35
36 static void store()
37 {
38         static time_t t;
39         time_t systime;
40         
41         time(&systime);
42         if (systime - t > INTERVAL) {
43                 FILE *f = fopen(FN, "w");
44                 if (f) {
45                         int i;
46                         struct mallinfo m;                      
47                         fprintf(f, "\nMSG STATISTICS\n");
48                         fprintf(f,   "==============\n\n");
49                         fprintf(f, "cmsg_count = %ld\n\n", cmsg_count);
50                         for (i = 0; i < MAXSORT+1; ++i) {
51                                 if (stats[i].new == 0 && stats[i].free == 0)
52                                         continue;
53                                 fprintf(f, "%d new: %ld free: %ld outstanding: %ld\n", i, stats[i].new, stats[i].free, stats[i].new-stats[i].free);
54                         }
55                         m = mallinfo();
56                         fprintf(f, "\nmalloc total arena used: %ld used: %ld free: %ld\n\n", m.arena, m.uordblks, m.fordblks);
57                         fclose(f);
58                 }
59                 t = systime;
60         }
61 }
62
63 void cmsg_clear_stats()
64 {
65         memset(stats, 0, sizeof stats);
66         store();
67 }
68
69 #endif
70
71 cmsg_t *cmsg_new(int size, int sort, void *pp)
72 {
73         cmsg_t *mp;
74         
75         mp = malloc(sizeof(cmsg_t) + size);
76         if (!mp)
77                 die("no room in cmsg_new");
78         mp->size = 0;
79         mp->sort = sort & CMSG_SORTMASK;
80         mp->portp = pp;
81         mp->state = mp->reply = 0;
82         mp->inp = mp->data;
83         mp->callback = 0;
84         ++cmsg_count;
85 #ifdef DB_CMSG
86         if (sort > MAXSORT)
87                 sort = MAXSORT;
88         ++stats[sort].new;      
89         store();
90 #endif
91         return mp;
92 }
93
94
95 void cmsg_send(reft *base, cmsg_t *mp, void (*callback)())
96 {
97         time(&mp->t);
98         mp->size = mp->inp - mp->data;     /* calc the real size */
99         mp->callback = callback;                   /* store the reply address */
100         chain_insert(base, mp);
101 #ifdef DB_CMSG
102         store();
103 #endif
104 }
105
106 void cmsg_priority_send(reft *base, cmsg_t *mp, void (*callback)())
107 {
108         time(&mp->t);
109         mp->size = mp->inp - mp->data;     /* calc the real size */
110         mp->callback = callback;                   /* store the reply address */
111         chain_add(base, mp);
112 #ifdef DB_CMSG
113         store();
114 #endif
115 }
116
117 /*
118  * get the next cmsg (from the front), this removes the message from the chain
119  */
120
121 cmsg_t *cmsg_next(reft *base)
122 {
123         cmsg_t *mp = chain_get_next(base, 0);
124         if (mp)
125                 chain_delete(mp);
126 #ifdef DB_CMSG
127         store();
128 #endif
129         return mp;
130 }
131
132 /*
133  * get the prev cmsg (from the back), this removes the message from the chain
134  */
135
136 cmsg_t *cmsg_prev(reft *base)
137 {
138         cmsg_t *mp = chain_get_prev(base, 0);
139         if (mp)
140                 chain_delete(mp);
141 #ifdef DB_CMSG
142         store();
143 #endif
144         return mp;
145 }
146
147 void cmsg_callback(cmsg_t *m, int reply)
148 {
149         if (m->callback)
150                 (m->callback)(m, reply);
151         cmsg_free(m);
152 }
153
154 void cmsg_free(cmsg_t *m)
155 {
156         --cmsg_count;
157 #ifdef DB_CMSG
158         if (m->sort > MAXSORT)
159                 m->sort = MAXSORT;
160         ++stats[m->sort].free;  
161         store();
162 #endif
163         free(m);
164 }
165
166 void cmsg_flush(reft *base, int reply)
167 {
168         cmsg_t *m;
169         
170         while (m = cmsg_next(base)) {
171                 cmsg_callback(m, reply);
172         }
173 #ifdef DB_CMSG
174         store();
175 #endif
176 }               
177
178 /*
179  * 
180  * $Log$
181  * Revision 1.3  2000-10-29 11:00:07  minima
182  * added echo cancelling
183  * started new filter code, objectifyed old filter code
184  *
185  * Revision 1.2  2000/07/20 14:16:00  minima
186  * can use Sourceforge now!
187  * added user->qra cleaning
188  * added 4 digit qra to user broadcast dxspots if available
189  *
190  * Revision 1.1  2000/03/26 00:03:30  djk
191  * first cut of client
192  *
193  * Revision 1.12  1998/05/05 14:01:27  djk
194  * Tidied up various global variables in the hope that there is likely
195  * to be less undefined interaction between modules.
196  * Added some extra LINUX debugging to check for possible cmsg memory leaks.
197  *
198  * Revision 1.11  1998/01/02 19:39:58  djk
199  * made various changes to cope with glibc
200  * fixed problem with extended status in etsi_router
201  *
202  * Revision 1.10  1997/06/13 16:51:17  djk
203  * fixed various library problems
204  * got the taipstack and hayes to the point of half duplex reliability
205  * hayes now successfully communicates with taiptest and has part of the
206  * command level taip stuff in.
207  *
208  * Revision 1.9  1997/05/20 20:45:14  djk
209  * The 1.22 version more or less unchanged
210  *
211  * Revision 1.8  1997/03/25 18:12:55  djk
212  * dunno
213  *
214  * Revision 1.7  1997/03/19 09:57:28  djk
215  * added a count to check for leaks
216  *
217  * Revision 1.6  1997/02/13 17:02:04  djk
218  * forgotten?
219  *
220  * Revision 1.5  1997/02/04 17:47:04  djk
221  * brought into line with public2
222  *
223  * Revision 1.4  1997/02/04 01:27:37  djk
224  * altered size semantics on create (size now = 0 not creation size)
225  *
226  * Revision 1.3  1997/01/20 22:29:27  djk
227  * added status back
228  *
229  * Revision 1.2  1997/01/13 23:34:29  djk
230  * The first working test version of smsd
231  *
232  * Revision 1.1  1997/01/03 23:42:21  djk
233  * added a general message handling module (still developing)
234  * added parity handling to ser.c
235  *
236  */