LTP GCOV extension - code coverage report
Current view: directory - ept/debtags - debtags.cc
Test: lcov.info
Date: 2008-08-14 Instrumented lines: 81
Code covered: 48.1 % Executed lines: 39

       1                 : /** -*- C++ -*-
       2                 :  * @file
       3                 :  * @author Enrico Zini (enrico) <enrico@enricozini.org>
       4                 :  */
       5                 : 
       6                 : /*
       7                 :  * System tag database
       8                 :  *
       9                 :  * Copyright (C) 2003-2008  Enrico Zini <enrico@debian.org>
      10                 :  *
      11                 :  * This library is free software; you can redistribute it and/or
      12                 :  * modify it under the terms of the GNU Lesser General Public
      13                 :  * License as published by the Free Software Foundation; either
      14                 :  * version 2.1 of the License, or (at your option) any later version.
      15                 :  *
      16                 :  * This library is distributed in the hope that it will be useful,
      17                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      19                 :  * Lesser General Public License for more details.
      20                 :  *
      21                 :  * You should have received a copy of the GNU Lesser General Public
      22                 :  * License along with this library; if not, write to the Free Software
      23                 :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
      24                 :  */
      25                 : 
      26                 : #include <ept/debtags/debtags.h>
      27                 : #include <ept/debtags/maint/path.h>
      28                 : #include <ept/debtags/maint/serializer.h>
      29                 : #include <ept/debtags/maint/debtagsindexer.h>
      30                 : 
      31                 : #include <tagcoll/input/stdio.h>
      32                 : #include <tagcoll/TextFormat.h>
      33                 : 
      34                 : #include <wibble/sys/fs.h>
      35                 : #include <wibble/string.h>
      36                 : 
      37                 : #include <iostream>
      38                 : #include <sstream>
      39                 : 
      40                 : #include <sys/wait.h>     // WIFEXITED WEXITSTATUS
      41                 : #include <sys/types.h>    // getpwuid, stat, mkdir, getuid
      42                 : #include <sys/stat.h>     // stat, mkdir
      43                 : #include <pwd.h>  // getpwuid
      44                 : #include <unistd.h>       // stat, getuid
      45                 : 
      46                 : 
      47                 : using namespace std;
      48                 : using namespace tagcoll;
      49                 : using namespace wibble;
      50                 : 
      51                 : namespace ept {
      52                 : namespace debtags {
      53                 : 
      54              10 : Debtags::Debtags(bool editable)
      55              10 :         : m_coll(m_rocoll)
      56                 : {
      57              10 :         std::string tagfname;
      58              10 :         std::string idxfname;
      59                 : 
      60              10 :         if (!DebtagsIndexer::obtainWorkingDebtags(vocabulary(), tagfname, idxfname))
      61                 :         {
      62               1 :                 m_timestamp = 0;
      63               1 :                 return;
      64                 :         } else {
      65               9 :                 m_timestamp = Path::timestamp(idxfname);
      66                 : 
      67               9 :                 mastermmap.init(idxfname);
      68                 : 
      69                 :                 // Initialize the readonly index
      70               9 :                 m_pkgid.init(mastermmap, 0);
      71               9 :                 m_rocoll.init(mastermmap, 1, 2);
      72                 :         }
      73                 : 
      74                 :         // Initialize the patch collection layer
      75               9 :         rcdir = Path::debtagsUserSourceDir();
      76                 : 
      77               9 :         string patchFile = str::joinpath(rcdir, "patch");
      78              18 :         if (Path::access(patchFile, F_OK) == 0)
      79                 :         {
      80               0 :                 input::Stdio in(patchFile);
      81               0 :                 PatchList<int, int> patch;
      82               0 :                 textformat::parsePatch(in, patchStringToInt(m_pkgid, vocabulary(), inserter(patch)));
      83               0 :                 m_coll.setChanges(patch);
      84               9 :         }
      85               0 : }
      86                 : 
      87               3 : tagcoll::PatchList<std::string, Tag> Debtags::changes() const
      88                 : {
      89               3 :         tagcoll::PatchList<int, int> patches = m_coll.changes();
      90               3 :         tagcoll::PatchList<std::string, Tag> res;
      91                 : 
      92               5 :         for (tagcoll::PatchList<int, int>::const_iterator i = patches.begin();
      93                 :                         i != patches.end(); ++i)
      94                 :         {
      95               2 :                 std::string pkg = packageByID(i->second.item);
      96               2 :                 if (pkg.empty())
      97               0 :                         continue;
      98                 : 
      99                 :                 res.addPatch(tagcoll::Patch<std::string, Tag>(pkg,
     100                 :                         vocabulary().tagsByID(i->second.added),
     101               2 :                         vocabulary().tagsByID(i->second.removed)));
     102                 :         }
     103                 : 
     104               3 :         return res;
     105                 : }
     106                 : 
     107                 : 
     108                 : #if 0
     109                 : bool Debtags::hasTagDatabase()
     110                 : {
     111                 :         if (Path::access(Path::tagdb(), R_OK) == -1)
     112                 :         {
     113                 :                 std::cerr << "Missing tag database " << Path::tagdb() << std::endl;
     114                 :                 return false;
     115                 :         }
     116                 :         if (Path::access(Path::tagdbIndex(), R_OK) == -1)
     117                 :         {
     118                 :                 std::cerr << "Missing tag database index " << Path::tagdbIndex() << std::endl;
     119                 :                 return false;
     120                 :         }
     121                 :         if (Path::access(Path::vocabulary(), R_OK) == -1)
     122                 :         {
     123                 :                 std::cerr << "Missing tag vocabulary " << Path::vocabulary() << std::endl;
     124                 :                 return false;
     125                 :         }
     126                 :         if (Path::access(Path::vocabularyIndex(), R_OK) == -1)
     127                 :         {
     128                 :                 std::cerr << "Missing index for tag vocabulary " << Path::vocabularyIndex() << std::endl;
     129                 :                 return false;
     130                 :         }
     131                 :         return true;
     132                 : }
     133                 : #endif
     134                 : 
     135                 : 
     136               1 : void Debtags::savePatch()
     137                 : {
     138               1 :         PatchList<std::string, std::string> spatch;
     139               1 :         m_coll.changes().output(patchIntToString(m_pkgid, vocabulary(), tagcoll::inserter(spatch)));
     140               1 :         savePatch(spatch);
     141               1 : }
     142                 : 
     143               1 : void Debtags::savePatch(const PatchList<std::string, std::string>& patch)
     144                 : {
     145               1 :         std::string patchFile = str::joinpath(rcdir, "patch");
     146               1 :         std::string backup = patchFile + "~";
     147                 : 
     148               1 :         wibble::sys::fs::mkFilePath(patchFile);
     149                 : 
     150               1 :         if (access(patchFile.c_str(), F_OK) == 0)
     151               0 :                 if (rename(patchFile.c_str(), backup.c_str()) == -1)
     152               0 :                         throw wibble::exception::System("Can't rename " + patchFile + " to " + backup);
     153                 : 
     154                 :         try {
     155               1 :                 FILE* out = fopen(patchFile.c_str(), "w");
     156               1 :                 if (out == 0)
     157               0 :                         throw wibble::exception::System("Can't write to " + patchFile);
     158                 : 
     159               1 :                 textformat::outputPatch(patch, out);
     160                 : 
     161               1 :                 fclose(out);
     162               0 :         } catch (std::exception& e) {
     163               0 :                 if (rename(backup.c_str(), patchFile.c_str()) == -1)
     164               0 :             std::cerr << "Warning: Cannot restore previous backup copy: " << e.what() << std::endl;
     165               0 :                 throw;
     166               1 :         }
     167               1 : }
     168                 : 
     169               0 : void Debtags::savePatch(const PatchList<std::string, Tag>& patch)
     170                 : {
     171               0 :         PatchList<std::string, std::string> spatch;
     172                 :         // patch.output(patchToString<C>(m_pkgs, m_pkgidx, m_tags, tagcoll::inserter(spatch)));
     173               0 :         savePatch(spatch);
     174               0 : }
     175                 : 
     176               0 : void Debtags::sendPatch()
     177                 : {
     178               0 :         PatchList<std::string, std::string> spatch;
     179               0 :         m_coll.changes().output(patchIntToString(m_pkgid, vocabulary(), tagcoll::inserter(spatch)));
     180               0 :         if (!spatch.empty())
     181                 :         {
     182               0 :                 sendPatch(spatch);
     183               0 :         }
     184               0 : }
     185                 : 
     186               0 : void Debtags::sendPatch(const PatchList<std::string, Tag>& patch)
     187                 : {
     188               0 :         PatchList<std::string, std::string> spatch;
     189                 :         // patch.output(patchToString<C>(m_pkgs, m_pkgidx, m_tags, tagcoll::inserter(spatch)));
     190               0 :         sendPatch(spatch);
     191               0 : }
     192                 : 
     193               0 : void Debtags::sendPatch(const PatchList<std::string, std::string>& patch)
     194                 : {
     195                 :         static const char* cmd = "/usr/sbin/sendmail -t";
     196               0 :         FILE* out = popen(cmd, "w");
     197               0 :         if (out == 0)
     198               0 :                 throw wibble::exception::System(std::string("trying to run `") + cmd + "'");
     199                 : 
     200               0 :         struct passwd* udata = getpwuid(getuid());
     201                 : 
     202                 :         fprintf(out,
     203                 :                         "To: enrico-debtags@debian.org\n"
     204                 :                         "Bcc: %s\n"
     205                 :                         "Subject: Tag patch\n"
     206                 :                         "Mime-Version: 1.0\n"
     207                 :                         "Content-Type: multipart/mixed; boundary=\"9amGYk9869ThD9tj\"\n"
     208                 :                         "Content-Disposition: inline\n"
     209                 :                         "X-Mailer: debtags-edit\n\n"
     210                 :                         "This mail contains a Debtags patch for the central archive\n\n"
     211                 :                         "--9amGYk9869ThD9tj\n"
     212                 :                         "Content-Type: text/plain; charset=utf-8\n"
     213                 :                         "Content-Disposition: inline\n\n"
     214               0 :                         "-- DEBTAGS DIFF V0.1 --\n", udata->pw_name);
     215                 : 
     216               0 :         textformat::outputPatch(patch, out);
     217                 : 
     218               0 :         fprintf(out, "\n--9amGYk9869ThD9tj\n");
     219                 : 
     220               0 :         int res = pclose(out);
     221               0 :         if (!WIFEXITED(res) || WEXITSTATUS(res) != 0)
     222                 :         {
     223               0 :                 std::stringstream str;
     224               0 :                 str << res;
     225               0 :                 throw wibble::exception::Consistency("checking mailer exit status", "sendmail returned nonzero (" + str.str() + "): the mail may have not been sent");
     226                 :         }
     227               0 : }
     228                 : 
     229                 : 
     230                 : template<typename OUT>
     231                 : void Debtags::outputSystem(const OUT& cons)
     232                 : {
     233                 :         m_rocoll.output(intToPkg(m_pkgid, vocabulary(), cons));
     234                 : }
     235                 : 
     236                 : template<typename OUT>
     237                 : void Debtags::outputPatched(const OUT& cons)
     238                 : {
     239                 :         m_coll.output(intToPkg(m_pkgid, vocabulary(), cons));
     240                 : }
     241                 : 
     242                 : }
     243                 : }
     244                 : 
     245                 : #include <tagcoll/patch.tcc>
     246                 : #include <tagcoll/coll/patched.tcc>
     247                 : #include <tagcoll/TextFormat.tcc>
     248                 : //#include <tagcoll/stream/filters.tcc>
     249                 : 
     250                 : // vim:set ts=4 sw=4:

Generated by: LTP GCOV extension version 1.6