"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.1/src/memory.c" (12 Oct 2016, 13786 Bytes) of archive /linux/misc/tin-2.4.1.tar.gz:


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