Wednesday, August 28, 2013

Arduino and Multi-Threading

Arduino itself does not support multi-threading. So, we need to use a library such as "proto-threads" to have multi-threading capabilities

Download the Multi-Threading library from:

https://code.google.com/p/arduinode/

In the below circuit, I'm turning on and turning off 2 LED's - one RED and one GREEN. Both of them are switching on and off in separate threads !

Here is the code:

#include <pt.h>

// PIN number on Arduino Board
static int LED_RED_PIN = 3;
static int LED_GREEN_PIN = 2;

// milli-seconds
static int LED_RED =  250; 
static int LED_GREEN = 1000; 

static struct pt pt1, pt2;

void led_toggle( int led ) {
  digitalWrite( led, !digitalRead( led ) );
}

static int thread1( struct pt *pt ) {
  static unsigned long timestamp = 0;
  PT_BEGIN( pt );
  while(1) {
    PT_WAIT_UNTIL( pt, millis() - timestamp > LED_RED  );
    led_toggle( LED_RED_PIN );
    timestamp = millis();
  }
  PT_END( pt );
}

static int thread2( struct pt *pt ) {
  static unsigned long timestamp = 0;
  PT_BEGIN( pt );
  while(1) {
    PT_WAIT_UNTIL( pt, millis() - timestamp > LED_GREEN );
    led_toggle( LED_GREEN_PIN );
    timestamp = millis();
  }
  PT_END( pt );
}

void setup() {
  pinMode( LED_RED_PIN, OUTPUT );
  pinMode( LED_GREEN_PIN, OUTPUT );
  PT_INIT( &pt1 );
  PT_INIT( &pt2 );
}

void loop() {
  thread1( &pt1 );
  thread2( &pt2 );
}

How to import the multi-threading library


Arduino Connections

Tuesday, August 13, 2013

Java Multi-Threading : Deadlock and how to avoid them (Example)

Account.java

package com.test;

public class Account {
 private int balance = 10000;
 
 private void deposit(int amount) {
  balance += amount;
 }
 
 private void withdraw(int amount) {
  balance -= amount;
 }
 
 public int getBalance() {
  return balance;
 }
 
 public static void transfer(Account acc1, Account acc2, int amount) {
  acc1.withdraw(amount);
  acc2.deposit(amount);
 }

}

Runner.java

package com.test;

import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class Runner {
 
 private Account acc1 = new Account();
 private Account acc2 = new Account();
 
 private Lock lock2 = new ReentrantLock();
 private Lock lock1 = new ReentrantLock();
 
 private void acquireLocks(Lock firstLock, Lock secondLock) {
  while(true) {
   
   boolean gotFirstLock = false;
   boolean gotSecondLock = false;
   try {
    gotFirstLock = firstLock.tryLock();
    gotSecondLock = secondLock.tryLock();
   } catch(Exception e) {
    e.printStackTrace();
   } finally {
    if(gotFirstLock && gotSecondLock) {
     return;
    }
    if(gotFirstLock) {
     firstLock.unlock();
    }
    if(gotSecondLock) {
     secondLock.unlock();
    }
   }
   
   try {
    Thread.sleep(10);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
 }
 
 public void firstThread() throws InterruptedException {
  Random random = new Random();
  for(int i =0; i<100; i++) {
   
   acquireLocks(lock1, lock2);
   
   try {
    Account.transfer(acc1, acc2, random.nextInt(100));
   } catch(Exception e) {
    e.printStackTrace();
   } finally {
    lock1.unlock();
    lock2.unlock();
   }
  }
 }
 
 public void secondThread() throws InterruptedException {
  Random random = new Random();
  
  for(int i =0; i<100; i++) {
   
   acquireLocks(lock1, lock2);
   
   try {
    Account.transfer(acc2, acc1, random.nextInt(100));
   } catch(Exception e) {
    e.printStackTrace();
   } finally {
    lock1.unlock();
    lock2.unlock();
   }
  }

 }
 
 public void finished() {
  System.out.println("Account 1 balance : " + acc1.getBalance());
  System.out.println("Account 2 balance : " + acc2.getBalance());
  
  System.out.println("Total balance : " + (acc1.getBalance() + acc2.getBalance()));
 }

}

Main.java

package com.test;

public class Main {

 public static void main(String[] args) {
  
  final Runner runner = new Runner();
  
  Thread t1 = new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     runner.firstThread();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   
  });
  
  Thread t2 = new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     runner.secondThread();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   
  });
  
  t1.start();
  t2.start();
  
  try {
   t1.join();
   t2.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
  runner.finished();
  
 }
}

Output

Account 1 balance : 10210
Account 2 balance : 9790
Total balance : 20000

Java - Re-entrant Locks in Multi-threading example

File: Runner.java

package com.test;

import java.util.Scanner;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Runner {
 
 private int count = 0;
 private Lock lock = new ReentrantLock();
 private Condition cond = lock.newCondition();
 
 private void increment() {
  for(int i=0;i<10000; i++) {
   count++;
  }
 }
 
 public void firstThread() throws InterruptedException {
  
  lock.lock();
  
  System.out.println("Waiting...");
  cond.await();
  System.out.println("Woken up...!");
  
  try {
   increment();
  } catch(Exception e) {
   e.printStackTrace();
  }
  finally {
   lock.unlock();
  }
 }
 
 public void secondThread() throws InterruptedException {
  
  Thread.sleep(2000);

  lock.lock();
  
  System.out.println("Press the return key...");
  Scanner scanner =  new Scanner(System.in);
  scanner.nextLine();
  System.out.println("Return key pressed !");
  scanner.close();
  
  cond.signal();
  
  try {
   increment();
  }catch (Exception e) {
   e.printStackTrace();
  } finally {
   lock.unlock();
  }
 }
 
 public void finished() {
  System.out.println("Count is : " + count);
 }

}

File: Main.java

package com.test;

public class Main {

 public static void main(String[] args) {
  
  final Runner runner = new Runner();
  
  Thread t1 = new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     runner.firstThread();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   
  });
  
  Thread t2 = new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     runner.secondThread();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   
  });
  
  t1.start();
  t2.start();
  
  try {
   t1.join();
   t2.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
  runner.finished();
  
 }

}

Output

Waiting...
Press the return key...

Return key pressed !
Woken up...!
Count is : 20000

Java Producer/Consumer problem : Threading wait/notify functions usage example

File : ProducerConsumer.java

package com.test;

import java.util.LinkedList;
import java.util.Random;

public class ProducerConsumer {
 
 private LinkedList list = new LinkedList();
 private final int LIMIT = 10;
 private Object lock = new Object();
 
 public void produce() throws InterruptedException {
  int value = 0;
  while(true) {
   synchronized(lock) {
    while(list.size() == LIMIT) {
     lock.wait();
    }
    list.add(value++);
    lock.notify();
   }
  }
 }
 
 public void consume() throws InterruptedException {
  Random random = new Random();
  while(true) {
   synchronized(lock) {
    while(list.size() == 0) {
     lock.wait();
    }
    System.out.print("List size is: " + list.size());
    int value = list.removeFirst();
    System.out.println(" ; value is " + value);
    lock.notify();
   }
   Thread.sleep(random.nextInt(1000));
  }
 }
}

File : ProducerConsumer.java

package com.test;

public class Main {

 public static void main(String[] args) {
  
  final ProducerConsumer pc = new ProducerConsumer();
  
  Thread t1 = new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     pc.produce();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   
  });
  
  Thread t2 = new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     pc.consume();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   
  });
  
  t1.start();
  t2.start();
  
  try {
   t1.join();
   t2.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
 }

}

Output:

List size is: 9 ; value is 0
List size is: 10 ; value is 1
List size is: 10 ; value is 2
List size is: 10 ; value is 3
List size is: 10 ; value is 4
List size is: 10 ; value is 5
List size is: 10 ; value is 6
List size is: 10 ; value is 7
List size is: 10 ; value is 8
List size is: 10 ; value is 9
List size is: 10 ; value is 10
List size is: 10 ; value is 11
List size is: 10 ; value is 12
List size is: 10 ; value is 13
List size is: 10 ; value is 14
List size is: 10 ; value is 15
List size is: 10 ; value is 16
List size is: 10 ; value is 17
List size is: 10 ; value is 18
List size is: 10 ; value is 19
List size is: 10 ; value is 20
List size is: 10 ; value is 21
List size is: 10 ; value is 22
List size is: 10 ; value is 23
List size is: 10 ; value is 24
List size is: 10 ; value is 25
List size is: 10 ; value is 26
List size is: 10 ; value is 27
List size is: 10 ; value is 28
List size is: 10 ; value is 29
List size is: 10 ; value is 30
List size is: 10 ; value is 31
List size is: 10 ; value is 32
List size is: 10 ; value is 33
List size is: 10 ; value is 34
List size is: 10 ; value is 35
List size is: 10 ; value is 36
List size is: 10 ; value is 37
List size is: 10 ; value is 38
List size is: 10 ; value is 39
List size is: 10 ; value is 40
List size is: 10 ; value is 41
List size is: 10 ; value is 42
List size is: 10 ; value is 43
List size is: 10 ; value is 44
List size is: 10 ; value is 45
List size is: 10 ; value is 46
List size is: 10 ; value is 47
List size is: 10 ; value is 48
List size is: 10 ; value is 49
List size is: 10 ; value is 50
List size is: 10 ; value is 51
List size is: 10 ; value is 52
List size is: 10 ; value is 53
List size is: 10 ; value is 54
List size is: 10 ; value is 55
List size is: 10 ; value is 56
List size is: 10 ; value is 57
List size is: 10 ; value is 58
List size is: 10 ; value is 59
List size is: 10 ; value is 60
List size is: 10 ; value is 61
List size is: 10 ; value is 62
List size is: 10 ; value is 63
List size is: 10 ; value is 64
List size is: 10 ; value is 65
List size is: 10 ; value is 66
List size is: 10 ; value is 67
List size is: 10 ; value is 68
List size is: 10 ; value is 69
List size is: 10 ; value is 70
List size is: 10 ; value is 71
List size is: 10 ; value is 72
List size is: 10 ; value is 73
List size is: 10 ; value is 74
List size is: 10 ; value is 75
List size is: 10 ; value is 76
List size is: 10 ; value is 77
List size is: 10 ; value is 78
List size is: 10 ; value is 79
List size is: 10 ; value is 80
List size is: 10 ; value is 81
List size is: 10 ; value is 82
List size is: 10 ; value is 83
List size is: 10 ; value is 84
List size is: 10 ; value is 85
List size is: 10 ; value is 86
List size is: 10 ; value is 87
List size is: 10 ; value is 88
List size is: 10 ; value is 89
List size is: 10 ; value is 90
List size is: 10 ; value is 91
List size is: 10 ; value is 92
List size is: 10 ; value is 93
List size is: 10 ; value is 94
List size is: 10 ; value is 95
List size is: 10 ; value is 96
List size is: 10 ; value is 97
List size is: 10 ; value is 98
List size is: 10 ; value is 99
List size is: 10 ; value is 100
List size is: 10 ; value is 101
List size is: 10 ; value is 102
List size is: 10 ; value is 103
List size is: 10 ; value is 104
List size is: 10 ; value is 105
List size is: 10 ; value is 106
List size is: 10 ; value is 107
List size is: 10 ; value is 108
List size is: 10 ; value is 109
List size is: 10 ; value is 110
List size is: 10 ; value is 111
List size is: 10 ; value is 112
List size is: 10 ; value is 113
List size is: 10 ; value is 114
List size is: 10 ; value is 115
List size is: 10 ; value is 116
...
...
...
...
(it goes on)

Monday, August 12, 2013

Java : Multi Threading - Producer/Consumer Problem and "synchronzied" code block

File: ProducerConsumer.java

package com.test;

import java.util.Scanner;

public class ProducerConsumer {
 public void produce() throws InterruptedException {
  synchronized(this) {
   System.out.println("Producer thread running...");
   wait(); // ****** Can be called only inside a synchronized code block *********
   System.out.println("Producer Resumed.");
  }
 }
 
 public void consume() throws InterruptedException {
  Scanner scanner = new Scanner(System.in);
  Thread.sleep(2000);
  
  synchronized(this) {
   System.out.println("Waiting for return key...");
   scanner.nextLine();
   System.out.println("Return key pressed");
   notify(); // ****** Can be called only inside a synchronized code block *********
   
   Thread.sleep(5000);
  }
 }

}

File: Main.java

package com.test;

public class Main {

 public static void main(String[] args) {
  
  final ProducerConsumer pc = new ProducerConsumer();
  
  Thread t1 = new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     pc.produce();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   
  });
  
  Thread t2 = new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     pc.consume();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   
  });
  
  t1.start();
  t2.start();
  
  try {
   t1.join();
   t2.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
 }

}

Output

Producer thread running...
Waiting for return key...

Return key pressed
Producer Resumed.

Java Producer/Consumer problem (example) - using Blocking Queue

