libzypp 17.31.23
sysconfig.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
13#include "sysconfig.h"
14
15#include <iostream>
16#include <fstream>
17
18#include <zypp-core/base/Logger.h>
19#include <zypp-core/base/String.h>
20#include <zypp-core/base/Regex.h>
21#include <zypp-core/base/IOStream.h>
22#include <zypp-core/base/InputStream>
23#include <zypp-core/Pathname.h>
24#include <zypp-core/fs/PathInfo.h>
25#include <zypp-core/fs/TmpPath.h>
26
27using std::endl;
28using namespace zypp::base;
29
30namespace 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 str::regex regex( "^[ \t]*"+key_r+"[ \t]*=" );
98 std::ofstream o( tmpf.path().c_str() );
100 [&]( int num_r, std::string line_r )->bool
101 {
102 if ( !found && regex.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
Convenience errno wrapper.
Definition: Errno.h:26
Base class for Exception.
Definition: Exception.h:146
Helper to create and pass std::istream.
Definition: inputstream.h:57
Wrapper class for stat/lstat.
Definition: PathInfo.h:221
bool userMayRW() const
Definition: PathInfo.h:349
const char * c_str() const
String representation.
Definition: Pathname.h:110
const std::string & asString() const
String representation.
Definition: Pathname.h:91
Provide a new empty temporary file and delete it when no longer needed.
Definition: TmpPath.h:128
static TmpFile makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Definition: TmpPath.cc:218
Pathname path() const
Definition: TmpPath.cc:146
Regular expression.
Definition: Regex.h:95
bool matches(const char *s, str::smatch &matches, int flags=none) const
Definition: Regex.cc:57
std::map< std::string, std::string > read(const Pathname &_path)
Read sysconfig file path_r and return (key,valye) pairs.
Definition: sysconfig.cc:34
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
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
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
std::string escape(const C_Str &str_r, const char sep_r)
Escape desired character c using a backslash.
Definition: String.cc:371
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:531
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:223
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:212
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:428
#define DBG
Definition: Logger.h:95
#define MIL
Definition: Logger.h:96
#define WAR
Definition: Logger.h:97
#define XXX
Definition: Logger.h:94