Wednesday, November 21, 2012

Lazy Fox fun set



import sets

magicc=sets.Set('the quick brown fox jumps over a lazy dog')
>>> sorted(magicc)
[' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
>>> 



Friday, October 26, 2012

Testing Unicode on this blog

Just recently made some small change in this blog's template.  I now implement unicode encoding.  See any changes?

If you right click and select "view source of this page", you should see html tag "<meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/>", which should now support UTF-8 encoding.

Sunday, October 21, 2012

Get Geodata (latitude, longitude, etc.) in Python


I let the API keys empty, 'cause I don't want to expose my keys. You need to register to infodb.com and google to get API keys !!


#!/usr/bin/python

import os
import sys
import socket
import httplib
import xml.dom.minidom as minidom
from googlemaps import GoogleMaps


""" Get googlemap API module from: http://pypi.python.org/pypi/googlemaps/1.0.2

    To get Googlemap API Key:
    https://code.google.com/apis/console/?pli=1#project:255524978890:access

"""

lat=38.4193
lon=-122.6978
myip = "99.9.21x.xx"  (hidden for the purpose of this blog)
debug=0


#time

lat2timeURL="www.earthtools.org"
#lat2timeFile="/timezone/" + str(lat) + '/' + str(lon)

lat2heightURL="www.earthtools.org"
#lat2heightFile="/height/" + str(lat) + "/" + str(lon)

infodb_apikey = "get your own key"
gmap_apikey = "get your own key"

ip2lat2URL = "api.ipinfodb.com"
ip2lat2File = "/v3/ip-city/?key=" + infodb_apikey + "&format=xml&ip="



def getText(nodeList):
    rc = []
    for node in nodeList:
        if node.nodeType == node.TEXT_NODE:
            rc.append(node.data)
    return ''.join(rc)

def getXmlElementFromObj(obj,  name):
    objList = obj.getElementsByTagName(name)[0]
    if objList:
        return getText(objList.childNodes)
    else:
        return ""


def DisplayUsage():
    sys.stderr.write("\nUsage: %s <address in double-quotes>\n\n" % sys.argv[0])


def EarthData(address):
    try:
        gmaps = GoogleMaps(gmap_apikey)
        lat, lon = gmaps.address_to_latlng(address)
    except:
        sys.stderr.write("\nUnable to query GoogleMaps\n")
        sys.exit(1)

    lat2timeFile="/timezone/" + str(lat) + '/' + str(lon)
    lat2heightFile="/height/" + str(lat) + "/" + str(lon)

    conn = httplib.HTTPConnection(lat2timeURL)
    conn.request("GET", lat2timeFile)
    resp = conn.getresponse()
    if resp.status == 200:
        data = resp.read()
        if debug:
            print data
        xml = minidom.parseString(data)
        timezoneObj = xml.getElementsByTagName("timezone")
        for tmObj in timezoneObj:
            nodes = tmObj.childNodes
            version = getXmlElementFromObj(tmObj, "version")
            lat = getXmlElementFromObj(tmObj, "latitude")
            lon = getXmlElementFromObj(tmObj, "longitude")
            localtime = getXmlElementFromObj(tmObj, "localtime")
            isotime = getXmlElementFromObj(tmObj, "isotime")
            utctime = getXmlElementFromObj(tmObj, "utctime")
            #print "version=%s" % version
            if debug:
                print "latitude  : %s" % lat
                print "longitude : %s" % lon
                print "localtime : %s" % localtime
    conn.close()

    conn = httplib.HTTPConnection(lat2heightURL)
    conn.request("GET", lat2heightFile)
    resp = conn.getresponse()
    if resp.status == 200:
        data = resp.read()
        if debug:
            print data
        xml = minidom.parseString(data)
        hObj = xml.getElementsByTagName("height")
        for h in hObj:
            meter = getText(h.getElementsByTagName("meters")[0].childNodes)
            feet = getText(h.getElementsByTagName("feet")[0].childNodes)
            if debug:
                print "Sea-level : %s meters = %s feet" % (meter, feet)

    conn.close()
    return (lat, lon, localtime, meter, feet)


def GetPublicIp(name):
    myip = str(socket.gethostbyname(name))

    iplatURL="api.hostip.info"
    ip2latFile="/?ip=" + myip + "&position=true"
    if debug:
        print "IP Address: %s" % myip
    ip2lat2File += myip
    conn = httplib.HTTPConnection(ip2lat2URL)
    conn.request("GET", ip2lat2File)
    resp = conn.getresponse()
    if resp.status == 200:
        data = resp.read()
        xml = minidom.parseString(data)
        #print data
        locObj = xml.getElementsByTagName("Response")
        for loc in locObj:
            nodes = loc.childNodes
            status = getXmlElementFromObj(loc,"statusCode")
            if status == "OK":
                lat = getXmlElementFromObj(loc, "latitude")
                lon = getXmlElementFromObj(loc, "longitude")
                countryCode = getXmlElementFromObj(loc, "countryCode")
                countryName = getXmlElementFromObj(loc, "countryName")
                regionName = getXmlElementFromObj(loc, "regionName")
                cityName = getXmlElementFromObj(loc, "cityName")
                zipCode = getXmlElementFromObj(loc, "zipCode")
                timezone = getXmlElementFromObj(loc, "timeZone")
                print "Address   : %s %s, %s %s" % (cityName, str(zipCode), regionName, countryName )
    conn.close()

"============================== MAIN =================================="
if __name__ == "__main__":
    if len(sys.argv) < 2:
        DisplayUsage()
        sys.exit(1)
    else:
        addr = sys.argv[1]
        print "Querying %s" % addr
        (lat, lon, ltime, meter, feet) = EarthData(addr)

    print "========================="
    print "Address   : %s" % addr
    print "Latitude  : %s" % lat
    print "Longitude : %s" % lon
    print "Local-time: %s" % ltime
    print "Sea-level : %s meters (%s feet)" % (meter,  feet)

#    print "ip2Lat2=%s%s" % (ip2lat2URL, ip2lat2File)


Example (assume the script above is saved as "earthdata.py"):


bash-4.2$ ./earthdata.py "1450 N McDowell Blvd, Petaluma, CA 94954"
Querying 1450 N McDowell Blvd, Petaluma, CA 94954
=========================
Address   : 1450 N McDowell Blvd, Petaluma, CA 94954
Latitude  : 38.279534
Longitude : -122.6709223
Local-time: 21 Oct 2012 16:47:33
Sea-level : 12 meters (39.4 feet)
bash-4.2$ 

Saturday, September 22, 2012

Message-based Client-Server



Server


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <sys/msg.h>
#include "msgdefs.h"


#define OK      0
#define LOG_ERROR(msg) { printf("%s:%u: %s %s\n", \
                __FUNCTION__, __LINE__, msg, \
                strerror(errno)); }
int msgQueue; 


int CreateMsgQueue(long id)
{
    int msgId;
    key_t key;
    struct msqid_ds ds;

    key = ftok("msgserv.c", id);
    msgId = msgget(key, 0644 | IPC_CREAT);
    if (msgId < 0)
    {
        LOG_ERROR("msgget");
    }
    if (EEXIST == errno)
    {
        // reuse
        msgctl(msgId, IPC_STAT, &ds);
        key = ftok("msgserv.key", id);
        msgId = msgget(key, 0777 | IPC_SET);
    }
    return msgId;
}


int SendMsg(void *msg, size_t msgsz, int msgflg)
{
    Msg_t *pMsg;
    char *pData;
    int retval = 0;
    
    pMsg = malloc(sizeof(Msg_t) + msgsz);
    pMsg->hdr.msgType = 1;
    pMsg->hdr.dataSize = msgsz;
    pData = (char*)(&pMsg->data[0]);
    memcpy(pData, msg, msgsz);
    retval = msgsnd(msgQueue, pMsg, msgsz, msgflg);
    free(pMsg);
  
    return retval;
}


void *SendMsgTask(void *arg)
{
    Msg_t msg;
    long tick = 0;

    if (arg)
   printf("This is task %d\n", *(int *) arg);
    else
    printf("This is task\n");
#if 1
    do {
        // send msg
        printf("Sending tick=%lu\n", tick);
        if (OK != SendMsg(&tick, sizeof(tick), 0))
        {
            LOG_ERROR("SendMsg failed");
        }
        tick++;
        usleep(500000);
        //sleep(1);
    } while (tick < 50);
    //send quit
    msg.hdr.msgType = 2;
    msgsnd(msgQueue, &msg, sizeof(msg), 0);
    return NULL;
#endif
}




int main()
{
    int retval;
    pthread_t SendMsgTaskId;
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    msgQueue = CreateMsgQueue(MESSAGE1);
    if (msgQueue > 0) {
        printf("Start the thread..\n");
        retval = pthread_create(&SendMsgTaskId, &attr, SendMsgTask, NULL);
        if (OK == retval)
            pthread_join(SendMsgTaskId, NULL);
    }
    else {
        LOG_ERROR("CreateMsgQueue");
    }
    if (OK != msgctl(msgQueue, IPC_RMID, NULL))
    {
        LOG_ERROR("msgctl");
        exit(1);
    }
    pthread_attr_destroy(&attr);
    return 0;
}




Client



#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <sys/msg.h>
#include "msgdefs.h"


#define OK      0
#define LOG_ERROR(msg) { printf("%s:%u: %s %s\n", \
                __FUNCTION__, __LINE__, msg, \
                strerror(errno)); }
int msgQueue; 


int InitMsgQueue(long id)
{
    int msgId;
    key_t key;

    key = ftok("msgserv.c", id);
    msgId = msgget(key, 0644);
    if (OK != msgId)
    {
        LOG_ERROR("msgget");
    }
    return msgId;
}


int ReceiveMsg(Msg_t **pMsg, size_t *msgsz)
{
    int sz;

    int retval = 0;
    
    sz = 256;
    *pMsg = malloc(sizeof(Msg_t) + sz);
    retval = msgrcv(msgQueue, *pMsg, sz, 0, 0);
    *msgsz = sz;
    return retval;
}


void *ReceiveMsgTask(void *arg)
{
    Msg_t *pMsg;
    size_t sz;

    if (arg)
   printf("This is task %d\n", *(int *) arg);
    else
    printf("This is task\n");

    for(;;) {
        // rcv msg
        if (ReceiveMsg(&pMsg, &sz) < 0)
        {
            LOG_ERROR("ReceiveMsg");
            return NULL;
        } 
        else {
            printf("MsgType = %lu\n", pMsg->hdr.msgType);
            switch (pMsg->hdr.msgType) {
                case 1:
                    printf("Received sz=%u, tick=%lu\n", 
                            pMsg->hdr.dataSize,
                            *(long*)(&pMsg->data[0]));
                    break;
                default:
                    printf("End of task\n");
                    free(pMsg);
                    return NULL;
            }

        }
        // msg must be freed
        free(pMsg);
    } 
    return NULL;
}




int main()
{
    int retval;
    pthread_t ReceiveMsgTaskId;
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    msgQueue = InitMsgQueue(MESSAGE1);
    if (msgQueue > 0) {
        printf("Start the thread..\n");
        retval = pthread_create(&ReceiveMsgTaskId, &attr, ReceiveMsgTask, NULL);
        if (OK == retval)
            pthread_join(ReceiveMsgTaskId, NULL);
    }
    else {
        LOG_ERROR("InitMsgQueue");
    }
    pthread_attr_destroy(&attr);
    return 0;
}



msgdefs.h

#ifndef __MSGDEFS_H__
#define __MSGDEFS_H__


enum {
    MESSAGE1 = 0x10000000
};

#define MSG_DATA_SIZE       1024

typedef struct {
    long msgType;
    unsigned int dataSize;
} MsgHdr_t;

typedef struct {
    MsgHdr_t hdr; /* our header */
    char data[0];   // just a place holder
} Msg_t;


#endif


Sunday, September 16, 2012

Ripping VCD to Various Formats


Using VCDXRIP

To convert to MPEG:

$ vcdxrip


USING MENCODER

mencoder [options] file [file|URL|-] [-o file | file://file | smb://[user:pass@]host/filepath]

mencoder vcd//:2 -oac lavc -ovc lavc -o filename.avi 

($ sign is the terminal prompt)


                 -oac lavc
                      Encode with a libavcodec codec

                 -ovc lavc
                      Encode with a libavcodec codec.




Using CDFS

The source can be downloaded here:

http://users.elis.ugent.be/~mronsse/cdfs/download/

(Unfortunately, the driver doesn't yet support later Linux versions).

$ mount -t cdfs -o ro /dev/cdrom /mnt/video

And copy the *.DAT files



FFMPEG

FFMPEG is a very powerful tool (command-line) to transcode media file.

For example, to extract audio from an AVI file:

$ ffmeg -i source_video.avi -vn -ar 44100 -ac 2 192 -f mp3 sound.mp3

To convert MPG to AVI (or vise-versa):

$ ffmeg -i video_original.mpg output.avi

To encode WAV to mp3:

$ ffmpeg -i video.wav -vn -ar 44100 -ac 2 -ab 192 -f mp3 song.mp3


To mix a WAV file with a video file:

$ ffmpeg -i audio.wav -i video.avi audio_video.avi

To convert AVI to MPEG suitable for DVD:

ffmpeg -i source_video.avi -target pal-dvd -ps 2000000000 -aspect 16:9 finale_video.mpeg 


AVI to VCD:

$ ffmpeg -i video.avi -target ntsc-vcd video_out.mpg

To use 2-pass encoding, pass "-pass 2 -passlogfile somefile" before output file.

HandBrake


We then can use Handbrake to transcode video from CD/DVD to various formats, especially for Apple products.
There are two versions of HandBrake, one is the GUI front-end, and the CLI version.


To list the built-in presets:

$ HandBrakeCLI -z

To use the preset, use capital "-Z"
For example:

$HandBrakeCLI -Z "iPhone 4" -i avseq0.avi -o output.mp4



Tuesday, September 11, 2012

Script to convert series of WAV files

Assume there are wav files named as "disc_1.wav", "disc_2.wav" so on.
There is also a cover file (a JPEG format file) to be used as cover album embedded into each encoded MP3 file.

If we want to convert them all into MP3:



#!/bin/sh

ARTIST="Hamza Yusuf"
ALB="The Rights and Responsibilities of Marriage"
TY="2002"
GENRE="Vocal"
for i in `ls disc_*.wav | sort -V` ;
do
    TN=`echo $i | awk 'BEGIN { FPAT="[[:digit:]]+"} ; {  print $1 }'`
    lame --ti "./the_rights_and_responsibilities_of_marriage.jpg" --tt "$ALB cd$TN" --ta "$ARTIST" --tl i"$ALB" --ty "$TY" --tn "$TN/13" --tg "$GENRE" $i "$ALB cd${TN}.mp3"

done

Sunday, September 9, 2012

Youtube Video to MP3


  1. Download script youtube-dl from  http://rg3.github.com/youtube-dl/
  2. Make sure we have ffmpeg installed
  3. Write a small script with content as below:

youtube-dl --extract-audio --audio-format mp3 -v -t "$1"

For example, to download and extract the audio and save it as MP3 (assuming the small script above has been saved as utube":

utube http://www.youtube.com/watch?v=RoqRbe3dgwU&feature=g-vrec

Post-processing:

concatenate multiple MP3 files to become one mp3:

mp3wrap <file1> <file2> ... <output>

To downmix the result file to a mono-aural:

lame -m s -a <file> <downmix.mp3>


to copy the ID3 data from the original file to the output file

id3cp <mp3 source> <mp3 dest>





Saturday, June 23, 2012

How to set root password on ReadyNAS

Recently I have forgotten my ReadyNAS password.  Even worse, I couldn't login at all due reckless upgrade I did on the box.  I was able to undo the upgrade by letting the box recopies the Linux from its firmware to the drive (see ReadyNAS forum/documentation on how to make the ReadyNAS box recopy the firmware), but still I forgot what my root password was.

Various steps I had tried as I found on the Internet as well as on the ReadyNAS website, but none of them work. Finally, I had an idea to just access the drive directly thru SATA-to-USB cable and reset the password manually.

Basically what I did was to set the root password stored in the file /etc/passwd (fortunately the authententication is still the old-fashioned one, where the MD5 encrypted password stored directly in the file instead in shadow file).

You might ask, "How the hell I access the drive?".  Well, first you need remove the drive from the ReadyNAS bay (make sure it is turned off!!) then  attach the SATA-to-USB cable to the drive.  Connect the usb end to our PC.

We cannot mount directly to the drive, because some other issues.  To mount, see my previous post ("How to mount disk used by ReadyNAS").  Once it is  mounted (just mount the ext3 partition [first partition], no need to mount the LVM), we can now modify the file /etc/passwd.

First, save the following script (thanks to somebody who posted it on the Internet), say, as /home/<yourloginname>/bin/setpasswd:


#!/usr/bin/perl
################################################################################
# Generate an MD5 hash for a string.
# Created to allow me to set a blank Linux password. Required this to create
# multiple VsFTP accounts with anonymous style credientials.
#
# If all you want is the MD5 Hash for NULL (blank password) here's one...
# $1$VNMbpxGH$sew7cnwH9ixU.x27UbFNn.
#
# Advice: If replacing a Linux password with a blank string, ensure you give 
# the user a shell of /sbin/nologin as you wouldn't want them to login!
################################################################################
# Load dependancies...
# perl -MCPAN -e 'install Crypt::PasswdMD5'
################################################################################


use strict;
use Crypt::PasswdMD5 qw(unix_md5_crypt);
my @salt = ( '.', '/', 0 .. 9, 'A' .. 'Z', 'a' .. 'z' );
my %encrypted;




sub abort {
print "ABORT: $_[0]\n";
exit 1
}




sub gensalt { #------------------------------------------------------------
# uses global @salt to construct salt string of requested length
my $count = shift;


my $salt;
for (1..$count) {
$salt .= (@salt)[rand @salt];
}


return $salt;
} # end gensalt




sub get_encryptedpw { #--------------------------------------------------
my $unencrypted="$_[0]";


# generate traditional (weak!) DES password, and more modern md5
$encrypted{des} = crypt( $unencrypted, gensalt(2) );
$encrypted{md5} = unix_md5_crypt( $unencrypted, gensalt(8) );


return %encrypted;
}


################################################################################
print "Enter password string to encrypt (can be blank) : ";
my $password = <STDIN>;
chomp $password;


get_encryptedpw($password);


print "Plaintext \"$password\" = MD5 Hash: $encrypted{md5}\n";
print "\nReplace the /etc/shadow password string with the above to force pass change\n";




(Don't forget to make it executable by doing "chmod +x ./setpasswd)
Run the script.  It will ask you to enter a password.  An example of the output (with blank password):


$ setpasswd
Enter password string to encrypt (can be blank) : 
Plaintext "" = MD5 Hash: $1$udf2EDLY$a/cLQQ4h25rwZQc9VKmG6/


Replace the /etc/shadow password string with the above to force pass change

Copy the portion after the string "MD5 Hash: " above and paste it in the <READYNAS MOUNTPOINT>/etc/passwd.  To be precise, it should be pasted in line where "root:...". Paste it right after "root:", and let the rest of the existing text still intact.

Save the file, unmount (just use the regular umount for this one), reinsert the drive into the ReadyNAS bay and turn it on.  Once it is running, try to SSH to the box as root and enter the new password.  It should work!


How to mount disk used by ReadyNAS

The following steps are useful if we want to salvage data stored in a drive in ReadyNAS.
I am not sure if the steps below are going to work on other ReadyNAS models, but it works on my ReadyNAS Duo (Sparc CPU).

Basically, what we need is a SATA-to-USB cabel (can be bought in the Internet for couple of bucks).
ReadyNAS partitions the drive into 4 partitions.  In my case, it is detected as /dev/sdc:


[root@r3000 media]# fdisk -l /dev/sdc


Disk /dev/sdc: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000


   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1               2     4096001     2048000   83  Linux
/dev/sdc2         4096002     4608001      256000   82  Linux swap / Solaris
/dev/sdc3         4608002  1953092233   974242116    5  Extended
/dev/sdc5         4608003  1953092233   974242115+  8e  Linux LVM
[root@r3000 media]# 


There are couple of issues if we try to mount the partitions directly:

  1. ReadyNAS uses non-standard ext3 block-size, which in my case is 16384 bytes (use command "lvsc
  2. The home directory is partitioned as LV group, so conventional mount command is not gonna work
Here's the steps:
  • Scan the usb for LVM volumes and identify in the output the volume group name that has your READYNAS volume (mine proved to be c):
# vgscan
[root@r3000 media]# vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "c" using metadata type lvm2
  Found volume group "vg_r3000" using metadata type lvm2
  Found volume group "VolGroup" using metadata type lvm2
  • Activate the group for ReadyNAS (in this case, the group name is "C")
# vgchange -ay c
  • Find the logical volume that  (mine proved to be 'c'):
# lvs
  • To display the logical name of the partition, use command "lvdisplay":
# lvdisplay /dev/c
  --- Logical volume ---
  LV Name                /dev/c/c
  VG Name                c
  LV UUID                7HUOrf-B5bL-ur6r-ULsd-yl4m-gCrA-zQc4s9
  LV Write Access        read/write
  LV Status              available
  # open                 0
  LV Size                929.09 GiB
  Current LE             29731
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:5


We cannot use regular command "mount" to mount the non-standard blocksize ext3 partition.  Fortunately, there is a tool called "fuse-ext3" running in userspace that can help us.  The tool can be downloaded here.

Here's an example how to mount my ReadyNAS's LV volume:

fuse-ext2 -o sync_read,allow_other,rw+ /dev/c/c /media/readynas2

And here is the command to mount the system (root) partition which has the Linux software (I will post later about how to reset root password without resetting the ReadyNAS to factory default etc.)

fuse-ext2 -o sync_read,allow_other,rw+ /dev/c/c /media/readynas2




Sunday, March 25, 2012

Undirected Graph

The following small program illustrate how to implement a undirected graph with costs to neighbor nodes.


#ifndef _GRAPH_HPP_
#define _GRAPH_HPP_

#include <iostream>
#include <map>
#include <list>

using namespace std;

/*
* Undirected graph class
*/
class Graph {
public:
Graph(unsigned int id=0) { m_id = id; m_Ecount = 0; }
virtual ~Graph();
void SetId(unsigned int id) { m_id = id; }
bool Match(Graph& g);
bool AddAdjacent(Graph* g, int cost=0);
bool AddAdjacentOne(Graph *g);
list GetAdjacents() { return m_Adjacents; }

int GetVCount() { return m_Adjacents.size(); }
int GetECount() { return m_Ecount; }
unsigned int GetId() { return m_id; }
void SetCostTo(Graph *g, int cost);
int GetCostTo(Graph* g);

private:
unsigned int m_id;
int m_Ecount;
map<Graph*,int> m_cost;
list<Graph*> m_Adjacents;
};


#endif




graph.pp:

#include "graph.hpp"

using namespace std;

Graph::~Graph()
{
// TODO:
m_Adjacents.clear();
}


bool Graph::Match(Graph& g)
{
cout << "this=" << this << endl;
cout << "&g =" << &g << endl;
if ((this == &g) || (g.GetId() == this->GetId()) &&
(g.GetECount() == this->GetECount()) &&
(g.GetVCount() == this->GetVCount()) )
return true;
return false;
}

bool Graph::AddAdjacentOne(Graph *g)
{
m_Adjacents.push_back(g);
//TODO: we need to tell g to add also edge to this object
m_Ecount++;
return true;
}


void Graph::SetCostTo(Graph *g, int cost)
{
if (g == NULL)
return;
// Use hash-table to set the cost from this node to g
m_cost[g] = cost;
}

int Graph::GetCostTo(Graph *g)
{
if (g == NULL)
return -1;
// use hash-table to get the cost from this node to g
return m_cost[g];
}

bool Graph::AddAdjacent(Graph* g, int cost)
{
if (!g) return false;

if (Match(*g))
{
cout << "ERROR: Tried to add itself" << endl;
return false;
}
else {
AddAdjacentOne(g);
// tell other node to set its adjacent to this node too
g->AddAdjacentOne(this);
// add cost from this object to g
g->SetCostTo(this, cost);
SetCostTo(g, cost);
return true;
}
}



int main()
{
Graph g[10];
int i;
int numOfVertices = 4;

for(i=0; i<numOfVertices; i++)
g[i].SetId(i);

// g0 --- g1
g[0].AddAdjacent(&g[1]);
//g1 --- g2
g[1].AddAdjacent(&g[2]);
// g2 --- g3
g[2].AddAdjacent(&g[3]);
// g3 --- g0
g[3].AddAdjacent(&g[0]);
// g0 -- g2
g[0].AddAdjacent(&g[2], 5);

list<Graph*>::iterator it;
list<Graph*> adjacents;

for(i=0; i<numOfVertices; i++)
{
cout << "NODE g[" << i << "]" << endl;
cout << "\tNumber of Edges in G[" << i << "] = " << g[i].GetECount() << endl;

adjacents = g[i].GetAdjacents();
cout << "\tNeighbors:" << endl;
for ( it=adjacents.begin() ; it != adjacents.end(); it++ )
cout << "\t\tNode=" << *it << ", g[" << (*it)->GetId() << "], cost="
<< g[i].GetCostTo(*it) << endl;
}
}

Friday, March 23, 2012

MIVO.TV Network Analysis

While my browser was playing the video streaming (tru flash-plugin) from mivo.tv,  a "netstat -t" revealed high traffic as below:


tcp        0      0 192.168.0.29:56448          68.68.29.24.:macromedia-fcs ESTABLISHED

After googling this "macromedia-fcs" I found:

TCP & UDP Port 1935 (Macromedia-fcs)



Technical description for port 1935:
The RTMP (Real Time Messaging Protocol) service associated with the computer port 1935 is a plain protocol utilized by the Adobe Macromedia Flash application. This proprietary service allows for the streaming of data, video and audio using an active Internet connection among a Flash Server and its associated player. This port supports the three variations of the RTMP service.

The communication port 1935 along with the TCP protocol is used for the delivery of encapsulated RTMPT that traverses firewall applications using HTTPS (secured) connections. The design of this protocol was intended to provide a persistent service for the Flash technology along with other programs like Adobe LiveCycle Data Services ES.

The raw TCP RTMP protocol uses one persistent connection for allowing the implementation of real time communication and smooth delivery of multimedia contents.

The protocol running on the port 1935 achieves this quality of transmission without affecting its ability to send bigger chunks of information including the fragmentation of data.


Digging deeper to the HTML code, I found a port in Javascript like this:


<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
     <codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" 
               width="610" height="878" id="MivoTV" align="top">'
         <param name="wmode" value="transparent">
         <param name="allowScriptAccess" value="always" />
         <param name="allowFullScreen" value="true" />
         <param name="SeamlessTabbing" value="false"/>
         <param name="movie" value="http://mivotv-static.com/swf/MivoTV.swf?r=99123"/>
         <param name="quality" value="high" />
         <param name="scale" value="noscale" />
         <param name="menu" value="true" />
         <param name="devicefont" value="false" />
         <param name="bgcolor" value="#ffffff" />
         <param name="name" value="MivoTV" />
         <embed src="http://mivotv-static.com/swf/MivoTV.swf?r=99999" quality="high" scale="noscale" bgcolor="#ffffff" width="610" height="878" name="MivoTV" align="top" allowScriptAccess="always" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" wmode="transparent" menu="true" devicefont="false" />
         
<font style="white-space: pre-wrap;"><font face="inherit">But why it doesn't work if I open the URL directly and put some random number at the end [0..99999]?</font></font></p>
<p>


<font style="white-space: pre-wrap;"><font face="inherit"><br></font></font></p>
</object></pre>



'
























But why it doesn't work if I open the URL directly and put some random number at the end [0..99999]?







Hash template in C++

 

#include <map>
#include <iostream>
#include <cstring>

using namespace std;

struct eqstr {
bool operator() (const char *s1, const char *s2) const {
return (::strcmp(s1, s2) < 0 ? true : false);
}
};


int main()
{
// template
map <const char *, int, eqstr> months;

months["january"] = 31;
months["february"] = 28;
months["march"] = 31;
months["april"] = 30;
months["may"] = 31;
months["june"] = 30;
months["july"] = 31;
months["august"] = 31;
months["september"] = 30;
months["october"] = 31;
months["november"] = 30;
months["december"] = 31;

cout << "february -> " << months["february"] << endl;
cout << "september -> " << months["september"] << endl;
cout << "april -> " << months["april"] << endl;
cout << "july -> " << months["july"] << endl;
cout << "november -> " << months["november"] << endl;

for(map::iterator it=months.begin();
it != months.end(); it++)
{
cout << (*it).first << " => " << (*it).second << endl;
}
}

Wednesday, March 21, 2012

ELF File Format

The C++ source code below:


#include <cstdio>
#include <iostream>

using namespace std;

class CParent {
public:
CParent() {
ref++;
cout << "class CParent: constructor ref=" << ref << endl;
Function();
};
virtual ~CParent() {
ref--;
cout << "class CParent: destructor ref=" << ref << endl;
}
virtual int Function() {
cout << "\tA::Function()" << endl;
return ref;
}
static unsigned int ref;
};


class CChild : public CParent {
public:
CChild() {
ref++;
cout << "\tclass CChild: constructor ref=" << ref << endl;
m_a = new CParent();
};
virtual ~CChild() {
ref--;
cout << "\tclass CChild: destructor ref=" << ref << endl;
delete m_a;
}

static unsigned int ref;
private:
CParent *m_a;
};


unsigned int CParent::ref = 0;
unsigned int CChild::ref = 0;

int main()
{
int i;
int n = 2;

CChild *c = new CChild[n];
for(i=0; i(&c[i]);
printf("p[%d].Function()=%d\n", i, p->Function());
}
cout << "CChild::Ref=" << CChild::ref << endl;
delete [] c;
}

A in-depth view of the generated ELF file format from the above C++ code is as below:


[buhadram@localhost src]$ readelf -a virt
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x80487d0
Start of program headers: 52 (bytes into file)
Start of section headers: 5192 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 8
Size of section headers: 40 (bytes)
Number of section headers: 31
Section header string table index: 28

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 08048134 000134 000013 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 08048148 000148 000020 00 A 0 0 4
[ 3] .note.gnu.build-i NOTE 08048168 000168 000024 00 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0804818c 00018c 000040 04 A 5 0 4
[ 5] .dynsym DYNSYM 080481cc 0001cc 000160 10 A 6 1 4
[ 6] .dynstr STRTAB 0804832c 00032c 000214 00 A 0 0 1
[ 7] .gnu.version VERSYM 08048540 000540 00002c 02 A 5 0 2
[ 8] .gnu.version_r VERNEED 0804856c 00056c 000080 00 A 6 3 4
[ 9] .rel.dyn REL 080485ec 0005ec 000020 08 A 5 0 4
[10] .rel.plt REL 0804860c 00060c 000080 08 A 5 12 4
[11] .init PROGBITS 0804868c 00068c 000030 00 AX 0 0 4
[12] .plt PROGBITS 080486bc 0006bc 000110 04 AX 0 0 4
[13] .text PROGBITS 080487d0 0007d0 0005dc 00 AX 0 0 16
[14] .fini PROGBITS 08048dac 000dac 00001c 00 AX 0 0 4
[15] .rodata PROGBITS 08048dc8 000dc8 000114 00 A 0 0 8
[16] .eh_frame_hdr PROGBITS 08048edc 000edc 000074 00 A 0 0 4
[17] .eh_frame PROGBITS 08048f50 000f50 00022c 00 A 0 0 4
[18] .gcc_except_table PROGBITS 0804917c 00117c 000041 00 A 0 0 1
[19] .ctors PROGBITS 0804a1c0 0011c0 00000c 00 WA 0 0 4
[20] .dtors PROGBITS 0804a1cc 0011cc 000008 00 WA 0 0 4
[21] .jcr PROGBITS 0804a1d4 0011d4 000004 00 WA 0 0 4
[22] .dynamic DYNAMIC 0804a1d8 0011d8 0000e0 08 WA 6 0 4
[23] .got PROGBITS 0804a2b8 0012b8 000004 04 WA 0 0 4
[24] .got.plt PROGBITS 0804a2bc 0012bc 00004c 04 WA 0 0 4
[25] .data PROGBITS 0804a308 001308 000004 00 WA 0 0 4
[26] .bss NOBITS 0804a320 00130c 000120 00 WA 0 0 32
[27] .comment PROGBITS 00000000 00130c 00002c 01 MS 0 0 1
[28] .shstrtab STRTAB 00000000 001338 00010e 00 0 0 1
[29] .symtab SYMTAB 00000000 001920 000680 10 30 49 4
[30] .strtab STRTAB 00000000 001fa0 0005a2 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)

There are no section groups in this file.

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4
INTERP 0x000134 0x08048134 0x08048134 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x011bd 0x011bd R E 0x1000
LOAD 0x0011c0 0x0804a1c0 0x0804a1c0 0x0014c 0x00280 RW 0x1000
DYNAMIC 0x0011d8 0x0804a1d8 0x0804a1d8 0x000e0 0x000e0 RW 0x4
NOTE 0x000148 0x08048148 0x08048148 0x00044 0x00044 R 0x4
GNU_EH_FRAME 0x000edc 0x08048edc 0x08048edc 0x00074 0x00074 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4

Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame .gcc_except_table
03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.ABI-tag .note.gnu.build-id
06 .eh_frame_hdr
07

Dynamic section at offset 0x11d8 contains 23 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0x804868c
0x0000000d (FINI) 0x8048dac
0x6ffffef5 (GNU_HASH) 0x804818c
0x00000005 (STRTAB) 0x804832c
0x00000006 (SYMTAB) 0x80481cc
0x0000000a (STRSZ) 532 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x804a2bc
0x00000002 (PLTRELSZ) 128 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x804860c
0x00000011 (REL) 0x80485ec
0x00000012 (RELSZ) 32 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0x804856c
0x6fffffff (VERNEEDNUM) 3
0x6ffffff0 (VERSYM) 0x8048540
0x00000000 (NULL) 0x0

Relocation section '.rel.dyn' at offset 0x5ec contains 4 entries:
Offset Info Type Sym.Value Sym. Name
0804a2b8 00000206 R_386_GLOB_DAT 00000000 __gmon_start__
0804a320 00000f05 R_386_COPY 0804a320 _ZTVN10__cxxabiv117__c
0804a360 00001405 R_386_COPY 0804a360 _ZSt4cout
0804a400 00001005 R_386_COPY 0804a400 _ZTVN10__cxxabiv120__s

Relocation section '.rel.plt' at offset 0x60c contains 16 entries:
Offset Info Type Sym.Value Sym. Name
0804a2c8 00000107 R_386_JUMP_SLOT 00000000 __cxa_atexit
0804a2cc 00000207 R_386_JUMP_SLOT 00000000 __gmon_start__
0804a2d0 00000407 R_386_JUMP_SLOT 00000000 _ZdlPv
0804a2d4 00000507 R_386_JUMP_SLOT 00000000 _ZNSt8ios_base4InitC1E
0804a2d8 00000607 R_386_JUMP_SLOT 00000000 __libc_start_main
0804a2dc 00001307 R_386_JUMP_SLOT 0804871c _ZNSt8ios_base4InitD1E
0804a2e0 00000707 R_386_JUMP_SLOT 00000000 _ZStlsISt11char_traits
0804a2e4 00000807 R_386_JUMP_SLOT 00000000 printf
0804a2e8 00000907 R_386_JUMP_SLOT 00000000 _ZNSolsEj
0804a2ec 00000a07 R_386_JUMP_SLOT 00000000 _Znwj
0804a2f0 00000b07 R_386_JUMP_SLOT 00000000 _Znaj
0804a2f4 00000c07 R_386_JUMP_SLOT 00000000 _ZdaPv
0804a2f8 00000d07 R_386_JUMP_SLOT 00000000 _ZNSolsEPFRSoS_E
0804a2fc 00001207 R_386_JUMP_SLOT 0804879c _ZSt4endlIcSt11char_tr
0804a300 00001507 R_386_JUMP_SLOT 080487ac __gxx_personality_v0
0804a304 00000e07 R_386_JUMP_SLOT 00000000 _Unwind_Resume

There are no unwind sections in this file.

Symbol table '.dynsym' contains 22 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@GLIBC_2.1.3 (2)
2: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
3: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
4: 00000000 0 FUNC GLOBAL DEFAULT UND _ZdlPv@GLIBCXX_3.4 (3)
5: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitC1Ev@GLIBCXX_3.4 (3)
6: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (4)
7: 00000000 0 FUNC GLOBAL DEFAULT UND _ZStlsISt11char_traitsIcE@GLIBCXX_3.4 (3)
8: 00000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.0 (4)
9: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNSolsEj@GLIBCXX_3.4 (3)
10: 00000000 0 FUNC GLOBAL DEFAULT UND _Znwj@GLIBCXX_3.4 (3)
11: 00000000 0 FUNC GLOBAL DEFAULT UND _Znaj@GLIBCXX_3.4 (3)
12: 00000000 0 FUNC GLOBAL DEFAULT UND _ZdaPv@GLIBCXX_3.4 (3)
13: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNSolsEPFRSoS_E@GLIBCXX_3.4 (3)
14: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume@GCC_3.0 (6)
15: 0804a320 44 OBJECT WEAK DEFAULT 26 _ZTVN10__cxxabiv117__clas@CXXABI_1.3 (5)
16: 0804a400 44 OBJECT WEAK DEFAULT 26 _ZTVN10__cxxabiv120__si_c@CXXABI_1.3 (5)
17: 08048dcc 4 OBJECT GLOBAL DEFAULT 15 _IO_stdin_used
18: 0804879c 0 FUNC GLOBAL DEFAULT UND _ZSt4endlIcSt11char_trait@GLIBCXX_3.4 (3)
19: 0804871c 0 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitD1Ev@GLIBCXX_3.4 (3)
20: 0804a360 140 OBJECT GLOBAL DEFAULT 26 _ZSt4cout@GLIBCXX_3.4 (3)
21: 080487ac 0 FUNC GLOBAL DEFAULT UND __gxx_personality_v0@CXXABI_1.3 (5)

Symbol table '.symtab' contains 104 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 08048134 0 SECTION LOCAL DEFAULT 1
2: 08048148 0 SECTION LOCAL DEFAULT 2
3: 08048168 0 SECTION LOCAL DEFAULT 3
4: 0804818c 0 SECTION LOCAL DEFAULT 4
5: 080481cc 0 SECTION LOCAL DEFAULT 5
6: 0804832c 0 SECTION LOCAL DEFAULT 6
7: 08048540 0 SECTION LOCAL DEFAULT 7
8: 0804856c 0 SECTION LOCAL DEFAULT 8
9: 080485ec 0 SECTION LOCAL DEFAULT 9
10: 0804860c 0 SECTION LOCAL DEFAULT 10
11: 0804868c 0 SECTION LOCAL DEFAULT 11
12: 080486bc 0 SECTION LOCAL DEFAULT 12
13: 080487d0 0 SECTION LOCAL DEFAULT 13
14: 08048dac 0 SECTION LOCAL DEFAULT 14
15: 08048dc8 0 SECTION LOCAL DEFAULT 15
16: 08048edc 0 SECTION LOCAL DEFAULT 16
17: 08048f50 0 SECTION LOCAL DEFAULT 17
18: 0804917c 0 SECTION LOCAL DEFAULT 18
19: 0804a1c0 0 SECTION LOCAL DEFAULT 19
20: 0804a1cc 0 SECTION LOCAL DEFAULT 20
21: 0804a1d4 0 SECTION LOCAL DEFAULT 21
22: 0804a1d8 0 SECTION LOCAL DEFAULT 22
23: 0804a2b8 0 SECTION LOCAL DEFAULT 23
24: 0804a2bc 0 SECTION LOCAL DEFAULT 24
25: 0804a308 0 SECTION LOCAL DEFAULT 25
26: 0804a320 0 SECTION LOCAL DEFAULT 26
27: 00000000 0 SECTION LOCAL DEFAULT 27
28: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
29: 0804a1c0 0 OBJECT LOCAL DEFAULT 19 __CTOR_LIST__
30: 0804a1cc 0 OBJECT LOCAL DEFAULT 20 __DTOR_LIST__
31: 0804a1d4 0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__
32: 08048800 0 FUNC LOCAL DEFAULT 13 __do_global_dtors_aux
33: 0804a42c 1 OBJECT LOCAL DEFAULT 26 completed.5530
34: 0804a430 4 OBJECT LOCAL DEFAULT 26 dtor_idx.5532
35: 08048860 0 FUNC LOCAL DEFAULT 13 frame_dummy
36: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
37: 0804a1c8 0 OBJECT LOCAL DEFAULT 19 __CTOR_END__
38: 08049178 0 OBJECT LOCAL DEFAULT 17 __FRAME_END__
39: 0804a1d4 0 OBJECT LOCAL DEFAULT 21 __JCR_END__
40: 08048d80 0 FUNC LOCAL DEFAULT 13 __do_global_ctors_aux
41: 00000000 0 FILE LOCAL DEFAULT ABS virt.cpp
42: 0804a43c 1 OBJECT LOCAL DEFAULT 26 _ZStL8__ioinit
43: 08048a08 64 FUNC LOCAL DEFAULT 13 _Z41__static_initializati
44: 08048a48 28 FUNC LOCAL DEFAULT 13 _GLOBAL__I__ZN7CParent3re
45: 0804a2bc 0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_
46: 0804a1bd 0 NOTYPE LOCAL DEFAULT 19 __init_array_end
47: 0804a1bd 0 NOTYPE LOCAL DEFAULT 19 __init_array_start
48: 0804a1d8 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC
49: 0804a308 0 NOTYPE WEAK DEFAULT 25 data_start
50: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@@GLIBC_2.1.3
51: 08048d70 5 FUNC GLOBAL DEFAULT 13 __libc_csu_fini
52: 080487d0 0 FUNC GLOBAL DEFAULT 13 _start
53: 08048ebc 12 OBJECT WEAK DEFAULT 15 _ZTI6CChild
54: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
55: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
56: 08048dc8 4 OBJECT GLOBAL DEFAULT 15 _fp_hw
57: 00000000 0 FUNC GLOBAL DEFAULT UND _ZdlPv@@GLIBCXX_3.4
58: 0804a434 4 OBJECT GLOBAL DEFAULT 26 _ZN7CParent3refE
59: 08048dac 0 FUNC GLOBAL DEFAULT 14 _fini
60: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitC1Ev@@
61: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
62: 08048e88 20 OBJECT WEAK DEFAULT 15 _ZTV6CChild
63: 08048b56 49 FUNC WEAK DEFAULT 13 _ZN7CParent8FunctionEv
64: 08048cea 30 FUNC WEAK DEFAULT 13 _ZN6CChildD0Ev
65: 08048b88 171 FUNC WEAK DEFAULT 13 _ZN6CChildC2Ev
66: 0804871c 0 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitD1Ev@@
67: 00000000 0 FUNC GLOBAL DEFAULT UND _ZStlsISt11char_traitsIcE
68: 08048dcc 4 OBJECT GLOBAL DEFAULT 15 _IO_stdin_used
69: 0804a308 0 NOTYPE GLOBAL DEFAULT 25 __data_start
70: 0804a320 44 OBJECT WEAK DEFAULT 26 _ZTVN10__cxxabiv117__clas
71: 0804a360 140 OBJECT GLOBAL DEFAULT 26 _ZSt4cout@@GLIBCXX_3.4
72: 08048dd0 0 OBJECT GLOBAL HIDDEN 15 __dso_handle
73: 0804a1d0 0 OBJECT GLOBAL HIDDEN 20 __DTOR_END__
74: 08048d10 90 FUNC GLOBAL DEFAULT 13 __libc_csu_init
75: 00000000 0 FUNC GLOBAL DEFAULT UND printf@@GLIBC_2.0
76: 08048a64 100 FUNC WEAK DEFAULT 13 _ZN7CParentC2Ev
77: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNSolsEj@@GLIBCXX_3.4
78: 08048ac8 112 FUNC WEAK DEFAULT 13 _ZN7CParentD1Ev
79: 00000000 0 FUNC GLOBAL DEFAULT UND _Znwj@@GLIBCXX_3.4
80: 00000000 0 FUNC GLOBAL DEFAULT UND _Znaj@@GLIBCXX_3.4
81: 08048a64 100 FUNC WEAK DEFAULT 13 _ZN7CParentC1Ev
82: 08048ed4 8 OBJECT WEAK DEFAULT 15 _ZTI7CParent
83: 08048b38 30 FUNC WEAK DEFAULT 13 _ZN7CParentD0Ev
84: 08048c34 182 FUNC WEAK DEFAULT 13 _ZN6CChildD2Ev
85: 0804a30c 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
86: 0804a400 44 OBJECT WEAK DEFAULT 26 _ZTVN10__cxxabiv120__si_c
87: 0804a438 4 OBJECT GLOBAL DEFAULT 26 _ZN6CChild3refE
88: 08048ec8 9 OBJECT WEAK DEFAULT 15 _ZTS7CParent
89: 08048ac8 112 FUNC WEAK DEFAULT 13 _ZN7CParentD2Ev
90: 08048eb4 8 OBJECT WEAK DEFAULT 15 _ZTS6CChild
91: 08048ea0 20 OBJECT WEAK DEFAULT 15 _ZTV7CParent
92: 00000000 0 FUNC GLOBAL DEFAULT UND _ZdaPv@@GLIBCXX_3.4
93: 0804a440 0 NOTYPE GLOBAL DEFAULT ABS _end
94: 00000000 0 FUNC GLOBAL DEFAULT UND _ZNSolsEPFRSoS_E@@GLIBCXX
95: 08048b88 171 FUNC WEAK DEFAULT 13 _ZN6CChildC1Ev
96: 0804879c 0 FUNC GLOBAL DEFAULT UND _ZSt4endlIcSt11char_trait
97: 0804a30c 0 NOTYPE GLOBAL DEFAULT ABS _edata
98: 08048c34 182 FUNC WEAK DEFAULT 13 _ZN6CChildD1Ev
99: 080487ac 0 FUNC GLOBAL DEFAULT UND __gxx_personality_v0@@CXX
100: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume@@GCC_3.0
101: 08048d75 0 FUNC GLOBAL HIDDEN 13 __i686.get_pc_thunk.bx
102: 08048884 388 FUNC GLOBAL DEFAULT 13 main
103: 0804868c 0 FUNC GLOBAL DEFAULT 11 _init

Histogram for `.gnu.hash' bucket list length (total of 3 buckets):
Length Number % of total Coverage
0 0 ( 0.0%)
1 0 ( 0.0%) 0.0%
2 2 ( 66.7%) 57.1%
3 1 ( 33.3%) 100.0%

Version symbols section '.gnu.version' contains 22 entries:
Addr: 0000000008048540 Offset: 0x000540 Link: 5 (.dynsym)
000: 0 (*local*) 2 (GLIBC_2.1.3) 0 (*local*) 0 (*local*)
004: 3 (GLIBCXX_3.4) 3 (GLIBCXX_3.4) 4 (GLIBC_2.0) 3 (GLIBCXX_3.4)
008: 4 (GLIBC_2.0) 3 (GLIBCXX_3.4) 3 (GLIBCXX_3.4) 3 (GLIBCXX_3.4)
00c: 3 (GLIBCXX_3.4) 3 (GLIBCXX_3.4) 6 (GCC_3.0) 5 (CXXABI_1.3)
010: 5 (CXXABI_1.3) 1 (*global*) 3 (GLIBCXX_3.4) 3 (GLIBCXX_3.4)
014: 3 (GLIBCXX_3.4) 5 (CXXABI_1.3)

Version needs section '.gnu.version_r' contains 3 entries:
Addr: 0x000000000804856c Offset: 0x00056c Link: 6 (.dynstr)
000000: Version: 1 File: libgcc_s.so.1 Cnt: 1
0x0010: Name: GCC_3.0 Flags: none Version: 6
0x0020: Version: 1 File: libstdc++.so.6 Cnt: 2
0x0030: Name: CXXABI_1.3 Flags: none Version: 5
0x0040: Name: GLIBCXX_3.4 Flags: none Version: 3
0x0050: Version: 1 File: libc.so.6 Cnt: 2
0x0060: Name: GLIBC_2.0 Flags: none Version: 4
0x0070: Name: GLIBC_2.1.3 Flags: none Version: 2

Notes at offset 0x00000148 with length 0x00000020:
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)

Notes at offset 0x00000168 with length 0x00000024:
Owner Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
[buhadram@localhost src]$