bktrans.cc

00001 //
00002 // ktrans.cc - print human readable version of usbfs_snoop kernel log
00003 //
00004 
00005 /*
00006     Copyright (C) 2005-2012, Net Direct Inc. (http://www.netdirect.ca/)
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016 
00017     See the GNU General Public License in the COPYING file at the
00018     root directory of this project for more details.
00019 */
00020 
00021 #include <iostream>
00022 #include <iomanip>
00023 #include <sstream>
00024 #include <string>
00025 #include <string.h>
00026 #include <barry/data.h>
00027 #include "i18n.h"
00028 
00029 using namespace std;
00030 
00031 void Usage()
00032 {
00033         cout << "ktrans - usbfs_snoop kernel log translator\n"
00034                 "\n"
00035                 "\tUsage:   ktrans logmarker < log\n"
00036                 "\n"
00037                 "\tExample:  ktrans \"kernel: \" < /var/log/kern.log\n"
00038                 "\n";
00039 }
00040 
00041 bool IsHexData(const char *logmarker, const char *str)
00042 {
00043         str = strstr(str, logmarker);
00044         if( !str )
00045                 return false;
00046         str += strlen(logmarker);
00047 
00048         if( strstr(str, "data ") || strstr(str, "data: ") ) {
00049                 // looks like a data line, make sure data from there on out
00050                 // is hex data
00051 
00052                 // skip "data"
00053                 str = strstr(str, "data") + 4;
00054                 for( ; *str == ':' || *str == ' '; str++ )
00055                         ;
00056 
00057                 while( *str ) {
00058                         if( !( isdigit(*str) || *str == ' ' ||
00059                             (*str >= 'a' && *str <= 'f')) )
00060                                 return false;
00061                         str++;
00062                 }
00063 
00064                 return true;
00065         }
00066         else {
00067                 while( *str ) {
00068                         if( !( isdigit(*str) || *str == ' ' ||
00069                             (*str >= 'a' && *str <= 'f')) )
00070                                 return false;
00071                         str++;
00072                 }
00073                 return true;    // all data is numeric, so this is a continuation line
00074         }
00075 }
00076 
00077 void SplitHex(const char *logmarker, const char *str, Barry::Data &data)
00078 {
00079         const char *hexptr = strstr(str, logmarker);
00080         if( !hexptr ) {
00081                 cout << str << endl;
00082                 return;
00083         }
00084         hexptr += strlen(logmarker);
00085         std::string readable(str, hexptr - str);
00086 
00087         str = hexptr;
00088 
00089         hexptr = strstr(str, "data ");
00090         if( hexptr ) {
00091                 hexptr += 5;
00092         }
00093         else {
00094                 hexptr = strstr(str, "data: ");
00095                 if( hexptr )
00096                         hexptr += 6;
00097         }
00098 
00099         if( !hexptr )
00100                 hexptr = str;
00101 
00102         for( ; *hexptr == ':' || *hexptr == ' '; hexptr++ )
00103                 ;
00104 
00105         readable.append(str, hexptr - str);
00106         cout << readable << endl;
00107 
00108         data.AppendHexString(hexptr);
00109 }
00110 
00111 int main(int argc, char *argv[])
00112 {
00113         INIT_I18N(PACKAGE);
00114 
00115         cout.sync_with_stdio(false);
00116 
00117         if( argc < 2 ) {
00118                 Usage();
00119                 return 0;
00120         }
00121 
00122         Barry::Data data;
00123         while( cin ) {
00124                 std::string buff;
00125                 getline(cin, buff);
00126                 if( IsHexData(argv[1], buff.c_str()) ) {
00127                         SplitHex(argv[1], buff.c_str(), data);
00128                 }
00129                 else {
00130                         if( data.GetSize() ) {
00131                                 cout << data;
00132                                 data.Zap();
00133                         }
00134                         cout << buff << "\n";
00135                 }
00136         }
00137 
00138         if( data.GetSize() ) {
00139                 cout << data;
00140         }
00141 }
00142