"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.5/src/debug.c" (1 Dec 2020, 12703 Bytes) of package /linux/misc/tin-2.4.5.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 "debug.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.4.4_vs_2.4.5.

    1 /*
    2  *  Project   : tin - a Usenet reader
    3  *  Module    : debug.c
    4  *  Author    : I. Lea
    5  *  Created   : 1991-04-01
    6  *  Updated   : 2020-05-19
    7  *  Notes     : debug routines
    8  *
    9  * Copyright (c) 1991-2021 Iain Lea <iain@bricbrac.de>
   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 #ifdef DEBUG
   46 #   ifndef NEWSRC_H
   47 #       include "newsrc.h"
   48 #   endif /* !NEWSRC_H */
   49 #endif /* DEBUG */
   50 
   51 unsigned short debug;
   52 
   53 #ifdef DEBUG
   54 /*
   55  * Local prototypes
   56  */
   57 static void debug_print_attributes(struct t_attribute *attr, FILE *fp);
   58 static void debug_print_filter(FILE *fp, int num, struct t_filter *the_filter);
   59 static void debug_print_newsrc(struct t_newsrc *lnewsrc, FILE *fp);
   60 
   61 
   62 /*
   63  * remove debug files
   64  */
   65 void
   66 debug_delete_files(
   67     void)
   68 {
   69     char file[PATH_LEN];
   70 
   71     if (debug & (DEBUG_NNTP | DEBUG_REMOVE)) {
   72         joinpath(file, sizeof(file), TMPDIR, "NNTP");
   73         unlink(file);
   74     }
   75 
   76     if (debug & (DEBUG_FILTER | DEBUG_REMOVE)) {
   77         joinpath(file, sizeof(file), TMPDIR, "ARTS");
   78         unlink(file);
   79         joinpath(file, sizeof(file), TMPDIR, "FILTER");
   80         unlink(file);
   81     }
   82 
   83     if (debug & (DEBUG_NEWSRC | DEBUG_REMOVE)) {
   84         joinpath(file, sizeof(file), TMPDIR, "BITMAP");
   85         unlink(file);
   86     }
   87 
   88     if (debug & (DEBUG_REFS | DEBUG_REMOVE)) {
   89         joinpath(file, sizeof(file), TMPDIR, "REFS.dump");
   90         unlink(file);
   91         joinpath(file, sizeof(file), TMPDIR, "REFS.info");
   92         unlink(file);
   93     }
   94 
   95     if (debug & (DEBUG_MEM | DEBUG_REMOVE)) {
   96         joinpath(file, sizeof(file), TMPDIR, "MALLOC");
   97         unlink(file);
   98     }
   99 
  100     if (debug & (DEBUG_ATTRIB | DEBUG_REMOVE)) {
  101         joinpath(file, sizeof(file), TMPDIR, "ATTRIBUTES");
  102         unlink(file);
  103         joinpath(file, sizeof(file), TMPDIR, "SCOPES-R");
  104         unlink(file);
  105         joinpath(file, sizeof(file), TMPDIR, "SCOPES-W");
  106         unlink(file);
  107     }
  108 
  109     if (debug & (DEBUG_MISC | DEBUG_REMOVE)) {
  110         joinpath(file, sizeof(file), TMPDIR, "ACTIVE");
  111         unlink(file);
  112         joinpath(file, sizeof(file), TMPDIR, "GNKSA");
  113         unlink(file);
  114     }
  115 }
  116 
  117 
  118 /*
  119  * tin specific debug routines
  120  */
  121 void
  122 debug_print_arts(
  123     void)
  124 {
  125     int i;
  126 
  127     for_each_art(i) /* fopen/close() horror */
  128         debug_print_header(&arts[i]);
  129 }
  130 
  131 
  132 void
  133 debug_print_header(
  134     struct t_article *s)
  135 {
  136     static char file[PATH_LEN] = { '\0' };
  137     FILE *fp;
  138 
  139     if (!(debug & DEBUG_FILTER))
  140         return;
  141 
  142     if (!*file)
  143         joinpath(file, sizeof(file), TMPDIR, "ARTS");
  144 
  145     if ((fp = fopen(file, "a")) != NULL) {
  146         fprintf(fp, "art=[%5"T_ARTNUM_PFMT"] tag=[%s] kill=[%s] selected=[%s]\n", s->artnum,
  147             bool_unparse(s->tagged),
  148             bool_unparse(s->killed),
  149             bool_unparse(s->selected));
  150         fprintf(fp, "subj=[%-38s]\n", s->subject);
  151         fprintf(fp, "date=[%ld]  from=[%s]  name=[%s]\n", (long) s->date, s->from,
  152             BlankIfNull(s->name));
  153         fprintf(fp, "msgid=[%s]  refs=[%s]\n",
  154             BlankIfNull(s->msgid),
  155             BlankIfNull(s->refs));
  156 
  157         if (s->killed)
  158             fprintf(fp, "score=[%d] gnksa=[%d] lines=[%d]\n", s->score, s->gnksa_code, s->line_count);
  159 
  160         if (s->archive) {
  161             fprintf(fp, "archive.name=[%-38s]  ", s->archive->name);
  162             if (s->archive->partnum)
  163                 fprintf(fp, "archive.partnum=[%s]  ", s->archive->partnum);
  164             if (s->archive->ispart)
  165                 fprintf(fp, "archive.ispart=[%s]\n", bool_unparse(s->archive->ispart));
  166         }
  167         fprintf(fp, "thread=[%d]  prev=[%d]  status=[%u]\n\n", s->thread, s->prev, s->status);
  168         fflush(fp);
  169 #ifdef HAVE_FCHMOD
  170         fchmod(fileno(fp), (S_IRUGO|S_IWUGO));
  171 #else
  172 #   ifdef HAVE_CHMOD
  173         chmod(file, (S_IRUGO|S_IWUGO));
  174 #   endif /* HAVE_CHMOD */
  175 #endif /* HAVE_FCHMOD */
  176         fclose(fp);
  177     }
  178 }
  179 
  180 
  181 void
  182 debug_print_active(
  183     void)
  184 {
  185     static char file[PATH_LEN] = { '\0' };
  186     FILE *fp;
  187 
  188     if (!(debug & DEBUG_MISC))
  189         return;
  190 
  191     if (!*file)
  192         joinpath(file, sizeof(file), TMPDIR, "ACTIVE");
  193 
  194     if ((fp = fopen(file, "w")) != NULL) {
  195         int i;
  196         struct t_group *group;
  197 
  198         for_each_group(i) {
  199             group = &active[i];
  200             fprintf(fp, "[%4d]=[%s] type=[%s] spooldir=[%s]\n",
  201                 i, group->name,
  202                 (group->type == GROUP_TYPE_NEWS ? "NEWS" : "MAIL"),
  203                 group->spooldir);
  204             fprintf(fp, "count=[%4"T_ARTNUM_PFMT"] max=[%4"T_ARTNUM_PFMT"] min=[%4"T_ARTNUM_PFMT"] mod=[%c]\n",
  205                 group->count, group->xmax, group->xmin, group->moderated);
  206             fprintf(fp, " nxt=[%4d] hash=[%lu]  description=[%s]\n", group->next,
  207                 hash_groupname(group->name), BlankIfNull(group->description));
  208             if (debug & DEBUG_NEWSRC)
  209                 debug_print_newsrc(&group->newsrc, fp);
  210             if (debug & DEBUG_ATTRIB)
  211                 debug_print_attributes(group->attribute, fp);
  212         }
  213 #ifdef HAVE_FCHMOD
  214         fchmod(fileno(fp), (S_IRUGO|S_IWUGO));
  215 #else
  216 #   ifdef HAVE_CHMOD
  217         chmod(file, (S_IRUGO|S_IWUGO));
  218 #   endif /* HAVE_CHMOD */
  219 #endif /* HAVE_FCHMOD */
  220         fclose(fp);
  221     }
  222 }
  223 
  224 
  225 static void
  226 debug_print_attributes(
  227     struct t_attribute *attr,
  228     FILE *fp)
  229 {
  230     if (attr == NULL)
  231         return;
  232 
  233     fprintf(fp, "global=[%u] show=[%u] thread=[%u] sort=[%u] author=[%u] auto_select=[%u] auto_save=[%u] batch_save=[%u] process=[%u]\n",
  234         attr->global,
  235         attr->show_only_unread_arts,
  236         attr->thread_articles,
  237         attr->sort_article_type,
  238         attr->show_author,
  239         attr->auto_select,
  240         attr->auto_save,
  241         attr->batch_save,
  242         attr->post_process_type);
  243     fprintf(fp, "select_header=[%u] select_global=[%s] select_expire=[%s]\n",
  244         attr->quick_select_header,
  245         BlankIfNull(attr->quick_select_scope),
  246         bool_unparse(attr->quick_select_expire));
  247     fprintf(fp, "kill_header  =[%u] kill_global  =[%s] kill_expire  =[%s]\n",
  248         attr->quick_kill_header,
  249         BlankIfNull(attr->quick_kill_scope),
  250         bool_unparse(attr->quick_kill_expire));
  251     fprintf(fp, "maildir=[%s] savedir=[%s] savefile=[%s]\n",
  252         BlankIfNull(attr->maildir),
  253         BlankIfNull(attr->savedir),
  254         BlankIfNull(attr->savefile));
  255     fprintf(fp, "sigfile=[%s] followup_to=[%s]\n\n",
  256         BlankIfNull(attr->sigfile),
  257         BlankIfNull(attr->followup_to));
  258     fflush(fp);
  259 }
  260 
  261 
  262 void
  263 debug_print_malloc(
  264     t_bool is_malloc,
  265     const char *xfile,
  266     int line,
  267     size_t size)
  268 {
  269     static char file[PATH_LEN] = { '\0' };
  270     static size_t total = 0;
  271     FILE *fp;
  272 
  273     if (!*file)
  274         joinpath(file, sizeof(file), TMPDIR, "MALLOC");
  275 
  276     if ((fp = fopen(file, "a")) != NULL) {
  277         total += size;
  278         /* sometimes size_t is long */
  279         fprintf(fp, "%12s:%-4d %s(%6lu). Total %lu\n", xfile, line, is_malloc ? " malloc" : "realloc", (unsigned long) size, (unsigned long) total);
  280 #ifdef HAVE_FCHMOD
  281         fchmod(fileno(fp), (S_IRUGO|S_IWUGO));
  282 #else
  283 #   ifdef HAVE_CHMOD
  284         chmod(file, (S_IRUGO|S_IWUGO));
  285 #   endif /* HAVE_CHMOD */
  286 #endif /* HAVE_FCHMOD */
  287         fclose(fp);
  288     }
  289 }
  290 
  291 
  292 static void
  293 debug_print_filter(
  294     FILE *fp,
  295     int num,
  296     struct t_filter *the_filter)
  297 {
  298     static const char sign[] = { ' ', '=', '<', '>', '\0' };
  299 
  300     fprintf(fp, "[%3d]  group=[%s]\n       inscope=[%s] score=[%d] case=[%s]\n",
  301         num, BlankIfNull(the_filter->scope),
  302         (the_filter->inscope ? "TRUE" : "FILTER"),
  303         the_filter->score,
  304         the_filter->icase ? "C" : "I");
  305 
  306     if (the_filter->subj)
  307         fprintf(fp, "       subj=[%s]\n", the_filter->subj);
  308     if (the_filter->from)
  309         fprintf(fp, "       from=[%s]\n", the_filter->from);
  310     if (the_filter->msgid)
  311         fprintf(fp, "       msgid=[%s]\n", the_filter->msgid);
  312     if (the_filter->xref)
  313         fprintf(fp, "       xref=[%s]\n", the_filter->xref);
  314     if (the_filter->path)
  315         fprintf(fp, "       path=[%s]\n", the_filter->path);
  316 
  317     fprintf(fp, "       lines=[%c%d] gnksa=[%c%d]\n",
  318         sign[(int) the_filter->lines_cmp], the_filter->lines_num,
  319         sign[(int) the_filter->gnksa_cmp], the_filter->gnksa_num);
  320 
  321     if (the_filter->time)
  322         fprintf(fp, "       time=[%ld][%s]\n", (long) the_filter->time, BlankIfNull(str_trim(ctime(&the_filter->time))));
  323 }
  324 
  325 
  326 void
  327 debug_print_filters(
  328     void)
  329 {
  330     int i, num;
  331     static char file[PATH_LEN] = { '\0' };
  332     struct t_filter *the_filter;
  333     FILE *fp;
  334 
  335     if (!*file)
  336         joinpath(file, sizeof(file), TMPDIR, "FILTER");
  337 
  338     if ((fp = fopen(file, "w")) != NULL) {
  339         /*
  340          * print global filter
  341          */
  342         num = glob_filter.num;
  343         the_filter = glob_filter.filter;
  344         fprintf(fp, "*** BEG GLOBAL FILTER=[%3d] ***\n", num);
  345         for (i = 0; i < num; i++) {
  346             debug_print_filter(fp, i, &the_filter[i]);
  347             fprintf(fp, "\n");
  348         }
  349         fprintf(fp, "*** END GLOBAL FILTER ***\n");
  350 
  351 #ifdef HAVE_FCHMOD
  352         fchmod(fileno(fp), (S_IRUGO|S_IWUGO));
  353 #else
  354 #   ifdef HAVE_CHMOD
  355         chmod(file, (S_IRUGO|S_IWUGO));
  356 #   endif /* HAVE_CHMOD */
  357 #endif /* HAVE_FCHMOD */
  358         fclose(fp);
  359     }
  360 }
  361 
  362 
  363 void
  364 debug_print_file(
  365     const char *fname,
  366     const char *fmt,
  367     ...)
  368 {
  369     FILE *fp;
  370     char *buf;
  371     char file[PATH_LEN];
  372     va_list ap;
  373 
  374     if (!debug)
  375         return;
  376 
  377     va_start(ap, fmt);
  378     buf = fmt_message(fmt, ap);
  379     va_end(ap);
  380 
  381     joinpath(file, sizeof(file), TMPDIR, fname);
  382 
  383     if ((fp = fopen(file, "a")) != NULL) {
  384         fprintf(fp, "%s\n", buf);
  385 #ifdef HAVE_FCHMOD
  386         fchmod(fileno(fp), (S_IRUGO|S_IWUGO));
  387 #else
  388 #   ifdef HAVE_CHMOD
  389         chmod(file, (S_IRUGO|S_IWUGO));
  390 #   endif /* HAVE_CHMOD */
  391 #endif /* HAVE_FCHMOD */
  392         fclose(fp);
  393     }
  394     free(buf);
  395 }
  396 
  397 
  398 void
  399 debug_print_comment(
  400     const char *comment)
  401 {
  402     if (!(debug & DEBUG_NEWSRC))
  403         return;
  404 
  405     debug_print_file("BITMAP", comment);
  406 }
  407 
  408 
  409 void
  410 debug_print_bitmap(
  411     struct t_group *group,
  412     struct t_article *art)
  413 {
  414     FILE *fp;
  415     char file[PATH_LEN];
  416 
  417     if (!(debug & DEBUG_NEWSRC))
  418         return;
  419 
  420     joinpath(file, sizeof(file), TMPDIR, "BITMAP");
  421     if (group != NULL) {
  422         if ((fp = fopen(file, "a")) != NULL) {
  423             fprintf(fp, "\nActive: Group=[%s] sub=[%c] min=[%"T_ARTNUM_PFMT"] max=[%"T_ARTNUM_PFMT"] count=[%"T_ARTNUM_PFMT"] num_unread=[%"T_ARTNUM_PFMT"]\n",
  424                 group->name, SUB_CHAR(group->subscribed),
  425                 group->xmin, group->xmax, group->count,
  426                 group->newsrc.num_unread);
  427             if (art != NULL) {
  428                 fprintf(fp, "art=[%5"T_ARTNUM_PFMT"] tag=[%s] kill=[%s] selected=[%s] subj=[%s]\n",
  429                     art->artnum,
  430                     bool_unparse(art->tagged),
  431                     bool_unparse(art->killed),
  432                     bool_unparse(art->selected),
  433                     art->subject);
  434                 fprintf(fp, "thread=[%d]  prev=[%d]  status=[%s]\n",
  435                     art->thread, art->prev,
  436                     (art->status == ART_READ ? "READ" : "UNREAD"));
  437             }
  438             debug_print_newsrc(&group->newsrc, fp);
  439 #ifdef HAVE_FCHMOD
  440             fchmod(fileno(fp), (S_IRUGO|S_IWUGO));
  441 #else
  442 #   ifdef HAVE_CHMOD
  443             chmod(file, (S_IRUGO|S_IWUGO));
  444 #   endif /* HAVE_CHMOD */
  445 #endif /* HAVE_FCHMOD */
  446             fclose(fp);
  447         }
  448     }
  449 }
  450 
  451 
  452 static void
  453 debug_print_newsrc(
  454     struct t_newsrc *lnewsrc,
  455     FILE *fp)
  456 {
  457     int j;
  458     t_artnum i;
  459 
  460     fprintf(fp, "Newsrc: min=[%"T_ARTNUM_PFMT"] max=[%"T_ARTNUM_PFMT"] bitlen=[%"T_ARTNUM_PFMT"] num_unread=[%"T_ARTNUM_PFMT"] present=[%d]\n",
  461         lnewsrc->xmin, lnewsrc->xmax, lnewsrc->xbitlen,
  462         lnewsrc->num_unread, (lnewsrc->present ? 1 : 0));
  463 
  464     fprintf(fp, "bitmap=[");
  465     if (lnewsrc->xbitlen && lnewsrc->xbitmap) {
  466         for (j = 0, i = lnewsrc->xmin; i <= lnewsrc->xmax; i++) {
  467             fprintf(fp, "%d",
  468                 (NTEST(lnewsrc->xbitmap, i - lnewsrc->xmin) == ART_READ ?
  469                 ART_READ : ART_UNREAD));
  470             if ((j++ % 8) == 7 && i < lnewsrc->xmax)
  471                 fprintf(fp, " ");
  472         }
  473     }
  474     fprintf(fp, "]\n");
  475     fflush(fp);
  476 }
  477 
  478 
  479 #   ifdef NNTP_ABLE
  480 const char *
  481 logtime(
  482     void)
  483 {
  484 #       if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_GETTIMEOFDAY)
  485     static struct t_tintime log_time;
  486     static char out[40];
  487 
  488     if (tin_gettime(&log_time) == 0) {
  489         if (my_strftime(out, 39, " [%H:%M:%S.", gmtime(&(log_time.tv_sec)))) {
  490             sprintf(out + 11, "%09ld", log_time.tv_nsec); /* strlen(" [hh:mm:ss.") */
  491             out[17] = '\0'; /* strlen(" [hh:mm:ss.uuuuuu") */
  492             strcat(out, "] ");
  493             return out;
  494         }
  495     }
  496 #       endif /* HAVE_CLOCK_GETTIME || HAVE_GETTIMEOFDAY */
  497     return " ";
  498 }
  499 #   endif /* NNTP_ABLE */
  500 #endif /* DEBUG */