Skip to content

Instantly share code, notes, and snippets.

@koenbollen
Created January 20, 2012 22:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save koenbollen/1650031 to your computer and use it in GitHub Desktop.
Save koenbollen/1650031 to your computer and use it in GitHub Desktop.
Send a wake-on-lan packet to a certain host specified by name.
#!/usr/bin/env python
# wake.py - Send a wake-on-lan packet to a certain host specified by name.
# The hosts that can be woken are stored a csv file.
#
# Default path for the hosts file is ~/.mac and the
# format is this (one host per line):
# Title, name, mac-address, port
# Example:
# My Computer, living, 00:11:22:33:44:55, 7
#
# Koen Bollen <meneer koenbollen nl>
# 2012 GPL
#
MACFILE="~/.mac"
from collections import namedtuple
import binascii
import csv
import os
import socket
import struct
import sys
host = namedtuple("host", "title name mac port")
def wol(mac, port):
mac = mac.replace(":", "")
data = "FFFFFFFFFFFF" + (mac * 16)
data = binascii.unhexlify( data )
s = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
s.setsockopt( socket.SOL_SOCKET, socket.SO_BROADCAST, 1 )
s.sendto( data, ("<broadcast>", int(port)) )
def lev(s,t):
s = ' ' + s
t = ' ' + t
d = {}
S = len(s)
T = len(t)
for i in range(S):
d[i, 0] = i
for j in range (T):
d[0, j] = j
for j in range(1,T):
for i in range(1,S):
if s[i] == t[j]:
d[i, j] = d[i-1, j-1]
else:
d[i, j] = min(d[i-1, j] + 1, d[i, j-1] + 1, d[i-1, j-1] + 1)
return d[S-1, T-1]
def main():
# Load hosts from ~/.mac
with open( os.path.expanduser( MACFILE ) ) as fp:
hosts = map( host._make, csv.reader(fp))
if len(hosts) == 0:
print >>sys.stderr, "error: no hosts found is macfile:", MACFILE
return
# check for --help or --list
target = sys.argv[1] if len(sys.argv)>1 else "-h"
if target == "--help" or target == "-h":
print "usage: wake.py <target host>"
return
if target == "--list" or target == "-l":
for h in sorted(hosts, key=lambda h: h.title):
print "{0}: {1} ({2})".format( h.name, h.title, h.mac )
return
# sort hosts by query
votes = sorted(map(lambda h: (lev(target,h[1]), h), hosts))
if votes[0][0] > 2:
print >>sys.stderr, "error: host not found:", target
return
target = votes[0][1]
# wake
print "Waking {0}...".format( target.title )
wol( target.mac, target.port )
if __name__ == "__main__":
main()
# vim: expandtab tabstop=4 softtabstop=0 shiftwidth=4 textwidth=0:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment