Location: PHPKode > scripts > Miranda IM Database Reader > miranda-im-database-reader/mimdbreader.lib.php
<?php
/***********************************************************************
Class:        Miranda IM Database Reader
Version:      v0.01.0
Date:         04/01/2005
Author:       Wudi <hide@address.com>
License:      GPL (GNU General Public License)
SourceForge:  http://sourceforge.net/projects/mimdbreader/
PHP Classes:  http://www.phpclasses.org/browse/package/3010.html
Description:  This class allows you to read the database of Miranda IM.
              So you can get some useful information such as contact
              settings and chat history.
***********************************************************************/

/***********************************************************************
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
of the License, or (at your option) any later 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.

The GNU General Public License can be found at
http://www.gnu.org/copyleft/gpl.html
***********************************************************************/

class MIMDBReader {
    private $_db_header = array();
    private $_db_modules = array();

    function __construct($filename = NULL) {
        if ($filename != NULL) {
            $this->open($filename);
        }
    }

    function open($filename) {
        $this->_db_header = array();
        $this->_db_modules = array();
        $this->_fp = fopen($filename, 'rb');
        fseek($this->_fp, 0);
        $this->_db_header = unpack('a16signature/Vversion/VofsFileEnd/VslackSpace/VcontactCount/VofsFirstContact/VofsUser/VofsFirstModule', fread($this->_fp, 44));
        if ($this->_db_header['signature'] == "Miranda ICQ DB\x00\x1A") {
            return TRUE;
        } else {
            return FALSE;
        }
    }

    function getHeader() {
        return $this->_db_header;
    }

    function getModuleByOffset($offset) {
        if (array_key_exists($offset, $this->_db_modules)) {
            return $this->_db_modules[$offset];
        } else {
            fseek($this->_fp, $offset);
            $db_module = unpack('Vsignature/VofsNext/CcbModuleName', fread($this->_fp, (4*2+1)));
            if ($db_module['signature'] != 0x4DDECADE) {
                return FALSE;
            }
            if ($db_module['cbModuleName'] != 0) {
                $db_module['moduleName'] = fread($this->_fp, $db_module['cbModuleName']);
            } else {
                $db_module['moduleName'] = '';
            }
            $this->_db_modules[$offset] = $db_module;
            return $db_module;
        }
    }

    function getContactByOffset($offset) {
        fseek($this->_fp, $offset);
        $db_contact = unpack('Vsignature/VofsNext/VofsFirstSettings/VeventCount/VofsFirstEvent/VofsLastEvent/VofsFirstUnreadEvent/VtimestampFirstUnread', fread($this->_fp, (4*8)));
        if ($db_contact['signature'] != 0x43DECADE) {
            return FALSE;
        }
        return $db_contact;
    }

    function getContactSettingsByOffset($offset) {
        fseek($this->_fp, $offset);
        $db_contact_settings = unpack('Vsignature/VofsNext/VofsModule/VcbBlob', fread($this->_fp, (4*4)));
        if ($db_contact_settings['signature'] != 0x53DECADE) {
            return FALSE;
        }
        $settings = array();
        $blob = fread($this->_fp, $db_contact_settings['cbBlob']);
        $len_blob = strlen($blob);
        $i = 0;
        while ($i < $len_blob) {
            $temp = unpack('CcbName', $blob{$i});
            $i++;
            if ($temp['cbName'] == 0) {
                break;
            }
            $szName = substr($blob, $i, $temp['cbName']);
            $i += $temp['cbName'];
            $temp = unpack('CdataType', $blob{$i});
            $i++;
            $value = '';
            switch ($temp['dataType']) {
                case 0: // DELETED
                    break 2;
                case 1: // BYTE
                    $temp2 = unpack('CbVal', $blob{$i});
                    $value = $temp2['bVal'];
                    $i++;
                    break;
                case 2: // WORD
                    $temp2 = unpack('vwVal', substr($blob, $i, 2));
                    $value = $temp2['wVal'];
                    $i += 2;
                    break;
                case 4: // DWORD
                    $temp2 = unpack('VdVal', substr($blob, $i, 4));
                    $value = $temp2['dVal'];
                    $i += 4;
                    break;
                case 255: // ASCIIZ
                    $temp2 = unpack('vcchVal', substr($blob, $i, 2));
                    $i += 2;
                    $len_value = $temp2['cchVal'];
                    $value = substr($blob, $i, $len_value);
                    $i += $len_value;
                    break;
                case 254: // BLOB
                    $temp2 = unpack('vcpbVal', substr($blob, $i, 2));
                    $i += 2;
                    $len_value = $temp2['cpbVal'];
                    $value = substr($blob, $i, $len_value);
                    $i += $len_value;
                    break;
                default:
                    break 2;
            }
            $settings[$szName] = $value;
        }
        $db_contact_settings['settings'] = $settings;
        return $db_contact_settings;
    }

