394
395
logger.error(bad_states[state] + ": %r", error)
396
397
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)
399
411
if error is None:
400
412
logger.debug("Unknown state: %r", state)
423
435
.format(self.name)))
426
def subprocess_call_pipe(connection, # : multiprocessing.Connection
438
def call_pipe(connection, # : multiprocessing.Connection
439
func, *args, **kwargs):
428
440
"""This function is meant to be called by multiprocessing.Process
430
This function runs a synchronous subprocess.call(), and writes the
431
resulting return code on the provided multiprocessing.Connection.
442
This function runs func(*args, **kwargs), and writes the resulting
443
return value on the provided multiprocessing.Connection.
433
connection.send(subprocess.call(*args, **kwargs))
445
connection.send(func(*args, **kwargs))
434
446
connection.close()
436
448
class Client(object):
645
657
# Also start a new checker *right now*.
646
658
self.start_checker()
648
def checker_callback(self, source, condition,
649
(connection, command)):
660
def checker_callback(self, source, condition, connection,
650
662
"""The checker has completed, so take appropriate actions."""
651
663
self.checker_callback_tag = None
652
664
self.checker = None
653
# Read return code from connection (see subprocess_call_pipe)
665
# Read return code from connection (see call_pipe)
654
666
returncode = connection.recv()
655
667
connection.close()
740
752
and self.server_settings["foreground"]):
741
753
popen_args.update({"stdout": wnull,
742
754
"stderr": wnull })
743
pipe = multiprocessing.Pipe(duplex=False)
755
pipe = multiprocessing.Pipe(duplex = False)
744
756
self.checker = multiprocessing.Process(
745
target=subprocess_call_pipe, args=(pipe[1], command),
758
args = (pipe[1], subprocess.call, command),
747
760
self.checker.start()
748
761
self.checker_callback_tag = gobject.io_add_watch(
749
762
pipe[0].fileno(), gobject.IO_IN,
750
self.checker_callback, (pipe[0], command))
763
self.checker_callback, pipe[0], command)
751
764
# Re-run this periodically if run by gobject.timeout_add
1097
1110
interface_names.add(alt_interface)
1098
1111
# Is this a D-Bus signal?
1099
1112
if getattr(attribute, "_dbus_is_signal", False):
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)
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
1106
1122
# Create a new, but exactly alike, function
1107
1123
# object, and decorate it to be a new D-Bus signal
1108
1124
# 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__)
1109
1139
new_function = (dbus.service.signal(
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)))
1141
attribute._dbus_signature)(new_function))
1117
1142
# Copy annotations, if any
1119
1144
new_function._dbus_annotations = dict(
1343
1368
Client.__del__(self, *args, **kwargs)
1345
1370
def checker_callback(self, source, condition,
1346
(connection, command), *args, **kwargs):
1371
connection, command, *args, **kwargs):
1347
1372
ret = Client.checker_callback(self, source, condition,
1348
(connection, command), *args,
1373
connection, command, *args,
1350
1375
exitstatus = self.last_checker_status
1351
1376
if exitstatus >= 0:
2168
2194
# avoid excessive use of external libraries.
2170
2196
# 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
2180
2197
Token = collections.namedtuple("Token", (
2181
2198
"regexp", # To match token; if "value" is not None, must have
2182
2199
# a "group" containing digits
2217
2234
# Define starting values
2218
2235
value = datetime.timedelta() # Value so far
2219
2236
found_token = None
2220
followers = frozenset((token_duration,)) # Following valid tokens
2237
followers = frozenset((token_duration, )) # Following valid tokens
2221
2238
s = duration # String left to parse
2222
2239
# Loop until end token is found
2223
2240
while found_token is not token_end:
2497
2515
pidfilename = "/var/run/mandos.pid"
2500
pidfile = open(pidfilename, "w")
2518
pidfile = codecs.open(pidfilename, "w", encoding="utf-8")
2501
2519
except IOError as e:
2502
2520
logger.error("Could not open file %r", pidfilename,
2562
2580
old_bus_name = dbus.service.BusName(
2563
2581
"se.bsnet.fukt.Mandos", bus,
2564
2582
do_not_queue=True)
2565
except dbus.exceptions.NameExistsException as e:
2583
except dbus.exceptions.DBusException as e:
2566
2584
logger.error("Disabling D-Bus:", exc_info=e)
2567
2585
use_dbus = False
2568
2586
server_settings["use_dbus"] = False