#!/usr/bin/python
# Hotplug script for gpsd by Eric S. Raymond, March 2005
# This script is part of the gpsd distribution: see http://gpsd.berlios.de
# Can be called like "gpsd.hotplug [add|remove] /dev/ttyUSB0" for test
# purposes.
import sys, time, os, syslog, glob, socket, stat
CONTROL_SOCKET = "/var/run/gpsd.sock"
WHEREAMI = "/etc/hotplug/usb/gpsd.hotplug"
def gpsd_control_connect():
"Acquire a connection to the GPSD control socket."
if not os.path.exists(CONTROL_SOCKET):
syslog.syslog("socket %s doesn't exist" % CONTROL_SOCKET)
return None
try:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
sock.connect(CONTROL_SOCKET)
except socket.error, msg:
syslog.syslog("socket %s creation failure: %s" % (CONTROL_SOCKET, msg))
if sock:
sock.close()
sock = None
#else:
# syslog.syslog("socket %s created OK" % CONTROL_SOCKET)
return sock
def gpsd_control(action, argument):
"Pass a command to gpsd; start the daemon if not already running."
syslog.syslog("gpsd_control(action=%s, arg=%s)" % (action, argument))
connect = gpsd_control_connect()
if connect:
syslog.syslog("reached a running gpsd")
elif action == 'add':
gpsdcmd = "gpsd -F " + CONTROL_SOCKET
syslog.syslog("launching %s" % gpsdcmd)
os.system(gpsdcmd)
connect = gpsd_control_connect()
if not connect:
syslog.syslog("can't reach gpsd")
return None
# We've got a live connection to the gpsd control socket. No
# need to parse the response, because gpsd will lock on to the
# device if it's really a GPS and ignore it if it's not.
if action == 'add':
# Force the group-read & group-write bits on, so gpsd will still be
# able to use this device after dropping root privileges.
os.chmod(argument, stat.S_IMODE(os.stat(argument)[stat.ST_MODE])|0660)
connect.sendall("+%s\r\n" % argument)
connect.recv(12)
elif action == 'remove':
connect.sendall("-%s\r\n" % argument)
connect.recv(12)
connect.close()
#syslog.syslog("gpsd_control ends")
return action
def hotplug(action, devpath):
#syslog.syslog("ACTION=%s" % action)
if not devpath:
syslog.syslog("No device")
else:
subnodes = glob.glob("/sys" + devpath + "/*")
subnodes = map(os.path.basename, subnodes)
subnodes = filter(lambda s: s.startswith("ttyUSB"), subnodes)
if len(subnodes) == 0:
syslog.syslog("no ttyUSB device under " + devpath)
return
elif len(subnodes) > 1:
syslog.syslog("too many ttyUSB devices under " + devpath)
return
else:
tty = "/dev/" + subnodes[0]
syslog.syslog("waiting for " + tty)
while not os.path.exists(tty):
time.sleep(1)
syslog.syslog(tty + " has gone active")
gpsd_control(action, tty)
remover = os.getenv("REMOVER")
#syslog.syslog("REMOVER=%s" % remover)
fp = open(remover, "w")
fp.write(WHEREAMI + " remove " + tty)
fp.close()
os.chmod(remover, stat.S_IRUSR|stat.S_IXUSR|stat.S_IRGRP|stat.S_IXGRP)
return
if __name__ == '__main__':
syslog.openlog('gpsd.hotplug', 0, syslog.LOG_DAEMON)
try:
if len(sys.argv) == 1: # Called as hotplug script
hotplug(os.getenv("ACTION"), os.getenv("DEVPATH"))
else: # Called by hand for testing
gpsd_control(sys.argv[1], sys.argv[2])
except:
(exc_type, exc_value, exc_traceback) = sys.exc_info()
syslog.syslog("gpsd.hotplug: exception %s yields %s" % (exc_type, exc_value))
raise exc_type, exc_value, exc_traceback
#syslog.syslog("gpsd.hotplug ends")
syslog.closelog()
syntax highlighted by Code2HTML, v. 0.9.1