"Fossies" - the Fresh Open Source Software Archive

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