"Fossies" - the Fresh Open Source Software Archive

Member "tcpflow-1.6.1/src/util.cpp" (19 Feb 2021, 5942 Bytes) of package /linux/misc/tcpflow-1.6.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 "util.cpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.4.5_vs_1.5.0.

    1 /*
    2  * This file is part of tcpflow.
    3  * Originally by Jeremy Elson <jelson@circlemud.org>
    4  * Now maintained by Simson L. Garfinkel <simsong@acm.org>
    5  *
    6  * This source code is under the GNU Public License (GPL).
    7  * See LICENSE for details.
    8  *
    9  */
   10 
   11 #include "tcpflow.h"
   12 
   13 #include <iomanip>
   14 
   15 static char *debug_prefix = NULL;
   16 
   17 /*
   18  * STD String sprintf wrapper for sane CPP formatting
   19  */
   20 std::string ssprintf(const char *fmt,...)
   21 {
   22     char buf[65536];
   23     va_list ap;
   24     va_start(ap,fmt);
   25     vsnprintf(buf,sizeof(buf),fmt,ap);
   26     va_end(ap);
   27     return std::string(buf);
   28 }
   29 
   30 /*
   31  * Insert readability commas into an integer without writing a custom locale facet
   32  */
   33 std::string comma_number_string(int64_t input)
   34 {
   35     std::vector<int16_t> tokens;
   36     std::stringstream ss;
   37     ss << std::setfill('0');
   38     int sign = 1;
   39 
   40     if(input < 0) {
   41         sign = -1;
   42         input *= -1;
   43     }
   44 
   45     while(input >= 1000) {
   46         tokens.push_back(input % 1000);
   47         input /= 1000;
   48     }
   49 
   50     ss << (input * sign);
   51 
   52     for(std::vector<int16_t>::const_reverse_iterator it = tokens.rbegin();
   53             it != tokens.rend(); it++) {
   54         ss << "," << std::setw(3) << *it;
   55     }
   56 
   57     return ss.str();
   58 }
   59 
   60 
   61 std::string macaddr(const uint8_t *addr)
   62 {
   63     char buf[256];
   64     snprintf(buf,sizeof(buf),"%02x:%02x:%02x:%02x:%02x:%02x",
   65              addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]);
   66     return std::string(buf);
   67 }
   68 
   69 /*
   70  * Remember our program name and process ID so we can use them later
   71  * for printing debug messages
   72  *
   73  */
   74 void init_debug(const char *pfx,int include_pid)
   75 {
   76     if(debug_prefix) free(debug_prefix);
   77     size_t debug_prefix_size = strlen(pfx) + 16;
   78     debug_prefix = (char *)calloc(sizeof(char), debug_prefix_size);
   79     if(debug_prefix==0) die("malloc failed");
   80     if(include_pid){
   81         snprintf(debug_prefix, debug_prefix_size, "%s[%d]", pfx, (int) getpid());
   82     } else {
   83         snprintf(debug_prefix, debug_prefix_size, "%s", pfx);
   84     }
   85 }
   86 
   87 
   88 /****************************************************************/
   89 /* C++ string splitting code from http://stackoverflow.com/questions/236129/how-to-split-a-string-in-c */
   90 #if 0
   91 static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems)
   92 {
   93     std::stringstream ss(s);
   94     std::string item;
   95     while(std::getline(ss, item, delim)) {
   96         elems.push_back(item);
   97     }
   98     return elems;
   99 }
  100 
  101 static std::vector<std::string> split(const std::string &s, char delim)
  102 {
  103     std::vector<std::string> elems;
  104     return split(s, delim, elems);
  105 }
  106 #endif
  107 
  108 
  109 /* mkdir all of the containing directories in path.
  110  * keep track of those made so we don't need to keep remaking them.
  111  */
  112 void mkdirs_for_path(std::string path)
  113 {
  114     static std::set<std::string> made_dirs; // track what we made
  115 
  116     std::string mpath;                  // the path we are making
  117 
  118     if(path.at(0)=='/'){
  119         mpath = "/";
  120         path = path.substr(1);
  121     }
  122 
  123     std::vector<std::string> parts = split(path,'/');
  124 
  125     /* Notice that this won't mkdir for the last part.
  126      * That's okay, because it's a filename.
  127      */
  128     for(std::vector<std::string>::const_iterator it=parts.begin();it!=parts.end();it++){
  129         if(made_dirs.find(mpath)==made_dirs.end()){
  130             if(mpath.size()){
  131                 int r = MKDIR(mpath.c_str(),0777);
  132                 if(r<0){
  133                     /* Can't make path; see if we can execute it*/
  134                     if(access(mpath.c_str(),X_OK)<0){
  135                         perror(mpath.c_str());
  136                         exit(1);
  137                     }
  138                 }
  139                 made_dirs.insert(mpath);
  140             }
  141         }
  142         if(mpath.size()>0) mpath += "/";
  143         mpath += *it;
  144     }
  145 }
  146 
  147 /*
  148  * Print a debugging message, given a va_list
  149  */
  150 void print_debug_message(const char *fmt, va_list ap)
  151 {
  152     /* print debug prefix */
  153     fprintf(stderr, "%s: ", debug_prefix);
  154 
  155     /* print the var-arg buffer passed to us */
  156     vfprintf(stderr, fmt, ap);
  157 
  158     /* add newline */
  159     fprintf(stderr, "\n");
  160     (void) fflush(stderr);
  161 }
  162 
  163 /* Print a debugging or informational message */
  164 void debug_real(const char *fmt, ...)
  165 {
  166     va_list ap;
  167 
  168     va_start(ap, fmt);
  169     print_debug_message(fmt, ap);
  170     va_end(ap);
  171 }
  172   
  173 
  174 /* Print a debugging or informatioal message, then exit  */
  175 [[noreturn]] void die(const char *fmt, ...)
  176 {
  177     va_list ap;
  178 
  179     va_start(ap, fmt);
  180     print_debug_message(fmt, ap);
  181     exit(1);
  182 }
  183 
  184 /* An attempt at making signal() portable.
  185  *
  186  * If we detect sigaction, use that;
  187  * otherwise if we have setsig, use that;
  188  * otherwise, cross our fingers and hope for the best using plain old signal().
  189  *
  190  * Our first choice is sigaction (sigaction() is POSIX; signal() is
  191  * not.)  Taken from Stevens' _Advanced Programming in the UNIX Environment_.
  192  *
  193  * 10/6/08 - slg - removed RETSIGTYPE, since it hasn't been needed to 15 years
  194  */
  195 void (*portable_signal(int signo, void (*func)(int)))(int)
  196 {
  197 #if defined(HAVE_SIGACTION)
  198     struct sigaction act, oact;
  199 
  200     memset(&act, 0, sizeof(act));
  201     memset(&oact, 0, sizeof(oact));
  202     act.sa_handler = func;
  203     sigemptyset(&act.sa_mask);
  204     act.sa_flags = 0;
  205     if (sigaction(signo, &act, &oact) < 0) return (SIG_ERR);
  206     return (oact.sa_handler);
  207 #elif defined(HAVE_SIGSET)
  208     return sigset(signo, func);
  209 #else
  210     return signal(signo, func);
  211 #endif /* HAVE_SIGACTION, HAVE_SIGSET */
  212 }
  213 
  214 
  215 /************
  216  *** MMAP ***
  217  ************/
  218 
  219 #ifdef HAVE_SYS_MMAN_H
  220 #include <sys/mman.h>
  221 #endif
  222 
  223 /**
  224  * fake implementation of mmap and munmap if we don't have them
  225  */
  226 #if !defined(HAVE_MMAP)
  227 #define PROT_READ 0
  228 #define MAP_FILE 0
  229 #define MAP_SHARED 0
  230 void *mmap(void *addr,size_t length,int prot, int flags, int fd, off_t offset)
  231 {
  232     void *buf = (void *)malloc(length);
  233     if(!buf) return 0;
  234     read(fd,buf,length);            // should explore return code
  235     return buf;
  236 }
  237 
  238 void munmap(void *buf,size_t size)
  239 {
  240     free(buf);
  241 }
  242 
  243 #endif
  244