package com.java.test;

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Main {

 private static BlockingQueue queue = new ArrayBlockingQueue(10);
 
 public static void main(String[] args) {
  
  Thread t1 = new Thread(new Runnable(){
   @Override
   public void run() {
    producer();
   }
  });
  
  Thread t2 = new Thread(new Runnable(){
   @Override
   public void run() {
    consumer();
   }
  });
  
  t1.start();
  t2.start();
  
  try {
   t1.join();
   t2.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 private static void producer() {
  Random random = new Random();
  while(true) {
   try {
    queue.put(random.nextInt(100));
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
 
 private static void consumer() {
  Random random = new Random();
  while(true) {
   try {
    Thread.sleep(100);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   if(random.nextInt(10) == 0) {
    try {
     Integer value = queue.take();
     System.out.println("Taken value : " + value + " ; Queue size is : " + queue.size());
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }
 }

}

Java Multi-Threading : Count down latches

Here is an example of count-down latches usage

Main.java

package com.java.latch;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Runner implements Runnable {
 
 private CountDownLatch latch;
 private String name;

 public Runner(CountDownLatch latch, String name) {
  super();
  this.latch = latch;
  this.name = name;
 }



 @Override
 public void run() {
  System.out.println("Started: " + name);
  System.out.println(name + " : Latch Count before sleep(): " + latch.getCount());
  
  try {
   Thread.sleep(4000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
  latch.countDown();
  
  System.out.println(name + " : Latch Count afer sleep() and countDown(): " + latch.getCount());
 }
 
}

public class Main {

 public static void main(String[] args) {
  
  CountDownLatch latch = new CountDownLatch(10);
  
  ExecutorService executor = Executors.newFixedThreadPool(3);
  
  for (int i=0; i<10;i++) {
   executor.submit(new Runner(latch, "Thread_" + i));
  }
  
  try {
   /*
   Causes the current thread to wait until the latch has 
   counted down to zero, unless the thread is interrupted.
   If the current count is zero then this method returns immediately.
   */
   latch.await();
   
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
  System.out.println("Completed..!");

 }
}

Output:

Started: Thread_1
Started: Thread_0
Started: Thread_2
Thread_0 : Latch Count before sleep(): 10
Thread_1 : Latch Count before sleep(): 10
Thread_2 : Latch Count before sleep(): 10
Thread_0 : Latch Count afer sleep() and countDown(): 7
Thread_1 : Latch Count afer sleep() and countDown(): 7
Started: Thread_3
Thread_2 : Latch Count afer sleep() and countDown(): 7
Thread_3 : Latch Count before sleep(): 7
Started: Thread_4
Thread_4 : Latch Count before sleep(): 7
Started: Thread_5
Thread_5 : Latch Count before sleep(): 7
Thread_3 : Latch Count afer sleep() and countDown(): 4
Thread_4 : Latch Count afer sleep() and countDown(): 4
Started: Thread_7
Thread_7 : Latch Count before sleep(): 4
Thread_5 : Latch Count afer sleep() and countDown(): 4
Started: Thread_6
Thread_6 : Latch Count before sleep(): 4
Started: Thread_8
Thread_8 : Latch Count before sleep(): 4
Thread_7 : Latch Count afer sleep() and countDown(): 2
Thread_8 : Latch Count afer sleep() and countDown(): 1
Thread_6 : Latch Count afer sleep() and countDown(): 2
Started: Thread_9
Thread_9 : Latch Count before sleep(): 1
Thread_9 : Latch Count afer sleep() and countDown(): 0
Completed..!

Java - Thread Pools (Multi-Threading)

Here is an example of thread pools implementation in Java

File:Job.java

package com.test.thread;

public class Job implements Runnable {
 
 private int id;
  
 public Job(int id) {
  super();
  this.id = id;
 }

 @Override
 public void run() {
  System.out.println("Starting: " + id);
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
  System.out.println("Completed: " + id);
 }

}

File:Main.java

package com.test.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Main {

 public static void main(String[] args) {
  
  /* Creates a thread pool that reuses a fixed number of threads 
   * operating off a shared unbounded queue. At any point, at 
   * most nThreads threads will be active processing tasks. 
   * If additional tasks are submitted when all threads are active, 
   * they will wait in the queue until a thread is available. 
   * If any thread terminates due to a failure during execution 
   * prior to shutdown, a new one will take its place if needed 
   * to execute subsequent tasks. The threads in the pool will 
   * exist until it is explicitly shutdown.
   */
  ExecutorService executor = Executors.newFixedThreadPool(2);
  
  for(int i=0; i<6; i++) {
   /* Submits a Runnable task for execution and returns a 
    * Future representing that task. The Future's get 
    * method will return null upon successful completion.
    */
   executor.submit(new Job(i));
  }
  
  /*
  Initiates an orderly shutdown in which previously submitted tasks 
  are executed, but no new tasks will be accepted. Invocation has 
  no additional effect if already shut down. */
  
  executor.shutdown();
  
  System.out.println("All tasks submitted !");
  
  try {
   /* Blocks until all tasks have completed execution 
    * after a shutdown request, or the timeout occurs, or 
    * the current thread is interrupted, whichever happens first.
    */
   executor.awaitTermination(50, TimeUnit.SECONDS);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
  System.out.println("All tasks completed..!");
 }

}

Output:

Starting: 0
Starting: 1
All tasks submitted !
Completed: 1
Completed: 0
Starting: 2
Starting: 3
Completed: 3
Completed: 2
Starting: 4
Starting: 5
Completed: 5
Completed: 4
All tasks completed..!

Java Multi-Threading - How to implement

Here are couple of ways to implement a thread in Java

(1). By "extending" the thread class

(2). By "implementing" the runnable interface

File: MyMainClass.java

package com.test.pkg;

public class MyMainClass {

 public static void main(String[] args) {
  
  // create the thread object
  ThreadClass thread1 = new ThreadClass("Thread-1");
  
  // start the thread
  thread1.start();
  
  // sleep for 8000 ms or 8 secs
  try {
   System.out.println("MyMainClass: Doing sleep in main loop...");
   Thread.sleep(5000);
   System.out.println("MyMainClass: Done !");
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  // after 8 secs, stop the thread
  thread1.shutDown();
  
  // runnable implementation
  Thread run1 = new Thread(new MyRunnableClass("Runnable-1"));
  run1.start();
  
  try {
   run1.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
  System.out.println("MyMainClass: End of main() !");
 }
}

File: ThreadClass.java

package com.test.pkg;

/****************************************************************************
         One way of creating a thread is to extend the "Thread" class
****************************************************************************/

public class ThreadClass extends Thread {
 
 // our thread class name
 private String threadName;
 
 // A boolean variable which we can use to pause or keep 
 // the thread running. Volatile keyword in Java is used 
 // as an indicator to Java compiler and Thread that do 
 // not cache value of this variable and always read it 
 // from main memory.
 private volatile boolean running = true;
 
 // Give the thread a name
 public ThreadClass(String threadName) {
  this.threadName = threadName;
 }
 
 // This will stop the thread from running
 public void shutDown() {
  System.out.println("shutDown() Called ..!!");
  this.running = false;
 }
 
 // when the thread starts, this function is called
 @Override
 public void run() {
  
  int i = 0;
  
  while(this.running) {
   
   System.out.println(" Thread name ["+this.threadName+"] , current thread status => ["+this.running+"]");
   
   System.out.println(" i => ["+Integer.toString(i++)+"]");
   
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
}

File: MyRunnableClass.java

package com.test.pkg;

/****************************************************************************
One way of creating a thread is to implement the "Runnable" interface
****************************************************************************/

public class MyRunnableClass implements Runnable {
 
 // thread name
 private String runnableClassName;
 
 // A boolean variable which we can use to pause or keep 
 // the thread running. Volatile keyword in Java is used 
 // as an indicator to Java compiler and Thread that do 
 // not cache value of this variable and always read it 
 // from main memory.
 private volatile boolean running = true;
 
 public MyRunnableClass(String name) {
  this.runnableClassName = name;
 }
 
 @Override
 public void run() {
  for(int i=0;i<7;i++) {
   System.out.println("\n RunnableName = [" + this.runnableClassName + "] ; i => ["+Integer.toString(i)+"]");
   try {
    Thread.sleep(500);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }

}

Output

MyMainClass: Doing sleep in main loop...
 Thread name [Thread-1] , current thread status => [true]
 i => [0]
 Thread name [Thread-1] , current thread status => [true]
 i => [1]
 Thread name [Thread-1] , current thread status => [true]
 i => [2]
 Thread name [Thread-1] , current thread status => [true]
 i => [3]
 Thread name [Thread-1] , current thread status => [true]
 i => [4]
MyMainClass: Done !
shutDown() Called ..!!

 RunnableName = [Runnable-1] ; i => [0]

 RunnableName = [Runnable-1] ; i => [1]

 RunnableName = [Runnable-1] ; i => [2]

 RunnableName = [Runnable-1] ; i => [3]

 RunnableName = [Runnable-1] ; i => [4]

 RunnableName = [Runnable-1] ; i => [5]

 RunnableName = [Runnable-1] ; i => [6]
MyMainClass: End of main() !

Dogs, Cats and Babies





Sunday, August 11, 2013

Mac OSX another Apple Script to start Screen-Saver

This apple script can be executed to start the screen saver

do shell script "open /System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resources/ScreenSaverEngine.app"

Saturday, August 10, 2013

Mac OSX - Keyboard Bindings/Shortcuts similar to that of Windows

My ~/Library/KeyBindings/DefaultKeyBinding.dict has the following contents

{
    /* Remap Home / End to be correct :-) */

    "\UF729"  = "moveToBeginningOfLine:";                   /* Home         */
    "\UF72B"  = "moveToEndOfLine:";                         /* End          */
    "$\UF729" = "moveToBeginningOfLineAndModifySelection:"; /* Shift + Home */
    "$\UF72B" = "moveToEndOfLineAndModifySelection:";       /* Shift + End  */

 "\UF72C"   = "pageUp:";                                 /* PageUp       */
 "\UF72D"   = "pageDown:";                               /* PageDown     */

 "^c" = "copy:";
 "^v" = "paste:";
 "^x" = "cut:";
 "^s" = "save:";
 "^S" = "saveAs:";
 "^z" = "undo:";

 "^\UF702"  = "moveWordBackward:";                         /* Ctrl  + LeftArrow */  
 "^\UF703"  = "moveWordForward:";                          /* Ctrl  + RightArrow */  
 "^$\UF702" = "moveWordBackwardAndModifySelection:";    /* Shift + Ctrl + Leftarrow */  
 "^$\UF703" = "moveWordForwardAndModifySelection:";     /* Shift + Ctrl + Rightarrow */  
}

How to Auto-Login to (Mac OSX) and (Immediately Lock Screen)

How to Auto-Login to (Mac OSX) and (Immediately Lock Screen)

Its very simple - all that has to be done is auto-login as a particular user and then immediately run a script (or rather a script exported as application) which does the actual locking - in this case, run the screen saver which will in turn lock the screen

Step (1): Create an apple script using apple script editor. The script is a one liner : tell application "ScreenSaverEngine" to launch


Step (2): Export the script as a application in apple script editor


Step (3): Goto "System Preferences"


Step (4): Goto "Users and Groups"


Step (5): Click on "+" sign to add the new application we just exported


Step (6): You should now see the application (In my case I exported the script as "LockScreenApp" application) as one of the "login" items.


Step (7): Goto "Users and Groups" and then click on "Login Options"


Step (8): Choose the user whom you want to be automatically logged in when the system boots up.


Step (9): Under "System Preferences" , click on "Security and Privacy" , then make sure "Require password - IMMEDIATELY" is checked/enabled - so that when the screen-saver starts, the screen is automatically locked, and it will force the user to enter the password to unlock the system

Mac OSX Dock Show/Hide Delay and Mission Control / Launchpad Animation Duration

By setting these floating point values, we can have an even more pleasant experience with the Mac OSX Dock :-)

$ defaults write com.apple.dock autohide-time-modifier -float 0.50;killall Dock
$ defaults write com.apple.Dock autohide-delay -float 0; killall Dock

Mission Control Animation Duration

$ defaults write com.apple.dock expose-animation-duration -float 0.01;killall Dock

Launchpad Animation Duration

$ defaults write com.apple.dock springboard-page-duration -float 0.2;killall Dock
$ defaults write com.apple.dock springboard-show-duration -float 0.1;killall Dock
$ defaults write com.apple.dock springboard-hide-duration -float 0.1;killall Dock

Thursday, August 8, 2013

Make Home/End keys work correctly on Mac OSX

To make the HOME/END keys work as expected (like on Windows), do the following:

1. Create this file : ~/Library/KeyBindings/DefaultKeyBinding.dict

2. Add the following text to it:

{
        /* Remap Home / End to be correct :-) */
        "\UF729"  = "moveToBeginningOfLine:";                   /* Home         */
        "\UF72B"  = "moveToEndOfLine:";                         /* End          */
        "$\UF729" = "moveToBeginningOfLineAndModifySelection:"; /* Shift + Home */
        "$\UF72B" = "moveToEndOfLineAndModifySelection:";       /* Shift + End  */
}

3. Quit and re-open the applications to see the effect.

Sublime Text 2 - Awesome Text/Source Code Editor

Here is how you can install PACKAGE CONTROL

Open the console by pressing the following keys

CTRL + `

Copy the following line and paste it in the console and press ENTER key

import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print('Please restart Sublime Text to finish installation')

Using package control, there are tons of color schemes and plugins you can install !


My favourite key bindings on MacOSX

[
 { "keys": ["end"], "command": "move_to", "args": {"to": "eol", "extend": false} },
 { "keys": ["home"], "command": "move_to", "args": {"to": "bol", "extend": false} },

 { "keys": ["super+plus"], "command": "increase_font_size" },
 { "keys": ["super+minus"], "command": "decrease_font_size" },

 { "keys": ["ctrl+f"], "command": "show_panel", "args": {"panel": "find"} },

 { "keys": ["super+."], "command": "next_bookmark" },
 { "keys": ["super+,"], "command": "prev_bookmark" },
 { "keys": ["super+/"], "command": "toggle_bookmark" },
 { "keys": ["super+shift+/"], "command": "clear_bookmarks" },

 { "keys": ["ctrl+shift+end"], "command": "move_to", "args": {"to": "eol", "extend": true} },
 { "keys": ["ctrl+shift+home"], "command": "move_to", "args": {"to": "bol", "extend": true} },

 {
  "keys": ["super+alt+1"],
  "command": "set_layout",
  "args":
  {
   "cols": [0.0, 1.0],
   "rows": [0.0, 1.0],
   "cells": [[0, 0, 1, 1]]
  }
 },
 {
  "keys": ["super+alt+2"],
  "command": "set_layout",
  "args":
  {
   "cols": [0.0, 0.5, 1.0],
   "rows": [0.0, 1.0],
   "cells": [[0, 0, 1, 1], [1, 0, 2, 1]]
  }
 },
 {
  "keys": ["super+alt+3"],
  "command": "set_layout",
  "args":
  {
   "cols": [0.0, 0.33, 0.66, 1.0],
   "rows": [0.0, 1.0],
   "cells": [[0, 0, 1, 1], [1, 0, 2, 1], [2, 0, 3, 1]]
  }
 },
 {
  "keys": ["super+alt+4"],
  "command": "set_layout",
  "args":
  {
   "cols": [0.0, 0.25, 0.5, 0.75, 1.0],
   "rows": [0.0, 1.0],
   "cells": [[0, 0, 1, 1], [1, 0, 2, 1], [2, 0, 3, 1], [3, 0, 4, 1]]
  }
 },

 { "keys": ["ctrl+x"], "command": "cut" },
 { "keys": ["ctrl+c"], "command": "copy" },
 { "keys": ["ctrl+v"], "command": "paste" },
 { "keys": ["ctrl+shift+v"], "command": "paste_and_indent" },

 { "keys": ["ctrl+alt+up"], "command": "scroll_lines", "args": {"amount": 1.0} },
 { "keys": ["ctrl+alt+down"], "command": "scroll_lines", "args": {"amount": -1.0} },

 { "keys": ["super+f"], "command": "show_panel", "args": {"panel": "find"} },
 { "keys": ["super+alt+f"], "command": "show_panel", "args": {"panel": "replace"} },

 { "keys": ["ctrl+super+up"], "command": "swap_line_up" },
 { "keys": ["ctrl+super+down"], "command": "swap_line_down" },

 { "keys": ["super+j"], "command": "join_lines" },
 { "keys": ["super+shift+d"], "command": "duplicate_line" },

 { "keys": ["super+]"], "command": "indent" },
 { "keys": ["super+["], "command": "unindent" },


 { "keys": ["ctrl+backspace"], "command": "delete_word", "args": { "forward": false, "sub_words": true } },
 { "keys": ["ctrl+delete"], "command": "delete_word", "args": { "forward": true, "sub_words": true } },

 { "keys": ["ctrl+s"], "command": "save" },
 { "keys": ["ctrl+z"], "command": "undo" },
 { "keys": ["ctrl+shift+z"], "command": "redo" },
 { "keys": ["ctrl+n"], "command": "new_file" },
 { "keys": ["ctrl+w"], "command": "close" }
]

My current user settings:

{
 "auto_complete_commit_on_tab": true,
 "color_scheme": "Packages/Color Scheme - Default/Twilight.tmTheme",
 "font_face": "Consolas",
 "font_options":
 [
  "no_bold",
  "no_italic",
  "subpixel_antialias"
 ],
 "font_size": 18.0,
 "highlight_line": true,
 "highlight_modified_tabs": true,
 "ignored_packages":
 [
  "Vintage"
 ],
 "word_wrap": "true"
}

Thursday, July 25, 2013

Installing JDK on Ubuntu / Linux Mint

Here is what you need to do to install Oracle JDK on Ubuntu / Linux Mint

sudo add-apt-repository ppa:webupd8team/java
sudo apt-fast update
sudo apt-fast install oracle-jdk7-installer
sudo update-alternatives --config java

Faster install using apt-fast on Ubuntu / Linux Mint

apt-fast for faster download/install

Normally you would use "sudo apt-get package-name" to install a package on LINUX MINT or UBUNTU

But, "apt-fast" would make it even faster !

Here is what you need to do to install apt-fast:

sudo add-apt-repository ppa:apt-fast/stable
sudo apt-get update
sudo apt-get install apt-fast

So in the future, you can use "apt-fast" instead of "apt-get" to download packages from the repositories even faster

Example:

apt-fast install vim terminator gedit

Saturday, June 1, 2013

Get HOME / END keys working on MacOSX

There is a possibility that the Home/End keys on the keyboard don't work as expected in your MacOSX. So, while editing the text, to make it work the way it is supposed to, create a file as described below

~/Library/KeyBindings/DefaultKeyBinding.dict

Contents of the file:

{
/* Remap Home / End to be correct :-) */
"\UF729"  = "moveToBeginningOfLine:";                   /* Home         */
"\UF72B"  = "moveToEndOfLine:";                         /* End          */
"$\UF729" = "moveToBeginningOfLineAndModifySelection:"; /* Shift + Home */
"$\UF72B" = "moveToEndOfLineAndModifySelection:";       /* Shift + End  */
}

Sunday, May 19, 2013

Persistent SSH Sessions - using SSHFS and AUTOSSH

In this example, we can establish persistent SSHFS mounts using AUTOSSH - advantage being that even if SSH session dies, AutoSSH will re-establish the SSHFS session

Question: What is so cool about this ?

Answer:

Assume that the IP address of my PC is 199.199.199.100. Now, I wish to access/edit files on 10.0.0.170. I want to edit those files using my favourite text editor (such as SUBLIME TEXT 2).


This cool editor is installed on my PC, but not on the remote machine. Even though I can edit it using "vim", I wish to edit the file using SUBLIME TEXT 2.

So, what I do is I mount the remote directory locally via SSH protocol.

Old way of doing things:

Usually, I do "ssh giridhar@10.0.0.170" , then do a "cd /home/giridhar/data/" and then edit via the usual command: "vim source.py".

New way of doing things:

Now that I have SUBLIME TEXT 2 on my PC, I mount it via SSH:

On my PC :

"mkdir -p /home/bhujanga/SSH_MOUNT_POINTS/giridhar-10.0.0.170"

Note: my home directory on my PC is /home/bhujanga

Then I run :

"sshfs giridhar@10.0.0.170:/home/giridhar /home/bhujanga/SSH_MOUNT_POINTS/giridhar-10.0.0.170"

What the above commands does is - it mount's my home directory /home/giridhar on the remote machine 10.0.0.170 on my PC locally in the directory /home/bhujanga/SSH_MOUNT_POINTS/giridhar-10.0.0.170

Now I can fire up SUBLIME TEXT 2 editor and edit the file /home/bhujanga/SSH_MOUNT_POINTS/giridhar-10.0.0.170/data/source.py

as though it was a local file. But it is actually a file on the remote machine /home/giridhar/data/file.py mounted locally via SSH protocol

Now to enable persistent SSH sessions - modify the following Python Script to your requirements and run it to have the SSHFS sessions running all the time !

mount_details array below has a arrays as elements - first one being the user@host, second being the remote directory to mount locally, third being local directory on which the remote directory is mounted

#!/usr/bin/python

import os
import sys
import commands
import traceback

mount_details = [\
    ["root@10.0.37.1",      "/", "/Users/giri/SSH_MOUNT_POINTS/root-10.0.37.1"      ],\
    ["root@10.0.37.3",      "/", "/Users/giri/SSH_MOUNT_POINTS/root-10.0.37.3"      ],\
    ["root@10.0.0.95",      "/", "/Users/giri/SSH_MOUNT_POINTS/root-10.0.0.95"      ],\
    ["giridhar@10.0.0.170", "/", "/Users/giri/SSH_MOUNT_POINTS/giridhar-10.0.0.170" ],\
    ["root@10.0.14.14",     "/", "/Users/giri/SSH_MOUNT_POINTS/root-10.0.14.14"     ],\
    ["root@10.0.14.18",     "/", "/Users/giri/SSH_MOUNT_POINTS/root-10.0.14.18"     ]\
]

#["root@10.0.18.128",    "/", "/Users/giri/SSH_MOUNT_POINTS/root-10.0.18.128"    ],\
def exe(cmd_to_exe):
    print "Executing command : [%s]" % (cmd_to_exe)
    status,output = commands.getstatusoutput(cmd_to_exe)
    if status == 0:
        print "Successful !"
    else:
        print "Failed !"

    # for now, lets comment the output of the commands
    '''
    print "Output:"
    print output
    '''
    return status,output

def do_mounts():
    try:
        for item_array in mount_details:
            dir_path = item_array[2]
            exe("mkdir -p %s" % (dir_path))
            mnt_cmd = "sshfs -o reconnect,compression=yes,"\
            "transform_symlinks,"\
            "ServerAliveInterval=30,"\
            "ServerAliveCountMax=30,"\
            "ssh_command='autossh -M 0' %s:%s %s" % (item_array[0],item_array[1],item_array[2])
            exe(mnt_cmd)
    except Exception,ex:
        print "Exception: %s" % (ex)
        print "%s" % (traceback.format_exc())

def main():
    do_mounts()

if __name__ == "__main__":
    main()

# shfs -o reconnect,compression=yes,transform_symlinks,ServerAliveInterval=30,ServerAliveCountMax=30,ssh_command='autossh -M 0' username@server:/ /mnt/remote"

Wednesday, May 15, 2013

My ~/.bashrc File

Here is my recent ~/.bashrc file

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
    # We have color support; assume it's compliant with Ecma-48
    # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
    # a case would tend to support setf rather than setaf.)
    color_prompt=yes
    else
    color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

alias _1='ssh root@10.0.37.1'
alias _2='ssh root@10.0.37.2'
alias _old='cd /mnt/SATA-OLD/giri/'
alias __='echo $PWD > /tmp/__PWD__;ssh root@localhost'
alias ___='ssh root@localhost'
alias _b='ssh -X giridhar@10.0.0.170'
alias ll='ls -ltrh'
alias ...='ssh root@199.199.199.120'
alias ..='cd ..'
alias _v='gvim >/dev/null 2>&1'

export PATH=$PATH:/home/giri/bin

export PS1="\[\033[01;33m\]\h\[\033[01;34m\] \W \$\[\033[00m\] "

export PATH=$PATH:/opt/TurboVNC/bin

alias do_all_mounts='/home/giri/do_ssfs_mounts_10.0.37.2.sh; /home/giri/do_ssfs_mounts_10.0.0.170.sh'

alias cd_build='/home/giri/do_ssfs_mounts_10.0.0.170.sh; cd /home/giri/REMOTE/giridhar-10.0.0.170'
alias cd_idb='/home/giri/do_ssfs_mounts_10.0.37.2.sh; cd /home/giri/REMOTE/root-10.0.37.2'

function setup_public_key()
{
    if [ -f "$HOME/.ssh/id_rsa.pub" ]; then
        pubkey=`cat $HOME/.ssh/id_rsa.pub`
        ssh "$1"@"$2" "echo \"$pubkey\" >> ~/.ssh/authorized_keys"
    else
        echo "File [ $HOME/.ssh/id_rsa.pub ] does not exist !"
        echo "To generate this, please run \"ssh-keygen -t rsa\" command first"
    fi
}

alias _pub=setup_public_key

## fix below assumes you have root login enabled ##

fix_1="mkdir -p ~/.ssh; touch ~/.ssh/id_rsa ; touch ~/.ssh/id_rsa.pub ; touch ~/.ssh/authorized_keys ; touch ~/.ssh/known_hosts"

fix_2="chmod 700 ~/.ssh ; chmod 600 ~/.ssh/id_rsa ; chmod 644 ~/.ssh/id_rsa.pub ; chmod 644 ~/.ssh/authorized_keys ; chmod 644 ~/.ssh/known_hosts"

fix_3="sed -i 's/#UseDNS\ yes/UseDNS\ no/' /etc/ssh/sshd_config;sed -i 's/GSSAPIAuthentication\ yes/GSSAPIAuthentication\ no/' /etc/ssh/sshd_config;service sshd restart"

function fix_ssh()
{
    if [ -f "$HOME/.ssh/id_rsa.pub" ]; then
        pubkey=`cat $HOME/.ssh/id_rsa.pub`
        ssh "$1"@"$2" "$fix_1"
        ssh "$1"@"$2" "$fix_2"
        ssh "$1"@"$2" "$fix_3"
    else
        echo "File [ $HOME/.ssh/id_rsa.pub ] does not exist !"
        echo "To generate this, please run \"ssh-keygen -t rsa\" command first"
    fi
}

alias _sshfix=fix_ssh

alias _sshfs='sh /home/giri/sshfs_do_umount_and_mount.sh'
# export EDITOR="/usr/local/sublime/sublime_text"
export EDITOR="/usr/bin/vim"

export _JAVA_OPTIONS="-Dawt.useSystemAAFontSettings=on -Dswing.aatext=true"

alias py='nohup /home/giri/Applications/PyCHARM/Linux/pycharm-2.7.1/bin/pycharm.sh >/dev/null 2>&1 &'

alias 150='ssh root@10.0.0.150'
alias 170='ssh giridhar@10.0.0.170'

alias 37-1='ssh root@10.0.37.1'
alias 37-2='ssh root@10.0.37.2'
alias 37-3='ssh root@10.0.37.3'

alias 95='ssh root@10.0.0.95'

alias sub='nohup sublime >/dev/null 2>&1 &'
alias 127='ssh root@10.0.18.127'
alias 128='ssh root@10.0.18.128'

alias 53-1='ssh root@10.0.53.1'
alias 53-2='ssh root@10.0.53.1'
alias 82-1='ssh root@10.0.82.1'

alias MBG='giridhar@10.0.0.170'
alias MBGTMP='giridhar@10.0.0.170:/tmp'

function sshfs_mkdir()
{
mkdir -p /home/giri/SSH_MOUNT_POINTS/giridhar-10.0.0.170/home/giridhar; \
mkdir -p /home/giri/SSH_MOUNT_POINTS/root-10.0.37.1/root/reverse_tunnel; \
mkdir -p /home/giri/SSH_MOUNT_POINTS/root-10.0.37.1/root/MS-SQL; \
mkdir -p /home/giri/SSH_MOUNT_POINTS/root-10.0.37.1_root; \
mkdir -p /home/giri/SSH_MOUNT_POINTS/root-10.0.0.150/home/rpm_path/GIRI; \
mkdir -p /home/giri/SSH_MOUNT_POINTS/root-10.0.0.95/root.build_rpm.MYSQL.CHICKEN_CURRY;
mkdir -p /home/giri/SSH_MOUNT_POINTS/root-10.0.18.128/slash
mkdir -p /home/giri/SSH_MOUNT_POINTS/root-10.0.14.14/slash
mkdir -p /home/giri/SSH_MOUNT_POINTS/root-10.0.14.18/slash
}

function sshfs_umount()
{
fusermount -u /home/giri/SSH_MOUNT_POINTS/giridhar-10.0.0.170/home/giridhar; \
fusermount -u /home/giri/SSH_MOUNT_POINTS/root-10.0.37.1/root/reverse_tunnel; \
fusermount -u /home/giri/SSH_MOUNT_POINTS/root-10.0.37.1/root/MS-SQL; \
fusermount -u /home/giri/SSH_MOUNT_POINTS/root-10.0.37.1_root; \
fusermount -u /home/giri/SSH_MOUNT_POINTS/root-10.0.0.150/home/rpm_path/GIRI; \
fusermount -u /home/giri/SSH_MOUNT_POINTS/root-10.0.0.95/root.build_rpm.MYSQL.CHICKEN_CURRY;
fusermount -u /home/giri/SSH_MOUNT_POINTS/root-10.0.18.128/slash;
fusermount -u /home/giri/SSH_MOUNT_POINTS/root-10.0.14.14/slash
fusermount -u /home/giri/SSH_MOUNT_POINTS/root-10.0.14.18/slash
}

function sshfs_mount()
{
sshfs giridhar@10.0.0.170:/home/giridhar /home/giri/SSH_MOUNT_POINTS/giridhar-10.0.0.170/home/giridhar;
sshfs root@10.0.37.1:/root/reverse_tunnel /home/giri/SSH_MOUNT_POINTS/root-10.0.37.1/root/reverse_tunnel;
sshfs root@10.0.37.1:/root/MS-SQL /home/giri/SSH_MOUNT_POINTS/root-10.0.37.1/root/MS-SQL;
sshfs root@10.0.37.1:/root /home/giri/SSH_MOUNT_POINTS/root-10.0.37.1_root;
sshfs root@10.0.0.150:/home/rpm_path/GIRI /home/giri/SSH_MOUNT_POINTS/root-10.0.0.150/home/rpm_path/GIRI;
sshfs root@10.0.0.95:/root/build_rpm/MYSQL/CHICKEN_CURRY /home/giri/SSH_MOUNT_POINTS/root-10.0.0.95/root.build_rpm.MYSQL.CHICKEN_CURRY;
sshfs root@10.0.18.128:/ /home/giri/SSH_MOUNT_POINTS/root-10.0.18.128/slash
sshfs root@10.0.14.14:/ /home/giri/SSH_MOUNT_POINTS/root-10.0.14.14/slash
sshfs root@10.0.14.18:/ /home/giri/SSH_MOUNT_POINTS/root-10.0.14.18/slash
}

function sshfs_umount_and_mount()
{
    sshfs_mkdir
    sshfs_umount
    killall -9 sshfs;
    sshfs_mount
}

alias _sshfs_umount_mount=sshfs_umount_and_mount

export pass="mypassword123"
alias rdp='nohup rdesktop -u admin -p $pass -g 1915x1055 -x l -a 16 10.0.0.35 >/dev/null 2>&1 &'

alias _tz='tar -zxvf'
alias _tj='tar -jxvf'

function start()
{
    ssh root@10.0.0.$1 "service mysqld start"
}

function stop()
{
    ssh root@10.0.0.$1 "service mysqld stop"
}

alias start='start'
alias stop='stop'

alias 14-14='ssh root@10.0.14.14'
alias 14-18='ssh root@10.0.14.18'

Ubuntu - Make Unity faster

Put this line in ~/.xprofile file

export UNITY_LOW_GFX_MODE=1

~/.Xresources file

This is my ~/.Xresources file

Xft.dpi:        96
Xft.antialias:  true
Xft.rgba:       rgb
Xft.hinting:    true
Xft.hintstyle:  hintslight

Tweak Mouse settings through a script

This 2 liner script can be used to tweak mouse settings - especially Razer Mice

First query the mice present on your system

$ xinput --list
⎡ Virtual core pointer                     id=2 [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer               id=4 [slave  pointer  (2)]
⎜   ↳ PixArt Microsoft USB Optical Mouse       id=8 [slave  pointer  (2)]
⎣ Virtual core keyboard                    id=3 [master keyboard (2)]
    ↳ Virtual core XTEST keyboard              id=5 [slave  keyboard (3)]
    ↳ Power Button                             id=6 [slave  keyboard (3)]
    ↳ Power Button                             id=7 [slave  keyboard (3)]
    ↳ Apple Inc. Apple Keyboard                id=9 [slave  keyboard (3)]
    ↳ Apple Inc. Apple Keyboard                id=10 [slave  keyboard (3)]
    ↳ Eee PC WMI hotkeys                       id=11 [slave  keyboard (3)]

setup_mouse.sh - Microsoft Mouse

#!/bin/bash
xinput set-prop "PixArt Microsoft USB Optical Mouse" "Device Accel Constant Deceleration" 1
xinput set-prop "PixArt Microsoft USB Optical Mouse" "Device Accel Velocity Scaling" 3

Tuesday, May 14, 2013

Python Daemon Example (with Logging)

Here is a small example of a Daemon implemented in Python - with Logging

File: Python-Daemon-Class.py

#!/usr/bin/python

import sys
import time
import os
import atexit
from signal import SIGTERM
import logging

logging.basicConfig(filename='/tmp/my_daemon.log',level=logging.DEBUG)

#logging.debug('This message should go to the log file')
#logging.info('So should this')
#logging.warning('And this, too')

class MyDaemon(object):
    """
        A generic daemon class.
        Usage: subclass the Daemon class and override the run() method
    """
    startmsg = "started with pid %s"

    def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
            self.stdin = stdin
            self.stdout = stdout
            self.stderr = stderr
            self.pidfile = pidfile

    def daemonize(self):
        """
        do the UNIX double-fork magic, see Stevens' "Advanced 
        Programming in the UNIX Environment" for details (ISBN 0201563177)
        http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
        """
        try: 
                pid = os.fork() 
                if pid > 0:
                        # exit first parent
                        sys.exit(0) 
        except OSError, e: 
                sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
                sys.exit(1)

        # decouple from parent environment
        os.chdir(".") 
        os.setsid() 
        os.umask(0) 

        # do second fork
        try: 
            pid = os.fork() 
            if pid > 0:
                # exit from second parent
                sys.exit(0) 
        except OSError, e: 
            sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
            sys.exit(1) 
        
        # redirect standard file descriptors
        si = file(self.stdin, 'r')
        so = file(self.stdout, 'a+')
        se = file(self.stderr, 'a+', 0)
        
        pid = str(os.getpid())
        
        sys.stderr.write("\n%s\n" % self.startmsg % pid)
        sys.stderr.flush()

        if self.pidfile:
            file(self.pidfile,'w+').write("%s\n" % pid)
        
        atexit.register(self.delpid)
        os.dup2(si.fileno(), sys.stdin.fileno())
        os.dup2(so.fileno(), sys.stdout.fileno())
        os.dup2(se.fileno(), sys.stderr.fileno())

    def delpid(self):
        os.remove(self.pidfile)

    def start(self):
        """
        Start the daemon
        """
        # Check for a pidfile to see if the daemon already runs
        try:
            pf = file(self.pidfile,'r')
            pid = int(pf.read().strip())
            pf.close()
        except IOError:
            pid = None

        if pid:
            message = "pidfile %s already exist. Daemon already running?\n"
            sys.stderr.write(message % self.pidfile)
            sys.exit(1)

        # Start the daemon
        self.daemonize()
        self.run()

    def stop(self):
        """
        Stop the daemon
        """
        # Get the pid from the pidfile
        try:
                pf = file(self.pidfile,'r')
                pid = int(pf.read().strip())
                pf.close()
        except IOError:
                pid = None

        if not pid:
            message = "pidfile %s does not exist. Daemon not running?\n"
            sys.stderr.write(message % self.pidfile)
            return # not an error in a restart

        # Try killing the daemon process        
        try:
            while 1:
                os.kill(pid, SIGTERM)
                time.sleep(0.1)
        except OSError, err:
            err = str(err)
            if err.find("No such process") > 0:
                if os.path.exists(self.pidfile):
                    os.remove(self.pidfile)
                else:
                    print str(err)
                    sys.exit(1)

    def restart(self):
        """
        Restart the daemon
        """
        self.stop()
        time.sleep(5)
        self.start()

    def run(self):
        """
        You should override this method when you subclass Daemon.
        It will be called after the process has been
        daemonized by start() or restart().
        """

class TaskDaemon(MyDaemon):
    def run(self):
        while True:
            ''' this function below is called every 1 second '''
            try:
                do_my_task()
            except Exception,ex:
                print "Error in doing do_my_task(): %s" % (ex)

            ''' sleep for 1 second before doing stuff again '''
            time.sleep(1)

def do_my_task():
    logging.info("%s" % (time.time()))

def main():

    PIDFILE = '/tmp/my_daemon.pid'
    daemon = TaskDaemon(PIDFILE)
    daemon_name = "TaskDemon"

    if len(sys.argv) == 2:
        #==============================================================
        if 'start' == sys.argv[1]:
            try:
                daemon.start()
            except Exception,ex:
                print "%s start() error: %s" % (daemon_name,ex)
        #==============================================================
        elif 'stop' == sys.argv[1]:
            try:
                daemon.stop()
            except Exception,ex:
                print "%s stop() error: %s" % (daemon_name,ex)
        #==============================================================
        elif 'restart' == sys.argv[1]:
            try:
                daemon.restart()
            except Exception,ex:
                print "%s retart() error: %s" % (daemon_name,ex)
        #==============================================================
        else:
            print "Unknown command"
            sys.exit(2)
        #==============================================================
        sys.exit(0)
    else:
        #==============================================================
        print "usage: %s start|stop|restart" % sys.argv[0]
        sys.exit(2)
        #==============================================================

if __name__ == "__main__":
    main()
    

Output:


~ $ ./Python-Daemon-Class.py start -------------> Start Daemon

started with pid 28387

~ $ ./Python-Daemon-Class.py stop --------------> Stop Daemon


~ $ ./Python-Daemon-Class.py restart -----------> Restart Daemon

started with pid 28534

~ $ tail -f /tmp/my_daemon.log 
INFO:root:1368539507.14
INFO:root:1368539508.14
INFO:root:1368539509.14
INFO:root:1368539510.14
INFO:root:1368539511.14
INFO:root:1368539512.14
INFO:root:1368539513.14
INFO:root:1368539514.15
INFO:root:1368539515.15

Sunday, May 12, 2013

Multi-Threaded (Socket) Server in Python

Here is a small example of Multi-Threaded Socket Server in Python

Server.py

#!/usr/bin/python

import SocketServer
import subprocess
import sys
from threading import Thread
import time

HOST = 'localhost'
PORT = 21212

############################################################################

def reverse_string(my_str):
    if my_str:
        return my_str[::-1]

############################################################################
'''  One instance per connection.
     Override handle(self) to customize action. '''

class TCPConnectionHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        
        print "SingleTCPHandler::handle()"

        # self.request is the client connection
        data = self.request.recv(1024)  # clip input at 1Kb
        print "handle(): Received data : data =>\n[%s]" % (data)

        reply = reverse_string(data)

        print "handle(): Sending reply [%s]" % (reply)

        if reply is not None:
            self.request.send(reply)
        self.request.close()

############################################################################

class Server(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    # Ctrl-C will cleanly kill all spawned threads
    daemon_threads = True
    # much faster rebinding
    allow_reuse_address = True

    def __init__(self, server_address, RequestHandlerClass):
        SocketServer.TCPServer.__init__(\
        self,\
        server_address,\
        RequestHandlerClass)

############################################################################

if __name__ == "__main__":
    server = Server((HOST, PORT), TCPConnectionHandler)
    # terminate with Ctrl-C
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        sys.exit(0)

############################################################################

Client.py

#!/usr/bin/python

import socket
import random

def client(string):
    HOST, PORT = 'localhost', 21212
    # SOCK_STREAM == a TCP socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #sock.setblocking(0)  # optional non-blocking
    sock.connect((HOST, PORT))

    print "sending data => [%s]" % (string)

    sock.send(string)
    reply = sock.recv(16384)  # limit reply to 16K
    print "reply => \n [%s]" % (reply)
    sock.close()
    return reply

def main():
    client('Python Rocks')

if __name__ == "__main__":
    main()

Client side output (Execute ./Client.py)

$ ./Client.py
sending data => [Python Rocks]
reply =>
 [skcoR nohtyP]

Server side output:

 ./Server.py
SingleTCPHandler::handle()
handle(): Received data : data =>
[Python Rocks]
handle(): Sending reply [skcoR nohtyP]

Saturday, May 11, 2013

Python - Passing function itself (and its arguments) as an argument to another function

In this Python program, we are passing function itself as an argument to another function

#!/usr/bin/python

import traceback

def exec_function(function,success_msg,failure_msg,throw,*args):
    print "Function: [%s] , Arguments: [%s]" % (function.func_name,args)
    try:
        ret = function(*args)
        print success_msg
        return ret
    except Exception,ex:
        print failure_msg
        print "\nException : [%s]" % (ex)
        print "\n%s" % (traceback.format_exc())
        if throw:
            raise Exception("%s" % (failure_msg))

def add1(a,b,c):
    return (a+b+c)

def add2(a,b):
    return (a+b)

def divide(a,b):
    return (a/b)

def add_multiply(a,b):
    return ((a+b) , (a*b))

def main():
    r1 = exec_function(add1,"Successfully Added !", "Addition Failed", False, 1,2,3)
    print "r1 => %s" % (r1)

    print "----"

    r2 = exec_function(add2,"Successfully Added !", "Addition Failed", False, 10,20)
    print "r2 => %s" % (r2)

    print "----"

    r3 = exec_function(divide, "Division Successful", "Division Failed", False, 4, 0)
    print "r3 => %s" % (r3)

    print "----"

    r4 = exec_function(add_multiply, "Add & Multiply Successful", "Add & Mutiply Failed !", False, 5,6)
    (result_add, result_multiply) = r4
    print "result_add => %s, result_multiply => %s" % (result_add, result_multiply)

    print "----\n"

if __name__ == "__main__":
    main()

Output:

$ ./test.py 
Function: [add1] , Arguments: [(1, 2, 3)]
Successfully Added !
r1 => 6
----
Function: [add2] , Arguments: [(10, 20)]
Successfully Added !
r2 => 30
----
Function: [divide] , Arguments: [(4, 0)]
Division Failed

Exception : [integer division or modulo by zero]

Traceback (most recent call last):
  File "./PYTHON-Stuff-Tips-and-Tricks.py", line 8, in exec_function
    ret = function(*args)
  File "./PYTHON-Stuff-Tips-and-Tricks.py", line 25, in divide
    return (a/b)
ZeroDivisionError: integer division or modulo by zero

r3 => None
----
Function: [add_multiply] , Arguments: [(5, 6)]
Add & Multiply Successful
result_add => 11, result_multiply => 30
----

Wednesday, May 8, 2013

Automatic Remote Desktop Re-connect in Linux

Here is a small shell script using which we can re-connect the remote desktop session, in case it dies for some reason

As long as the script below is running, the RDP will re-connect back

Typically, we issue the following command to do a remote desktop:

rdesktop -u <username> -p <password> -g <widthPixels x heightPixels> -x <bandwidth/type-of-network> -a <bit-depth> <server-ip>

In the below example, I have set my password in ~/.bashrc (or ~/.bash_profile) by inserting the following line at the end of the file:

export pass="myRemoteDesktopPassword"

Script: "establish_rdp"

Make sure you do chmod 755 establish_rdp and then to run ./establish_rdp to run

#!/bin/bash

#####################################################
#
# Author:
#    Giridhar Bhujanga : giridharmb@gmail.com
#
#####################################################

file="/tmp/__rdppdip.file__"
log_file="/tmp/__rdp__.log"
one_megabyte="1048576"

> $log_file

function get_logfile_size()
{
    size=$(du -s -B 1 $log_file|awk '{print $1}')
    echo $size
}

function rdp_cmd_exec()
{
    nohup rdesktop -u admin -p $pass -g 1900x1035 -x l -a 16 10.0.0.35 >/dev/null 2>&1 &
}

function my_log()
{
    echo "$1" >> $log_file 2>&1
}

function infinite_loop()
{
    for((;;))
    do
        curr_pid=`cat $file`
        ps -p $curr_pid > /dev/null 2>&1
        if [ "$?" = "0" ]; then
            my_log "PID $curr_pid is actually running ! Will (not) re-establish the RDP connection..."
        else
            rdp_cmd_exec
            echo "$!" > $file
        fi
        lfs=$(get_logfile_size)
        my_log "log-file-size: $lfs"
        if [ $lfs -ge $one_megabyte ]; then
            > $log_file
            my_log "Log file was greater than 1MB, so emptied it..."
        fi
        sleep 1
    done
}

curr_pid=`cat $file`

ps -p $curr_pid > /dev/null 2>&1

if [ "$?" = "0" ]; then
    my_log "I think the RDP session is already established ! Not doing anything. Exiting..."
    infinite_loop
else
    my_log "RDP session is not alive ! So, now trying to start it..."
    rdp_cmd_exec
    pid="$!"
    echo "$pid" > $file
    infinite_loop
fi

exit 0

To see what is going on do this:

tail -f /tmp/__rdp__.log

Serialization / De-serialization by writing (/reading) to (/from) disk - in Python

Here is a small example of serializing and de-serializing data using pickle module

In this example, we serialize data and write to disk and then again read it back from the disk and then de-serialize it

#!/usr/bin/python

import cPickle

array_file = "test_array.dat"
dict_file = "test_dict.dat"

def write_obj_to_disk(obj, pickle_file):
    cPickle.dump(obj, open(pickle_file, 'wb'))

def read_obj_from_disk(pickle_file):
    obj = cPickle.load(open(pickle_file, 'rb'))
    return obj


def write_stuff():
    print "write_stuff():"
    my_dict = {}
    my_dict["a"] = "linux"
    my_dict["b"] = "rocks"
    print my_dict
    write_obj_to_disk(my_dict, dict_file)
    print "done writing dictionary..."

    my_array = [1,2,3,4,5]
    print my_array
    write_obj_to_disk(my_array, array_file)
    print "done writing list..."

def read_stuff():
    print "read_stuff()"
    new_list = list(read_obj_from_disk(array_file))
    new_dict = dict(read_obj_from_disk(dict_file))
    return new_list, new_dict

def main():
    print "\n @ Now writing to disk ...\n"
    write_stuff()
    print "\n @ Done writing...\n"
    print "\n @ Now reading from disk ...\n"
    my_list, my_dict = read_stuff()
    print "\n @ Done reading...\n"

    print "---\n main(): After reading data from the files: \n---"
    print "my_list:"
    print my_list
    print "my_dict:"
    print my_dict

if __name__ == "__main__":
    main()

Output:

$ ./read-write.py 

 @ Now writing to disk ...

write_stuff():
{'a': 'linux', 'b': 'rocks'}
done writing dictionary...
[1, 2, 3, 4, 5]
done writing list...

 @ Done writing...


 @ Now reading from disk ...

read_stuff()

 @ Done reading...

---
 main(): After reading data from the files: 
---
my_list:
[1, 2, 3, 4, 5]
my_dict:
{'a': 'linux', 'b': 'rocks'}

Python - Simple Exception Handling (throw/catch)

Here is one of the ways to catch and again throw exceptions

#!/usr/bin/python

import sys
import traceback

def a():
    arr = []
    try:
        arr.insert(0, 'a')
        arr.insert(1, 'b')
        arr.insert(x, 'b') # ERROR here !
        
    except Exception,ex:
        print "Error (1) : %s" %(sys.exc_info()[0])
        print "Exception Msg (1): %s" % str(ex)
        print "Traceback (1): \n-->>\n%s<<--" % (traceback.format_exc())
        raise Exception("## RAISE (1): With Message ## ")
    finally:
        print "a(): finally block"

def b():
    try:
        a()
    except Exception,ex:
        print "Error (2) : Called a() , Got Error !"
        print "Msg(2) : %s" % sys.exc_info()[0]
        print "Exception Msg (2): %s" % str(ex)
        print "Traceback (2): \n-->>\n%s<<--" % (traceback.format_exc())

def main():
    print " $$ Before calling b() "
    b()
    print " $$ After calling b()"

if __name__ == "__main__":
    main()

Output:

$ ./test.py
 $$ Before calling b()
Error (1) : <type 'exceptions.NameError'>
Exception Msg (1): global name 'x' is not defined
Traceback (1):
-->>
Traceback (most recent call last):
  File "./test.py", line 11, in a
    arr.insert(x, 'b') # ERROR here !
NameError: global name 'x' is not defined
<<--
a(): finally block
Error (2) : Called a() , Got Error !
Msg(2) : <type 'exceptions.Exception'>
Exception Msg (2): ## RAISE (1): With Message ##
Traceback (2):
-->>
Traceback (most recent call last):
  File "./test.py", line 23, in b
    a()
  File "./test.py", line 17, in a
    raise Exception("## RAISE (1): With Message ## ")
Exception: ## RAISE (1): With Message ##
<<--
 $$ After calling b()

Sunday, May 5, 2013

Remove the delay in Apple Dock (Show/Hide)

To remove the delay, open Terminal, type or copy and paste the following line and hit return:

defaults write com.apple.Dock autohide-delay -float 0 && killall Dock

To restore the default behavior, enter:

defaults delete com.apple.Dock autohide-delay && killall Dock

Execute a shell command in case a file changes

Here is a small shell script - using which we can execute a shell command in case the file which we are monitoring changes

Usage:

file_changed.sh hello.txt "scp hello.txt root@10.0.37.1:/root"

file_changed.sh : Shell script below

hello.txt : File that we are monitoring (for any changes)

"scp hello.txt root@10.0.37.1:/root" : Command to execute in case the file that we are monitoring changes

File : file_changed.sh(For MacOSX)

#!/bin/bash

rand=$(echo $RANDOM)

tmp_md5sum_file=/tmp/$rand

> $tmp_md5sum_file

# filename to monitor
actual_file="$1"

# command to execute in case the file changes
command_to_exec="$2"

echo "File to monitor : [$1]"
echo "Command to execute if file changes: [$2]"

for((;;))
do
 cat $tmp_md5sum_file|grep "MD5"
 # in case we have already captured the MD5 of the file to monitor
 if [ "$?" = "0" ];then
  # current md5sum of the file
  new_md5=$(md5 $actual_file|grep "MD5"|cut -d '=' -f2|tr -d ' ')
  # old md5sum of the file (previously captured in the tmp file)
  old_md5=$(cat $tmp_md5sum_file|grep "MD5"|cut -d '=' -f2|tr -d ' ')
  # if the old and new md5 are same, don't do anything
  if [ "$new_md5" = "$old_md5" ];then
   echo "file not changed.."
  else
   # in case the md5 has changed, execute the command and
   # capture the new md5sum to the tmp file (save it)
   echo "file changed !"
   $command_to_exec
   md5 $actual_file > $tmp_md5sum_file
  fi
 else
  md5 $actual_file > $tmp_md5sum_file
 fi
 sleep 1
done

File : file_changed.sh(For Linux)

#!/bin/bash

rand=$(echo $RANDOM)

tmp_md5sum_file=/tmp/$rand

> $tmp_md5sum_file

# filename to monitor
actual_file="$1"

# command to execute in case the file changes
command_to_exec="$2"

echo "File to monitor : [$1]"
echo "Command to execute if file changes: [$2]"

for((;;))
do
 cat $tmp_md5sum_file|grep "$1"
 # in case we have already captured the MD5 of the file to monitor
 if [ "$?" = "0" ];then
  # current md5sum of the file
  new_md5=$(md5sum $actual_file|awk '{print $1}'|tr -d ' ')
  # old md5sum of the file (previously captured in the tmp file)
  old_md5=$(cat $tmp_md5sum_file|awk '{print $1}'|tr -d ' ')
  # if the old and new md5 are same, don't do anything
  if [ "$new_md5" = "$old_md5" ];then
   echo "file not changed.."
  else
   # in case the md5 has changed, execute the command and
   # capture the new md5sum to the tmp file (save it)
   echo "file changed !"
   $command_to_exec
   md5sum $actual_file > $tmp_md5sum_file
  fi
 else
  md5sum $actual_file > $tmp_md5sum_file
 fi
 sleep 1
done

How to mount a remote directory locally via SSH

Mounting a remote directory - locally via SSH protocol

Assume you have a directory /home/patrick/data on 192.168.1.100

You have a local directory /home/kate/remote-mounted-dir


How do you access all the files under /home/patrick/data on 192.168.1.100 locally ?

Answer : Pretty Simple ! Use SSHFS command for that ! Run this command locally on your machine:

sshfs patrick@192.168.1.100:/home/patrick/data /home/kate/remote-mounted-dir

How to restore "normal" scroll bars in Ubuntu

$ gsettings set com.canonical.desktop.interface scrollbar-mode normal
$ gconftool-2 --set /apps/metacity/general/button_layout --type string menu:minimize,maximize,close

How to install AMD/ATI Drivers in Linux

sudo apt-get install build-essential cdbs dh-make dkms execstack dh-modaliases linux-headers-generic fakeroot
sudo apt-get install lib32gcc1
sudo apt-get install linux-source fglrx fglrx-amdcccle
wget http://www2.ati.com/drivers/linux/amd-driver-installer-catalyst-13.1-linux-x86.x86_64.zip
unzip amd-driver-installer-catalyst-13.1-linux-x86.x86_64.zip
chmod +x amd-driver-installer-catalyst-13.1-linux-x86.x86_64.run
sudo sh ./amd-driver-installer-catalyst-13.1-linux-x86.x86_64.run --buildpkg Ubuntu/quantal
sudo dpkg -i fglrx*.deb

How to reset Unity in Ubuntu - in case it got screwed up

For Unity If SomeThing Went Wrong Enter following commands to Reset

# apt-get install dconf-tools
# dconf reset -f /org/compiz/ 
# setsid unity
# git clone https://github.com/phanimahesh/unity-revamp.git
# cd unity-revamp
# chmod +x unity-reset.py
# ln -s ./unity-reset.py /usr/bin/unity-reset

Then run in terminal:

# unity-reset
# gconftool-2 --recursive-unset /apps/compiz-1 unity --reset

How to burn ISO to a CD-R/W using command line in Linux

# cdrecord -scanbus

Output:

Cdrecord-Clone 2.01a34 (i686-pc-linux-gnu)
Copyright (C) 1995-2004 Jrg Schilling
scsidev: 'ATA:'
devname: 'ATA'
scsibus: -1 target: -1 lun: -1
Warning: Using badly designed ATAPI via /dev/hd*
interface.
Linux sg driver version: 3.5.27
Using libscg version 'schily-0.8'.
scsibus1:
1,0,0 100) 'SONY' 'CD-Writer' '1.0g'
1,1,0 101) *
1,2,0 102) *
1,3,0 103) *
1,4,0 104) *
1,5,0 105) *
1,6,0 106) *
1.7.0 107) *

In above example, my device name is 1,0,0. Now again use the cdrecord command to burn ISO image:

# cdrecord -v -dao dev=1,0,0 file.iso

You can also specify burning speed:

# cdrecord -v -dao dev=1,0,0 speed=8 file.iso

SSH tips

Here are some tips for SSH logins

This works on the network setup that we have :)

How to generate user's Public Key ?

RSA key:

ssh-keygen -t rsa

Problem: User's ssh directory and files inside it does not have right permissions

Solution:Run this command from where-ever you want (inside your home directory)

mkdir -p ~/.ssh; touch ~/.ssh/id_rsa ; touch ~/.ssh/id_rsa.pub ; touch ~/.ssh/authorized_keys ; touch ~/.ssh/known_hosts
chmod 700 ~/.ssh ; chmod 600 ~/.ssh/id_rsa ; chmod 644 ~/.ssh/id_rsa.pub ; chmod 644 ~/.ssh/authorized_keys ; chmod 644 ~/.ssh/known_hosts

Problem: SSH takes too long to login

Solution:Run this command as "root", only once on the remote SSH server"

sed -i 's/#UseDNS\ yes/UseDNS\ no/' /etc/ssh/sshd_config;sed -i 's/GSSAPIAuthentication\ yes/GSSAPIAuthentication\ no/' /etc/ssh/sshd_config;service sshd restart

Problem: Cannot SSH to the server as "root"

Solution:Run this command as "root", only once on the remote SSH server

sed -i 's/PermitRootLogin no/PermitRootLogin yes'/g /etc/ssh/sshd_config; sudo service sshd restart

Another easy way to SSH without a password !

Assume you are logged in as user "kate" on 192.168.0.10

Now assume you would want to ssh to 192.168.0.123 as user "patrick"

Command you issue to SSH (from kate@192.168.0.10) is:

ssh patrick@192.168.0.123

Now if you want to SSH to 192.168.0.123 as "patrick" without being asked for password, all you have to do is run this command once (when logged in as "kate" on 192.168.0.10)

ssh-copy-id patrick@192.168.0.123

After you run that once, it will not ask you for password the next time you issue this command ssh patrick@192.168.0.123

Automatic VPN Connection

For MacOSX Only

Here is a sample Apple Script - that automatically reconnects the VPN in case of a disconnection

In this example, the name of the VPN connection is "My-VPN"

Create this script in Apple Script editor & export it as application. Make sure you choose "Stay Open" option while exporting the apple script as application

After that, you can run this exported application. Also, you may want to add this application in the list of "start up items" when the user logs is, so that VPN is "always on"

on idle
 tell application "System Events"
  tell current location of network preferences
   set myConnection to the service "My-VPN"
   if myConnection is not null then
    if current configuration of myConnection is not connected then
     connect myConnection
    end if
   end if
  end tell
  return 120
 end tell
end idle

File - [/etc/ppp/ip-up] : Sets up routing after the VPN connects (this is optional - you may or may not need it)

#!/bin/bash
/sbin/route add -net 10.0.0.0/8 10.0.254.37

Wednesday, January 30, 2013

SATA HDD Simple Benchmark

Simple Hard Disk Drive Read/Write Performance Test

Parameters to "hdparm" command line tool (below)

       -t     Perform timings of device reads for benchmark and comparison purposes.  For mean‐
              ingful results, this operation should be repeated 2-3 times on an otherwise inac‐
              tive  system  (no  other active processes) with at least a couple of megabytes of
              free memory.  This displays the speed of reading through the buffer cache to  the
              disk without any prior caching of data.  This measurement is an indication of how
              fast the drive can  sustain  sequential  data  reads  under  Linux,  without  any
              filesystem  overhead.   To  ensure  accurate  measurements,  the  buffer cache is
              flushed during the processing of -t using the BLKFLSBUF ioctl.

       -T     Perform timings of cache reads for benchmark and comparison purposes.  For  mean‐
              ingful results, this operation should be repeated 2-3 times on an otherwise inac‐
              tive system (no other active processes) with at least a couple  of  megabytes  of
              free  memory.   This displays the speed of reading directly from the Linux buffer
              cache without disk access.  This measurement is essentially an indication of  the
              throughput of the processor, cache, and memory of the system under test.

mbg ~ # hdparm -Tt /dev/sda

/dev/sda:
 Timing cached reads:   5730 MB in  2.00 seconds = 2865.99 MB/sec
 Timing buffered disk reads: 318 MB in  3.00 seconds = 105.91 MB/sec

mbg ~ # dd if=/dev/zero of=/home/tempfile bs=1M count=1024 conv=fdatasync,notrunc -----> Write Test
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 10.9301 s, 98.2 MB/s

mbg ~ # echo 3 > /proc/sys/vm/drop_caches ---------------------------------------------> Turn Off Cache

mbg ~ # dd if=/home/tempfile of=/dev/null bs=1M count=1024 ----------------------------> Read Test

1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 13.5827 s, 79.1 MB/s

HDD Information


mbg ~ # hdparm -I /dev/sda

/dev/sda:

ATA device, with non-removable media
 Model Number:       ST31000524AS                            
 Serial Number:      9VPGJNW2
 Firmware Revision:  JC45    
 Transport:          Serial, SATA Rev 3.0
Standards:
 Used: unknown (minor revision code 0x0029) 
 Supported: 8 7 6 5 
 Likely used: 8
Configuration:
 Logical  max current
 cylinders 16383 16383
 heads  16 16
 sectors/track 63 63
 --
 CHS current addressable sectors:   16514064
 LBA    user addressable sectors:  268435455
 LBA48  user addressable sectors: 1953525168
 Logical/Physical Sector size:           512 bytes
 device size with M = 1024*1024:      953869 MBytes
 device size with M = 1000*1000:     1000204 MBytes (1000 GB)
 cache/buffer size  = unknown
 Nominal Media Rotation Rate: 7200
Capabilities:
 LBA, IORDY(can be disabled)
 Queue depth: 32
 Standby timer values: spec'd by Standard, no device specific minimum
 R/W multiple sector transfer: Max = 16 Current = 16
 Recommended acoustic management value: 208, current value: 208
 DMA: mdma0 mdma1 mdma2 udma0 udma1 udma2 udma3 udma4 udma5 *udma6 
      Cycle time: min=120ns recommended=120ns
 PIO: pio0 pio1 pio2 pio3 pio4 
      Cycle time: no flow control=120ns  IORDY flow control=120ns
Commands/features:
 Enabled Supported:
    * SMART feature set
      Security Mode feature set
    * Power Management feature set
    * Write cache
    * Look-ahead
    * Host Protected Area feature set
    * WRITE_BUFFER command
    * READ_BUFFER command
    * DOWNLOAD_MICROCODE
      SET_MAX security extension
    * Automatic Acoustic Management feature set
    * 48-bit Address feature set
    * Device Configuration Overlay feature set
    * Mandatory FLUSH_CACHE
    * FLUSH_CACHE_EXT
    * SMART error logging
    * SMART self-test
    * General Purpose Logging feature set
    * WRITE_{DMA|MULTIPLE}_FUA_EXT
    * 64-bit World wide name
      Write-Read-Verify feature set
    * WRITE_UNCORRECTABLE_EXT command
    * {READ,WRITE}_DMA_EXT_GPL commands
    * Segmented DOWNLOAD_MICROCODE
    * Gen1 signaling speed (1.5Gb/s)
    * Gen2 signaling speed (3.0Gb/s)
    * Gen3 signaling speed (6.0Gb/s)
    * Native Command Queueing (NCQ)
    * Phy event counters
    * unknown 76[15]
      Device-initiated interface power management
    * Software settings preservation
    * SMART Command Transport (SCT) feature set
    * SCT Long Sector Access (AC1)
    * SCT LBA Segment Access (AC2)
    * SCT Error Recovery Control (AC3)
    * SCT Features Control (AC4)
    * SCT Data Tables (AC5)
      unknown 206[12] (vendor specific)
Security: 
 Master password revision code = 65534
  supported
 not enabled
 not locked
  frozen
 not expired: security count
  supported: enhanced erase
 164min for SECURITY ERASE UNIT. 164min for ENHANCED SECURITY ERASE UNIT.
Logical Unit WWN Device Identifier: 5000c5004eaa8387
 NAA  : 5
 IEEE OUI : 000c50
 Unique ID : 04eaa8387
Checksum: correct

Find total space occupied by a set of files

Here is a one liner using which we can find the total space occupied by a file with a specific extension

Sum of all *.tgz files in MEGABYTES (blocks of 1M) in the current directory only and not the sub-folders (maxdepth=1)

find . -maxdepth 1 -type f -name "*.tgz" -exec du -s -B 1M {} \; | awk '{print $1}'|while read line;do echo "$line";done|paste -sd+ | bc

Just to verify, doing a "ls -lh"

giri@mbg ~ $ ls -lh *.tgz
-rw-rw-r-- 1 giri giri 3.6G Jan 30 13:00 __Downloads.tgz
-rw-rw-r-- 1 giri giri  11G Jan 30 13:26 __ISO-Images.tgz
-rw-rw-r-- 1 giri giri 3.5G Jan 30 15:51 __Others.tgz
-rw-rw-r-- 1 giri giri 1.2M Jan 30 12:46 __scripts_and_settings_and_fluxbox.tgz
-rw-rw-r-- 1 giri giri 818M Jan 30 12:46 __SOFTWARE.tgz
-rw-rw-r-- 1 giri giri 2.1G Jan 30 12:55 __SOURCE_CODE.tgz
-rw-rw-r-- 1 giri giri 225K Jan 29 20:05 vim-tarball.tgz
-rw-rw-r-- 1 giri giri  17M Jan 30 12:43 __Windows-Fonts.tgz

Output

20989

Sum of all *.h and *.c files in current folder and all sub-folders in MB

find . -type f \( -iname "*.h" -o -iname "*.c" \) -exec du -s -B 1M {} \; | awk '{print $1}'|while read line;do echo "$line";done|paste -sd+ | bc

Output

17122

Monday, January 7, 2013

Reverse SSH Tunnel

Here is an example which illustrates reverse SSH tunneling

First, I will configure the virtual IP's. It is not needed for your setup, but doing this just for this example.

ifconfig bond0:20 192.168.0.10 netmask 255.255.255.0
route add -net 192.168.0.0 netmask 255.255.255.0 dev bond0

Node-1 IP = 192.168.0.10 : Source node (origin)

Node-2 IP = 192.168.0.20 : Intermediate node (some node that may exist between source and destination)

Node-3 IP = 192.168.0.30 : Destination Node (target node)

Idea is: From destination, I do the reverse SSH to the origin (source) after setting up the tunneling

Normal SSH connection

[source]->[intermediate]->[target]

Reverse Tunneling

[source]<-[intermediate]<-[target]

Next I do the SSH tunneling, which should be active in order to do the reverse SSH

On node with IP 192.168.0.10

[root@gary-blade ~]#ssh -R 20000:localhost:22 root@192.168.0.20
The authenticity of host '192.168.0.20 (192.168.0.20)' can't be established.
RSA key fingerprint is e2:94:30:8b:0b:91:a0:2b:01:fa:eb:fc:98:8e:3f:3b.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.20' (RSA) to the list of known hosts.
Last login: Mon Jan  7 16:57:30 2013 from 10.2.140.140
[root@gary380 ~]#

On node with IP 192.168.0.20

[root@gary380 ~]#ssh -R 20001:localhost:22 root@192.168.0.30
The authenticity of host '192.168.0.30 (192.168.0.30)' can't be established.
RSA key fingerprint is 25:fb:c3:04:66:77:0d:a9:05:d5:e5:b7:9e:57:39:3a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.30' (RSA) to the list of known hosts.
root@192.168.0.30's password: 
Last login: Mon Jan  7 16:34:57 2013 from 16.154.137.27
[root@ibrix55-gpu ~]#

Now do the reverse SSH : from 192.168.0.30 (to 192.168.0.20)

[root@ibrix55-gpu ~]#ssh localhost -p 20001
Password: 
Last login: Mon Jan  7 17:16:58 2013 from 127.0.0.1
[root@gary380 ~]#

Now do the reverse SSH : from 192.168.0.20 (to 192.168.0.10)

[root@gary380 ~]#ssh root@localhost -p 20000
The authenticity of host 'localhost (127.0.0.1)' can't be established.
RSA key fingerprint is 12:5a:2e:9a:bb:ff:7a:46:66:79:36:d0:2c:b0:14:fc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
Last login: Mon Jan  7 16:56:06 2013 from 10.2.140.140
[root@gary-blade ~]#

Password-less SSH Test and Copy (SCP)

Here is a small script, which will test if password-less SSH is setup. If yes, then it will copy a file called "deploy.jar" present somewhere in the current working directory to the target node specified, in the directory "/usr/local/install/bin/" of the target node.

Also, after doing the "scp", it will do some task. In this example, it will restart a daemon "my_daemon" on the target node after the "scp"

Pre-requisite for this script to work: Password-less SSH must be setup between these nodes

Script: copy.sh

How to run the script: ./copy.sh "10.2.4.100" "10.4.55.200"

#!/bin/bash

if [ $# -eq 0 ] ; then
    echo ""
    echo "Usage:"
    echo "   Example-1: $0 \"IP-address-of-target-machine\""
    echo "   Example-2: $0 \"IP-address-of-target-machine-1\" \"IP-address-of-target-machine-2\" \"IP-address-of-target-machine-3\""
    echo ">> Requirement: Passwordless SSH must be setup between the machines <<"
    echo ""
    exit 1
fi

for node in "$@"
do
    ssh -o 'PreferredAuthentications=publickey' root@"$node" "echo" 2>/dev/null 1>/dev/null
    if [ "$?" != "0" ]
    then
        echo "Badnews: Passwordless SSH is NOT setup between this node and [$node]"
        exit 1
    else
        echo "Goodnews: Passwordless SSH is setup between this node and [$node]"
    fi
done

for node in "$@"
do
    file=`find . -name "deploy.jar" -type f|tail -1`
    if [ "$file" = "" ]
    then
        cwd=`pwd`
        echo "Could not find 'deploy.jar' under $cwd"
        echo "Are you sure you are in the right directory ?"
        exit 1
    fi
    echo "Copying [$file] to Node: [$node] in the following location: '/usr/local/install/bin'"
    scp `find . -name "deploy.jar" -type f|tail -1` root@$node:/usr/local/install/bin
    echo "Restarting FM..."
    ssh root@$node "service my_daemon restart"
done

OpenBox rc.xml

Here is my ~/.config/openbox/rc.xml of the CRUNCHBANG Linux

<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file, it will be overwritten on install.
        Copy the file to $HOME/.config/openbox/ instead. -->
<openbox_config xmlns="http://openbox.org/3.4/rc" xmlns:xi="http://www.w3.org/2001/XInclude">
  <resistance>
    <strength>10</strength>
    <screen_edge_strength>20</screen_edge_strength>
  </resistance>
  <focus>
    <focusNew>yes</focusNew>
    <!-- always try to focus new windows when they appear. other rules do
       apply -->
    <followMouse>yes</followMouse>
    <!-- move focus to a window when you move the mouse into it -->
    <focusLast>yes</focusLast>
    <!-- focus the last used window when changing desktops, instead of the one
       under the mouse pointer. when followMouse is enabled -->
    <underMouse>yes</underMouse>
    <!-- move focus under the mouse, even when the mouse is not moving -->
    <focusDelay>200</focusDelay>
    <!-- when followMouse is enabled, the mouse must be inside the window for
       this many milliseconds (1000 = 1 sec) before moving focus to it -->
    <raiseOnFocus>no</raiseOnFocus>
    <!-- when followMouse is enabled, and a window is given focus by moving the
       mouse into it, also raise the window -->
  </focus>
  <placement>
    <policy>UnderMouse</policy>
    <!-- 'Smart' or 'UnderMouse' -->
    <center>yes</center>
    <!-- whether to place windows in the center of the free area found or
       the top left corner -->
    <monitor>Mouse</monitor>
    <!-- with Smart placement on a multi-monitor system, try to place new windows
       on: 'Any' - any monitor, 'Mouse' - where the mouse is, 'Active' - where
       the active window is, 'Primary' - only on the primary monitor -->
    <primaryMonitor>1</primaryMonitor>
    <!-- The monitor where Openbox should place popup dialogs such as the
       focus cycling popup, or the desktop switch popup.  It can be an index
       from 1, specifying a particular monitor.  Or it can be one of the
       following: 'Mouse' - where the mouse is, or
                  'Active' - where the active window is -->
  </placement>
  <theme>
    <name>Onyx</name>
    <titleLayout>NLIMC</titleLayout>
    <!--
      available characters are NDSLIMC, each can occur at most once.
      N: window icon
      L: window label (AKA title).
      I: iconify
      M: maximize
      C: close
      S: shade (roll up/down)
      D: omnipresent (on all desktops).
  -->
    <keepBorder>yes</keepBorder>
    <animateIconify>yes</animateIconify>
    <font place="ActiveWindow">
      <name>Sans</name>
      <size>8</size>
      <!-- font size in points -->
      <weight>Normal</weight>
      <!-- 'bold' or 'normal' -->
      <slant>Normal</slant>
      <!-- 'italic' or 'normal' -->
    </font>
    <font place="InactiveWindow">
      <name>Sans</name>
      <size>8</size>
      <!-- font size in points -->
      <weight>Normal</weight>
      <!-- 'bold' or 'normal' -->
      <slant>Normal</slant>
      <!-- 'italic' or 'normal' -->
    </font>
    <font place="MenuHeader">
      <name>sans</name>
      <size>9</size>
      <!-- font size in points -->
      <weight>normal</weight>
      <!-- 'bold' or 'normal' -->
      <slant>normal</slant>
      <!-- 'italic' or 'normal' -->
    </font>
    <font place="MenuItem">
      <name>sans</name>
      <size>9</size>
      <!-- font size in points -->
      <weight>normal</weight>
      <!-- 'bold' or 'normal' -->
      <slant>normal</slant>
      <!-- 'italic' or 'normal' -->
    </font>
    <font place="ActiveOnScreenDisplay">
      <name>Sans</name>
      <size>9</size>
      <!-- font size in points -->
      <weight>Normal</weight>
      <!-- 'bold' or 'normal' -->
      <slant>Normal</slant>
      <!-- 'italic' or 'normal' -->
    </font>
    <font place="InactiveOnScreenDisplay">
      <name>Sans</name>
      <size>9</size>
      <!-- font size in points -->
      <weight>Normal</weight>
      <!-- 'bold' or 'normal' -->
      <slant>Normal</slant>
      <!-- 'italic' or 'normal' -->
    </font>
  </theme>
  <desktops>
    <!-- this stuff is only used at startup, pagers allow you to change them
       during a session

       these are default values to use when other ones are not already set
       by other applications, or saved in your session

       use obconf if you want to change these without having to log out
       and back in -->
    <number>6</number>
    <firstdesk>1</firstdesk>
    <names>
      <name>1</name>
      <name>2</name>
      <name>3</name>
      <name>4</name>
      <name>5</name>
      <name>6</name>
    </names>
    <popupTime>875</popupTime>
    <!-- The number of milliseconds to show the popup for when switching
       desktops.  Set this to 0 to disable the popup. -->
  </desktops>
  <resize>
    <drawContents>yes</drawContents>
    <popupShow>Nonpixel</popupShow>
    <!-- 'Always', 'Never', or 'Nonpixel' (xterms and such) -->
    <popupPosition>Center</popupPosition>
    <!-- 'Center', 'Top', or 'Fixed' -->
    <popupFixedPosition>
      <!-- these are used if popupPosition is set to 'Fixed' -->
      <x>10</x>
      <!-- positive number for distance from left edge, negative number for
         distance from right edge, or 'Center' -->
      <y>10</y>
      <!-- positive number for distance from top edge, negative number for
         distance from bottom edge, or 'Center' -->
    </popupFixedPosition>
  </resize>
  <!-- You can reserve a portion of your screen where windows will not cover when
     they are maximized, or when they are initially placed.
     Many programs reserve space automatically, but you can use this in other
     cases. -->
  <margins>
    <top>0</top>
    <bottom>0</bottom>
    <left>0</left>
    <right>0</right>
  </margins>
  <dock>
    <position>TopLeft</position>
    <!-- (Top|Bottom)(Left|Right|)|Top|Bottom|Left|Right|Floating -->
    <floatingX>0</floatingX>
    <floatingY>0</floatingY>
    <noStrut>no</noStrut>
    <stacking>Above</stacking>
    <!-- 'Above', 'Normal', or 'Below' -->
    <direction>Vertical</direction>
    <!-- 'Vertical' or 'Horizontal' -->
    <autoHide>no</autoHide>
    <hideDelay>300</hideDelay>
    <!-- in milliseconds (1000 = 1 second) -->
    <showDelay>300</showDelay>
    <!-- in milliseconds (1000 = 1 second) -->
    <moveButton>Middle</moveButton>
    <!-- 'Left', 'Middle', 'Right' -->
  </dock>
  <keyboard>
    <chainQuitKey>C-g</chainQuitKey>
    <!-- Keybindings for desktop switching -->
    <keybind key="C-A-Left">
      <action name="GoToDesktop">
        <to>left</to>
        <wrap>no</wrap>
      </action>
    </keybind>
    <keybind key="C-A-Right">
      <action name="GoToDesktop">
        <to>right</to>
        <wrap>no</wrap>
      </action>
    </keybind>
    <keybind key="C-A-Up">
      <action name="GoToDesktop">
        <to>up</to>
        <wrap>no</wrap>
      </action>
    </keybind>
    <keybind key="C-A-Down">
      <action name="GoToDesktop">
        <to>down</to>
        <wrap>no</wrap>
      </action>
    </keybind>
    <keybind key="S-A-Left">
      <action name="SendToDesktop">
        <to>left</to>
        <wrap>no</wrap>
      </action>
    </keybind>
    <keybind key="S-A-Right">
      <action name="SendToDesktop">
        <to>right</to>
        <wrap>no</wrap>
      </action>
    </keybind>
    <keybind key="S-A-Up">
      <action name="SendToDesktop">
        <to>up</to>
        <wrap>no</wrap>
      </action>
    </keybind>
    <keybind key="S-A-Down">
      <action name="SendToDesktop">
        <to>down</to>
        <wrap>no</wrap>
      </action>
    </keybind>
    <keybind key="W-F1">
      <action name="GoToDesktop">
        <to>1</to>
      </action>
    </keybind>
    <keybind key="W-F2">
      <action name="GoToDesktop">
        <to>2</to>
      </action>
    </keybind>
    <keybind key="W-F3">
      <action name="GoToDesktop">
        <to>3</to>
      </action>
    </keybind>
    <keybind key="W-F4">
      <action name="GoToDesktop">
        <to>4</to>
      </action>
    </keybind>
    <keybind key="W-d">
      <action name="ToggleShowDesktop"/>
    </keybind>
    <!-- Keybindings for windows -->
    <keybind key="A-F4">
      <action name="Close"/>
    </keybind>
    <keybind key="A-Escape">
      <action name="Lower"/>
      <action name="FocusToBottom"/>
      <action name="Unfocus"/>
    </keybind>
    <keybind key="A-space">
      <action name="ShowMenu">
        <menu>client-menu</menu>
      </action>
    </keybind>
    <!-- Take a screenshot of the current window with gnome-screenshot when Alt+Print are pressed -->
    <keybind key="A-Print">
      <action name="Execute">
        <command>gnome-screenshot -w</command>
      </action>
    </keybind>
    <!-- GIRI >> START  -->
    <keybind key="C-A-t">
      <action name="Execute">
        <command>/usr/bin/terminator</command>
      </action>
    </keybind>
    <keybind key="C-A-c">
      <action name="Execute">
        <command>/usr/bin/google-chrome</command>
      </action>
    </keybind>
    <keybind key="C-A-s">
      <action name="Execute">
        <command>/usr/bin/virtualbox</command>
      </action>
    </keybind>
    <keybind key="C-A-g">
      <action name="Execute">
        <command>/usr/bin/gedit</command>
      </action>
    </keybind>
    <keybind key="C-A-e">
      <action name="Execute">
        <command>/home/giri/Downloads/eclipse/eclipse</command>
      </action>
    </keybind>
    <keybind key="C-A-v">
      <action name="Execute">
        <command>/opt/TurboVNC/bin/vncviewer</command>
      </action>
    </keybind>
    <keybind key="C-A-p">
      <action name="Execute">
        <command>/usr/bin/pidgin</command>
      </action>
    </keybind>
    <!-- GIRI <<   END  -->
    <!-- Keybindings for window switching -->
    <keybind key="A-Tab">
      <action name="NextWindow">
        <finalactions>
          <action name="Focus"/>
          <action name="Raise"/>
          <action name="Unshade"/>
        </finalactions>
      </action>
    </keybind>
    <keybind key="A-S-Tab">
      <action name="PreviousWindow">
        <finalactions>
          <action name="Focus"/>
          <action name="Raise"/>
          <action name="Unshade"/>
        </finalactions>
      </action>
    </keybind>
    <keybind key="C-A-Tab">
      <action name="NextWindow">
        <panels>yes</panels>
        <desktop>yes</desktop>
        <finalactions>
          <action name="Focus"/>
          <action name="Raise"/>
          <action name="Unshade"/>
        </finalactions>
      </action>
    </keybind>
    <!-- Keybindings for window switching with the arrow keys -->
    <keybind key="W-S-Right">
      <action name="DirectionalCycleWindows">
        <direction>right</direction>
      </action>
    </keybind>
    <keybind key="W-S-Left">
      <action name="DirectionalCycleWindows">
        <direction>left</direction>
      </action>
    </keybind>
    <keybind key="W-S-Up">
      <action name="DirectionalCycleWindows">
        <direction>up</direction>
      </action>
    </keybind>
    <keybind key="W-S-Down">
      <action name="DirectionalCycleWindows">
        <direction>down</direction>
      </action>
    </keybind>
    <!-- Keybindings for running applications -->
    <keybind key="W-e">
      <action name="Execute">
        <startupnotify>
          <enabled>true</enabled>
          <name>Konqueror</name>
        </startupnotify>
        <command>kfmclient openProfile filemanagement</command>
      </action>
    </keybind>
    <!-- Launch gnome-screenshot when Print is pressed -->
    <keybind key="Print">
      <action name="Execute">
        <command>gnome-screenshot</command>
      </action>
    </keybind>
  </keyboard>
  <mouse>
    <dragThreshold>1</dragThreshold>
    <!-- number of pixels the mouse must move before a drag begins -->
    <doubleClickTime>200</doubleClickTime>
    <!-- in milliseconds (1000 = 1 second) -->
    <screenEdgeWarpTime>400</screenEdgeWarpTime>
    <!-- Time before changing desktops when the pointer touches the edge of the
       screen while moving a window, in milliseconds (1000 = 1 second).
       Set this to 0 to disable warping -->
    <screenEdgeWarpMouse>false</screenEdgeWarpMouse>
    <!-- Set this to TRUE to move the mouse pointer across the desktop when
       switching due to hitting the edge of the screen -->
    <context name="Frame">
      <mousebind button="A-Left" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
      </mousebind>
      <mousebind button="A-Left" action="Click">
        <action name="Unshade"/>
      </mousebind>
      <mousebind button="A-Left" action="Drag">
        <action name="Move"/>
      </mousebind>
      <mousebind button="A-Right" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="Unshade"/>
      </mousebind>
      <mousebind button="A-Right" action="Drag">
        <action name="Resize"/>
      </mousebind>
      <mousebind button="A-Middle" action="Press">
        <action name="Lower"/>
        <action name="FocusToBottom"/>
        <action name="Unfocus"/>
      </mousebind>
      <mousebind button="A-Up" action="Click">
        <action name="GoToDesktop">
          <to>previous</to>
        </action>
      </mousebind>
      <mousebind button="A-Down" action="Click">
        <action name="GoToDesktop">
          <to>next</to>
        </action>
      </mousebind>
      <mousebind button="C-A-Up" action="Click">
        <action name="GoToDesktop">
          <to>previous</to>
        </action>
      </mousebind>
      <mousebind button="C-A-Down" action="Click">
        <action name="GoToDesktop">
          <to>next</to>
        </action>
      </mousebind>
      <mousebind button="A-S-Up" action="Click">
        <action name="SendToDesktop">
          <to>previous</to>
        </action>
      </mousebind>
      <mousebind button="A-S-Down" action="Click">
        <action name="SendToDesktop">
          <to>next</to>
        </action>
      </mousebind>
    </context>
    <context name="Titlebar">
      <mousebind button="Left" action="Drag">
        <action name="Move"/>
      </mousebind>
      <mousebind button="Left" action="DoubleClick">
        <action name="ToggleMaximize"/>
      </mousebind>
      <mousebind button="Up" action="Click">
        <action name="if">
          <shaded>no</shaded>
          <then>
            <action name="Shade"/>
            <action name="FocusToBottom"/>
            <action name="Unfocus"/>
            <action name="Lower"/>
          </then>
        </action>
      </mousebind>
      <mousebind button="Down" action="Click">
        <action name="if">
          <shaded>yes</shaded>
          <then>
            <action name="Unshade"/>
            <action name="Raise"/>
          </then>
        </action>
      </mousebind>
    </context>
    <context name="Titlebar Top Right Bottom Left TLCorner TRCorner BRCorner BLCorner">
      <mousebind button="Left" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="Unshade"/>
      </mousebind>
      <mousebind button="Middle" action="Press">
        <action name="Lower"/>
        <action name="FocusToBottom"/>
        <action name="Unfocus"/>
      </mousebind>
      <mousebind button="Right" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="ShowMenu">
          <menu>client-menu</menu>
        </action>
      </mousebind>
    </context>
    <context name="Top">
      <mousebind button="Left" action="Drag">
        <action name="Resize">
          <edge>top</edge>
        </action>
      </mousebind>
    </context>
    <context name="Left">
      <mousebind button="Left" action="Drag">
        <action name="Resize">
          <edge>left</edge>
        </action>
      </mousebind>
    </context>
    <context name="Right">
      <mousebind button="Left" action="Drag">
        <action name="Resize">
          <edge>right</edge>
        </action>
      </mousebind>
    </context>
    <context name="Bottom">
      <mousebind button="Left" action="Drag">
        <action name="Resize">
          <edge>bottom</edge>
        </action>
      </mousebind>
      <mousebind button="Right" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="ShowMenu">
          <menu>client-menu</menu>
        </action>
      </mousebind>
    </context>
    <context name="TRCorner BRCorner TLCorner BLCorner">
      <mousebind button="Left" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="Unshade"/>
      </mousebind>
      <mousebind button="Left" action="Drag">
        <action name="Resize"/>
      </mousebind>
    </context>
    <context name="Client">
      <mousebind button="Left" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
      </mousebind>
      <mousebind button="Middle" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
      </mousebind>
      <mousebind button="Right" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
      </mousebind>
    </context>
    <context name="Icon">
      <mousebind button="Left" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="Unshade"/>
        <action name="ShowMenu">
          <menu>client-menu</menu>
        </action>
      </mousebind>
      <mousebind button="Right" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="ShowMenu">
          <menu>client-menu</menu>
        </action>
      </mousebind>
    </context>
    <context name="AllDesktops">
      <mousebind button="Left" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="Unshade"/>
      </mousebind>
      <mousebind button="Left" action="Click">
        <action name="ToggleOmnipresent"/>
      </mousebind>
    </context>
    <context name="Shade">
      <mousebind button="Left" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
      </mousebind>
      <mousebind button="Left" action="Click">
        <action name="ToggleShade"/>
      </mousebind>
    </context>
    <context name="Iconify">
      <mousebind button="Left" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
      </mousebind>
      <mousebind button="Left" action="Click">
        <action name="Iconify"/>
      </mousebind>
    </context>
    <context name="Maximize">
      <mousebind button="Left" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="Unshade"/>
      </mousebind>
      <mousebind button="Middle" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="Unshade"/>
      </mousebind>
      <mousebind button="Right" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="Unshade"/>
      </mousebind>
      <mousebind button="Left" action="Click">
        <action name="ToggleMaximize"/>
      </mousebind>
      <mousebind button="Middle" action="Click">
        <action name="ToggleMaximize">
          <direction>vertical</direction>
        </action>
      </mousebind>
      <mousebind button="Right" action="Click">
        <action name="ToggleMaximize">
          <direction>horizontal</direction>
        </action>
      </mousebind>
    </context>
    <context name="Close">
      <mousebind button="Left" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
        <action name="Unshade"/>
      </mousebind>
      <mousebind button="Left" action="Click">
        <action name="Close"/>
      </mousebind>
    </context>
    <context name="Desktop">
      <mousebind button="Up" action="Click">
        <action name="GoToDesktop">
          <to>previous</to>
        </action>
      </mousebind>
      <mousebind button="Down" action="Click">
        <action name="GoToDesktop">
          <to>next</to>
        </action>
      </mousebind>
      <mousebind button="A-Up" action="Click">
        <action name="GoToDesktop">
          <to>previous</to>
        </action>
      </mousebind>
      <mousebind button="A-Down" action="Click">
        <action name="GoToDesktop">
          <to>next</to>
        </action>
      </mousebind>
      <mousebind button="C-A-Up" action="Click">
        <action name="GoToDesktop">
          <to>previous</to>
        </action>
      </mousebind>
      <mousebind button="C-A-Down" action="Click">
        <action name="GoToDesktop">
          <to>next</to>
        </action>
      </mousebind>
      <mousebind button="Left" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
      </mousebind>
      <mousebind button="Right" action="Press">
        <action name="Focus"/>
        <action name="Raise"/>
      </mousebind>
    </context>
    <context name="Root">
      <!-- Menus -->
      <mousebind button="Middle" action="Press">
        <action name="ShowMenu">
          <menu>client-list-combined-menu</menu>
        </action>
      </mousebind>
      <mousebind button="Right" action="Press">
        <action name="ShowMenu">
          <menu>root-menu</menu>
        </action>
      </mousebind>
    </context>
    <context name="MoveResize">
      <mousebind button="Up" action="Click">
        <action name="GoToDesktop">
          <to>previous</to>
        </action>
      </mousebind>
      <mousebind button="Down" action="Click">
        <action name="GoToDesktop">
          <to>next</to>
        </action>
      </mousebind>
      <mousebind button="A-Up" action="Click">
        <action name="GoToDesktop">
          <to>previous</to>
        </action>
      </mousebind>
      <mousebind button="A-Down" action="Click">
        <action name="GoToDesktop">
          <to>next</to>
        </action>
      </mousebind>
    </context>
  </mouse>
  <menu>
    <!-- You can specify more than one menu file in here and they are all loaded,
       just don't make menu ids clash or, well, it'll be kind of pointless -->
    <!-- default menu file (or custom one in $HOME/.config/openbox/) -->
    <!-- system menu files on Debian systems -->
    <file>/var/lib/openbox/debian-menu.xml</file>
    <file>menu.xml</file>
    <hideDelay>200</hideDelay>
    <!-- if a press-release lasts longer than this setting (in milliseconds), the
       menu is hidden again -->
    <middle>no</middle>
    <!-- center submenus vertically about the parent entry -->
    <submenuShowDelay>100</submenuShowDelay>
    <!-- time to delay before showing a submenu after hovering over the parent
       entry.
       if this is a negative value, then the delay is infinite and the
       submenu will not be shown until it is clicked on -->
    <submenuHideDelay>400</submenuHideDelay>
    <!-- time to delay before hiding a submenu when selecting another
       entry in parent menu
       if this is a negative value, then the delay is infinite and the
       submenu will not be hidden until a different submenu is opened -->
    <applicationIcons>yes</applicationIcons>
    <!-- controls if icons appear in the client-list-(combined-)menu -->
    <manageDesktops>yes</manageDesktops>
    <!-- show the manage desktops section in the client-list-(combined-)menu -->
  </menu>
  <applications>
    <!--
  # this is an example with comments through out. use these to make your
  # own rules, but without the comments of course.
  # you may use one or more of the name/class/role/title/type rules to specify
  # windows to match

  <application name="the window's _OB_APP_NAME property (see obxprop)"
              class="the window's _OB_APP_CLASS property (see obxprop)"
               role="the window's _OB_APP_ROLE property (see obxprop)"
              title="the window's _OB_APP_TITLE property (see obxprop)"
               type="the window's _OB_APP_TYPE property (see obxprob)..
                      (if unspecified, then it is 'dialog' for child windows)">
  # you may set only one of name/class/role/title/type, or you may use more
  # than one together to restrict your matches.

  # the name, class, role, and title use simple wildcard matching such as those
  # used by a shell. you can use * to match any characters and ? to match
  # any single character.

  # the type is one of: normal, dialog, splash, utility, menu, toolbar, dock,
  #    or desktop

  # when multiple rules match a window, they will all be applied, in the
  # order that they appear in this list


    # each rule element can be left out or set to 'default' to specify to not 
    # change that attribute of the window

    <decor>yes</decor>
    # enable or disable window decorations

    <shade>no</shade>
    # make the window shaded when it appears, or not

    <position force="no">
      # the position is only used if both an x and y coordinate are provided
      # (and not set to 'default')
      # when force is "yes", then the window will be placed here even if it
      # says you want it placed elsewhere.  this is to override buggy
      # applications who refuse to behave
      <x>center</x>
      # a number like 50, or 'center' to center on screen. use a negative number
      # to start from the right (or bottom for <y>), ie -50 is 50 pixels from the
      # right edge (or bottom).
      <y>200</y>
      <monitor>1</monitor>
      # specifies the monitor in a xinerama setup.
      # 1 is the first head, or 'mouse' for wherever the mouse is
    </position>

    <focus>yes</focus>
    # if the window should try be given focus when it appears. if this is set
    # to yes it doesn't guarantee the window will be given focus. some
    # restrictions may apply, but Openbox will try to

    <desktop>1</desktop>
    # 1 is the first desktop, 'all' for all desktops

    <layer>normal</layer>
    # 'above', 'normal', or 'below'

    <iconic>no</iconic>
    # make the window iconified when it appears, or not

    <skip_pager>no</skip_pager>
    # asks to not be shown in pagers

    <skip_taskbar>no</skip_taskbar>
    # asks to not be shown in taskbars. window cycling actions will also
    # skip past such windows

    <fullscreen>yes</fullscreen>
    # make the window in fullscreen mode when it appears

    <maximized>true</maximized>
    # 'Horizontal', 'Vertical' or boolean (yes/no)
  </application>

  # end of the example
-->
  </applications>
</openbox_config>