#!/usr/bin/python3 # This file is part of Elixir, a source code cross-referencer. # # Copyright (C) 2017 Mikaƫl Bouillot # # # Elixir 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. # # Elixir 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 Elixir. If not, see . from subprocess import check_output def shell_exec (cmd): try: a = check_output (cmd, shell=True) except: a = b'error\n' # decode('ascii') fails on special chars # FIXME: major hack until we handle everything as bytestrings try: a = a.decode ('utf-8') except UnicodeDecodeError: a = a.decode ('iso-8859-1') a = a.split ('\n') del a[-1] return a realprint = print outputBuffer = '' def print (arg, end='\n'): global outputBuffer outputBuffer += arg + end; # enable debugging import cgitb cgitb.enable() import cgi import os from re import search, sub from collections import OrderedDict status = 200 form = cgi.FieldStorage() version = form.getvalue ('v') if not (version and search ('^[A-Za-z0-9.-]+$', version)): version = '4.10' url = os.environ['SCRIPT_URL'] m = search ('^/source/(.*)$', url) if m: mode = 'source' path = m.group (1) if not search ('^[A-Za-z0-9_/.,+-]*$', path): path = 'INVALID' url2 = 'source/'+path+'?' elif url == '/ident': mode = 'ident' ident = form.getvalue ('i') if not (ident and search ('^[A-Za-z0-9_-]*$', ident)): ident = '' url2 = 'ident?i='+ident+'&' elif url == '/search': mode = 'search' url2 = 'search?' head = open ('template-head').read() head = sub ('\$baseurl', 'http://' + os.environ['HTTP_HOST'], head) head = sub ('\$vvar', version, head) lines = shell_exec ('cd ..; ./query.py versions') va = OrderedDict() for l in lines: if search ('^2\.6', l): m = search ('^(2\.6)(\.[0-9]*)((\.|-).*)?$', l) else: m = search ('^([0-9]*)(\.[0-9]*)((\.|-).*)?$', l) m1 = m.group(1) m2 = m.group(2) if m1 not in va: va[m1] = OrderedDict() if m1+m2 not in va[m1]: va[m1][m1+m2] = [] va[m1][m1+m2].append (l) v = '\n' head = sub ('\$versions', v, head) if mode == 'source': banner = 'Linux/' p2 = '' p3 = path.split ('/') last = p3[-1] p3 = p3[:-1] for p in p3: banner += ''+p+'/' p2 += p+'/' if last != '': banner += ''+last+'' head = sub ('\$banner', banner, head) head = sub ('\$title', 'Linux/'+path+' - Linux Cross Reference - Free Electrons', head) print (head, end='') lines = ['null - -'] if path[-1:] == '/' or path == '': type = 'tree' lines += shell_exec ('cd ..; ./query.py dir '+version+' \''+path+'\'') else: type = 'blob' lines += shell_exec ('cd ..; ./query.py file '+version+' \''+path+'\'') if len (lines) == 1: print ('
This file does not exist.') status = 404 if type == 'tree': if path != '': lines[0] = 'back - -' print ('\n') for l in lines: type, name, size = l.split (' ') if type == 'null': continue elif type == 'tree': icon = 'folder.gif' size = '' path2 = path+name+'/' name = name+'/' elif type == 'blob': icon = 'text.gif' size = size+' bytes' path2 = path+name elif type == 'back': icon = 'back.gif' size = '' path2 = os.path.dirname (path[:-1]) + '/' if path2 == '/': path2 = './' name = 'Parent directory' print (' ') print (' ') print (' ') print (' ') print (' \n') print ('
'+icon+''+name+''+size+'
', end='') elif type == 'blob': del (lines[0]) print ('
') print ('
')

        width1 = len (str (len (lines)))
        num = 1
        width2 = len (str (num))
        space = ' ' * (width1 - width2)
        for l in lines:
            print ('  '+space+''+str(num)+' ')
            num += 1
            width2 = len (str (num))
            space = ' ' * (width1 - width2)

        print ('
')

        for l in lines:
            l = cgi.escape (l)
            l = sub ('"', '"', l)
            l = sub ('\033\[31m(.*?)\033\[0m', '\\1', l)
            l = sub ('\033\[32m', '', l)
            l = sub ('\033\[0m', '', l)
            print (l)

        print ('
') print ('
', end='') elif mode == 'ident': field = '\n
\n\nIdentifier: \n\n
\n

' + ident head = sub ('\$banner', field, head) head = sub ('\$title', 'Linux identifier search "'+ident+'" - Linux Cross Reference - Free Electrons', head) print (head, end='') lines = shell_exec ('cd .. ; ./query.py ident '+version+" '"+ident+"'") lines = iter (lines) m = search ('Defined in (\d*) file', next (lines)) if m: num = int (m.group(1)) print ('Defined in '+str(num)+' files:') print ('
    ') for i in range (0, num): l = next (lines) m = search ('^(.*): (\d*) \((.*)\)$', l) f, n, t = m.groups() print ('
  • '+f+', line '+n+' (as a '+t+')', end='') print ('
') next (lines) m = search ('Referenced in (\d*) file', next (lines)) num = int (m.group(1)) print ('Referenced in '+str(num)+' files:') print ('
    ') for i in range (0, num): l = next (lines) m = search ('^(.*): (.*)$', l) f = m.group (1) ln = m.group (2).split (',') if len (ln) == 1: n = ln[0] print ('
  • '+f+', line '+str(n)+'', end='') else: if num > 100: # Concise display n = len (ln) print ('
  • '+f+', '+str(n)+' times') else: # Verbose display print ('
  • '+f) print ('') print ('
') else: if ident != '': print ('
Not used') status = 404 elif mode == 'search': head = sub ('\$banner', '', head) head = sub ('\$title', 'Linux freetext search - Linux Cross Reference - Free Electrons', head) print (head, end='') print ('
The Weblxr.free-electrons.com/source
') else: print (head) print ('Invalid request') print (open ('template-tail').read(), end='') if status == 404: realprint ('Status: 404 Not Found') realprint ('Content-Type: text/html;charset=utf-8\n') realprint (outputBuffer, end='')