Tuesday, November 1, 2011

What's the problem

No matter how much you think you know C/C++ there are things that you can always miss if you are not thorough. This small program is one of them. Can you tell me how many times "Java Rules" is printed ?
#include <stdio.h>

  int main()
  {
   int counter = -1;
   
   while( counter < sizeof(int))
   {
     printf("Java Rules!! \n");
     counter++;
   }
    
   return 0;
  }
The answer is none, because the fact is Java doesn't Rule :P
Alright alright, the reason is sizeof operator returns unsigned int :)

Sunday, October 16, 2011

Removing packages not supported by the Repository

Here's a small tip for rpm based systems (like fedora, centos etc) to remove all the obsolete packages that are not supported by the current repository.

  • List all packages not supported by the repository.
    $ package-cleanup --orphans


  • One can use xargs with the above command to remove them.
    $ package-cleanup --orphans | xargs yum remove -y
    

Monday, October 3, 2011

Calling C++ library function from C code

Recently one of my friend asked this question. I had done this in past but I had to struggle to do this again. So I am documenting this in case i need this again in future.

Let's first create a C++ shared library containing the functions we need.
Since, I am not good with names so I'll call it the "Person" class.


Person.h
#ifndef __PERSON_H__
#define __PERSON_H__

void globalMethod();

class Person
{
 public:
 void instanceMethod();
 static void classMethod();
};

#endif


Person.cpp
#include "Person.h"
#include <iostream>
using namespace std;

void globalMethod()
{
 cout<<"Global method"<<endl;
}

void Person::instanceMethod()
{
 cout<<"Instance method"<<endl;
}

void Person::classMethod()
{
 cout<<"Class method"<<endl;
}


After creating the source files we need to compile them into shared object.

$ g++ -fPIC -c Person.cpp
$ g++ -shared -o libPerson.so Person.o
$


At this point we have our C++ shared library.
A simple client in C++ for this library looks like this.

Client.cpp
#include "Person.h"

int main()
{
 Person p;
 p.instanceMethod();
 Person::classMethod();
 globalMethod();
}


We can compile and run this small program as such. We need to export LD_LIBRARY_PATH before running the binary, so that the loader can find the shared object.

$ g++ Client.cpp -o Client -L. -lPerson
$ export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
$ ./Client
Instance method
Class method
Global method
$


Till here we know that everything works.
Now, lets call these methods from C code. But, as we know that C++ does name mangling we cannot directly call these methods from the C code. We first have to write some kind of wrapper over the existing library using C naming convention so that the names are not mangled.

Here is what the wrapper class looks like

Wrapper.cpp
#include "Person.h"

extern "C" void GlobalMethod()
{
 globalMethod();
}

extern "C" void InstanceMethod(Person *p)
{
 p->instanceMethod();
}

extern "C" void ClassMethod()
{
 Person::classMethod();
}

Note the InstanceMethod() takes a pointer to Person object. Why ??? Remember the *this* pointer in C++; since this method will be called from C code, we need to manually pass this variable.

This will be our wrapper shared library over the libPerson.so library. lets compile and create the library.

$ g++ -fPIC -c Wrapper.cpp
$ g++ -shared -o libWrapper.so Wrapper.o
$


Now, its time to write our Client in C; it looks like this

Client.c
struct Person
{
};

int main(){
 GlobalMethod();
 struct Person p;
 InstanceMethod(p);
 ClassMethod();
}

Pay attention that we have to create a Struct for the Person class. We need to link this binary against the wrapper library (libWrapper.so) and the actual library(libPerson.so), since the Wrapper depends upon it.


$ gcc Client.c -o C_Client -L. -lWrapper -lPerson
$ ./C_Client
Global method
Instance method
Class method
$


And, we're done !!

Any comments/suggestions are welcomed !!

Saturday, September 3, 2011

Package management in Fedora (or RPM based systems)

The two tools/command used for package management in a RPM based system (like Fedora or Redhat) are:

