395
394
logger.error(bad_states[state] + ": %r", error)
397
396
elif state == avahi.SERVER_RUNNING:
400
except dbus.exceptions.DBusException as error:
401
if (error.get_dbus_name()
402
== "org.freedesktop.Avahi.CollisionError"):
403
logger.info("Local Zeroconf service name"
405
return self.rename(remove=False)
407
logger.critical("D-Bus Exception", exc_info=error)
411
399
if error is None:
412
400
logger.debug("Unknown state: %r", state)
435
423
.format(self.name)))
438
def call_pipe(connection, # : multiprocessing.Connection
439
func, *args, **kwargs):
426
def subprocess_call_pipe(connection, # : multiprocessing.Connection
440
428
"""This function is meant to be called by multiprocessing.Process
442
This function runs func(*args, **kwargs), and writes the resulting
443
return value on the provided multiprocessing.Connection.
430
This function runs a synchronous subprocess.call(), and writes the
431
resulting return code on the provided multiprocessing.Connection.
445
connection.send(func(*args, **kwargs))
433
connection.send(subprocess.call(*args, **kwargs))
446
434
connection.close()
448
436
class Client(object):
657
645
# Also start a new checker *right now*.
658
646
self.start_checker()
660
def checker_callback(self, source, condition, connection,
648
def checker_callback(self, source, condition,
649
(connection, command)):
662
650
"""The checker has completed, so take appropriate actions."""
663
651
self.checker_callback_tag = None
664
652
self.checker = None
665
# Read return code from connection (see call_pipe)
653
# Read return code from connection (see subprocess_call_pipe)
666
654
returncode = connection.recv()
667
655
connection.close()
752
740
and self.server_settings["foreground"]):
753
741
popen_args.update({"stdout": wnull,
754
742
"stderr": wnull })
755
pipe = multiprocessing.Pipe(duplex = False)
743
pipe = multiprocessing.Pipe(duplex=False)
756
744
self.checker = multiprocessing.Process(
758
args = (pipe[1], subprocess.call, command),
745
target=subprocess_call_pipe, args=(pipe[1], command),
760
747
self.checker.start()
761
748
self.checker_callback_tag = gobject.io_add_watch(
762
749
pipe[0].fileno(), gobject.IO_IN,
763
self.checker_callback, pipe[0], command)
750
self.checker_callback, (pipe[0], command))
764
751
# Re-run this periodically if run by gobject.timeout_add
1110
1097
interface_names.add(alt_interface)
1111
1098
# Is this a D-Bus signal?
1112
1099
if getattr(attribute, "_dbus_is_signal", False):
1113
if sys.version_info.major == 2:
1114
# Extract the original non-method undecorated
1115
# function by black magic
1116
nonmethod_func = (dict(
1117
zip(attribute.func_code.co_freevars,
1118
attribute.__closure__))
1119
["func"].cell_contents)
1121
nonmethod_func = attribute
1100
# Extract the original non-method undecorated
1101
# function by black magic
1102
nonmethod_func = (dict(
1103
zip(attribute.func_code.co_freevars,
1104
attribute.__closure__))
1105
["func"].cell_contents)
1122
1106
# Create a new, but exactly alike, function
1123
1107
# object, and decorate it to be a new D-Bus signal
1124
1108
# with the alternate D-Bus interface name
1125
if sys.version_info.major == 2:
1126
new_function = types.FunctionType(
1127
nonmethod_func.func_code,
1128
nonmethod_func.func_globals,
1129
nonmethod_func.func_name,
1130
nonmethod_func.func_defaults,
1131
nonmethod_func.func_closure)
1133
new_function = types.FunctionType(
1134
nonmethod_func.__code__,
1135
nonmethod_func.__globals__,
1136
nonmethod_func.__name__,
1137
nonmethod_func.__defaults__,
1138
nonmethod_func.__closure__)
1139
1109
new_function = (dbus.service.signal(
1141
attribute._dbus_signature)(new_function))
1110
alt_interface, attribute._dbus_signature)
1111
(types.FunctionType(
1112
nonmethod_func.func_code,
1113
nonmethod_func.func_globals,
1114
nonmethod_func.func_name,
1115
nonmethod_func.func_defaults,
1116
nonmethod_func.func_closure)))
1142
1117
# Copy annotations, if any
1144
1119
new_function._dbus_annotations = dict(
1368
1343
Client.__del__(self, *args, **kwargs)
1370
1345
def checker_callback(self, source, condition,
1371
connection, command, *args, **kwargs):
1346
(connection, command), *args, **kwargs):
1372
1347
ret = Client.checker_callback(self, source, condition,
1373
connection, command, *args,
1348
(connection, command), *args,
1375
1350
exitstatus = self.last_checker_status
1376
1351
if exitstatus >= 0:
2194
2168
# avoid excessive use of external libraries.
2196
2170
# New type for defining tokens, syntax, and semantics all-in-one
2171
Token = collections.namedtuple("Token",
2172
("regexp", # To match token; if
2173
# "value" is not None,
2174
# must have a "group"
2176
"value", # datetime.timedelta or
2178
"followers")) # Tokens valid after
2197
2180
Token = collections.namedtuple("Token", (
2198
2181
"regexp", # To match token; if "value" is not None, must have
2199
2182
# a "group" containing digits
2234
2217
# Define starting values
2235
2218
value = datetime.timedelta() # Value so far
2236
2219
found_token = None
2237
followers = frozenset((token_duration, )) # Following valid tokens
2220
followers = frozenset((token_duration,)) # Following valid tokens
2238
2221
s = duration # String left to parse
2239
2222
# Loop until end token is found
2240
2223
while found_token is not token_end:
2515
2497
pidfilename = "/var/run/mandos.pid"
2518
pidfile = codecs.open(pidfilename, "w", encoding="utf-8")
2500
pidfile = open(pidfilename, "w")
2519
2501
except IOError as e:
2520
2502
logger.error("Could not open file %r", pidfilename,
2580
2562
old_bus_name = dbus.service.BusName(
2581
2563
"se.bsnet.fukt.Mandos", bus,
2582
2564
do_not_queue=True)
2583
except dbus.exceptions.DBusException as e:
2565
except dbus.exceptions.NameExistsException as e:
2584
2566
logger.error("Disabling D-Bus:", exc_info=e)
2585
2567
use_dbus = False
2586
2568
server_settings["use_dbus"] = False