libzypp 17.37.10

sysconfig.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12
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
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;
95 filesystem::TmpFile tmpf( filesystem::TmpFile::makeSibling( path_r ) );
96 {
97 str::regex regex( "^[ \t]*"+key_r+"[ \t]*=" );
98 std::ofstream o( tmpf.path().c_str() );
99 iostr::forEachLine( InputStream( path_r ),
100 [&]( int num_r, const 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
zypp::Errno
Convenience errno wrapper.
Definition Errno.h:26
zypp::Exception
Base class for Exception.
Definition Exception.h:153
zypp::InputStream
Helper to create and pass std::istream.
Definition inputstream.h:57
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::filesystem::PathInfo::userMayRW
bool userMayRW() const
Definition PathInfo.h:357
zypp::filesystem::PathInfo::isFile
bool isFile() const
Definition PathInfo.h:295
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:47
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition Pathname.h:112
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition Pathname.h:93
zypp::filesystem::TmpFile
Provide a new empty temporary file and delete it when no longer needed.
Definition TmpPath.h:128
zypp::filesystem::TmpFile::makeSibling
static TmpFile makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Definition TmpPath.cc:222
zypp::filesystem::TmpPath::path
Pathname path() const
Definition TmpPath.cc:152
zypp::str::regex
Regular expression.
Definition Regex.h:95
zypp::str::regex::matches
bool matches(const char *s, str::smatch &matches, int flags=none) const
Definition Regex.cc:57
zypp::base::sysconfig
Definition sysconfig.cc:32
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
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::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
zypp::base
Definition Random.cc:7
zypp::iostr::forEachLine
int forEachLine(std::istream &str_r, const function< bool(int, std::string)> &consume_r)
Simple lineparser: Call functor consume_r for each line.
Definition IOStream.cc:100
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:374
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:602
zypp::str::trim
std::string trim(const std::string &s, const Trim trim_r)
Definition String.cc:226
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition Application.cc:20
zypp::str::Str
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition String.h:213
sysconfig.h
Pathname.h
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
IOStream.h
Logger.h
DBG
#define DBG
Definition Logger.h:99
MIL
#define MIL
Definition Logger.h:100
WAR
#define WAR
Definition Logger.h:101
XXX
#define XXX
Definition Logger.h:98
Regex.h
String.h
PathInfo.h
TmpPath.h