a). rpm
 - Originally standing for "RedHat Package Manager"
 - Now a recursive acronym for "RPM Package Manager"
 - No pacakge dependencies resolution.

b). yum
 - It stands for "Yellodog Updater, Modified".
 - Re-write of existing tool called "Yellodog Updater (YUP), hence the name.
 - Supports package dependencies resolution.


1. Search for a package named "foobar"
    yum search foobar
    yum search all foobar

2. Install the development files for "foobar"
    yum install foobar-devel

3. Install documentation for "foobar"
    yum install foobar-doc

4. Check if package "foobar" is installed
    rpm -q foobar

5. List all the files installed by package "foobar"
    rpm -ql foobar
    rpm -q foobar | xargs rpm -ql

6. If you have a file say "/etc/foobar.conf" and want to know which package does it belongs to
    rpm -qf /etc/foobar.conf

Sunday, February 27, 2011

SSH Tunneling to overcome Firewall rules.....

A Typical network scenario in an Organisation
So, what is SSH Tunneling ?
When one network protocol(delivery protocol) encapsulates another protocol over itself, it's called Tunneling (Wikipedia)
And when the delivery protocol is SSH its called SSH Tunneling. Simple !!

Usage Scenario
Consider a typical scenario as shown above.
We have a web server called Atlantis and a SSH server called Endeavour.
For some reason(company policy ??) users are allowed access only to SSH server and not to the webserver. What if a user wants to access the webserver ?? Without tunneling he cannot access the webserver because port 80 is blocked by the firewall rules; so what's next ?

SSH tunneling can come to rescue in such situations.
We can Tunnel HTTP protocol (web server) over SSH protocol. So, how do we do it ?
Connect to SSH server as:

$ ssh Endeavour -L8080:Atlantis:80
$ ssh [ssh server] -L[local port]:[remote machine]:[port on remote machine]


The only thing to keep in mind is that the remote machine must be accessible by your ssh server. What this does is, it opens a local port 8080 and forwards all the traffic on that port to Atlantis on port 80 through your SSH server. The SSH server acts as the relay between your machine and the webserver.

To access the webserver, just point your browser to http://localhost:8080

Other Advantages
Since SSH is a secure protocol, meaning all the communication between your machine and the server is encrypted; it helps to transfer unencrypted traffic(http) over the network through secure channel(ssh).

Wednesday, February 23, 2011

Windows: Of 32-bit and 64-bit application registry

I recently ran into a problem where i was doing some development work and tried to read the value of a registry from under HKLM:software\microsoft\"Myprogram" using a C# program. The program kept failing and was not able to read it; it was not even able to open the said registry key. Initially, i thought that it might be a permissions problem, but NO !! To add to my frustation, i can clearly "see" the key being present in the registry.

After banging my head in the wall for some time and googling, i finally found that on 64 bit machines (where i a was doing my development work) there are 2 versions of the application registry. One for 32 bit applications to use and another version for 64 bit appications to use. regedit for 32-bit version resides under C:\Windows\System32 and 64-bit version resides under C:\Windows\SysWOW64.

The installer which wrote those registry keys was a 32 bit application; hence the registry entries were made to 32 bit version of the registry. The C# application that I was developing was targeting "x86" architecture. When I ran the application it always tried to open the 64 bit version of the registry and kept failing. I then changed the "platform target" in the project properties page from "x86" to "AnyCPU" and wholla!! problem solved :)

-----
Q. Why is 6 afraid of 7 ?
A. Because 7 8 9 :)
-----

Sunday, February 20, 2011

Transform Linux to Mac OS X

Before I proceed, let me first state that i LOVE the simplicity of my Linux desktop (Gnome to be precise). I am writing this post just to demonstrate that how easy it is to make your Linux desktop look like a Mac 

The two things that are characteristic of Mac are :
1. It's Dock at the bottom.
2. Global menu bar at the top.

