The trunk can use the main server again (for the time being).
[switzerland.git] / setup.py
blobbeaa122292d822d674998a5ea140a47c5e7a6864
1 #!/usr/bin/env python
3 from distutils.core import setup
4 import distutils.sysconfig
5 import sys
6 import os
7 import os.path
8 import platform
9 import shutil
11 OPERATING_SYSTEM = platform.system()
13 # Fix up the %PATH% on Windows so that we can use Cygwin if it is present.
14 if "Windows" == OPERATING_SYSTEM:
15 os.environ["PATH"] += os.pathsep + r"c:\cygwin\bin"
17 def check_version():
18 if sys.version_info < (2,4,0):
19 # This is a bad start, but let's see if there is a python2.4 around:
20 backup_plan = False
21 if "PATH" in os.environ:
22 for dir in os.environ["PATH"].split(os.pathsep):
23 if os.path.exists(dir + os.sep + "python2.4"):
24 backup_plan = True
26 if not backup_plan:
27 print "Unfortunately you need Python 2.4 to run Switzerland."
28 print "Please install Python 2.4"
29 print "(or send us a patch so that Switzerland runs with your version of Python ;)"
30 sys.exit(1)
31 else:
32 print "It looks like Python2.4 is installed on your system, but it is not the"
33 print 'default Python version. Try running setup.py using "python2.4" '
34 print 'instead of "python"'
35 sys.exit(0)
37 def try_precompiled_binaries():
38 plat = OPERATING_SYSTEM
39 if plat == "Linux":
40 return try_binary("bin/FastCollector.linux")
41 elif plat == "Windows":
42 return try_binary("bin\\FastCollector.exe")
43 elif plat == "Darwin":
44 if platform.release() < "9.0.0":
45 return try_binary("bin/FastCollector.tiger")
46 else:
47 return try_binary("bin/FastCollector.leopard")
48 return False
50 def try_binary(path):
51 if not os.path.exists(path):
52 print "Cannot try precompiled binary %s," % path
53 print "(probably because you are in the wrong directory....)"
54 return False
55 print "Testing executable %s:" % path
56 try:
57 from subprocess import Popen, PIPE
58 # os.chmod does not work on, of all platforms, Windows, where cygwin may
59 # nonetheless require it.
60 p=Popen("chmod a+x " + path, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
61 p.wait()
62 except:
63 pass
64 inp,outp,errors = os.popen3(path+ " -d notadeviceanywhere")
65 line = errors.read()
66 if "Couldn't" in line:
67 # magic to keep things quiet
68 print "Looks like it executes on this machine!"
69 return path
70 print "This is what we got when we tried the precompiled binary:\n%s" % line[:-1]
71 print "Looks like that isn't going to work :("
72 return False
74 source = os.path.join("switzerland", "client", "FastCollector.c")
75 if OPERATING_SYSTEM == "Windows":
76 dest = os.path.join("switzerland", "client", "FastCollector.exe")
77 else:
78 dest = os.path.join("switzerland", "client", "FastCollector")
80 def try_gcc_compile():
81 cmd = "gcc -O3 -lpcap -o %s %s" % (dest,source)
82 print "Trying compile:", cmd
83 os.system(cmd)
84 if try_binary(dest):
85 return dest
86 else:
87 return False
89 def try_gcc_compile_static_libpcap():
90 cmd = "gcc -O3 -lpcap `locate libpcap.a | head -1` -o %s %s" % (dest,source)
91 print "Trying compile:", cmd
92 os.system(cmd)
93 if try_binary(dest):
94 return dest
95 else:
96 return False
98 def try_vaguely_responsible_compile():
99 cc = os.environ.get("CC", "gcc")
100 cflags = os.environ.get("CFLAGS", "")
101 ldflags = os.environ.get("LDFLAGS", "")
103 cmd = cc + " " + cflags + " " + ldflags + (" -lpcap -o %s %s" % (dest,source))
105 print "Trying compile:", cmd
106 os.system(cmd)
107 if try_binary(dest):
108 return dest
109 else:
110 return False
112 def try_cc_compile():
113 cmd = "cc -lpcap -o %s %s" % (dest,source)
114 print "Trying compile:", cmd
115 os.system(cmd)
116 if try_binary(dest):
117 return dest
118 else:
119 return False
121 def find_binary():
122 attempt = try_precompiled_binaries()
123 if attempt:
124 return attempt
125 else:
126 print "Trying to compile a binary for you..."
128 attempts = try_gcc_compile() or try_cc_compile() or \
129 try_vaguely_responsible_compile() or try_gcc_compile_static_libpcap()
130 if attempts:
131 print "Compile successful!"
132 else:
133 print "No luck with compilers"
134 return attempts
136 def ntpdate_runs():
137 "No guarantees that it does what you want..."
138 try:
139 print "Checking to see if we can execute ntpdate"
140 from subprocess import Popen, PIPE
141 p = Popen("ntpdate", stdin=PIPE, stdout=PIPE, stderr=PIPE)
142 p.wait()
143 return True
144 except ImportError:
145 print "Can't test ntpdate with old pythons, assuming ntpdate works..."
146 return True
147 except:
148 print "No ntpdate executable in the PATH..."
149 return False
151 def main():
152 check_version()
153 executables = ["switzerland-client","switzerland-server", "study-switzerland-pcaps"]
154 if OPERATING_SYSTEM == "Windows":
155 for e in executables:
156 shutil.copyfile(e, e + ".py")
157 executables = [e + ".py" for e in executables]
158 if not ntpdate_runs():
159 executables.append("bin\\ntpdate.exe")
160 executables.append('win32_postinstall.py')
161 bin = find_binary()
162 if bin:
163 if bin != dest:
164 # Since FastCollector.linux isn't what we wan't in /usr/bin
165 shutil.copy(bin,dest)
166 executables.append(dest)
169 # Gah. It would be fair to say that distutils sucks. The following hack
170 # adding the undocumented -f flag is necessary to ensure that the installer
171 # overwrites outdated previously installed versions of Switzerland.
172 if sys.argv[-1] == "install":
173 sys.argv.append("--force")
175 setup(name = "Switzerland",
176 version = "0.1.0",
177 description = "EFF Network Testing System",
178 author = "Peter Eckersley, Jered Wierzbicki and Steven Lucy",
179 author_email = "switzerland-devel@eff.org",
180 url = "http://www.eff.org/testyourisp/switzerland",
181 packages = ["switzerland", "switzerland.lib","switzerland.client",\
182 "switzerland.common","switzerland.server",\
183 "switzerland.lib.shrunk_scapy",\
184 "switzerland.lib.shrunk_scapy.layers"],
185 scripts = executables
187 if "install" in sys.argv:
188 if not bin:
189 print """
190 Well, Switzerland is sort of installed, but we can't seem to obtain a
191 working FastCollector executable on your machine. Please make sure you
192 have libpcap, then try again. If it still doesn't work, make sure you
193 have a C compiler and try again. If it *still* doesn't work, go and
194 compile %s yourself. Once you've done that, make sure you put it somewhere
195 in your system PATH. Then run Switzerland!""" % source
196 else:
197 if OPERATING_SYSTEM == "Windows":
198 print "running post-installation script"
199 import win32_postinstall
200 print "Switzerland installed successfully!"
202 main()