libzypp  10.5.0
CurlConfig.cc
Go to the documentation of this file.
00001 #include <iostream>
00002 #include <fstream>
00003 
00004 #include "zypp/base/Logger.h"
00005 #include "zypp/base/IOStream.h"
00006 #include "zypp/Pathname.h"
00007 #include "zypp/PathInfo.h"
00008 
00009 #include "zypp/media/CurlConfig.h"
00010 
00011 using namespace std;
00012 
00013 namespace zypp
00014 {
00015   namespace media
00016   {
00017 
00018 
00020   //
00021   //  METHOD NAME : CurlConfig::parseConfig
00022   //  METHOD TYPE : int
00023   //
00024   int CurlConfig::parseConfig(CurlConfig & config, const std::string & filename)
00025   {
00026     Pathname curlrcFile;
00027 
00028     if(filename.empty())
00029     {
00030       // attempts to load .curlrc from the homedir
00031       char *home = getenv("HOME");
00032       if(home)
00033         curlrcFile = string( home ) + string( "/.curlrc" );
00034     }
00035     else
00036       curlrcFile = filename;
00037 
00038     PathInfo h_info(curlrcFile.dirname(), PathInfo::LSTAT);
00039     PathInfo c_info(curlrcFile,           PathInfo::LSTAT);
00040 
00041     if( h_info.isDir()  && h_info.owner() == getuid() &&
00042         c_info.isFile() && c_info.owner() == getuid())
00043     {
00044       MIL << "Going to parse " << curlrcFile << endl;
00045     }
00046     else
00047     {
00048       char buf[32] = "";
00049       WAR << "Not allowed to parse '" << curlrcFile
00050           << "': dir/file owner: " << h_info.owner() << "/" << c_info.owner()
00051           << ", process uid: " << getuid()
00052           << " (" << (!getlogin_r(buf, 31) ? buf : "") << ")" << std::endl;
00053 
00054       return 1;
00055     }
00056 
00057     ifstream inp(curlrcFile.c_str());
00058     for(iostr::EachLine in( inp ); in; in.next())
00059     {
00060       string line = str::trim(*in);
00061 
00062       // skip empty lines and comments
00063       if (line.empty())
00064         continue;
00065       switch (line[0])
00066       {
00067       case '#':
00068       case '/':
00069       case '\r':
00070       case '\n':
00071       case '*':
00072       case '\0':
00073         continue;
00074       }
00075 
00076       // DBG << "line " << in.lineNo() << ": " << line << endl; // can't log passwords
00077 
00078       const char * beg = line.c_str();
00079       const char * cur = beg;
00080 
00081 // space, '=' and ':' are all valid separators in curlrc
00082 #define ISSEP(x) (((x)=='=') || ((x) == ':') || isspace(x))
00083 
00084       // skip leading dashes (they are optional)
00085       while (*cur && *cur == '-')
00086         cur++;
00087       beg = cur;
00088 
00089       // skip non-separator characters
00090       while (*cur && !ISSEP(*cur))
00091         cur++;
00092 
00093       string option(beg, cur - beg);
00094 
00095       // skip separator characters
00096       while (*cur && ISSEP(*cur))
00097         cur++;
00098 
00099       // rewind to the end of the line
00100       beg = cur;
00101       while (*cur)
00102         cur++;
00103 
00104       string value(beg, cur - beg);
00105 
00106       DBG << "GOT: " << option << endl;
00107 
00108       if (!value.empty())
00109       {
00110         // quoted parameter
00111         if (value[0] == '\"')
00112         {
00113           // remove the quotes
00114           string::size_type pos = value.rfind('\"');
00115           bool cut_last =
00116             pos == value.size() - 1 && pos > 1 && value[pos-1] != '\\';
00117           value = value.substr(1,
00118               cut_last ? value.size() - 2 : value.size() - 1);
00119 
00120           // replace special characters:
00121           pos = 0;
00122           while ((pos = value.find('\\', pos)) != string::npos)
00123           {
00124             // just erase the backslash if it is found at the end
00125             if (pos == value.size() - 1)
00126             {
00127               value = value.erase(pos, 1);
00128               break;
00129             }
00130 
00131             switch(value[pos+1])
00132             {
00133             case 't':
00134               value = value.replace(pos, 2, "\t");
00135               break;
00136             case 'n':
00137               value = value.replace(pos, 2, "\n");
00138               break;
00139             case 'r':
00140               value = value.replace(pos, 2, "\r");
00141               break;
00142             case 'v':
00143               value = value.replace(pos, 2, "\v");
00144               break;
00145             case '\\':
00146               value = value.erase(pos++, 1);
00147               break;
00148             default:;
00149               value = value.erase(pos, 1);
00150             }
00151           }
00152         }
00153 
00154         // DBG << "PARAM: " << value << endl; // can't log passwords
00155       }
00156 
00157       CurlConfig::setParameter(config, option, value);
00158     } // for EachLine in curlrc
00159 
00160     return 0;
00161   }
00162 
00163 
00165   //
00166   //  METHOD NAME : CurlConfig::setParameter
00167   //  METHOD TYPE : int
00168   //
00169   int CurlConfig::setParameter(CurlConfig & config,
00170                                const std::string & option,
00171                                const std::string & value)
00172   {
00173     if (option == "proxy-user")
00174       config.proxyuserpwd = value;
00175     // add more curl config data here as they become needed
00176     // else if (option == "foo")
00177     else
00178       DBG << "Ignoring option " << option << endl;
00179 
00180     return 0;
00181   }
00182 
00183 
00184   } // namespace media
00185 } // namespace zypp