public
Last active

Send a message to all users on a system. Depends on the `libnotify-bin` package.

  • Download Gist
spam.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Licensed under MIT license: http://www.opensource.org/licenses/mit-license.php
import os, subprocess, sys
 
# thanks: Martin-√Čric Racine, Roger Pate
# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=433960
# http://chat.askubuntu.com/rooms/3/conversation/spam-py
 
message = " ".join(sys.argv[1:])
command = "notify-send -u critical -i dialog-warning Warning!".split() + [message]
if not message:
sys.exit("Usage: spam Your message to all users goes here.")
if not os.geteuid() == 0:
sys.exit("Sorry, you need to be root to spam all users on this system.")
command = "notify-send -u critical -i dialog-warning Warning!".split() + [message]
 
def readfile(fname):
with open(fname, "r") as fobj:
return fobj.read()
 
def get_enviro_for(pid, interesting_fields = None):
environment = {}
for line in readfile("/proc/%s/environ" % pid).split("\x00")[:-1]:
param, _, value = line.partition("=")
if (interesting_fields) and (param in interesting_fields):
environment[param] = value
return environment
 
#warning: reading world-readable files such as /etc/passwd
# will make people go apeshit -- especially if you're skype.
def __get_uname_for(uid):
users = (line.split(":") for line in open("/etc/passwd"))
for line in users:
if line[2] == uid:
return line[0]
 
_usernames = {}
def get_uname_for(uid):
try:
return _usernames[uid]
except KeyError:
uname = _usernames[uid] = __get_uname_for(uid)
return uname
 
def get_basic_info_about(pid):
status = readfile("/proc/%s/status" % pid).split("\n")
for line in status:
if line.startswith("Name"):
_, _, proc_name = line.partition(":\t")
if line.startswith("Uid"):
_, _, uids = line.partition(":\t")
uid = uids.split()[0]
break
return proc_name, get_uname_for(uid)
 
for pid in os.listdir("/proc"):
if not pid.isdigit():
continue
 
proc_name, user_name = get_basic_info_about(pid)
if "gnome-session" != proc_name:
continue
 
# get display and auth
enviro = get_enviro_for(pid, ["DISPLAY","XAUTHORITY"])
 
print "Notifying %s..." % user_name,
sys.stdout.flush()
error_code = subprocess.check_call(command, env=enviro)
if error_code == 0:
print "success."
else:
print "failed (error %d)." % error_code

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.