#include <unistd.h>
#include "proxy.h"
+ /*}}}*/
-
-// AutoDetectProxy - auto detect proxy /*{{{*/
+// AutoDetectProxy - auto detect proxy /*{{{*/
// ---------------------------------------------------------------------
/* */
bool AutoDetectProxy(URI &URL)
if (Debug)
std::clog << "Using auto proxy detect command: " << AutoDetectProxyCmd << std::endl;
- int Pipes[2] = {-1,-1};
- if (pipe(Pipes) != 0)
- return _error->Errno("pipe", "Failed to create Pipe");
-
- pid_t Process = ExecFork();
- if (Process == 0)
+ std::string const urlstring = URL;
+ std::vector<const char *> Args;
+ Args.push_back(AutoDetectProxyCmd.c_str());
+ Args.push_back(urlstring.c_str());
+ Args.push_back(nullptr);
+ FileFd PipeFd;
+ pid_t Child;
+ if(Popen(&Args[0], PipeFd, Child, FileFd::ReadOnly) == false)
+ return _error->Error("ProxyAutoDetect command '%s' failed!", AutoDetectProxyCmd.c_str());
+ char buf[512];
+ bool const goodread = PipeFd.ReadLine(buf, sizeof(buf)) != nullptr;
+ PipeFd.Close();
+ if (ExecWait(Child, "ProxyAutoDetect") == false)
+ return false;
+ // no output means the detector has no idea which proxy to use
+ // and apt will use the generic proxy settings
+ if (goodread == false)
+ return true;
+ auto const cleanedbuf = _strstrip(buf);
+ // We warn about this as the implementor probably meant to use DIRECT instead
+ if (cleanedbuf[0] == '\0')
{
- close(Pipes[0]);
- dup2(Pipes[1],STDOUT_FILENO);
- SetCloseExec(STDOUT_FILENO,false);
-
- std::string foo = URL;
- const char *Args[4];
- Args[0] = AutoDetectProxyCmd.c_str();
- Args[1] = foo.c_str();
- Args[2] = 0;
- execv(Args[0],(char **)Args);
- std::cerr << "Failed to exec method " << Args[0] << std::endl;
- _exit(100);
+ _error->Warning("ProxyAutoDetect command returned an empty line");
+ return true;
}
- char buf[512];
- int InFd = Pipes[0];
- close(Pipes[1]);
- int res = read(InFd, buf, sizeof(buf)-1);
- ExecWait(Process, "ProxyAutoDetect", true);
-
- if (res < 0)
- return _error->Errno("read", "Failed to read");
- if (res == 0)
- return _error->Warning("ProxyAutoDetect returned no data");
-
- // add trailing \0
- buf[res] = 0;
if (Debug)
- std::clog << "auto detect command returned: '" << buf << "'" << std::endl;
+ std::clog << "auto detect command returned: '" << cleanedbuf << "'" << std::endl;
- if (strstr(buf, URL.Access.c_str()) == buf)
- _config->Set("Acquire::"+URL.Access+"::proxy::"+URL.Host, _strstrip(buf));
+ if (strstr(cleanedbuf, URL.Access.c_str()) == cleanedbuf || strcmp(cleanedbuf, "DIRECT") == 0)
+ _config->Set("Acquire::"+URL.Access+"::proxy::"+URL.Host, cleanedbuf);
return true;
}