Skip to content

Instantly share code, notes, and snippets.

@badp
Created November 11, 2010 14:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save badp/672546 to your computer and use it in GitHub Desktop.
Save badp/672546 to your computer and use it in GitHub Desktop.
Send a message to all users on a system. Depends on the `libnotify-bin` package.
#!/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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment