libzypp  13.10.6
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 namespace std;
28 using namespace zypp::base;
29 
30 namespace zypp {
31  namespace base {
32  namespace sysconfig {
33 
34  map<string,string> read( const Pathname & _path )
35  {
36  DBG << "Load '" << _path << "'" << endl;
37  map<string,string> ret;
38 
39  string line;
40  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  string::size_type pos = line.find( '=', 0 );
50 
51  if ( pos != string::npos ) {
52 
53  string key = str::trim( line.substr( 0, pos ) );
54  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;
95  filesystem::TmpFile tmpf( filesystem::TmpFile::makeSibling( path_r ) );
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 ( auto 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
#define MIL
Definition: Logger.h:47
int exchange(const Pathname &lpath, const Pathname &rpath)
Exchanges two files or directories.
Definition: PathInfo.cc:688
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:320
Pathname path() const
Definition: TmpPath.cc:146
Convenience errno wrapper.
Definition: Errno.h:25
unsigned split(const C_Str &line_r, _OutputIterator result_r, const C_Str &sepchars_r=" \t")
Split line_r into words.
Definition: String.h:394
String matching (STRING|SUBSTRING|GLOB|REGEX).
Definition: StrMatcher.h:297
std::string escape(const C_Str &str_r, const char sep_r)
Escape desired character c using a backslash.
Definition: String.cc:339
#define XXX
Definition: Logger.h:45
Helper to create and pass std::istream.
Definition: InputStream.h:56
Provide a new empty temporary file and delete it when no longer needed.
Definition: TmpPath.h:126
map< string, string > read(const Pathname &_path)
Read sysconfig file path_r and return (key,valye) pairs.
Definition: Sysconfig.cc:34
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
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
std::string getline(std::istream &str)
Read one line from stream.
Definition: IOStream.cc:33
Convenient building of std::string via std::ostream::operator&lt;&lt;.
Definition: String.h:193
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:204
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:100
const char * c_str() const
String representation.
Definition: Pathname.h:109
#define WAR
Definition: Logger.h:48
SolvableIdType size_type
Definition: PoolMember.h:99
Base class for Exception.
Definition: Exception.h:143
#define DBG
Definition: Logger.h:46