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