Make Proxy-Auto-Detect check for each host
[ntk/apt.git] / apt-pkg / contrib / proxy.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 /* ######################################################################
4
5 Proxy - Proxy releated functions
6
7 ##################################################################### */
8 /*}}}*/
9 // Include Files /*{{{*/
10 #include<apt-pkg/configuration.h>
11 #include<apt-pkg/error.h>
12 #include<apt-pkg/fileutl.h>
13 #include<apt-pkg/strutl.h>
14
15 #include<iostream>
16 #include <unistd.h>
17
18 #include "proxy.h"
19
20
21 // AutoDetectProxy - auto detect proxy /*{{{*/
22 // ---------------------------------------------------------------------
23 /* */
24 bool AutoDetectProxy(URI &URL)
25 {
26 // we support both http/https debug options
27 bool Debug = _config->FindB("Debug::Acquire::"+URL.Access,false);
28
29 // option is "Acquire::http::Proxy-Auto-Detect" but we allow the old
30 // name without the dash ("-")
31 std::string AutoDetectProxyCmd = _config->Find("Acquire::"+URL.Access+"::Proxy-Auto-Detect",
32 _config->Find("Acquire::"+URL.Access+"::ProxyAutoDetect"));
33
34 if (AutoDetectProxyCmd.empty())
35 return true;
36
37 if (Debug)
38 std::clog << "Using auto proxy detect command: " << AutoDetectProxyCmd << std::endl;
39
40 int Pipes[2] = {-1,-1};
41 if (pipe(Pipes) != 0)
42 return _error->Errno("pipe", "Failed to create Pipe");
43
44 pid_t Process = ExecFork();
45 if (Process == 0)
46 {
47 close(Pipes[0]);
48 dup2(Pipes[1],STDOUT_FILENO);
49 SetCloseExec(STDOUT_FILENO,false);
50
51 std::string foo = URL;
52 const char *Args[4];
53 Args[0] = AutoDetectProxyCmd.c_str();
54 Args[1] = foo.c_str();
55 Args[2] = 0;
56 execv(Args[0],(char **)Args);
57 std::cerr << "Failed to exec method " << Args[0] << std::endl;
58 _exit(100);
59 }
60 char buf[512];
61 int InFd = Pipes[0];
62 close(Pipes[1]);
63 int res = read(InFd, buf, sizeof(buf)-1);
64 ExecWait(Process, "ProxyAutoDetect", true);
65
66 if (res < 0)
67 return _error->Errno("read", "Failed to read");
68 if (res == 0)
69 return _error->Warning("ProxyAutoDetect returned no data");
70
71 // add trailing \0
72 buf[res] = 0;
73
74 if (Debug)
75 std::clog << "auto detect command returned: '" << buf << "'" << std::endl;
76
77 if (strstr(buf, URL.Access.c_str()) == buf)
78 _config->Set("Acquire::"+URL.Access+"::proxy::"+URL.Host, _strstrip(buf));
79
80 return true;
81 }
82 /*}}}*/