1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/target/HistoryLog.cc
16 #include "zypp/ZConfig.h"
17 #include "zypp/base/String.h"
18 #include "zypp/base/Logger.h"
20 #include "zypp/PathInfo.h"
21 #include "zypp/Date.h"
23 #include "zypp/PoolItem.h"
24 #include "zypp/Package.h"
25 #include "zypp/RepoInfo.h"
27 #include "zypp/HistoryLog.h"
28 #include "zypp/HistoryLogData.h"
35 inline string timestamp()
36 { return zypp::Date::now().form( HISTORY_LOG_DATE_FORMAT ); }
38 inline string userAtHostname()
42 char * tmp = ::cuserid(buf);
46 if (!::gethostname(buf, 255))
47 result += "@" + string(buf);
52 static std::string pidAndAppname()
54 static std::string _val;
57 pid_t mypid = getpid();
58 zypp::Pathname p( "/proc/"+zypp::str::numstring(mypid)+"/exe" );
59 zypp::Pathname myname( zypp::filesystem::readlink( p ) );
61 _val += zypp::str::numstring(mypid);
63 _val += myname.basename();
73 ///////////////////////////////////////////////////////////////////
75 // CLASS NAME : HistoryLog
77 ///////////////////////////////////////////////////////////////////
79 Pathname HistoryLog::_fname(ZConfig::instance().historyLogFile());
80 std::ofstream HistoryLog::_log;
81 unsigned HistoryLog::_refcnt = 0;
82 const char HistoryLog::_sep = '|';
84 ///////////////////////////////////////////////////////////////////
86 HistoryLog::HistoryLog( const Pathname & rootdir )
89 if (!rootdir.empty() && rootdir.absolute())
90 _fname = rootdir / ZConfig::instance().historyLogFile();
93 void HistoryLog::openLog()
95 if ( !_fname.empty() )
98 _log.open( _fname.asString().c_str(), std::ios::out|std::ios::app );
100 ERR << "Could not open logfile '" << _fname << "'" << endl;
104 void HistoryLog::closeLog()
110 void HistoryLog::refUp()
117 void HistoryLog::refDown()
125 void HistoryLog::setRoot( const Pathname & rootdir )
127 if (rootdir.empty() || !rootdir.absolute())
133 _fname = rootdir / "/var/log/zypp/history";
134 filesystem::assert_dir( _fname.dirname() );
135 MIL << "installation log file " << _fname << endl;
142 const Pathname & HistoryLog::fname()
145 /////////////////////////////////////////////////////////////////////////
147 void HistoryLog::comment( const string & comment, bool timestamp )
154 _log << ::timestamp() << " ";
156 const char * s = comment.c_str();
158 unsigned size = comment.size();
160 // ignore the last newline
161 if (comment[size-1] == '\n')
164 for ( unsigned i = 0; i < size; ++i, ++c )
167 _log << string( s, c + 1 - s ) << "# ";
172 _log << std::string( s, c-s );
177 /////////////////////////////////////////////////////////////////////////
179 void HistoryLog::install( const PoolItem & pi )
181 const Package::constPtr p = asKind<Package>(pi.resolvable());
186 << timestamp() // 1 timestamp
187 << _sep << HistoryActionID::INSTALL.asString(true) // 2 action
188 << _sep << p->name() // 3 name
189 << _sep << p->edition() // 4 evr
190 << _sep << p->arch(); // 5 arch
192 // ApplLow is what the solver selected on behalf of the user.
193 if (pi.status().isByUser() || pi.status().isByApplLow() )
194 _log << _sep << userAtHostname(); // 6 reqested by
195 else if (pi.status().isByApplHigh())
196 _log << _sep << pidAndAppname();
201 << _sep << p->repoInfo().alias() // 7 repo alias
202 << _sep << p->checksum().checksum(); // 8 checksum
206 //_log << pi << endl;
210 void HistoryLog::remove( const PoolItem & pi )
212 const Package::constPtr p = asKind<Package>(pi.resolvable());
217 << timestamp() // 1 timestamp
218 << _sep << HistoryActionID::REMOVE.asString(true) // 2 action
219 << _sep << p->name() // 3 name
220 << _sep << p->edition() // 4 evr
221 << _sep << p->arch(); // 5 arch
223 // ApplLow is what the solver selected on behalf of the user.
224 if ( pi.status().isByUser() || pi.status().isByApplLow() )
225 _log << _sep << userAtHostname(); // 6 reqested by
226 else if (pi.status().isByApplHigh())
227 _log << _sep << pidAndAppname();
231 // we don't have checksum in rpm db
232 // << _sep << p->checksum().checksum(); // x checksum
236 //_log << pi << endl;
239 /////////////////////////////////////////////////////////////////////////
241 void HistoryLog::addRepository(const RepoInfo & repo)
244 << timestamp() // 1 timestamp
245 << _sep << HistoryActionID::REPO_ADD.asString(true) // 2 action
246 << _sep << str::escape(repo.alias(), _sep) // 3 alias
247 // what about the rest of the URLs??
248 << _sep << *repo.baseUrlsBegin() // 4 primary URL
253 void HistoryLog::removeRepository(const RepoInfo & repo)
256 << timestamp() // 1 timestamp
257 << _sep << HistoryActionID::REPO_REMOVE.asString(true) // 2 action
258 << _sep << str::escape(repo.alias(), _sep) // 3 alias
263 void HistoryLog::modifyRepository(
264 const RepoInfo & oldrepo, const RepoInfo & newrepo)
266 if (oldrepo.alias() != newrepo.alias())
269 << timestamp() // 1 timestamp
270 << _sep << HistoryActionID::REPO_CHANGE_ALIAS.asString(true) // 2 action
271 << _sep << str::escape(oldrepo.alias(), _sep) // 3 old alias
272 << _sep << str::escape(newrepo.alias(), _sep) // 4 new alias
276 if (*oldrepo.baseUrlsBegin() != *newrepo.baseUrlsBegin())
279 << timestamp() //1 timestamp
280 << _sep << HistoryActionID::REPO_CHANGE_URL.asString(true) // 2 action
281 << _sep << str::escape(oldrepo.alias(), _sep) // 3 old url
282 << _sep << *newrepo.baseUrlsBegin() // 4 new url
287 ///////////////////////////////////////////////////////////////////