"Fossies" - the Fresh Open Source Software Archive 
Member "tin-2.6.1/src/memory.c" (22 Dec 2021, 14328 Bytes) of package /linux/misc/tin-2.6.1.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "memory.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.6.0_vs_2.6.1.
1 /*
2 * Project : tin - a Usenet reader
3 * Module : memory.c
4 * Author : I. Lea & R. Skrenta
5 * Created : 1991-04-01
6 * Updated : 2021-09-22
7 * Notes :
8 *
9 * Copyright (c) 1991-2022 Iain Lea <iain@bricbrac.de>, Rich Skrenta <skrenta@pbm.com>
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * 3. Neither the name of the copyright holder nor the names of its
24 * contributors may be used to endorse or promote products derived from
25 * this software without specific prior written permission.
26 *
27 * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40
41 #ifndef TIN_H
42 # include "tin.h"
43 #endif /* !TIN_H */
44
45
46 /*
47 * Dynamic arrays maximum (initialized in init_alloc()) & current sizes
48 * num_* values are one past top of used part of array
49 */
50 int max_active;
51 int num_active = -1;
52 int max_newnews;
53 int num_newnews = 0;
54 int max_art;
55 int max_base;
56 int max_save;
57 int num_save = 0;
58 int max_scope;
59 int num_scope = -1;
60
61 /*
62 * Dynamic arrays
63 */
64 int *my_group; /* .newsrc --> active[] */
65 t_artnum *base; /* base articles for each thread */
66 struct t_group *active; /* active newsgroups */
67 struct t_scope *scopes = NULL; /* attributes stores in .tin/attributes */
68 struct t_newnews *newnews; /* active file sizes on different servers */
69 struct t_article *arts; /* articles headers in current group */
70 struct t_save *save; /* sorts articles before saving them */
71
72 /*
73 * Local prototypes
74 */
75 static void free_active_arrays(void);
76 static void free_attributes(struct t_attribute *attributes);
77 static void free_scopes_arrays(void);
78 static void free_newnews_array(void);
79 static void free_if_not_default(char **attrib, const char *deflt);
80 static void free_input_history(void);
81
82
83 /*
84 * Dynamic table management
85 * These settings are memory conservative: small initial allocations
86 * and a 50% expansion on table overflow. A fast vm system with
87 * much memory might want to start with higher initial allocations
88 * and a 100% expansion on overflow, especially for the arts[] array.
89 */
90 void
91 init_alloc(
92 void)
93 {
94 /*
95 * active file arrays
96 */
97 max_active = DEFAULT_ACTIVE_NUM;
98 max_newnews = DEFAULT_NEWNEWS_NUM;
99
100 active = my_malloc(sizeof(*active) * (size_t) max_active);
101 newnews = my_malloc(sizeof(*newnews) * (size_t) max_newnews);
102 my_group = my_calloc(1, sizeof(int) * (size_t) max_active);
103
104 /*
105 * article headers array
106 */
107 max_art = DEFAULT_ARTICLE_NUM;
108 max_base = DEFAULT_ARTICLE_NUM;
109
110 arts = my_calloc(1, sizeof(*arts) * (size_t) max_art);
111 base = my_malloc(sizeof(t_artnum) * (size_t) max_base);
112
113 ofmt = my_calloc(1, sizeof(*ofmt) * 9); /* initial number of overview fields */
114
115 /*
116 * save file array
117 */
118 max_save = DEFAULT_SAVE_NUM;
119
120 save = my_malloc(sizeof(*save) * (size_t) max_save);
121
122 /*
123 * scope array
124 */
125 max_scope = DEFAULT_SCOPE_NUM;
126 expand_scope();
127
128 #ifndef USE_CURSES
129 screen = (struct t_screen *) 0;
130 #endif /* !USE_CURSES */
131 }
132
133
134 void
135 expand_art(
136 void)
137 {
138 int i = max_art;
139
140 max_art += max_art >> 1; /* increase by 50% */
141 arts = my_realloc(arts, sizeof(*arts) * (size_t) max_art);
142 /*
143 * memset(&arts[i].artnum, 0, (max_art - i - 1) * sizeof(*arts));
144 * seems to be not faster at all
145 */
146 for (; i < max_art; i++)
147 arts[i].subject = arts[i].from = arts[i].xref = arts[i].path = arts[i].refs = arts[i].msgid = NULL;
148 }
149
150
151 void
152 expand_active(
153 void)
154 {
155 max_active += max_active >> 1; /* increase by 50% */
156 if (active == NULL) {
157 active = my_malloc(sizeof(*active) * (size_t) max_active);
158 my_group = my_calloc(1, sizeof(int) * (size_t) max_active);
159 } else {
160 active = my_realloc(active, sizeof(*active) * (size_t) max_active);
161 my_group = my_realloc(my_group, sizeof(int) * (size_t) max_active);
162 }
163 }
164
165
166 void
167 expand_base(
168 void)
169 {
170 max_base += max_base >> 1; /* increase by 50% */
171 base = my_realloc(base, sizeof(t_artnum) * (size_t) max_base);
172 }
173
174
175 void
176 expand_save(
177 void)
178 {
179 max_save += max_save >> 1; /* increase by 50% */
180 save = my_realloc(save, sizeof(struct t_save) * (size_t) max_save);
181 }
182
183
184 void
185 expand_scope(
186 void)
187 {
188 if ((scopes == NULL) || (num_scope < 0)) {
189 if (scopes == NULL)
190 scopes = my_malloc(sizeof(*scopes) * (size_t) max_scope);
191 num_scope = 0;
192 } else {
193 max_scope += max_scope >> 1; /* increase by 50% */
194 scopes = my_realloc(scopes, sizeof(*scopes) * (size_t) max_scope);
195 }
196 }
197
198
199 void
200 expand_newnews(
201 void)
202 {
203 max_newnews += max_newnews >> 1; /* increase by 50% */
204 newnews = my_realloc(newnews, sizeof(struct t_newnews) * (size_t) max_newnews);
205 }
206
207
208 #ifndef USE_CURSES
209 void
210 init_screen_array(
211 t_bool allocate)
212 {
213 int i;
214
215 if (allocate) {
216 screen = my_malloc(sizeof(struct t_screen) * (size_t) cLINES + 1);
217
218 for (i = 0; i < cLINES; i++)
219 # if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
220 screen[i].col = my_malloc((size_t) ((size_t) cCOLS * MB_CUR_MAX + 2));
221 # else
222 screen[i].col = my_malloc((size_t) ((size_t) cCOLS + 2));
223 # endif /* MULTIBYTE_ABLE && !NO_LOCALE */
224 } else {
225 if (screen != NULL) {
226 for (i = 0; i < cLINES; i++)
227 FreeAndNull(screen[i].col);
228
229 FreeAndNull(screen);
230 }
231 }
232 }
233 #endif /* !USE_CURSES */
234
235
236 void
237 free_all_arrays(
238 void)
239 {
240 hash_reclaim();
241
242 #ifndef USE_CURSES
243 if (!batch_mode)
244 init_screen_array(FALSE);
245 #endif /* !USE_CURSES */
246
247 free_art_array();
248 free_msgids();
249 FreeAndNull(arts);
250 free_filter_array(&glob_filter);
251 free_active_arrays();
252 free_scopes_arrays();
253
254 #ifdef HAVE_COLOR
255 FreeIfNeeded(quote_regex.re);
256 FreeIfNeeded(quote_regex.extra);
257 FreeIfNeeded(quote_regex2.re);
258 FreeIfNeeded(quote_regex2.extra);
259 FreeIfNeeded(quote_regex3.re);
260 FreeIfNeeded(quote_regex3.extra);
261 FreeIfNeeded(extquote_regex.re);
262 FreeIfNeeded(extquote_regex.extra);
263 #endif /* HAVE_COLOR */
264 FreeIfNeeded(slashes_regex.re);
265 FreeIfNeeded(slashes_regex.extra);
266 FreeIfNeeded(stars_regex.re);
267 FreeIfNeeded(stars_regex.extra);
268 FreeIfNeeded(strokes_regex.re);
269 FreeIfNeeded(strokes_regex.extra);
270 FreeIfNeeded(underscores_regex.re);
271 FreeIfNeeded(underscores_regex.extra);
272 FreeIfNeeded(strip_re_regex.re);
273 FreeIfNeeded(strip_re_regex.extra);
274 FreeIfNeeded(strip_was_regex.re);
275 FreeIfNeeded(strip_was_regex.extra);
276 FreeIfNeeded(uubegin_regex.re);
277 FreeIfNeeded(uubegin_regex.extra);
278 FreeIfNeeded(uubody_regex.re);
279 FreeIfNeeded(uubody_regex.extra);
280 FreeIfNeeded(verbatim_begin_regex.re);
281 FreeIfNeeded(verbatim_begin_regex.extra);
282 FreeIfNeeded(verbatim_end_regex.re);
283 FreeIfNeeded(verbatim_end_regex.extra);
284 FreeIfNeeded(url_regex.re);
285 FreeIfNeeded(url_regex.extra);
286 FreeIfNeeded(mail_regex.re);
287 FreeIfNeeded(mail_regex.extra);
288 FreeIfNeeded(news_regex.re);
289 FreeIfNeeded(news_regex.extra);
290 FreeIfNeeded(shar_regex.re);
291 FreeIfNeeded(shar_regex.extra);
292
293 if (!batch_mode) {
294 free_keymaps();
295 free_input_history();
296 }
297
298 FreeAndNull(base);
299
300 if (save != NULL) {
301 free_save_array();
302 FreeAndNull(save);
303 }
304
305 if (newnews != NULL) {
306 free_newnews_array();
307 FreeAndNull(newnews);
308 }
309
310 FreeAndNull(nntp_caps.headers_range);
311 FreeAndNull(nntp_caps.headers_id);
312 FreeAndNull(nntp_caps.implementation);
313
314 if (ofmt) { /* ofmt might not be allocated yet on early abort */
315 int i;
316 for (i = 0; ofmt[i].name; i++)
317 free(ofmt[i].name);
318 free(ofmt);
319 }
320
321 tin_fgets(NULL, FALSE);
322 rfc1522_decode(NULL);
323
324 free(tin_progname);
325 }
326
327
328 void
329 free_art_array(
330 void)
331 {
332 int i;
333
334 for_each_art(i) {
335 arts[i].artnum = T_ARTNUM_CONST(0);
336 arts[i].date = (time_t) 0;
337 FreeAndNull(arts[i].xref);
338 FreeAndNull(arts[i].path);
339
340 /*
341 * .refs & .msgid are usually free()d in build_references()
342 * nevertheless we try to free() it here in case tin_done()
343 * was called before build_references()
344 */
345 FreeAndNull(arts[i].refs);
346 FreeAndNull(arts[i].msgid);
347
348 arts[i].tagged = 0;
349 arts[i].thread = ART_EXPIRED;
350 arts[i].prev = ART_NORMAL;
351 arts[i].status = ART_UNREAD;
352 arts[i].killed = ART_NOTKILLED;
353 arts[i].selected = FALSE;
354 }
355 }
356
357
358 /*
359 * Use this only for attributes that have a fixed default of a static string
360 * in tinrc
361 */
362 static void
363 free_if_not_default(
364 char **attrib,
365 const char *deflt)
366 {
367 if (*attrib != deflt)
368 FreeAndNull(*attrib);
369 }
370
371
372 /*
373 * Free memory of one attributes struct only
374 */
375 static void
376 free_attributes(
377 struct t_attribute *attributes)
378 {
379 free_if_not_default(&attributes->group_format, tinrc.group_format);
380 free_if_not_default(&attributes->thread_format, tinrc.thread_format);
381 free_if_not_default(&attributes->date_format, tinrc.date_format);
382 free_if_not_default(&attributes->editor_format, tinrc.editor_format);
383 FreeAndNull(attributes->fcc);
384 free_if_not_default(&attributes->from, tinrc.mail_address);
385 FreeAndNull(attributes->followup_to);
386 #ifdef HAVE_ISPELL
387 FreeAndNull(attributes->ispell);
388 #endif /* HAVE_ISPELL */
389 free_if_not_default(&attributes->maildir, tinrc.maildir);
390 FreeAndNull(attributes->mailing_list);
391 FreeAndNull(attributes->mime_types_to_save);
392 free_if_not_default(&attributes->news_headers_to_display, tinrc.news_headers_to_display);
393 free_if_not_default(&attributes->news_headers_to_not_display, tinrc.news_headers_to_not_display);
394 if (attributes->headers_to_display) {
395 if (attributes->headers_to_display->header)
396 FreeIfNeeded(*attributes->headers_to_display->header);
397 FreeAndNull(attributes->headers_to_display->header);
398 free(attributes->headers_to_display);
399 attributes->headers_to_display = (struct t_newsheader *) 0;
400 }
401 if (attributes->headers_to_not_display) {
402 if (attributes->headers_to_not_display->header)
403 FreeIfNeeded(*attributes->headers_to_not_display->header);
404 FreeAndNull(attributes->headers_to_not_display->header);
405 free(attributes->headers_to_not_display);
406 attributes->headers_to_not_display = (struct t_newsheader *) 0;
407 }
408 free_if_not_default(&attributes->news_quote_format, tinrc.news_quote_format);
409 free_if_not_default(&attributes->organization, default_organization);
410 FreeAndNull(attributes->quick_kill_scope);
411 FreeAndNull(attributes->quick_select_scope);
412 free_if_not_default(&attributes->quote_chars, tinrc.quote_chars);
413 free_if_not_default(&attributes->savedir, tinrc.savedir);
414 FreeAndNull(attributes->savefile);
415 free_if_not_default(&attributes->sigfile, tinrc.sigfile);
416 #ifdef CHARSET_CONVERSION
417 FreeAndNull(attributes->undeclared_charset);
418 #endif /* CHARSET_CONVERSION */
419 FreeAndNull(attributes->x_headers);
420 FreeAndNull(attributes->x_body);
421 }
422
423
424 void
425 free_scope(
426 int num)
427 {
428 struct t_scope *scope;
429
430 scope = &scopes[num];
431 FreeAndNull(scope->scope);
432 free_attributes(scope->attribute);
433 free(scope->attribute);
434 scope->attribute = (struct t_attribute *) 0;
435 free(scope->state);
436 scope->state = (struct t_attribute_state *) 0;
437 }
438
439
440 static void
441 free_scopes_arrays(
442 void)
443 {
444 while (num_scope > 0)
445 free_scope(--num_scope);
446 FreeAndNull(scopes);
447 num_scope = -1;
448 }
449
450
451 static void
452 free_active_arrays(
453 void)
454 {
455 FreeAndNull(my_group); /* my_group[] */
456
457 if (active != NULL) { /* active[] */
458 int i;
459
460 for_each_group(i) {
461 FreeAndNull(active[i].name);
462 FreeAndNull(active[i].description);
463 FreeAndNull(active[i].aliasedto);
464 if (active[i].type == GROUP_TYPE_MAIL || active[i].type == GROUP_TYPE_SAVE) {
465 FreeAndNull(active[i].spooldir);
466 }
467 FreeAndNull(active[i].newsrc.xbitmap);
468 if (active[i].attribute && !active[i].attribute->global) {
469 free(active[i].attribute);
470 active[i].attribute = (struct t_attribute *) 0;
471 }
472 }
473 FreeAndNull(active);
474 }
475 num_active = -1;
476 }
477
478
479 void
480 free_save_array(
481 void)
482 {
483 int i;
484
485 for (i = 0; i < num_save; i++) {
486 FreeAndNull(save[i].path);
487 /* file does NOT need to be freed */
488 save[i].file = NULL;
489 save[i].mailbox = FALSE;
490 }
491 num_save = 0;
492 }
493
494
495 static void
496 free_newnews_array(
497 void)
498 {
499 int i;
500
501 for (i = 0; i < num_newnews; i++)
502 FreeAndNull(newnews[i].host);
503
504 num_newnews = 0;
505 }
506
507
508 static void
509 free_input_history(
510 void)
511 {
512 int his_w, his_e;
513
514 for (his_w = 0; his_w <= HIST_MAXNUM; his_w++) {
515 for (his_e = 0; his_e < HIST_SIZE; his_e++) {
516 FreeIfNeeded(input_history[his_w][his_e]);
517 }
518 }
519 }
520
521
522 void *
523 my_malloc1(
524 const char *file,
525 int line,
526 size_t size)
527 {
528 void *p;
529
530 #ifdef DEBUG
531 if (debug & DEBUG_MEM)
532 debug_print_malloc(TRUE, file, line, size);
533 #endif /* DEBUG */
534
535 if ((p = malloc(size)) == NULL) {
536 error_message(2, txt_out_of_memory, tin_progname, (unsigned long) size, file, line);
537 giveup();
538 }
539 return p;
540 }
541
542
543 /*
544 * TODO: add fallback code with malloc(nmemb*size);memset(0,nmemb*size)?
545 */
546 void *
547 my_calloc1(
548 const char *file,
549 int line,
550 size_t nmemb,
551 size_t size)
552 {
553 void *p;
554
555 #ifdef DEBUG
556 if (debug & DEBUG_MEM)
557 debug_print_malloc(TRUE, file, line, nmemb * size);
558 #endif /* DEBUG */
559
560 if ((p = calloc(nmemb, size)) == NULL) {
561 error_message(2, txt_out_of_memory, tin_progname, (unsigned long) (nmemb * size), file, line);
562 giveup();
563 }
564 return p;
565 }
566
567
568 void *
569 my_realloc1(
570 const char *file,
571 int line,
572 void *p,
573 size_t size)
574 {
575 #ifdef DEBUG
576 if (debug & DEBUG_MEM)
577 debug_print_malloc(FALSE, file, line, size);
578 #endif /* DEBUG */
579
580 if (!size) {
581 if (p)
582 free(p);
583
584 return NULL;
585 }
586
587 if (p) {
588 void *q = realloc(p, size);
589
590 if (q != NULL)
591 p = q;
592 else {
593 free(p);
594 p = NULL;
595 }
596 } else
597 p = malloc(size);
598
599 if (p == NULL) {
600 error_message(2, txt_out_of_memory, tin_progname, (unsigned long) size, file, line);
601 giveup();
602 }
603 return p;
604 }