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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
#!/usr/bin/python2
# coding: utf-8
#
# pkgdistcache daemon v0.3.1
# by Alessio Bianchi <venator85@gmail.com>
#
# Daemon code by Chad J. Schroeder
# http://code.activestate.com/recipes/278731/
#
import sys
import os
import os.path
import subprocess
import string
import avahi
import dbus
import gobject
import dbus.glib
import SimpleHTTPServer
import BaseHTTPServer
import signal
avahi_service = None
def terminate(signum, frame):
avahi_service.unpublish()
sys.exit(0)
# Run a command synchronously, redirecting stdout and stderr to strings
def runcmd(cmd, cwd=None):
pipe = subprocess.Popen(cmd, shell=True, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = pipe.communicate() # wait for process to terminate and return stdout and stderr
return {'stdout': stdout.strip(), 'stderr': stderr.strip(), 'retcode': pipe.returncode}
# Detach a process from the controlling terminal and run it in the background as a daemon
def daemonize():
try:
pid = os.fork()
except OSError, e:
raise Exception, "%s [%d]" % (e.strerror, e.errno)
if (pid == 0): # The first child.
os.setsid()
try:
pid = os.fork() # Fork a second child.
except OSError, e:
raise Exception, "%s [%d]" % (e.strerror, e.errno)
if (pid != 0): # The second child.
os._exit(0) # Exit parent (the first child) of the second child.
else:
os._exit(0) # Exit parent of the first child.
import resource # Resource usage information.
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
if (maxfd == resource.RLIM_INFINITY):
maxfd = 1024
# Iterate through and close all file descriptors.
for fd in range(0, maxfd):
try:
os.close(fd)
except OSError: # ERROR, fd wasn't open to begin with (ignored)
pass
# The standard I/O file descriptors are redirected to /dev/null by default.
os.open("/dev/null", os.O_RDWR) # standard input (0)
os.dup2(0, 1) # standard output (1)
os.dup2(0, 2) # standard error (2)
return(0)
class AvahiPublisher:
#Based on http://avahi.org/wiki/PythonPublishExample
def __init__(self, name, stype, host, port):
self.name = name
self.stype = stype
self.domain = 'local'
self.host = host
self.port = port
self.systemBus = dbus.SystemBus()
self.server = dbus.Interface(self.systemBus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)
def publish(self):
self.group = dbus.Interface(
self.systemBus.get_object(avahi.DBUS_NAME, self.server.EntryGroupNew()),
avahi.DBUS_INTERFACE_ENTRY_GROUP)
self.group.AddService(
avahi.IF_UNSPEC, #interface
avahi.PROTO_UNSPEC, #protocol
dbus.UInt32(0), #flags
self.name, self.stype,
self.domain, self.host,
dbus.UInt16(self.port),
avahi.string_array_to_txt_array([]))
self.group.Commit()
def unpublish(self):
self.group.Reset()
def main(args):
import optparse
parser = optparse.OptionParser()
parser.add_option("-F", "--foreground", action="store_true", dest="no_daemon", default=False,
help="run pkgdistcache-daemon in foreground")
(options, args) = parser.parse_args()
if options.no_daemon == False:
# fork daemon in background
daemonize()
# load configuration file
conf_file = '/etc/pkgdistcache.conf'
if os.path.isfile(conf_file):
config = eval(open(conf_file).read())
else:
printerr("Config file " + conf_file + " not found")
return 2
port = config['port']
hostname = runcmd('hostname')['stdout']
global avahi_service
avahi_service = AvahiPublisher(hostname, '_pkgdistcache._tcp', '', port)
avahi_service.publish()
os.chdir('/var/cache/pacman/pkg')
handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = BaseHTTPServer.HTTPServer(('', port), handler)
try:
httpd.serve_forever()
except KeyboardInterrupt:
avahi_service.unpublish()
return 0
if __name__ == '__main__':
signal.signal(signal.SIGTERM, terminate)
main(sys.argv)
|