1
2
3
4
5
6
7
8
9
10
11
12
13
14 __doc__="""ConfDaemon
15
16 Base class for makeing deamon programs
17
18 $Id: ConfDaemon.py,v 1.9 2003/08/29 20:33:10 edahl Exp $"""
19
20 __version__ = "$Revision: 1.9 $"[11:-2]
21
22 import signal
23 import os
24 import sys
25 import socket
26 import time
27
28 from CmdBase import CmdBase
29 from Utils import zenPath
30
32
34 CmdBase.__init__(self)
35 signal.signal(signal.SIGINT, self.sigTerm)
36 signal.signal(signal.SIGTERM, self.sigTerm)
37 if self.options.daemon and sys.platform != 'win32':
38 self.becomeDaemon()
39 self.dnstries = 3
40 self.forwarddnscache = {}
41 self.reversednscache = {}
42
44 """fork twice to become a daemon"""
45 pid = 0
46 try:
47 pid = os.fork()
48 if pid > 0:
49 sys.exit(0)
50 except OSError, e:
51 print >>sys.stderr, ("fork #1 failed: %d (%s)" %
52 (e.errno, e.strerror))
53 os.chdir("/")
54 os.setsid()
55 os.umask(0)
56 try:
57 pid = os.fork()
58 if pid > 0:
59 sys.exit(0)
60 except OSError, e:
61 print >>sys.stderr, ("fork #2 failed: %d (%s)" %
62 (e.errno, e.strerror))
63 myname = sys.argv[0].split(os.sep)[-1] + ".pid"
64 varhome = zenPath('var')
65 pidfile = os.path.join(varhome, myname)
66 if os.path.exists(varhome):
67 file = open(pidfile, 'w')
68 file.write(str(os.getpid()))
69 file.close()
70 else:
71 print "ERROR: unable to open pid file %s" % pidfile
72 sys.exit(1)
73
74
86
87
89 """try the reverse lookup dnstries times if it fails look in cache"""
90 try:
91 ip = self._dsnLookup(socket.gethostbyaddr, addr)
92 self.reversednscache[addr] = ip
93 return ip
94 except socket.error:
95 if self.reversednscache.has_key(addr):
96 return self.reversednscache[addr]
97 else:
98 raise
99
100
102 """try dns lookup dnstries times"""
103 ip = None
104 i=0
105 while 1:
106 try:
107 i+=1
108 ip = function(target)
109 except socket.error:
110 if i > self.getDnsTries():
111 raise
112 if ip: break
113 return ip
114
115
117 if not hasattr(self, 'dnstries'):
118 self.dnstries=3
119 return self.dnstries
120
121
123 self.log.info('Daemon %s shutting down' % self.__class__.__name__)
124 sys.exit(0)
125
126
127
129 """handle errors when loading config from server
130 we try configtries times if no previous config is found"""
131 for i in range(self.options.configtries):
132 try:
133 self.loadConfig()
134 return
135 except SystemExit: raise
136 except:
137 if self.validConfig():
138 self.log.exception(
139 "configuration load exception using previous configuration")
140 return
141 else:
142 self.log.exception('config load failed')
143 if i <= (self.options.configtries - 2):
144 self.log.warn(
145 "initial config load failed will retry")
146 time.sleep(self.options.configsleep)
147 else:
148 self.log.critical(
149 "initial config load failed %d times exiting"
150 % self.options.configtries)
151 sys.exit(2)
152
153
155 CmdBase.buildOptions(self)
156 self.parser.add_option('-c', '--cycle',
157 dest='cycle',
158 default=0,
159 action="store_true",
160 help="Cycle continuously on cycleInterval from zope")
161 self.parser.add_option('-d', '--daemon',
162 dest='daemon',
163 default=0,
164 action="store_true",
165 help="Become a unix daemon")
166 self.parser.add_option('-T', '--configtries',
167 dest='configtries',
168 default=5,
169 action="store",
170 help="How many times to retry config connection")
171 self.parser.add_option('-S', '--configsleep',
172 dest='configsleep',
173 default=20,
174 action="store",
175 help="How long to sleep between config connections")
176