There are many projects (like cairo dock, avant window navigator etc) out there that provide Mac like Dock for Linux. But the one that i find more useful and easy to configure is Docky. To find a list of dock applications go to http://en.wikipedia.org/wiki/List_of_dock_applications.

Since i am using Fedora, the details will be specific to it, but it would be somewhat similar in other distros as well.
Before we start, lets see how the default desktop looks like in fedora 14.

Default Desktop in Fedora 14

























Let's get started

1. Installing the Dock
Fedora uses yum as the package manager. So to install docky, open a terminal and execute
$ yum install docky

2. Installing Global Menu
Open up a terminal and execute
$ yum install gnome-applet-globalmenu

Post Install configuration
Delete bottom panel
At this point there will be no visible changes, because our installed programs are not running. We need to get rid of the bottom panel. To do this right click on empty space on the bottom panel to bring the context menu and click on "Delete This Panel". Similarly delete the custom menu bar in the top left corner.





Add to Panel
The next step is to add the main GNOME menu. This is similar to custom menu bar but does not have "Application", "Place" and "System" as shown in the custom menu bar. To do this right click on empty space on the top panel and click on "Add to Panel".








Add Global Menu to Top Panel
Similarly add Global menu to the top panel. If you cannot find this item, try logging out and login back.














Enable Docky from StartUp applications list.

The next step is to enable Docky from startup applications list. To do that execute $ gnome-session-properties from a terminal and select Docky from the list.










Change the wallpaper if you like. I have also installed gnome-color-icon theme. It provides different colored icon themes; i have selected purple one. To install, open a terminal and execute $ yum install gnome-colors-icon-theme

Log-off and login again. Here is the final desktop look.

Pseudo Mac
























----- Insanity is hereditary, you get it from your kids :) -----

Thursday, February 17, 2011

Password free login to SSH using public keys

Many of us at some point in time have faced this situation of working remotely on a Unix/Linux box. The most preferred way is through SSH. But every time you login to a machine remotely you have to provide your password. How about logging in without password; using public keys ???

To demonstrate this method, I will be using 2 Linux machines.
1. Caffeine: This will act as ssh server.
2. Coffee: This machine will act as client.

Server Side Settings (Caffeine)
On the server we need to start the ssh daemon.  $ sudo /etc/init.d/sshd start

Start the SSH server
That's all we need to do on the server side !!

Client Side Settings (Coffee)
In order to login without password, first you need to create public-private key pairs.
In order to do this on linux (fedora or ubuntu ) execute   $ ssh-keygen

Create public-private key pair
Just hit and accept the default file name. Enter the pass-phrase or hit enter for none.
This step would have created 2 files as shown below in your  ~/.ssh folder.

Public/Private key files
Of the two files, id_rsa contains the private key and id_rsa.pub contains the public key.
After we have the public and private key files, we need to add these keys to the authenticating agent. Its the authentication agent who performs the authentication on our behalf. To add the keys execute $ ssh-add
If you have provided the password in the above step, it will ask for a password

ssh-add, keys with password
else it will not

ssh-add, keys without password
The next step is to copy and paste the public key from id_rsa.pub into Server's (Caffeine)   ~/.ssh/authorized_keys file on a new line. This step needs to be done once, either manually or by executing    $ ssh-copy-id user@machine. You will be prompted for your password.

** Important: The file permission for   ~/.ssh/authorized_keys must be 400, else it will not work. **

ssh-copy-id
Testing !!
That's all that is needed. You can now try to login to the server without passwords.
To login just type  $ ssh user@machine or like most of the cases if the user-name is same on both machines then just $ ssh machine

Login with user and machine names


If the username is same, just use machine name
----- I tried so hard and got so far, but in the end it doesn't even matter -----

Wednesday, February 16, 2011

Some Shots at Photography

Last week I went to seattle downtown and here are some of the clicks that somehow turned nice. I must say that I am not at all a photographer, but I like to click :)

Space Needle at Dusk

Seattle Downtown Skyline

Seattle Downtown

From a child's viewpoint