!c99Shell v. 1.0 pre-release build #16!

Software: Apache/2.2.3 (CentOS). PHP/5.1.6 

uname -a: Linux mx-ll-110-164-51-230.static.3bb.co.th 2.6.18-194.el5PAE #1 SMP Fri Apr 2 15:37:44
EDT 2010 i686
 

uid=48(apache) gid=48(apache) groups=48(apache) 

Safe-mode: OFF (not secure)

/usr/lib/rhythmbox/plugins/artdisplay/   drwxr-xr-x
Free 50.91 GB of 127.8 GB (39.83%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     CoverArtDatabase.py (8.24 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# -*- Mode: python; coding: utf-8; tab-width: 8; indent-tabs-mode: t; -*- 
#
# Copyright (C) 2006 - Gareth Murphy, Martin Szulecki, 
# Ed Catmur <ed@catmur.co.uk>
#
# This program 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, or (at your option)
# any later version.
#
# The Rhythmbox authors hereby grants permission for non-GPL compatible
# GStreamer plugins to be used and distributed together with GStreamer
# and Rhythmbox. This permission is above and beyond the permissions granted
# by the GPL license by which Rhythmbox is covered. If you modify this code
# you may extend this exception to your version of the code, but you are not
# obligated to do so. If you do not wish to do so, delete this exception
# statement from your version.

# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.

import rhythmdb, rb
import os
import gtk
import itertools
import gobject

from PodcastCoverArtSearch import PodcastCoverArtSearch
from AmazonCoverArtSearch import AmazonCoverArtSearch
from LocalCoverArtSearch import LocalCoverArtSearch

from urllib import unquote

ART_SEARCHES_LOCAL = [LocalCoverArtSearch]
ART_SEARCHES_REMOTE = [PodcastCoverArtSearch, AmazonCoverArtSearch]
OLD_ART_FOLDER = '~/.gnome2/rhythmbox/covers'
# complicated way of saying ~/.cache/rhythmbox/covers
ART_FOLDER = os.path.join(os.environ.get('XDG_CACHE_HOME',
        os.path.join(os.environ.get('XDG_HOME_DIR',
                os.environ.get('HOME','~')),
                '.cache')), 'rhythmbox/covers')
ART_CACHE_EXTENSION_JPG = 'jpg'
ART_CACHE_EXTENSION_PNG = 'png'
ART_CACHE_FORMAT_JPG = 'jpeg'
ART_CACHE_FORMAT_PNG = 'png'
ART_CACHE_SETTINGS_JPG = {"quality": "100"}
ART_CACHE_SETTINGS_PNG = {"compression": "9"}

class TicketSystem:
    def __init__ (self):
        self.counter = itertools.count ()
        self.hash = {}
        self.dead = set ()

    def get (self, item):
        ticket = self.counter.next ()
        self.hash.setdefault (item, set ()).add (ticket)
        return ticket

    def bury (self, ticket):
        try:
            self.dead.remove (ticket)
            return True
        except KeyError:
            return False

    def forget (self, item, ticket):
        try:
            self.hash[item].remove (ticket)
            return True
        except KeyError:
            self.dead.remove (ticket)
            return False

    def purge (self, item):
        self.dead.update (self.hash.pop (item, set ()))

    def release (self, item, ticket):
        try:
            self.dead.update (self.hash.pop (item) - set([ticket]))
            return True
        except KeyError:
            self.dead.remove (ticket)
            return False

class CoverArtDatabase (object):
    def __init__ (self):
        self.loader = rb.Loader()
        self.ticket = TicketSystem ()

    def build_art_cache_filename (self, db, entry, extension):
        artist = db.entry_get (entry, rhythmdb.PROP_ARTIST)
        album = db.entry_get (entry, rhythmdb.PROP_ALBUM)
        art_folder = os.path.expanduser (ART_FOLDER)
        old_art_folder = os.path.expanduser (OLD_ART_FOLDER)
        if not os.path.exists (art_folder) and os.path.exists (old_art_folder):
            parent = os.path.dirname(os.path.abspath(art_folder))
            if not os.path.exists (parent):
                os.makedirs (parent)
            os.rename (old_art_folder, art_folder)
        if not os.path.exists (art_folder):
            os.makedirs (art_folder)

        # FIXME: the following block of code is messy and needs to be redone ASAP
        return art_folder + '/%s - %s.%s' % (artist.replace ('/', '-'), album.replace ('/', '-'), extension)    

    def engines (self, blist):
        for Engine in ART_SEARCHES_LOCAL:
            yield Engine (self.loader), Engine.__name__, False
        for Engine in ART_SEARCHES_REMOTE:
            if Engine.__name__ not in blist:
                yield Engine (self.loader), Engine.__name__, True
    
    def set_pixbuf_from_uri (self, db, entry, uri, callback):
        def loader_cb (data):
            self.set_pixbuf (db, entry, self.image_data_load (data), callback)
        self.loader.get_url (str (uri), loader_cb)

    def set_pixbuf (self, db, entry, pixbuf, callback):
        if entry is None or pixbuf is None:
            return
        if pixbuf.get_has_alpha():
            art_location = self.build_art_cache_filename (db, entry, ART_CACHE_EXTENSION_PNG)
            art_cache_format = ART_CACHE_FORMAT_PNG
            art_cache_settings = ART_CACHE_SETTINGS_PNG
        else:
            art_location = self.build_art_cache_filename (db, entry, ART_CACHE_EXTENSION_JPG)
            art_cache_format = ART_CACHE_FORMAT_JPG
            art_cache_settings = ART_CACHE_SETTINGS_JPG
        self.ticket.purge (entry)
        pixbuf.save (art_location, art_cache_format, art_cache_settings)
        callback (entry, pixbuf, art_location)
        for Engine in ART_SEARCHES_LOCAL:
            try:
                Engine (self.loader).save_pixbuf (db, entry, pixbuf)
            except AttributeError:
                pass

    def cancel_get_pixbuf (self, entry):
        self.ticket.purge (entry)
  
    def get_pixbuf (self, db, entry, callback):
        if entry is None:
            callback (entry, None, None)
            return
            
        st_artist = db.entry_get (entry, rhythmdb.PROP_ARTIST) or _("Unknown")
        st_album = db.entry_get (entry, rhythmdb.PROP_ALBUM) or _("Unknown")

        # replace quote characters
        # don't replace single quote: could be important punctuation
        for char in ["\""]:
            st_artist = st_artist.replace (char, '')
            st_album = st_album.replace (char, '')

        rb.Coroutine (self.image_search, db, st_album, st_artist, entry, callback).begin ()

    def image_search (self, plexer, db, st_album, st_artist, entry, callback):
        art_location_jpg = self.build_art_cache_filename (db, entry, ART_CACHE_EXTENSION_JPG)
        art_location_png = self.build_art_cache_filename (db, entry, ART_CACHE_EXTENSION_PNG)
        blist_location = self.build_art_cache_filename (db, entry, "rb-blist")

        art_location = None
        if os.path.exists (art_location_jpg):
            art_location = art_location_jpg
        if os.path.exists (art_location_png):
            art_location = art_location_png

        # Check local cache
        if art_location:
            self.ticket.purge (entry)
            pixbuf = gtk.gdk.pixbuf_new_from_file (art_location)    
            callback (entry, pixbuf, art_location)
            return

        blist = self.read_blist (blist_location)
        ticket = self.ticket.get (entry)
        for engine, engine_name, engine_remote in self.engines (blist):
            plexer.clear ()
            engine.search (db, entry, plexer.send ())
            while True:
                yield None
                _, (engine, entry, results) = plexer.receive ()
                if not results:
                    break
                for url in engine.get_best_match_urls (results):
                    if str(url) == "":
                        print "got empty url from engine %s." % (engine)
                        continue

                    yield self.loader.get_url (str (url), plexer.send ())
                    _, (data, ) = plexer.receive ()
                    pixbuf = self.image_data_load (data)
                    if pixbuf:
                        if self.ticket.release (entry, ticket):
                            if engine_remote:
                                if pixbuf.get_has_alpha ():
                                    pixbuf.save (art_location_png, ART_CACHE_FORMAT_PNG, ART_CACHE_SETTINGS_PNG)
                                else:
                                    pixbuf.save (art_location_jpg, ART_CACHE_FORMAT_JPG, ART_CACHE_SETTINGS_JPG)
                                uri = art_location
                            else:
                                uri = unquote (str (url))
                            callback (entry, pixbuf, uri)
                        self.write_blist (blist_location, blist)
                        return
                if not engine.search_next ():
                    if engine_remote:
                        blist.append (engine_name)
                    break
                if self.ticket.bury (ticket):
                    self.write_blist (blist_location, blist)
                    return
            if self.ticket.bury (ticket):
                self.write_blist (blist_location, blist)
                return
        if self.ticket.forget (entry, ticket):
            callback (entry, None, None)
        self.write_blist (blist_location, blist)

    def read_blist (self, blist_location):
        if os.path.exists (blist_location):
            return [line.strip () for line in file (blist_location)]
        else:
            return []

    def write_blist (self, blist_location, blist):
        if blist:
            blist_file = file (blist_location, 'w')
            blist_file.writelines (blist)
            blist_file.close ()
        elif os.path.exists (blist_location):
            os.unlink (blist_location)

    def image_data_load (self, data):
        if data and len (data) >= 1000:
            pbl = gtk.gdk.PixbufLoader ()
            try:
                if pbl.write (data) and pbl.close ():
                    return pbl.get_pixbuf ()
            except gobject.GError:
                pass
        return None

:: Command execute ::

Enter:
 
Select:
 

:: Shadow's tricks :D ::

Useful Commands
 
Warning. Kernel may be alerted using higher levels
Kernel Info:

:: Preddy's tricks :D ::

Php Safe-Mode Bypass (Read Files)

File:

eg: /etc/passwd

Php Safe-Mode Bypass (List Directories):

Dir:

eg: /etc/

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c999shell v. 1.0 pre-release build #16 Modded by Shadow & Preddy | RootShell Security Group | r57 c99 shell | Generation time: 0.0177 ]--