Guest User

parser2

a guest
Jul 27th, 2011
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.55 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cctype>
  3. #include <ciso646>
  4. #include <ctime>
  5. #include <fstream>
  6. #include <functional>
  7. #include <iomanip>
  8. #include <iostream>
  9. #include <iterator>
  10. #include <sstream>
  11. #include <string>
  12. #include <vector>
  13. using namespace std;
  14.  
  15. //----------------------------------------------------------------------------
  16. string titlecase( const string& s )
  17.   {
  18.   string result( s );
  19.   if (result.length())
  20.     {
  21.     transform(
  22.       s.begin(),
  23.       s.end(),
  24.       result.begin(),
  25.       ptr_fun <int, int> ( tolower )
  26.       );
  27.     result[ 0 ] = toupper( s[ 0 ] );
  28.     }
  29.   return result;
  30.   }
  31.  
  32.  
  33. //----------------------------------------------------------------------------
  34. struct date_t
  35. //----------------------------------------------------------------------------
  36.   {
  37.   // (table driven data)
  38.   static const char* month_names_abbr[ 12 ];
  39.   static unsigned days_per_month[ 2 ][ 13 ];
  40.   static unsigned yday_per_month[ 2 ][ 13 ];
  41.  
  42.   unsigned year, month, day;  // 0..N, 1..12, 1..31
  43.  
  44.   // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  45.   date_t( unsigned year = 0, unsigned month = 0, unsigned day = 0 ):
  46.     year( year ), month( month ), day( day )
  47.     { }
  48.  
  49.   // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  50.   bool is_leap_year() const
  51.     {
  52.     return ((year % 400) == 0) or (((year % 4) == 0) and ((year % 100) != 0));
  53.     }
  54.  
  55.   // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  56.   unsigned day_of_year() const
  57.     {
  58.     return yday_per_month[ is_leap_year() ][ month - 1 ] + day;
  59.     }
  60.  
  61.   // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  62.   void day_of_year( unsigned d )
  63.     {
  64.     unsigned leap;
  65.  
  66.     // The following trick allows us to add days...
  67.     while (d > yday_per_month[ leap = is_leap_year() ][ 12 ])
  68.       {
  69.       d    -= yday_per_month[ leap ][ 12 ];
  70.       year += 1;
  71.       }
  72.  
  73.     if (d > yday_per_month[ leap ][ 12 ]) return;
  74.  
  75.     month = find_if(
  76.               yday_per_month[ leap ],
  77.               yday_per_month[ leap ] + 12,
  78.               bind2nd( greater_equal <unsigned> (), d )
  79.               )
  80.           - yday_per_month[ leap ];
  81.     day = d - yday_per_month[ leap ][ month - 1 ];
  82.     }
  83.  
  84.   // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  85.   bool valid() const
  86.     {
  87.     if ((year < 0) or (month < 1) or (month > 12) or (day < 1))
  88.       return false;
  89.     return day <= days_per_month[ is_leap_year() ][ month ];
  90.     }
  91.   };
  92.  
  93. //............................................................................
  94. const char* date_t::month_names_abbr[ 12 ] =
  95.   {
  96.   "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  97.   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  98.   };
  99.  
  100. unsigned date_t::days_per_month[ 2 ][ 13 ] =
  101.   {
  102.   { 0, 31, 28, 31,  30,  31,  30,  31,  31,  30,  31,  30,  31 },
  103.   { 0, 31, 29, 31,  30,  31,  30,  31,  31,  30,  31,  30,  31 }
  104.   };
  105.  
  106. unsigned date_t::yday_per_month[ 2 ][ 13 ] =
  107.   {
  108.   { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
  109.   { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
  110.   };
  111.  
  112. //............................................................................
  113. istream& operator >> ( istream& ins, date_t& date )
  114.   {
  115.   int    day, year;
  116.   string month;
  117.   ins >> day >> month >> year;
  118.   if (ins)
  119.     {
  120.     month = titlecase( month.substr( 0, 3 ) );
  121.     date.year  = year;
  122.     date.month = find(
  123.                    date_t::month_names_abbr,
  124.                    date_t::month_names_abbr + 12,
  125.                    month
  126.                    )
  127.                - date_t::month_names_abbr + 1;
  128.     date.day   = day;
  129.     if (!date.valid())
  130.       ins.setstate( ios::failbit );
  131.     }
  132.   return ins;
  133.   }
  134.  
  135. //............................................................................
  136. ostream& operator << ( ostream& outs, const date_t& date )
  137.   {
  138.   ostringstream ss;
  139.   ss << setw( 2 ) << date.day << " " << date_t::month_names_abbr[ date.month - 1 ] << " " << date.year;
  140.   if (!ss) outs.setstate( ss.rdstate() );
  141.   else     outs << ss.str();
  142.   return outs;
  143.   }
  144.  
  145. //............................................................................
  146. date_t& operator += ( date_t& date, unsigned days )
  147.   {
  148.   date.day_of_year( days + date.day_of_year() );
  149.   return date;
  150.   }
  151.  
  152. //............................................................................
  153. bool operator == ( const date_t& lhs, const date_t& rhs )
  154.   {
  155.   return (lhs.year == rhs.year) && (lhs.month == rhs.month) && (lhs.day == rhs.day);
  156.   }
  157.  
  158. //............................................................................
  159. bool operator < ( const date_t& lhs, const date_t& rhs )
  160.   {
  161.   return (lhs.year          != rhs.year)
  162.        ? (lhs.year          <  rhs.year)
  163.        : (lhs.day_of_year() <  rhs.day_of_year());
  164.   }
  165.  
  166. //............................................................................
  167. bool operator <= ( const date_t& lhs, const date_t& rhs )
  168.   {
  169.   return (lhs == rhs) or (lhs < rhs);
  170.   }
  171.  
  172. //............................................................................
  173. date_t now()
  174.   {
  175.   date_t    result;
  176.   time_t    t   =  time( NULL );
  177.   struct tm now = *gmtime( &t );
  178.  
  179.   result.year   = now.tm_year + 1900;
  180.   result.month  = now.tm_mon  + 1;
  181.   result.day    = now.tm_mday;
  182.  
  183.   return result;
  184.   }
  185.  
  186.  
  187. template <bool Verbose = false>
  188. //----------------------------------------------------------------------------
  189. struct certificate_t
  190. //----------------------------------------------------------------------------
  191.   {
  192.   string name;
  193.   string password_policy;
  194.   string type;
  195.   date_t renewal_start_date;
  196.   date_t private_key_expiry;
  197.   string DN;
  198.  
  199.   certificate_t() { }
  200.  
  201.   template <bool V>
  202.   certificate_t( const certificate_t <V> & certificate ):
  203.     name               ( certificate.name               ),
  204.     password_policy    ( certificate.password_policy    ),
  205.     type               ( certificate.type               ),
  206.     renewal_start_date ( certificate.renewal_start_date ),
  207.     private_key_expiry ( certificate.private_key_expiry ),
  208.     DN                 ( certificate.DN                 )
  209.     { }
  210.   };
  211.  
  212. //............................................................................
  213. template <bool Verbose>
  214. istream& operator >> ( istream& ins, certificate_t <Verbose> & certificate )
  215.   {
  216.   string s;
  217.  
  218.   // Get the next non-empty line
  219.   do getline( ins, s );
  220.   while (ins && s.empty());
  221.  
  222.   // Remove any trailing whitespace
  223.   s.erase( s.find_last_not_of( " \t\v\f\r\n" ) + 1 );
  224.  
  225.   istringstream ss( s );
  226.   ss >> s;
  227.   ss >> certificate.name
  228.      >> certificate.password_policy
  229.      >> certificate.type
  230.      >> certificate.renewal_start_date
  231.      >> certificate.private_key_expiry
  232.      >> ws;
  233.   getline( ss, certificate.DN );
  234.  
  235.   certificate.name = s + " " + certificate.name;
  236.  
  237.   if (ss.fail())
  238.     ins.setstate( ss.rdstate() );
  239.  
  240.   // Do some error checking here on password_policy, type, and DN //
  241.  
  242.   return ins;
  243.   }
  244.  
  245. //............................................................................
  246. template <bool Verbose>
  247. ostream& operator << ( ostream& outs, const certificate_t <Verbose> & certificate )
  248.   {
  249.   ostringstream ss;
  250.   ss << left;
  251.   if (Verbose)
  252.     ss << setw( 16 ) << certificate.name               << " "
  253.        << setw( 11 ) << certificate.password_policy    << " "
  254.        << setw( 12 ) << certificate.type               << " "
  255.        << setw( 15 ) << certificate.renewal_start_date << " "
  256.        << setw( 15 ) << certificate.private_key_expiry << " "
  257.        <<               certificate.DN;
  258.   else
  259.     ss << setw( 16 ) << certificate.name               << " "
  260.        << setw( 15 ) << certificate.renewal_start_date << " "
  261.        << setw( 15 ) << certificate.private_key_expiry;
  262.   if (!ss) outs.setstate( ss.rdstate() );
  263.   else     outs << ss.str();
  264.   return outs;
  265.   }
  266.  
  267.  
  268. //----------------------------------------------------------------------------
  269. struct expired
  270. //----------------------------------------------------------------------------
  271.   {
  272.   date_t when;
  273.  
  274.   explicit expired( const date_t& when ):
  275.     when( when )
  276.     { }
  277.  
  278.   template <bool Verbose>
  279.   bool operator () ( const certificate_t <Verbose> & certificate ) const
  280.     {
  281.     return not(    (certificate.renewal_start_date <= when)
  282.                 or (certificate.private_key_expiry <= when) );
  283.     }
  284.   };
  285.  
  286.  
  287. //----------------------------------------------------------------------------
  288. int usage( const char* arg0, int exitcode, const char* message = "" )
  289.   {
  290.   (exitcode ? cerr : cout) << message << (message ? "\n" : "") <<
  291.     "usage:\n"
  292.     "  " << arg0 << " --help\n"
  293.     "  " << arg0 << " /?\n"
  294.     "    Display this help.\n\n"
  295.  
  296.     "  " << arg0 << " [--verbose] DAYS FILENAME\n"
  297.     "  " << arg0 << " [/v]        DAYS FILENAME\n"
  298.     "    Search the file for certificates expiring in DAYS days or less.\n"
  299.     "    If the VERBOSE option (\"--verbose\" or \"/v\") is specified, then\n"
  300.     "    all data about the matching entry is displayed, otherwise only the\n"
  301.     "    entry name is displayed.\n"
  302.     "    DAYS must be a non-negative whole number.\n\n";
  303.   return exitcode;
  304.   }
  305.  
  306. //----------------------------------------------------------------------------
  307. int getdays( const char* days )
  308.   {
  309.   int result = -1;
  310.   istringstream ss( days );
  311.   ss >> result;
  312.   return result;
  313.   }
  314.  
  315. //----------------------------------------------------------------------------
  316. bool ishelp( const string& arg1 )
  317.   {
  318.   return (arg1 == "--help") or (arg1 == "/?");
  319.   }
  320.  
  321. //----------------------------------------------------------------------------
  322. bool isverbose( const string& arg1 )
  323.   {
  324.   return (arg1 == "--verbose") or (arg1 == "/v");
  325.   }
  326.  
  327. //----------------------------------------------------------------------------
  328. int main( int argc, char** argv )
  329.   {
  330.   // Parse command arguments .................................................
  331.   if ((argc == 1) or ishelp( argv[ 1 ] ))
  332.     return usage( argv[ 0 ], 0 );
  333.  
  334.   bool verbose = isverbose( argv[ 1 ] );
  335.   if (argc != (verbose ? 4 : 3))
  336.     return usage( argv[ 0 ], 1, "Incorrect arguments" );
  337.  
  338.   int days = getdays( argv[ verbose ? 2 : 1 ] );
  339.   if (days < 0)
  340.     return usage( argv[ 0 ], 1, "Invalid DAYS" );
  341.  
  342.   ifstream f( argv[ verbose ? 3 : 2 ] );
  343.   if (!f)
  344.     return usage( argv[ 0 ], 1, "Invalid FILENAME" );
  345.  
  346.   date_t today = now();
  347.   date_t tomorrow = today; tomorrow += days;
  348.  
  349.   // Skip the non-data lines .................................................
  350.   // (up to and including the first line starting with a "-")
  351.   vector <certificate_t <> > certificates;
  352.  
  353.   {
  354.     string s;
  355.     do { getline( f, s ); }
  356.     while (s.substr( 0, 1 ) != "-");
  357.  
  358.   copy(
  359.     istream_iterator <certificate_t <> > ( f ),
  360.     istream_iterator <certificate_t <> > (),
  361.     back_inserter( certificates )
  362.     );
  363. }
  364.   cout << "There are " << certificates.size() << " certificates.\n\n";
  365.  
  366.   // Find and display all items past due .....................................
  367.   // (Expired items are moved to the END of the vector)
  368.   vector <certificate_t <> > ::iterator
  369.   certificates_past_due_begin
  370.     = stable_partition(
  371.         certificates.begin(),
  372.         certificates.end(),
  373.         expired( today )
  374.         );
  375.   if (certificates_past_due_begin != certificates.end())
  376.     {
  377.     cout << "Items PAST DUE\n  ";
  378.     if (verbose)
  379.       copy(
  380.         certificates_past_due_begin,
  381.         certificates.end(),
  382.         ostream_iterator <certificate_t <true> > ( cout, "\n  " )
  383.         );
  384.     else
  385.       copy(
  386.         certificates_past_due_begin,
  387.         certificates.end(),
  388.         ostream_iterator <certificate_t <false> > ( cout, "\n  " )
  389.         );
  390.     certificates.erase( certificates_past_due_begin, certificates.end() );
  391.     }
  392.   else
  393.     cout << "No items past due\n";
  394.  
  395.   // Find and display all items due "tomorrow" (today + DAYS) ................
  396.   // (Erase all items not soon to expire)
  397.   certificates.erase(
  398.     remove_if(
  399.       certificates.begin(),
  400.       certificates.end(),
  401.       expired( tomorrow )
  402.       ),
  403.     certificates.end()
  404.     );
  405.   if (certificates.size())
  406.     {
  407.     cout << "\nItems due to expire in " << days << " DAYS\n  ";
  408.     if (verbose)
  409.       copy(
  410.         certificates.begin(),
  411.         certificates.end(),
  412.         ostream_iterator <certificate_t <true> > ( cout, "\n  " )
  413.         );
  414.     else
  415.       copy(
  416.         certificates.begin(),
  417.         certificates.end(),
  418.         ostream_iterator <certificate_t <false> > ( cout, "\n  " )
  419.         );
  420.     }
  421.   else
  422.     cout << "\nNo items due to expire in " << days << " days\n";
  423.  
  424.   return 0;
  425. }
Advertisement
Add Comment
Please, Sign In to add comment