mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00

This is so that people working from the current stable version can still start using git.
283 lines
5.8 KiB
Python
283 lines
5.8 KiB
Python
#! /usr/bin/env python
|
|
#
|
|
# $Id: util.py 6956 2009-12-14 22:01:17Z robin $
|
|
|
|
import os
|
|
import sys
|
|
import socket
|
|
import imp
|
|
import re
|
|
import time
|
|
import tempfile
|
|
import signal
|
|
import StringIO
|
|
import tty
|
|
import termios
|
|
import select
|
|
import curses
|
|
import atexit
|
|
|
|
import config
|
|
import execute
|
|
|
|
def fmttime(t):
|
|
return time.strftime(config.Config.timefmt, time.localtime(float(t)))
|
|
|
|
Buffer = None
|
|
|
|
def bufferOutput():
|
|
global Buffer
|
|
Buffer = StringIO.StringIO()
|
|
|
|
def getBufferedOutput():
|
|
global Buffer
|
|
buffer = Buffer.getvalue()
|
|
Buffer.close()
|
|
Buffer = None
|
|
return buffer
|
|
|
|
def output(msg = "", nl = True):
|
|
|
|
debug(1, "[output] %s %s" % (msg, (not nl) and "..." or ""))
|
|
|
|
if Buffer:
|
|
out = Buffer
|
|
else:
|
|
out = sys.stderr
|
|
|
|
out.write(msg)
|
|
if nl:
|
|
out.write("\n")
|
|
|
|
def error(msg):
|
|
output("error: %s" % msg)
|
|
sys.exit(1)
|
|
|
|
def warn(msg):
|
|
output("warning: %s" % msg)
|
|
|
|
DebugOut = None
|
|
|
|
def debug(msglevel, msg):
|
|
global DebugOut
|
|
|
|
try:
|
|
level = int(config.Config.debug)
|
|
except ValueError:
|
|
level = 0
|
|
|
|
if level < msglevel:
|
|
return
|
|
|
|
if not DebugOut:
|
|
try:
|
|
DebugOut = open(config.Config.debuglog, "a")
|
|
except IOError:
|
|
# During the initial install, tmpdir hasn't been setup yet. So we
|
|
# fall back to current dir.
|
|
DebugOut = open("debug.log", "a")
|
|
|
|
print >>DebugOut, time.strftime(config.Config.timefmt, time.localtime(time.time())), msg
|
|
DebugOut.flush()
|
|
|
|
def sendMail(subject, body):
|
|
cmd = "%s '%s'" % (os.path.join(config.Config.scriptsdir, "send-mail"), subject)
|
|
(success, output) = execute.captureCmd(cmd, "", body)
|
|
if not success:
|
|
warn("cannot send mail")
|
|
|
|
lockCount = 0
|
|
|
|
def _breakLock():
|
|
try:
|
|
# Check whether lock is stale.
|
|
pid = open(config.Config.lockfile, "r").readline().strip()
|
|
(success, output) = execute.runHelper(config.Config.manager(), "check-pid", args=[pid])
|
|
if success:
|
|
# Process still exissts.
|
|
return False
|
|
|
|
# Break lock.
|
|
warn("removing stale lock")
|
|
os.unlink(config.Config.lockfile)
|
|
return True
|
|
|
|
except IOError:
|
|
return False
|
|
|
|
def _aquireLock():
|
|
if not config.Config.manager() or config.Installing:
|
|
# Initial install.
|
|
return True
|
|
|
|
pid = str(os.getpid())
|
|
tmpfile = config.Config.lockfile + "." + pid
|
|
|
|
try:
|
|
try:
|
|
# This should be NFS-safe.
|
|
f = open(tmpfile, "w")
|
|
print >>f, pid
|
|
f.close()
|
|
|
|
n = os.stat(tmpfile)[3]
|
|
os.link(tmpfile, config.Config.lockfile)
|
|
m = os.stat(tmpfile)[3]
|
|
|
|
if n == m-1:
|
|
return True
|
|
|
|
# File is locked.
|
|
if _breakLock():
|
|
return _aquireLock()
|
|
|
|
except OSError, e:
|
|
# File is already locked.
|
|
if _breakLock():
|
|
return _aquireLock()
|
|
|
|
except IOError, e:
|
|
if not config.Config.installing():
|
|
error("cannot aquire lock: %s" % e)
|
|
return False
|
|
else:
|
|
# The spool directory may not exist yet so we
|
|
# silently ignore the failed lock.
|
|
return True
|
|
|
|
finally:
|
|
try:
|
|
os.unlink(tmpfile)
|
|
except OSError:
|
|
pass
|
|
except IOError:
|
|
pass
|
|
|
|
return False
|
|
|
|
def _releaseLock():
|
|
try:
|
|
os.unlink(config.Config.lockfile)
|
|
except OSError, e:
|
|
if not config.Config.installing():
|
|
warn("cannot remove lock file: %s" % e)
|
|
|
|
def lock():
|
|
global lockCount
|
|
|
|
if lockCount > 0:
|
|
# Already locked.
|
|
lockCount += 1
|
|
return True
|
|
|
|
if not _aquireLock():
|
|
|
|
if config.Config.cron == "1":
|
|
do_output = 0
|
|
else:
|
|
do_output = 2
|
|
|
|
if do_output:
|
|
output("waiting for lock ...", nl=False)
|
|
|
|
count = 0
|
|
while not _aquireLock():
|
|
if do_output:
|
|
output(".", nl=False)
|
|
time.sleep(1)
|
|
|
|
count += 1
|
|
if count > 30:
|
|
output("cannot get lock") # always output this one.
|
|
return False
|
|
|
|
if do_output:
|
|
output(" ok")
|
|
|
|
lockCount = 1
|
|
return True
|
|
|
|
def unlock():
|
|
global lockCount
|
|
|
|
if lockCount == 0:
|
|
error("mismatched lock/unlock")
|
|
|
|
if lockCount > 1:
|
|
# Still locked.
|
|
lockCount -= 1
|
|
return
|
|
|
|
_releaseLock()
|
|
|
|
lockCount = 0
|
|
|
|
# Keyboard interrupt handler.
|
|
def sigIntHandler(signum, frame):
|
|
config.Config.config["sigint"] = "1"
|
|
|
|
def enableSignals():
|
|
signal.signal(signal.SIGINT, sigIntHandler)
|
|
|
|
def disableSignals():
|
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
|
|
|
|
# Curses functions
|
|
|
|
_Stdscr = None
|
|
|
|
def _finishCurses():
|
|
curses.nocbreak();
|
|
curses.echo()
|
|
curses.endwin()
|
|
|
|
def _initCurses():
|
|
global _Stdscr
|
|
atexit.register(_finishCurses)
|
|
_Stdscr = curses.initscr()
|
|
|
|
def enterCurses():
|
|
if not _Stdscr:
|
|
_initCurses()
|
|
|
|
curses.cbreak()
|
|
curses.noecho()
|
|
_Stdscr.nodelay(1)
|
|
|
|
signal.signal(signal.SIGWINCH, signal.SIG_IGN)
|
|
|
|
def leaveCurses():
|
|
curses.reset_shell_mode()
|
|
signal.signal(signal.SIGWINCH, signal.SIG_DFL)
|
|
|
|
# Check non-blockingly for a key press and returns it, or return None if no
|
|
# key is found. enter/leaveCurses must surround the getc() call.
|
|
def getCh():
|
|
ch = _Stdscr.getch()
|
|
|
|
if ch < 0:
|
|
return None
|
|
|
|
return chr(ch)
|
|
|
|
def clearScreen():
|
|
if not _Stdscr:
|
|
_initCurses()
|
|
|
|
_Stdscr.clear()
|
|
|
|
def printLines(lines):
|
|
y = 0
|
|
for line in lines.split("\n"):
|
|
try:
|
|
_Stdscr.insnstr(y, 0, line, len(line))
|
|
except:
|
|
pass
|
|
y += 1
|
|
|
|
try:
|
|
_Stdscr.insnstr(y, 0, "", 0)
|
|
except:
|
|
pass
|
|
|