ccnr_msg.c

Go to the documentation of this file.
00001 /**
00002  * @file ccnr_msg.c
00003  *
00004  * Logging support for ccnr.
00005  * 
00006  * Part of ccnr -  CCNx Repository Daemon.
00007  *
00008  */
00009 
00010 /*
00011  * Copyright (C) 2008, 2009, 2011 Palo Alto Research Center, Inc.
00012  *
00013  * This work is free software; you can redistribute it and/or modify it under
00014  * the terms of the GNU General Public License version 2 as published by the
00015  * Free Software Foundation.
00016  * This work is distributed in the hope that it will be useful, but WITHOUT ANY
00017  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00019  * for more details. You should have received a copy of the GNU General Public
00020  * License along with this program; if not, write to the
00021  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00022  * Boston, MA 02110-1301, USA.
00023  */
00024  
00025 #include <stdio.h>
00026 #include <sys/time.h>
00027 #include <stdarg.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <strings.h>
00031 #include <time.h>
00032 #include <unistd.h>
00033 
00034 #include <ccn/ccn.h>
00035 #include <ccn/charbuf.h>
00036 #include <ccn/uri.h>
00037 
00038 #include "ccnr_private.h"
00039 
00040 #include "ccnr_msg.h"
00041 
00042 /*
00043  * Translate a symbolic debug level into a numeric code.
00044  * Also accepts valid decimal values.
00045  * @returns CCNL_ code, or 1 to use built-in default, or -1 for error. 
00046  */
00047 int
00048 ccnr_msg_level_from_string(const char *s)
00049 {
00050     long v;
00051     char *ep;
00052     
00053     if (s == NULL || s[0] == 0)
00054         return(1);
00055     if (0 == strcasecmp(s, "NONE"))
00056         return(CCNL_NONE);
00057     if (0 == strcasecmp(s, "SEVERE"))
00058         return(CCNL_SEVERE);
00059     if (0 == strcasecmp(s, "ERROR"))
00060         return(CCNL_ERROR);
00061     if (0 == strcasecmp(s, "WARNING"))
00062         return(CCNL_WARNING);
00063     if (0 == strcasecmp(s, "INFO"))
00064         return(CCNL_INFO);
00065     if (0 == strcasecmp(s, "FINE"))
00066         return(CCNL_FINE);
00067     if (0 == strcasecmp(s, "FINER"))
00068         return(CCNL_FINER);
00069     if (0 == strcasecmp(s, "FINEST"))
00070         return(CCNL_FINEST);
00071     v = strtol(s, &ep, 10);
00072     if (v > CCNL_FINEST || v < 0 || ep[0] != 0)
00073         return(-1);
00074     return(v);
00075 }
00076 
00077 /**
00078  *  Produce ccnr debug output.
00079  *  Output is produced via h->logger under the control of h->debug;
00080  *  prepends decimal timestamp and process identification.
00081  *  Caller should not supply newlines.
00082  *  @param      h  the ccnr handle
00083  *  @param      fmt  printf-like format string
00084  */
00085 void
00086 ccnr_msg(struct ccnr_handle *h, const char *fmt, ...)
00087 {
00088     struct timeval t;
00089     va_list ap;
00090     struct ccn_charbuf *b;
00091     int res;
00092     if (h == NULL || h->debug == 0 || h->logger == 0)
00093         return;
00094     b = ccn_charbuf_create();
00095     if (b == NULL)
00096         return;
00097     gettimeofday(&t, NULL);
00098     if ((h->debug >= CCNL_FINE) &&
00099         ((h->logbreak-- < 0 && t.tv_sec != h->logtime) ||
00100           t.tv_sec >= h->logtime + 30)) {
00101         ccn_charbuf_putf(b, "%ld.000000 ccnr[%d]: %s ____________________ %s",
00102                          (long)t.tv_sec, h->logpid, h->portstr ? h->portstr : "", ctime(&t.tv_sec));
00103         h->logtime = t.tv_sec;
00104         h->logbreak = 30;
00105     }
00106     ccn_charbuf_putf(b, "%ld.%06u ccnr[%d]: %s\n",
00107         (long)t.tv_sec, (unsigned)t.tv_usec, h->logpid, fmt);
00108     va_start(ap, fmt);
00109     /* b should already have null termination, but use call for cleanliness */
00110     res = (*h->logger)(h->loggerdata, ccn_charbuf_as_string(b), ap);
00111     va_end(ap);
00112     ccn_charbuf_destroy(&b);
00113     /* if there's no one to hear, don't make a sound */
00114     if (res < 0)
00115         h->debug = 0;
00116 }
00117 
00118 /**
00119  *  Produce a ccnr debug trace entry.
00120  *  Output is produced by calling ccnr_msg.
00121  *  @param      h  the ccnr handle
00122  *  @param      lineno  caller's source line number (usually __LINE__)
00123  *  @param      msg  a short text tag to identify the entry
00124  *  @param      fdholder    handle of associated fdholder; may be NULL
00125  *  @param      ccnb    points to ccnb-encoded Interest or ContentObject
00126  *  @param      ccnb_size   is in bytes
00127  */
00128 void
00129 ccnr_debug_ccnb(struct ccnr_handle *h,
00130                 int lineno,
00131                 const char *msg,
00132                 struct fdholder *fdholder,
00133                 const unsigned char *ccnb,
00134                 size_t ccnb_size)
00135 {
00136     struct ccn_charbuf *c;
00137     struct ccn_parsed_interest pi;
00138     const unsigned char *nonce = NULL;
00139     size_t nonce_size = 0;
00140     size_t i;
00141     
00142     
00143     if (h != NULL && h->debug == 0)
00144         return;
00145     c = ccn_charbuf_create();
00146     ccn_charbuf_putf(c, "debug.%d %s ", lineno, msg);
00147     if (fdholder != NULL)
00148         ccn_charbuf_putf(c, "%u ", fdholder->filedesc);
00149     ccn_uri_append(c, ccnb, ccnb_size, 1);
00150     ccn_charbuf_putf(c, " (%u bytes)", (unsigned)ccnb_size);
00151     if (ccn_parse_interest(ccnb, ccnb_size, &pi, NULL) >= 0) {
00152         const char *p = "";
00153         ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb,
00154                   pi.offset[CCN_PI_B_Nonce],
00155                   pi.offset[CCN_PI_E_Nonce],
00156                   &nonce,
00157                   &nonce_size);
00158         if (nonce_size > 0) {
00159             ccn_charbuf_putf(c, " ");
00160             if (nonce_size == 12)
00161                 p = "CCC-P-F-T-NN";
00162             for (i = 0; i < nonce_size; i++)
00163                 ccn_charbuf_putf(c, "%s%02X", (*p) && (*p++)=='-' ? "-" : "", nonce[i]);
00164         }
00165     }
00166     ccnr_msg(h, "%s", ccn_charbuf_as_string(c));
00167     ccn_charbuf_destroy(&c);
00168 }
00169 
Generated on Tue Aug 21 14:54:15 2012 for Content-Centric Networking in C by  doxygen 1.6.3