File: inspect.py

package info (click to toggle)
reglookup 1.0.1%2Bsvn296-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 948 kB
  • sloc: ansic: 6,676; python: 3,762; makefile: 40; sh: 27
file content (278 lines) | stat: -rw-r--r-- 8,284 bytes parent folder | download | duplicates (5)
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#!/usr/bin/python
""" Module to inspect the contents of an AFF4 volume """
import sys, pdb, os
import re, cmd, readline
import optparse
import pyaff4
import shlex
import fnmatch, time
import subprocess
import readline

time.sleep(1)

## Set more sane completer delimiters
readline.set_completer_delims(' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?')

## Configure colors
colors = {}
colors['cyan']   = '\033[96m'
colors['purple'] = '\033[95m'
colors['blue']   = '\033[94m'
colors['green']  = '\033[92m'
colors['yellow'] = '\033[93m'
colors['red']    = '\033[91m'
colors['end']    = '\033[0m'

#If the output is not a terminal, remove the colors
if not sys.stdout.isatty():
   for key, value in colors.iteritems():
      colors[key] = ''

parser = optparse.OptionParser()
(options, args) = parser.parse_args()

## Load the specified args as volumes
oracle = pyaff4.Resolver()
VOLUMES = []
STREAMS = {}

for arg in args:
    volume = pyaff4.RDFURN()
    volume.set(arg)
    if oracle.load(volume):
        VOLUMES.append(volume)
        urn = pyaff4.RDFURN()
        iter = oracle.get_iter(volume, pyaff4.AFF4_CONTAINS)
        while oracle.iter_next(iter, urn):
           print urn.value
           if not urn: break

           ## We store is as a simplified path
           path = "/%s%s" % (urn.parser.netloc, urn.parser.query)
           STREAMS[path] = urn

class Inspector(cmd.Cmd):
    prompt = "/:>"
    intro = "Inspecting the volumes %s. Type 'help' for help." % args
    CWD = "/"

    def cmdloop(self, *args):
        while 1:
            try:
                if not cmd.Cmd.cmdloop(self, *args):
                    break
            except KeyboardInterrupt,e:
                print "Type %sexit%s to exit, %shelp%s for help" % (
                    colors['yellow'],
                    colors['end'],
                    colors['cyan'],
                    colors['end'])

    def do_EOF(self, args):
        """ Exit this program """
        print "%sGoodbye%s" % (colors['yellow'],
                               colors['end'])
        return True

    def do_cd(self, line):
        """ Change directory """
        args = shlex.split(line)
        if not args[0].startswith("/"):
            args[0] = self.CWD + args[0]

        try:
            potential_cd = os.path.normpath(args[0])
            if not potential_cd.endswith('/'):
                potential_cd += "/"

            for s in STREAMS:
                if s.startswith(potential_cd):
                    self.CWD = potential_cd
                    self.prompt = "%s:>" % self.CWD
                    return

            raise IOError("No such directory %s" % potential_cd)
        except IndexError:
            print "CWD: %s" % self.CWD

    def complete_cd(self, *args):
        return self.complete_stream(*args)

    def do_help(self, line):
        """ Provide help for commands """
        args = shlex.split(line)
        if not args:
            ## List all commands
            for k in dir(self):
                if k.startswith("do_"):
                    method = getattr(self, k)
                    print "%s%s%s: %s" % (colors['red'],
                                          k[3:],
                                          colors['end'],
                                          method.__doc__)
            return

        for arg in args:
            try:
                method = getattr(self, "do_%s" % arg)
            except AttributeError:
                print "%sError:%s Command %s%s%s not found" % (colors['red'],
                                                               colors['end'],
                                                               colors['yellow'],
                                                               arg,
                                                               colors['end'])

            print "%s: %s" % (arg, method.__doc__)

    def do_ls(self, line):
        """ List streams matching a glob expression """
        globs = shlex.split(line)
        if not globs: globs=[self.CWD]

        result = []

        for s in STREAMS:
            for g in globs:
                if fnmatch.fnmatch(s, g + "*"):
                    if s.startswith(self.CWD):
                        s = s[len(self.CWD):]

                    path = s.split("/")[0]
                    if path == s:
                        decoration = colors['blue']
                    else:
                        decoration = colors['end']

                    if path not in result:
                        print "%s%s%s" % (decoration, path, colors['end'])
                        result.append(path)

    def do_less(self, line):
        """ Read the streams specified and pipe them through the pager """
        globs = shlex.split(line)
        for s in STREAMS:
            for g in globs:
                if not g.startswith("/"):
                    g = self.CWD + g

                g = os.path.normpath(g)
                if fnmatch.fnmatch(s, g):
                    ## Try to open the stream
                    try:
                        fd = oracle.open(STREAMS[s], 'r')
                    except IOError, e:
                        raise

                    pager = os.environ.get("PAGER","less")
                    pipe=os.popen(pager,"w")

                    while 1:
                        data = fd.read(1024 * 1024)
                        if not data: break

                        pipe.write(data)

                    pipe.close()

    def do_cp(self, line):
        """ Copy a stream from a source to a destination. """
        globs = shlex.split(line)
        src = globs[0]
        dest = globs[1]
        if(len(globs) > 2):
           print "usage: cp src dest"
           return

        if not src.startswith("/"):
           src = self.CWD + src

        src = os.path.normpath(src)
        src_urn = pyaff4.RDFURN()
        src_urn.set("aff4:/" + src)
        ## Try to open the stream
        try:
           fd = oracle.open(src_urn, 'r')
        except IOError, e:
           raise

        dest_fd = open(dest, "w")
        while 1:
           data = fd.read(1024 * 1024)
           if not data: break

           dest_fd.write(data)

        dest_fd.close()

    def complete_cp(self, *args):
       return self.complete_stream(*args)

    def complete_less(self, *args):
        return self.complete_stream(*args)

    def _display_attribute(self, iter):
       while 1:
          obj = oracle.alloc_from_iter(iter)
          if not obj: break

          print "    -> type (%s) " % (obj.dataType)
          print "    -> data (%s) " % (obj.serialise(iter.urn))


    def do_resolve(self, line):
       globs = shlex.split(line)
       attribute = pyaff4.XSDString()
       subject = pyaff4.RDFURN()
       iter = pyaff4.RESOLVER_ITER()

       subject.set(globs[0])
       try:
          attribute.set(globs[1])
          print attribute.value
          self._display_attribute(iter)

       except IndexError:
          ## Just display all the attributes
          while oracle.attributes_iter(subject, attribute, iter):
             print attribute.value
             self._display_attribute(iter)

    def complete_stream(self, text, line, begidx, endidx):
        if not text.startswith("/"):
            text = self.CWD + text

        if not text:
            completions = STREAMS.keys()

        completions = [ text + f[len(text):].split("/")[0]
                        for f in STREAMS.keys()
                        if f.startswith(text)
                        ]

        return completions

    def do_pwd(self, line):
        print "CWD: %s" % self.CWD

    def do_exit(self, *args):
        """ Exits the program """
        return self.do_EOF(*args)

    def emptyline(self):
        return

    def onecmd(self, line):
        try:
            return cmd.Cmd.onecmd(self, line)
        except Exception,e:
            print "%sError:%s %s%s%s %s" % (colors['red'],
                                            colors['end'],
                                            colors['yellow'],
                                            e.__class__.__name__,
                                            colors['end'],
                                            e)

        return None

Inspector().cmdloop()