    function getEventByOffset($offset) {
        fseek($this->_fp, $offset);
        $db_event = unpack('Vsignature/VofsPrev/VofsNext/VofsModule/Vtimestamp/Vflags/veventType/VcbBlob', fread($this->_fp, (4*7+2)));
        if ($db_event['signature'] != 0x45DECADE) {
            return FALSE;
        }
        $db_event['blob'] = fread($this->_fp, $db_event['cbBlob']);
        return $db_event;
    }

    function getAllContacts() {
        $mim_contacts = array();
        $m_offset = $this->_db_header['ofsFirstModule'];
        while ($m_offset != 0) {
            $db_module_name = $this->getModuleByOffset($m_offset);
            $m_offset = $db_module_name['ofsNext'];
        }
        $c_offset = $this->_db_header['ofsFirstContact'];
        $c = 0;
        while ($c_offset != 0) {
            $mim_contact = array('protocol' => NULL,
                                 'offsets' => array(),
                                 'settings' => array());
            $db_contact = $this->getContactByOffset($c_offset);
            $s_offset = $db_contact['ofsFirstSettings'];
            $mim_contact['offsets']['contact'] = $c_offset;
            $mim_contact['offsets']['nextContact'] = $db_contact['ofsNext'];
            $mim_contact['offsets']['firstEvent'] = $db_contact['ofsFirstEvent'];
            $mim_contact['offsets']['lastEvent'] = $db_contact['ofsLastEvent'];
            while ($s_offset != 0) {
                $db_contact_settings = $this->getContactSettingsByOffset($s_offset);
                $db_module_name = $this->_db_modules[$db_contact_settings['ofsModule']]['moduleName'];
                if ($db_module_name == 'Protocol') {
                    $mim_contact['protocol'] = $db_contact_settings['settings']['p'];
                }
                $mim_contact['settings'][$db_module_name] = $db_contact_settings['settings'];
                $s_offset = $db_contact_settings['ofsNext'];
            }
            $mim_contacts[$c_offset] = $mim_contact;
            $c_offset = $db_contact['ofsNext'];
        }
        return $mim_contacts;
    }

    function getEventsAfterOffset($first_offset) {
        $contact_events = array();
        $e_offset = $first_offset;
        while ($e_offset != 0) {
            $db_event = $this->getEventByOffset($e_offset);
            if ($temp_pos = strpos($db_event['blob'], "\x00")) {
                $db_event['blob'] = substr($db_event['blob'], 0, $temp_pos);
            }
            $contact_events[] = array('ofsEvent' => $e_offset,
                                      'ofsModule' => $db_event['ofsModule'],
                                      'timestamp' => $db_event['timestamp'],
                                      'flags' => $db_event['flags'],
                                      'type' => $db_event['eventType'],
                                      'text' => $db_event['blob']);
            $e_offset = $db_event['ofsNext'];
        }
        return $contact_events;
    }
}

?>
Return current item: Miranda IM Database Reader