Monday, May 10, 2010

Desktop icons missing and right click not working on Ubuntu

I had been using Ubuntu for a couple of years now. I upgraded my antiquated work machine (not to mention the low resources) to 10.04 LTS last week. With great pain I setup NVIDIA drivers and dual monitors. But today morning, apparently Canonical had released an update for nvidia-current package, which screwed up my previous settings.
The result - no icons on desktop and right-click refuses to work on desktop. But I was able to view the files that were on desktop, through Places->Home->Desktop.
Googled around to see if I could find a solution for this, when I stumbled upon this ubuntu forums post.
The solution basically, was to `sudo apt-get install gtweakui`. And then System->Preferences->gTweakUI-Nautilus. Then check 'Use nautilus to draw desktop'.
If you find it already checked, uncheck it. Restart X (Ctrl-Alt-Backspace) and then re-check the option. It worked for me.

Until we meet again,
-Srini-

Wednesday, November 25, 2009

Automatic configuration managment through Puppet!

For those readers who are in the professional field of (Unix/Linux) systems administration, you would appreciate the difficulty in maintaining consistent configurations across multiple servers and workstations. This becomes tricky with remote management infrastructures like SNMP, LDAP user database, etc.

It would be really nice if there is some mechanism which follows user-defined rules to check individual machines for consistency, install required packages, start required services and check/update their configurations. This reduces the overhead of maintenance a lot, especially as the size of the network increases. Fortunately, Puppet is one such automatic configuration management tool that helps sysadmins manage individual machines through a simple declarative language similar to Ruby.

Puppet can be found at http://reductivelabs.com/trac/puppet

The advantage with Puppet is that sysadmins can share their way of managing a particular package/service (called Puppet Recipe) with other sysadmins. This way the effort put in by individual sysadmins gets distributed locally resulting in reusability of administration code. I've started using it at my work. Its really cool!!

Until we meet again,
Srini

Friday, October 23, 2009

Yo Conficker!

It so happens that finally am doing my favorite crypto and security stuff. I ended up investigating the Conficker (aka Kido or Downadup) worm which is successfully nearing its second birthday. It has undergone several revisions (guess the latest is G). I should say this is one worm that has impressed me with its use of latest crypto techniques (it uses MD6!), extreme code obfuscations and what not. I'm sure there is a extraordinarily brilliant geek group behind this.

It is still not clear what it is set out to do. For now, it just occupies unpatched Windows machines and keeps multiplying. I'm not aware of any kind of malicious behavior from this worm so far. But since it uses P2P technique to spread itself, it is an interesting area of research to try and curb this worm before it starts its nasty attacks.

I find new information every day about this revolutionary worm. It shows how intelligently one can devise malware. Lets see if I get something interesting on this worm in the next few months!

Until we meet again,
-Srini-

Friday, September 25, 2009

Access Ubuntu Wubi installation files (root.disk)

Hi,

It has been a busy start to the semester, and I'd not really gotten time to blog. But here I am, after doing something stupid again.

Today I commented out my 'root' password entry in the /etc/passwd file. Then I could neither do "sudo" nor my Ubuntu Jaunty boots up. It just freezes at login. The recovery console couldn't get me a root console either, because it cannot find any user named 'root'.

Ah, my only resort was Ubuntu Live CD - got it from my roommate after quite some search. Here is what I did:
1. Boot the system with Live CD (I used Hardy 8.04). I think you can use any Live CD for that sake (just that the later commands might differ).
2. Mounted my WUBI Ubuntu's host drive (D:\ in my case) by clicking Places->SecDrive, where SecDrive was the volume label of my D:\
As we know, this gets mounted in /media/SecDrive in Ubuntu.
3. Opened a terminal on the Live Ubuntu's desktop. Then:
sudo mkdir vdisk
sudo mount -o loop /media/SecDrive/ubuntu/disks/root.disk vdisk
4. Then "sudo -i" to open a root prompt
5. Finally "vi /home/ubuntu/Desktop/vdisk/etc/passwd" and uncommented the "root" password (where 'ubuntu' was the name of the Live CD default user)

Poof... It worked finally... Sometimes I wonder how stupid can I get....

Until we meet again,
-Srini-

Friday, August 14, 2009

Awesome utility called 'Testdisk'

Hi,
For those who have run into lots of boot record corruption issues or file table corruption issues and for those who aren't aware of a convenient way to get it repaired, I've some good news....

One of my friends recently crashed her Vista and skipped the CHKDISK warning a couple of times, until she realized that her NTFS MFT (Master File Table) got corrupted.

Lesson learnt - Never ignore CHKDISK warnings. They are usually an omen for a possible disaster to your data.


Inspite of running checkdisk regularly, I myself have gotten into such NTFS file corruption as well as file table corruption issues a couple of times in the past. But luckily I could get into a DOS prompt those times either using Windows XP command prompt or using a legacy Win 98 bootdisk or so. But this time it was a deadlock because Vista just freezes when you login, so that the hope of getting a terminal is totally unimaginable. (I cursed myself for leaving back my Win98 boot disk back in India)

Since my friend had an Ubuntu Jaunty (Inside Windows) installation, I just used it to gain entry into the system. But the problem is that the NTFS media just doesn't get detected because its MFT is corrupt.

As every other human being does, my natural instinct was to lookup Google. And as always, I got a panacea for this irritating problem - TESTDISK.

