Bump to 17.31.23
[platform/upstream/libzypp.git] / zypp-curl / curlconfig.cc
1 #include <iostream>
2 #include <fstream>
3
4 #include <zypp-core/base/Logger.h>
5 #include <zypp-core/base/IOStream.h>
6 #include <zypp-core/Pathname.h>
7 #include <zypp-core/fs/PathInfo.h>
8
9 #include <zypp-curl/CurlConfig>
10
11 using std::endl;
12
13 namespace zypp
14 {
15   namespace media
16   {
17
18
19   ///////////////////////////////////////////////////////////////////
20   //
21   //  METHOD NAME : CurlConfig::parseConfig
22   //  METHOD TYPE : int
23   //
24   int CurlConfig::parseConfig(CurlConfig & config, const std::string & filename)
25   {
26     Pathname curlrcFile;
27
28     if(filename.empty())
29     {
30       // attempts to load .curlrc from the homedir
31       char *home = getenv("HOME");
32       if(home)
33         curlrcFile = std::string( home ) + std::string( "/.curlrc" );
34     }
35     else
36       curlrcFile = filename;
37
38     PathInfo h_info(curlrcFile.dirname(), PathInfo::LSTAT);
39     PathInfo c_info(curlrcFile,           PathInfo::LSTAT);
40
41     if( h_info.isDir()  && h_info.userMayRX() &&
42         c_info.isFile() && c_info.userMayR() )
43     {
44       MIL << "Going to parse " << curlrcFile << endl;
45     }
46     else
47     {
48       char buf[32] = "";
49       WAR << "Not allowed to parse '" << curlrcFile
50           << "': dir/file owner: " << h_info.owner() << "/" << c_info.owner()
51           << ", process uid: " << getuid()
52           << " (" << (!getlogin_r(buf, 31) ? buf : "") << ")" << std::endl;
53
54       return 1;
55     }
56
57     std::ifstream inp(curlrcFile.c_str());
58     for(iostr::EachLine in( inp ); in; in.next())
59     {
60       std::string line = str::trim(*in);
61
62       // skip empty lines and comments
63       if (line.empty())
64         continue;
65       switch (line[0])
66       {
67       case '#':
68       case '/':
69       case '\r':
70       case '\n':
71       case '*':
72       case '\0':
73         continue;
74       }
75
76       // DBG << "line " << in.lineNo() << ": " << line << endl; // can't log passwords
77
78       const char * beg = line.c_str();
79       const char * cur = beg;
80
81 // space, '=' and ':' are all valid separators in curlrc
82 #define ISSEP(x) (((x)=='=') || ((x) == ':') || isspace(x))
83
84       // skip leading dashes (they are optional)
85       while (*cur && *cur == '-')
86         cur++;
87       beg = cur;
88
89       // skip non-separator characters
90       while (*cur && !ISSEP(*cur))
91         cur++;
92
93       std::string option(beg, cur - beg);
94
95       // skip separator characters
96       while (*cur && ISSEP(*cur))
97         cur++;
98
99       // rewind to the end of the line
100       beg = cur;
101       while (*cur)
102         cur++;
103
104       std::string value(beg, cur - beg);
105
106       DBG << "GOT: " << option << endl;
107
108       if (!value.empty())
109       {
110         // quoted parameter
111         if (value[0] == '\"')
112         {
113           // remove the quotes
114           std::string::size_type pos = value.rfind('\"');
115           bool cut_last =
116             pos == value.size() - 1 && pos > 1 && value[pos-1] != '\\';
117           value = value.substr(1,
118               cut_last ? value.size() - 2 : value.size() - 1);
119
120           // replace special characters:
121           pos = 0;
122           while ((pos = value.find('\\', pos)) != std::string::npos)
123           {
124             // just erase the backslash if it is found at the end
125             if (pos == value.size() - 1)
126             {
127               value = value.erase(pos, 1);
128               break;
129             }
130
131             switch(value[pos+1])
132             {
133             case 't':
134               value = value.replace(pos, 2, "\t");
135               break;
136             case 'n':
137               value = value.replace(pos, 2, "\n");
138               break;
139             case 'r':
140               value = value.replace(pos, 2, "\r");
141               break;
142             case 'v':
143               value = value.replace(pos, 2, "\v");
144               break;
145             case '\\':
146               value = value.erase(pos++, 1);
147               break;
148             default:;
149               value = value.erase(pos, 1);
150             }
151           }
152         }
153
154         // DBG << "PARAM: " << value << endl; // can't log passwords
155       }
156
157       CurlConfig::setParameter(config, option, value);
158     } // for EachLine in curlrc
159
160     return 0;
161   }
162
163
164   ///////////////////////////////////////////////////////////////////
165   //
166   //  METHOD NAME : CurlConfig::setParameter
167   //  METHOD TYPE : int
168   //
169   int CurlConfig::setParameter(CurlConfig & config,
170                                const std::string & option,
171                                const std::string & value)
172   {
173     if (option == "proxy-user")
174       config.proxyuserpwd = value;
175     // add more curl config data here as they become needed
176     // else if (option == "foo")
177     else
178       DBG << "Ignoring option " << option << endl;
179
180     return 0;
181   }
182
183
184   } // namespace media
185 } // namespace zypp