Files
2015-10-14 00:15:07 -05:00

126 lines
4.5 KiB
Python

# Volatility
#
# Authors:
# Mike Auty <mike.auty@gmail.com>
#
# This file is part of Volatility.
#
# Volatility is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Volatility is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Volatility. If not, see <http://www.gnu.org/licenses/>.
#
import os, time, calendar
import datetime
import volatility.conf as conf
import volatility.debug as debug
try:
import pytz
tz_pytz = True
except ImportError:
tz_pytz = False
config = conf.ConfObject()
class OffsetTzInfo(datetime.tzinfo):
"""Timezone implementation that allows offsets specified in seconds"""
def __init__(self, offset = None, *args, **kwargs):
"""Accepts offset in seconds"""
self.offset = offset
datetime.tzinfo.__init__(self, *args, **kwargs)
def set_offset(self, offset):
"""Simple setter for offset"""
self.offset = offset
def utcoffset(self, dt):
"""Returns the offset from UTC"""
if self.offset is None:
return None
return datetime.timedelta(seconds = self.offset) + self.dst(dt)
def dst(self, _dt):
"""We almost certainly can't know about DST, so we say it's always off"""
# FIXME: Maybe we can know or make guesses about DST?
return datetime.timedelta(0)
def tzname(self, _dt):
"""Return a useful timezone name"""
if self.offset is None:
return "UNKNOWN"
return ""
class UTC(datetime.tzinfo):
"""Concrete instance of the UTC timezone"""
def utcoffset(self, _dt):
"""Returns an offset from UTC of 0"""
return datetime.timedelta(0)
def dst(self, _dt):
"""Returns no daylight savings offset"""
return datetime.timedelta(0)
def tzname(self, _dt):
"""Returns the timezone name"""
return "UTC"
def display_datetime(dt, custom_tz = None):
"""Returns a string from a datetime according to the display TZ (or a custom one"""
timeformat = "%Y-%m-%d %H:%M:%S %Z%z"
if dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None:
if custom_tz is not None:
dt = dt.astimezone(custom_tz)
elif config.TZ is not None:
if isinstance(config.TZ, str):
secs = calendar.timegm(dt.timetuple())
os.environ['TZ'] = config.TZ
time.tzset()
# Remove the %z which appears not to work
timeformat = timeformat[:-2]
return time.strftime(timeformat, time.localtime(secs))
else:
dt = dt.astimezone(config.tz)
return ("{0:" + timeformat + "}").format(dt)
def tz_from_string(_option, _opt_str, value, parser):
"""Stores a tzinfo object from a string"""
if value is not None:
if value[0] in ['+', '-']:
# Handed a numeric offset, create an OffsetTzInfo
valarray = [value[i:i + 2] for i in range(1, len(value), 2)]
multipliers = [3600, 60]
offset = 0
for i in range(min(len(valarray), len(multipliers))):
offset += int(valarray[i]) * multipliers[i]
if value[0] == '-':
offset = -offset
timezone = OffsetTzInfo(offset = offset)
else:
# Value is a lookup, choose pytz over time.tzset
if tz_pytz:
try:
timezone = pytz.timezone(value)
except pytz.UnknownTimeZoneError:
debug.error("Unknown display timezone specified")
else:
if not hasattr(time, 'tzset'):
debug.error("This operating system doesn't support tzset, please either specify an offset (eg. +1000) or install pytz")
timezone = value
parser.values.tz = timezone
config.add_option("TZ", action = "callback", callback = tz_from_string,
cache_invalidator = False,
help = "Sets the (Olson) timezone for displaying timestamps using pytz (if installed) or tzset",
default = None, nargs = 1, type = str)