Then the sequence of steps that I followed -
  • sudo apt-get install testdisk
  • sudo testdisk
  • Choose the partition to repair and rewrite the MFT from its mirror (for those who weren't aware of this, NTFS has a mirror MFT to help restore a corrupt MFT).
  • Reboot the system and get into Vista - Viola, it worked!

Until we meet again,
-Srini-

Monday, July 27, 2009

Parsing input configuration files - Part 1

Hi,

When dealing with loading input configuration files, it is annoying to parse each line of the file and store the value in a parameter for each line. This often clutters the code due to the extensive if-else if-else if...-else statements for each config parameter. In the end this greatly affects the code maintainability. So let me introduce you a better approach to minimize the pain of maintenance.

Assumptions
I take it for granted that I'm addressing the audience who have their code in C++. I assume that you all might have stored the set of input parameters in a structure or a class, say ConfigStruct. If you haven't done so, I recommend encapsulating your input/output parameters in a nice structure atleast now. I use STL in this example to make things easier - you may also use your own version of the STL container if you are against using STL for some personal reasons.
Scenario: (existing parser logic)
If your input config parsing logic is something like,

if ( !strcmp(inputParam1,"paramStr1") ) {
load paramStr1's value into inputParam1
} else if ( !strcmp(inputParam2,"paramStr2") ) {
load paramStr2's value into inputParam2
} else {
print that the config parameter is unrecognized and probably quit
}

then you've come to the right place.

Pointer-based approach
This method deals with two forms of association:
a. Tying each config file tag to the datatype of corresponding variable - introduce a STL "map" called tagTypeMap
b. Tying each config file tag to the address of corresponding variable - introduce a STL "map" called tagAddrMap

Declaration of these maps
std::map<std::string,std::string> tagTypeMap;
std::map<std::string,void*> tagAddrMap;

New parser logic
registerConfig() {
#define REGISTER(tag,var) tagTypeMap[tag]=typeid(var).name();
REGISTER("paramStr1",inputParam1)
REGISTER("paramStr2",inputParam2)
//and so on.
#define REGISTER_ADDR(tag,var) tagAddrMap[tag]=(void*)&var;
REGISTER_ADDR("paramStr1",inputParam1)
REGISTER_ADDR("paramStr2",inputParam2)
//and so on.
}

parseTag() {
if ( tagTypeMap.find(tag) == tagTypeMap.end() )
return; //variable not found

std::string type = tagTypeMap.find(tag)->second;

if ( tagAddrMap.find(tag) == tagAddrMap.end() )
return; //addr not registered

void *vptr = tagAddrMap.find(tag)->second;

// If you include a new data type
// as input parameter, please define
// conversion for that data type in here
if ( type == typeid(std::string).name() ) {
std::string *ptr = (std::string*) vptr;
*ptr = value;
} else if ( type == typeid(int).name() ) {
int *ptr = (int*) vptr;
*ptr = atoi(value.c_str());
} else if ( type == typeid(float).name() ) {
float *ptr = (float*) vptr;
*ptr = atof(value.c_str());
} //and so on
}

I'll go over the second approach (template-based) in one of my future blogs (possibly the next one).

Until we meet again,
-Srini-

Monday, July 20, 2009

[C++] Playing with the preprocessor directives

Hi,

This was something I shared with my friends when I worked in Juno Online. Thought it'd be interesting to share it with rest of the world! Without much waiting, here we go -

We have the following 3 files:
--file1.h--
#ifndef __file1_h
#define __file1_h
#include <iostream>

struct S
{
#ifdef _SRINI
int a;
#endif
int b;

void Assign(int x, int y)
{
#ifdef _SRINI
a=x;
#endif
b=y;
}

void Print()
{
#ifdef _SRINI
std::cout<<"a="<<a<<std::endl;
#endif
std::cout<<"b="<<b<<std::endl;
}
};

void Assign(int,int);

#endif


--file1.cpp--
#include "file1.h"

S s;

void Assign(int x, int y)
{
s.Assign(x,y);
}

--file2.cpp--
#include "file1.h"

int main()
{
extern S s;
Assign(1,2);
s.Print();
return 0;
}


Compile using the commands:
g++ -D_SRINI -c file1.cpp
g++ -c file2.cpp
g++ -o file file1.o file2.o


What do you expect when you run the 'file' binary?
Will it result in a compilation error?

Or will it output:
a=1
b=2 ?
Or is it just "b=2" ?

But actually the output will be "b=1". Let me reason it out.

According the file1.o, the "struct S" is defined as:
struct S {
int a;
int b;

void Assign(int x, int y)
{
a=x;
b=y;
}

void Print()
{
std::cout<<"a="<<a<<std::endl;
std::cout<<"b="<<b<<std::endl;
}
};


but according to file2.o the "struct S" is defined as:
struct S {
int b;

void Assign(int x, int y)
{
b=y;
}

void Print()
{
std::cout<<"b="<<b<<std::endl;
}
};


Now when main() calls Assign(1,2) of file1.0, the struct S sets a=1 and b=2 according to file1.o's definition. In the viewpoint of struct S, it has initialized its FIRST member to 1 and SECOND member to 2.
When Print() is invoked by main(), file2.o's version of struct S is being used. But this structure has only one member, i.e. 'b'. Since struct S knows that its first value is 1, it doesn't care about the variable name, it just prints 'b=1'.

To reconfirm this, if you set the datatype of 'a' to 'char', the output will contain the ASCII value of the character stored in 'a'.

Until we meet again,
- Srini -