summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib/proxy.cc
blob: 0c753131da31cf934bc886e2c8cad0c3c205dd5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// -*- mode: cpp; mode: fold -*-
// Description								/*{{{*/
/* ######################################################################
   
   Proxy - Proxy releated functions
   
   ##################################################################### */
									/*}}}*/
// Include Files							/*{{{*/
#include<apt-pkg/configuration.h>
#include<apt-pkg/error.h>
#include<apt-pkg/fileutl.h>
#include<apt-pkg/strutl.h>

#include<iostream>
#include <unistd.h>

#include "proxy.h"


// AutoDetectProxy - auto detect proxy          			/*{{{*/
// ---------------------------------------------------------------------
/* */
bool AutoDetectProxy(URI &URL)
{
   // we support both http/https debug options
   bool Debug = _config->FindB("Debug::Acquire::"+URL.Access,false);

   // the user already explicitly set a proxy for this host
   if(_config->Find("Acquire::"+URL.Access+"::proxy::"+URL.Host, "") != "")
      return true;

   // option is "Acquire::http::Proxy-Auto-Detect" but we allow the old
   // name without the dash ("-")
   std::string AutoDetectProxyCmd = _config->Find("Acquire::"+URL.Access+"::Proxy-Auto-Detect",
                                      _config->Find("Acquire::"+URL.Access+"::ProxyAutoDetect"));

   if (AutoDetectProxyCmd.empty())
      return true;

   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)
   {
      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);
   }
   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;

   if (strstr(buf, URL.Access.c_str()) == buf)
      _config->Set("Acquire::"+URL.Access+"::proxy::"+URL.Host, _strstrip(buf));

   return true;
}
									/*}}}*/