libzypp  17.23.8
Sysconfig.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
13 #include <iostream>
14 #include <fstream>
15 
16 #include <zypp/base/Logger.h>
17 #include <zypp/base/String.h>
18 #include <zypp/base/StrMatcher.h>
19 #include <zypp/base/IOStream.h>
20 #include <zypp/base/InputStream.h>
21 #include <zypp/Pathname.h>
22 #include <zypp/PathInfo.h>
23 #include <zypp/TmpPath.h>
24 
25 #include <zypp/base/Sysconfig.h>
26 
27 using std::endl;
28 using namespace zypp::base;
29 
30 namespace zypp {
31  namespace base {
32  namespace sysconfig {
33 
34  std::map<std::string,std::string> read( const Pathname & _path )
35  {
36  DBG << "Load '" << _path << "'" << endl;
37  std::map<std::string,std::string> ret;
38 
39  std::string line;
40  std::ifstream in( _path.asString().c_str() );
41  if ( in.fail() ) {
42  WAR << "Unable to load '" << _path << "'" << endl;
43  return ret;
44  }
45 
46  while( getline( in, line ) ) {
47  if ( *line.begin() != '#' ) {
48 
49  std::string::size_type pos = line.find( '=', 0 );
50 
51  if ( pos != std::string::npos ) {
52 
53  std::string key = str::trim( line.substr( 0, pos ) );
54  std::string value = str::trim( line.substr( pos + 1, line.length() - pos - 1 ) );
55 
56  if ( value.length() >= 2
57  && *(value.begin()) == '"'
58  && *(value.rbegin()) == '"' )
59  {
60  value = value.substr( 1, value.length() - 2 );
61  }
62  if ( value.length() >= 2
63  && *(value.begin()) == '\''
64  && *(value.rbegin()) == '\'' )
65  {
66  value = value.substr( 1, value.length() - 2 );
67  }
68  XXX << "KEY: '" << key << "' VALUE: '" << value << "'" << endl;
69  ret[key] = value;
70 
71  } // '=' found
72 
73  } // not comment
74 
75  } // while getline
76  MIL << "done reading '" << _path << "'" << endl;
77  return ret;
78  }
79 
80  bool write( const Pathname & path_r, const std::string & key_r, const std::string & val_r, const std::string & newcomment_r )
81  {
82  if ( key_r.empty() )
83  {
84  WAR << "Empty key in write " << path_r << endl;
85  return false;
86  }
87 
88  PathInfo pi( path_r );
89  if ( ! pi.isFile() )
90  ZYPP_THROW( Exception( str::Str() << path_r << ": " << Errno(ENOENT) ) );
91  if ( ! pi.userMayRW() )
92  ZYPP_THROW( Exception( str::Str() << path_r << ": " << Errno(EACCES) ) );
93 
94  bool found = false;
96  {
97  StrMatcher matches( "^[ \t]*"+key_r+"[ \t]*=", Match::REGEX );
98  std::ofstream o( tmpf.path().c_str() );
100  [&]( int num_r, std::string line_r )->bool
101  {
102  if ( !found && matches( line_r ) )
103  {
104  o << key_r << '=' << val_r << endl;
105  found = true;
106  MIL << path_r << ": " << key_r << '=' << val_r << " changed on line " << num_r << endl;
107  }
108  else
109  o << line_r << endl;
110  return true;
111  } );
112  if ( !found )
113  {
114  if ( newcomment_r.empty() )
115  {
116  WAR << path_r << ": " << key_r << '=' << val_r << " can not be added (no comment provided)." << endl;
117  }
118  else
119  {
120  std::vector<std::string> lines;
121  str::split( newcomment_r, std::back_inserter(lines), "\r\n" );
122  o << endl;
123  for ( const std::string & line : lines )
124  {
125  if ( line[0] != '#' )
126  o << "# ";
127  o << line << endl;
128  }
129  o << key_r << '=' << val_r << endl;
130  found = true;
131  MIL << path_r << ": " << key_r << '=' << val_r << " appended. " << endl;
132  }
133  }
134 
135  if ( ! o )
136  ZYPP_THROW( Exception( str::Str() << tmpf.path() << ": " << Errno(EIO) ) );
137  }
138 
139  // If everything is fine, exchange the files:
140  int res = exchange( tmpf.path(), path_r );
141  if ( res )
142  {
143  ZYPP_THROW( Exception( str::Str() << tmpf.path() << ": " << Errno(res) ) );
144  }
145  return found;
146  }
147 
148  bool writeStringVal( const Pathname & path_r, const std::string & key_r, const std::string & val_r, const std::string & newcomment_r )
149  {
150  return write( path_r, key_r, str::Str() << '"' << str::escape( val_r, '"' )<< '"', newcomment_r );
151  }
152 
153  } // namespace sysconfig
154  } // namespace base
155 } // namespace zypp
zypp::base::sysconfig::read
std::map< std::string, std::string > read(const Pathname &_path)
Read sysconfig file path_r and return (key,valye) pairs.
Definition: Sysconfig.cc:34
TmpPath.h
PathInfo.h
zypp::Exception
Base class for Exception.
Definition: Exception.h:145
zypp::StrMatcher
String matching (STRING|SUBSTRING|GLOB|REGEX).
Definition: StrMatcher.h:297
zypp::filesystem::TmpPath::path
Pathname path() const
Definition: TmpPath.cc:146
zypp::base::sysconfig::writeStringVal
bool writeStringVal(const Pathname &path_r, const std::string &key_r, const std::string &val_r, const std::string &newcomment_r)
Convenience to add or change a string-value in sysconfig file path_r.
Definition: Sysconfig.cc:148
MIL
#define MIL
Definition: Logger.h:79
zypp::Match::REGEX
Regular Expression.
Definition: StrMatcher.h:48
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
Pathname.h
IOStream.h
zypp::iostr::getline
std::string getline(std::istream &str)
Read one line from stream.
Definition: IOStream.cc:32
zypp::str::split
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", const Trim trim_r=NO_TRIM)
Split line_r into words.
Definition: String.h:527
zypp::filesystem::exchange
int exchange(const Pathname &lpath, const Pathname &rpath)
Exchanges two files or directories.
Definition: PathInfo.cc:704
zypp::base::sysconfig::write
bool write(const Pathname &path_r, const std::string &key_r, const std::string &val_r, const std::string &newcomment_r)
Add or change a value in sysconfig file path_r.
Definition: Sysconfig.cc:80
zypp::filesystem::PathInfo
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:220
zypp::filesystem::TmpFile
Provide a new empty temporary file and delete it when no longer needed.
Definition: TmpPath.h:127
zypp::iostr::forEachLine
int forEachLine(std::istream &str_r, function< bool(int, std::string)> consume_r)
Simple lineparser: Call functor consume_r for each line.
Definition: IOStream.cc:99
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition: Pathname.h:110
Sysconfig.h
Logger.h
WAR
#define WAR
Definition: Logger.h:80
zypp::filesystem::PathInfo::isFile
bool isFile() const
Definition: PathInfo.h:289
zypp::InputStream
Helper to create and pass std::istream.
Definition: InputStream.h:56
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
zypp::str::escape
std::string escape(const C_Str &str_r, const char sep_r)
Escape desired character c using a backslash.
Definition: String.cc:362
zypp::str::Str
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:208
zypp::filesystem::PathInfo::userMayRW
bool userMayRW() const
Definition: PathInfo.h:349
String.h
zypp::filesystem::Pathname
Pathname.
Definition: Pathname.h:44
zypp::Errno
Convenience errno wrapper.
Definition: Errno.h:25
zypp::sat::detail::size_type
SolvableIdType size_type
Definition: PoolMember.h:126
zypp::base
Definition: DrunkenBishop.cc:24
DBG
#define DBG
Definition: Logger.h:78
InputStream.h
XXX
#define XXX
Definition: Logger.h:77
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition: Pathname.h:91
zypp::str::trim
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:216
zypp::filesystem::TmpFile::makeSibling
static TmpFile makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Definition: TmpPath.cc:218
StrMatcher.h