"Fossies" - the Fresh Open Source Software Archive

Member "dbtool-1.9.1/engine.cc" (15 May 2015, 13538 Bytes) of package /linux/privat/dbtool-1.9.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 "engine.cc" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.9_vs_1.9.1.

    1 /*
    2  * 'dbtool' is a simple but powerful  commandline interface to the
    3  * GNU gdbm system (or, alternatively the Berkeley DB), useful for
    4  * shellscripts which needs a database for data storage.
    5  */
    6 
    7 /*
    8  *
    9  *  This file  is part of the DBTOOL program.
   10  *
   11  *  By  accessing  this software,  DBTOOL, you  are  duly informed
   12  *  of and agree to be  bound  by the  conditions  described below
   13  *  in this notice:
   14  *
   15  *  This software product,  DBTOOL,  is developed by T.v. Dein
   16  *  and  copyrighted  (C)  2001-2015  by  T.v. Dein,  with all
   17  *  rights reserved.
   18  *
   19  *  There  is no charge for DBTOOL software.  You can redistribute
   20  *  it and/or modify it under the terms of the GNU  General Public
   21  *  License, which is incorporated by reference herein.
   22  *
   23  *  DBTOOL is distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS,
   24  *  OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE or that
   25  *  the use of it will not infringe on any third party's intellec-
   26  *  tual property rights.
   27  *
   28  *  You  should  have received a copy of the  GNU  General  Public
   29  *  License  along with DBTOOL.  Copies can also be obtained from:
   30  *
   31  *    http://www.gnu.org/licenses/gpl.txt
   32  *
   33  *  or by writing to:
   34  *
   35  *  Free Software Foundation, Inc.
   36  *  59 Temple Place, Suite 330
   37  *  Boston, MA 02111-1307
   38  *  USA
   39  *
   40  *  Or contact:
   41  *
   42  *   "T.v. Dein" <tlinden@cpan.org>
   43  *
   44  *
   45  */
   46 
   47 
   48 
   49 
   50 #include "dbtool.h"
   51 #include "engine.h"
   52 #include "platform.h"
   53 /*
   54  * Initialize the database and get a new Db instance pointer
   55  */
   56 void Engine::init() {
   57   pkg = PACKAGE;
   58   int mode;
   59 #ifdef HAVE_BERKELEY
   60   int err;
   61 #endif
   62   if(config.filename == "") {
   63     cerr << pkg << ": no database file specified!" << endl;
   64     exit(1);
   65   }
   66 #ifdef HAVE_BERKELEY
   67   db = new Db(NULL,0);
   68   db->set_error_stream(&cerr);
   69   db->set_errpfx(pkg.c_str());
   70   if(config.readonly == 1)
   71     mode = DB_RDONLY;
   72   else
   73     mode = DB_CREATE;
   74 #else
   75   if(config.readonly == 1)
   76     mode = GDBM_READER;
   77   else
   78     mode = GDBM_WRCREAT;
   79 #endif
   80 
   81 
   82   if(config.force == 1) {
   83 #ifdef HAVE_BERKELEY
   84     if ((err = db->open(NULL, config.filename.c_str(), NULL, DB_HASH, mode, FILEMODE)) != 0) {
   85       cerr << "Failed to open " + config.filename << "(" << strerror(err) << ")" << endl;
   86       exit(1);
   87     }
   88 #else 
   89 
   90     db = gdbm_open(
   91            (char *)config.filename.c_str(),
   92            BLOCKSIZE,
   93            mode,
   94            FILEMODE,
   95            0
   96            );
   97 #endif
   98   }
   99   else {
  100 #ifdef HAVE_BERKELEY
  101     if ((err = db->open(NULL, config.filename.c_str(), NULL, DB_HASH, mode, FILEMODE)) != 0) {
  102       cerr << "Failed to open " + config.filename << "(" << strerror(err) << ")" << endl;
  103       exit(1);
  104     }
  105 #else
  106     db = gdbm_open(
  107            (char *)config.filename.c_str(),
  108            BLOCKSIZE,
  109            mode,
  110            FILEMODE,
  111            0
  112            );
  113 #endif
  114   }
  115 #ifndef HAVE_BERKELEY
  116   if(!db) {
  117     cerr << pkg << ": " << gdbm_strerror(gdbm_errno) << endl;
  118     exit(1);
  119   }
  120 #endif
  121 
  122   /*
  123    * ok, at this point everything is ok, usage is correct,
  124    * database is open, now check the passphrase, if encrypted
  125    * database requested.
  126    */
  127   if(config.encrypted) {
  128     if(config.phrase == "") {
  129       config.phrase = readpass();
  130     }
  131     rijn.init(config.phrase); /* this might fail */
  132     config.phrase = "                                                                       ";
  133   }
  134 }
  135 
  136 
  137 /*
  138  * dump out all data in db
  139  */
  140 void Engine::dump() {
  141   init();
  142 #ifdef HAVE_BERKELEY
  143   try {
  144     Dbc *dbcp;
  145     db->cursor(NULL, &dbcp, 0);
  146     Dbt key;
  147     Dbt data;
  148     while (dbcp->get(&key, &data, DB_NEXT) == 0) {
  149       /* iterate over every tuple and dump it out */
  150       string K((char *)key.get_data(), key.get_size());
  151       string V((char *)data.get_data(), data.get_size());
  152       if(config.reverse == 1) {
  153     cout << decode(V) << config.separator << K << endl;
  154       }
  155       else {
  156     cout << K << config.separator << decode(V) << endl;
  157       }
  158     }
  159     dbcp->close();
  160   }
  161   catch (DbException &dbe) {
  162     cerr << pkg << ": " << dbe.what() << "\n";
  163   }
  164   db->close(0);
  165 #else
  166   datum key;
  167   datum value;
  168   key = gdbm_firstkey(db);
  169   while ( key.dptr != NULL ) {
  170     /* iterate over every tuple and dump it out */
  171     value = gdbm_fetch(db, key);   
  172     string K(key.dptr, key.dsize);
  173     string V(value.dptr, value.dsize);
  174     if(config.reverse == 1) {
  175       cout << decode(V) << config.separator << K << endl;
  176       }
  177     else {
  178       cout << K << config.separator << decode(V) << endl;
  179     }
  180     key = gdbm_nextkey(db,key);
  181   }
  182   gdbm_close(db);
  183 #endif
  184 }
  185 
  186 
  187 
  188 
  189 /*
  190  * search for regexp given in config.key
  191  */
  192 void Engine::regexp() {
  193   init();
  194   int num;
  195   pcre *p_pcre;
  196   pcre_extra *p_pcre_extra;
  197   char *err_str;
  198   int sub_len = 9;
  199   int *sub_vec;
  200   int erroffset;
  201   p_pcre_extra = NULL;
  202   p_pcre = pcre_compile((char *)config.key.c_str(), 0,
  203             (const char **)(&err_str), &erroffset, NULL);
  204 #ifdef HAVE_BERKELEY
  205     Dbc *dbcp;
  206     db->cursor(NULL, &dbcp, 0);
  207     Dbt key;
  208     Dbt data;
  209     while (dbcp->get(&key, &data, DB_NEXT) == 0) {
  210       string K((char *)key.get_data(), key.get_size());
  211       string V((char *)data.get_data(), data.get_size());
  212 #else
  213     datum key;
  214     datum value;
  215     key = gdbm_firstkey(db);
  216     while ( key.dptr != NULL ) {
  217       value = gdbm_fetch(db, key);
  218       string K(key.dptr, key.dsize);
  219       string V(value.dptr, value.dsize);
  220 #endif
  221       sub_vec = new int(sub_len);
  222       num = pcre_exec(p_pcre, p_pcre_extra, (char *)K.c_str(),
  223               (int)K.length(), 0, 0, (int *)sub_vec, sub_len);
  224       if(num == 1){
  225     if(config.reverse == 1) {
  226       cout << decode(V);
  227       if(config.with == 1) {
  228         cout << config.separator << K;
  229       }
  230       cout << endl;
  231     }
  232     else {
  233       if(config.with == 1) {
  234         cout << K << config.separator;
  235       }
  236       cout << decode(V) << endl;
  237     }
  238       }
  239       K = "";
  240       V = "";
  241       delete(sub_vec);
  242 #ifndef HAVE_BERKELEY
  243       key = gdbm_nextkey(db,key);
  244 #endif
  245     }
  246     pcre_free(p_pcre);
  247 #ifdef HAVE_BERKELEY
  248     dbcp->close();
  249     db->close(0);
  250 #else
  251   gdbm_close(db);
  252 #endif
  253 }
  254 
  255 
  256 
  257 
  258 
  259 
  260 /*
  261  * Insert data into the db
  262  */
  263 void Engine::from_input() {
  264   init();
  265 #ifdef HAVE_BERKELEY
  266   int err;
  267 #else
  268   int ret;
  269 #endif
  270 
  271   FILE *stream;
  272   stream = fdopen(0, "r");
  273   char c;
  274   string mode = "key";
  275   string key = "";
  276   string value = "";
  277   string line = "";
  278   
  279   int num, match;
  280   pcre *p_pcre;
  281   pcre_extra *p_pcre_extra;
  282   char *err_str;
  283   int sub_len = 9;
  284   int *sub_vec;
  285   char *v1;
  286   char *v2;
  287   int erroffset;
  288   p_pcre_extra = NULL;
  289   p_pcre = pcre_compile((char *)config.token.c_str(), 0,
  290             (const char **)(&err_str), &erroffset, NULL);
  291   while((c = fgetc(stream)) != EOF) {
  292     if(c == '\n') {
  293       // record end
  294       mode = "key";
  295       if(config.token != "") {
  296     v1 = new char[line.length()];
  297     v2 = new char[line.length()];
  298     sub_vec = new int[sub_len];
  299     num = pcre_exec(p_pcre, p_pcre_extra, (char *)line.c_str(),
  300             (int)line.length(), 0, 0, (int *)sub_vec, sub_len);
  301     if(num < 0)
  302       cerr << "Token \"" << config.token << "\" did not match on \"" << line << "\"!\n";
  303     else if(num == 1)
  304       cerr << "Token " << config.token << " did not produce sub strings!\n";
  305     else {
  306       match = pcre_copy_substring((char *)line.c_str(), sub_vec, num, 1, v1, line.length());
  307       match = pcre_copy_substring((char *)line.c_str(), sub_vec, num, 2, v2, line.length());
  308       if(config.reverse) {
  309         value = v1;
  310         key   = v2;
  311       }
  312       else {
  313         value = v2;
  314         key   = v1;
  315       }
  316     }
  317     delete(sub_vec);
  318     pcre_free((void *)v1);
  319     pcre_free((void *)v2);
  320     line = "";
  321       }
  322       value = encode(value);
  323 #ifdef HAVE_BERKELEY
  324       Dbt d_key((char *)key.c_str(), key.length());
  325       Dbt d_value((char *)value.c_str(), value.length());
  326 #else
  327       datum d_key = {(char *)key.c_str(), key.length()};
  328       datum d_value = {(char *)value.c_str(), value.length()};
  329 #endif
  330       if(config.force == 1) {
  331 #ifdef HAVE_BERKELEY
  332     if((err = db->put(0, &d_key, &d_value, 0)) != 0) {
  333       cerr << "Database error" << "(" << strerror(err) << ")" << endl;
  334       exit(1);
  335     }
  336 #else
  337     ret = gdbm_store(db, d_key, d_value, GDBM_REPLACE);
  338 #endif
  339       }
  340       else {
  341 #ifdef HAVE_BERKELEY
  342     if((err = db->put(NULL, &d_key, &d_value, DB_NOOVERWRITE)) != 0) {
  343       if(err == DB_KEYEXIST) {
  344         cerr << "Key " + config.key + " already exists" << "(" << strerror(err) << ")" << endl;
  345         exit(1);
  346       }
  347       else {
  348         cerr << "Database error" << "(" << strerror(err) << ")" << endl;
  349         exit(1);
  350       }
  351     }
  352 #else
  353     ret = gdbm_store(db, d_key, d_value, GDBM_INSERT);
  354 #endif
  355       }
  356 #ifndef HAVE_BERKELEY
  357       if(ret != 0) {
  358     cerr << pkg << ": " << gdbm_strerror(gdbm_errno) << endl;
  359     exit(1);
  360       }
  361 #endif
  362       key = "";
  363       value = "";
  364       continue;
  365     }
  366     else if(c == config.separator && mode != "value" && config.token == "") {
  367       // key ready, the following stuff is the data!
  368       mode = "value";
  369       continue;
  370     }
  371     if(config.token != "") {
  372       /* we have a split token */
  373       line += char(c);
  374     }
  375     else {
  376       if(mode == "key")
  377     key += char(c);
  378       else
  379     value += char(c);
  380     }
  381   }
  382   pcre_free(p_pcre);
  383 #ifdef HAVE_BERKELEY
  384   db->close(0);
  385 #else
  386   gdbm_close(db);
  387 #endif
  388 }
  389 
  390 
  391 /*
  392  * Insert data into the db
  393  */
  394 void Engine::insert() {
  395   init();
  396   string __value;
  397   __value = encode(config.value);
  398 #ifdef HAVE_BERKELEY
  399   int err;
  400   char *k;
  401   char *v;
  402   k = (char *)config.key.c_str();
  403   v = (char *)__value.c_str();
  404   Dbt key(k, strlen(k));
  405   Dbt value(v, strlen(v));
  406 #else
  407   int ret;
  408   datum key   = {(char *)config.key.c_str(), config.key.length()};
  409   datum value = {(char *)__value.c_str(), __value.length()};
  410 #endif
  411 
  412   if(config.force == 1) {
  413 #ifdef HAVE_BERKELEY
  414     if((err = db->put(0, &key, &value, 0)) != 0) {
  415       cerr << "Database error" << "(" << strerror(err) << ")" << endl;
  416       exit(1);
  417     }
  418 #else
  419     ret = gdbm_store(db, key, value, GDBM_REPLACE);
  420 #endif
  421   }
  422   else {
  423 #ifdef HAVE_BERKELEY
  424     if((err = db->put(NULL, &key, &value, DB_NOOVERWRITE)) != 0) {
  425       if(err == DB_KEYEXIST) {
  426     cerr << "Key " + config.key + " already exists" << "(" << strerror(err) << ")" << endl;
  427     exit(1);
  428       }
  429       else {
  430     cerr << "Database error" << "(" << strerror(err) << ")" << endl;
  431     exit(1);
  432       }
  433     }
  434 #else
  435     ret = gdbm_store(db, key, value, GDBM_INSERT);
  436 #endif
  437   }
  438 #ifdef HAVE_BERKELEY
  439   db->close(0);
  440 #else
  441   if(ret != 0) {
  442     cerr << pkg << ": " << gdbm_strerror(gdbm_errno) << endl;
  443     exit(1);
  444   }
  445   gdbm_close(db);
  446 #endif
  447 }
  448 
  449 
  450 
  451 /*
  452  * update a database
  453  */
  454 void Engine::update() {
  455   init();
  456   string __value;
  457   __value = encode(config.value);
  458 #ifdef HAVE_BERKELEY
  459   int err;
  460   char *k;
  461   char *v;
  462   k = (char *)config.key.c_str();
  463   v = (char *)__value.c_str();
  464   Dbt key(k, strlen(k));
  465   Dbt value(v, strlen(v));
  466 #else
  467   int ret;
  468   datum key   = {(char *)config.key.c_str(), config.key.length()};
  469   datum value = {(char *)__value.c_str(), __value.length()};
  470 #endif
  471 
  472   if(config.force == 1) {
  473 #ifdef HAVE_BERKELEY
  474     if((err = db->put(0, &key, &value, 0)) != 0) {
  475       cerr << "Database error" << "(" << strerror(err) << ")" << endl;
  476       exit(1);
  477     }
  478 #else
  479     ret = gdbm_store(db, key, value, GDBM_REPLACE);
  480 #endif
  481   }
  482   else {
  483 #ifdef HAVE_BERKELEY
  484     Dbt val;
  485     err = db->get(0, &key, &val, 0);
  486     if(err == 0) {
  487       /* key exists, do the update */
  488       if((err = db->put(0, &key, &value, 0)) != 0) {
  489     cerr << "Database error" << "(" << strerror(err) << ")" << endl;
  490     exit(1);
  491       }
  492     }
  493     else if(err == DB_NOTFOUND) {
  494       cerr << "Key " << config.key << " does not exist\n";
  495       exit(1);
  496     }
  497     else {
  498       cerr << "Database error" << "(" << strerror(err) << ")" << endl;
  499       exit(1);
  500     }
  501 #else
  502     ret = gdbm_exists(db, key);
  503     if(ret) {
  504       ret = gdbm_store(db, key, value, GDBM_REPLACE);
  505     }
  506     else {
  507       cerr << "Key " << config.key << " does not exist\n";
  508       exit(1);
  509     }
  510 #endif
  511   }
  512 #ifdef HAVE_BERKELEY
  513   db->close(0);
  514 #else
  515   if(ret != 0) {
  516     cerr << pkg << ": " << gdbm_strerror(gdbm_errno) << endl;
  517     exit(1);
  518   }
  519   gdbm_close(db);
  520 #endif
  521 }
  522 
  523 
  524 
  525 /*
  526  * remove an entry
  527  */
  528 void Engine::remove() {
  529   init();
  530   int ret;
  531 #ifdef HAVE_BERKELEY
  532   Dbt key((char *)config.key.c_str(), config.key.length() + 1);
  533   if((ret = db->del(NULL, &key, 0)) != 0) {
  534     cerr << "Database error" << "(" << strerror(ret) << ")" << endl;
  535     exit(1);
  536   }
  537   db->close(0);
  538 #else
  539   datum key   = {(char *)config.key.c_str(), config.key.length()};
  540   ret = gdbm_delete(db, key);
  541   gdbm_close(db);
  542 #endif
  543 }
  544 
  545 
  546 
  547 /*
  548  * search for specific data
  549  */
  550 void Engine::select() {
  551   init();
  552 #ifdef HAVE_BERKELEY
  553   int err;
  554   char *k;
  555   k = (char *)config.key.c_str();
  556   Dbt key(k, strlen(k));
  557   Dbt value;
  558   err = db->get(0, &key, &value, 0);
  559   if(err == 0) {
  560     string gotvalue((char *)value.get_data(), value.get_size());
  561     if(config.reverse == 1) {
  562       cout << decode(gotvalue);
  563       if(config.with == 1) {
  564     cout << config.separator << config.key;
  565       }
  566       cout << endl;
  567     }
  568     else {
  569       if(config.with == 1) {
  570     cout << config.key << config.separator;
  571       }
  572       cout << decode(gotvalue) << endl;
  573     }
  574   }
  575   else {
  576     cerr << "Database error" << "(" << strerror(err) << ")" << endl;
  577     exit(1);
  578   }
  579   db->close(0);
  580 #else
  581   datum content;
  582   datum key   = {(char *)config.key.c_str(), config.key.length()};
  583   content = gdbm_fetch(db, key);
  584   string V(content.dptr, content.dsize);
  585   if(config.with == 1)
  586     cout << config.key << config.separator;
  587   cout << decode(V) << endl;
  588   gdbm_close(db);
  589 #endif
  590 }
  591 
  592 string Engine::encode(const string& data) {
  593   if(config.encrypted) {
  594     return rijn.encrypt(data);
  595   }
  596   else
  597     return data;
  598 }
  599 
  600 string Engine::decode(const string& data) {
  601   if(config.encrypted) {
  602     return rijn.decrypt(data);
  603   }
  604   else
  605     return data;
  606 }
  607