Monday, March 28, 2016

How to Enable Search History Feature with Bash

Assume your ~/.bash_history file has the following content:
gcc test.c
gcc -g test.c
cat test.c
vim test.c
ssh root@localhost
ssh root@192.168.1.1
g++ test.cpp
g++ test.cxx

Now, say you type
$ gcc[up arrow]

Normally, the [up arrow] key will simply give you the last command, that is
$ g++ test.cxx

However, this is quite annoying. When you type gcc first and pressing the [up arrow] should intuitively tell bash to search for all the previous commands starting with gcc. What you probably expected was
$ gcc -g test.c
or
$ gcc test.c

Well, there is a way to do this. Edit your ~/.bashrc file and add the following lines:
bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-forward'

NOTE: if you are on Mac OS X, append the above two lines to ~/.bash_profile instead.

Save the file and exit bash. Now when you restart bash, you should see search history feature enabled. That is, when you type
$ gcc[up arrow]
will show you
$ gcc -g test.c

Another [up arrow] will show you
$ gcc test.c

Similarly, typing
$ ssh[up arrow]
will show
$ ssh root@192.168.1.1

One more [up arrow] will yield
$ ssh root@localhost

Sunday, March 27, 2016

How to Build and Add Custom C Library

For those who are familiar with Matlab, you may know the functions tic and toc. These two functions are used to print out elapsed time in between tic and toc. Let us implement this in C and create a library, so that we can use these functions easily later.

First, create tictoc.c file with the following:
#include <tictoc.h>
#include <time.h>
#include <sys/time.h>
#include <stdio.h>

/* indicates whether tic has been called */
static int tic_flag = 0;

/* tic timeval */
static struct timeval start;

void tic() {
    tic_flag = 1;
    if (gettimeofday(&start, NULL)) {
        fprintf(stderr, "libtictoc: error from gettimeofday()\n");
    }
}

void toc() {
    if (tic_flag == 0) {
        fprintf(stderr, "libtictoc: tic() has not been called\n");
        return;
    }
    struct timeval end;
    if (gettimeofday(&end, NULL)) {
        fprintf(stderr, "libtictoc: error from gettimeofday()\n");
        return;
    }
    printf("Time elapsed: %lfs\n", 
            (double) (end.tv_sec-start.tv_sec)
            + (double)(end.tv_usec-start.tv_usec)/1000000.0);
}


Next, create tictoc.h file with the following:
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#ifndef _TICTOC_H_
#define _TICTOC_H_

extern void tic();
extern void toc();

#endif // _TICTOC_H_

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

Note that the first three lines and the last three lines in the header enable C++ compatibility.

Now, let's see if we can compile this
$ gcc -c -Wall  -I . tictoc.c
You should see it compile successfully, and tictoc.o file has been created.

Make sure you have binutils installed on the system. For Ubuntu/Debian, simply run
$ sudo apt-get install -y binutils

For Mac OS X, run
$ brew install binutils

To create a library file, we run
$ ar -cvq libtictoc.a tictoc.o

This command will use tictoc.o file to create libtictoc.a library file. To examine the newly created file, run
$ ar -t libtictoc.a
You should see tictoc.o file listed.

We are now ready to copy the library file and the header file into the default user library and include folders.
$ sudo cp libtictoc.a /usr/local/lib
$ sudo cp tictoc.h /usr/local/include

Finally, we test whether the library works well. Create a test.c file with the following:
#include <tictoc.h>
#include <unistd.h>
int main() {
    tic();
    sleep(1);
    toc();
    sleep(2);
    toc();
    return 0;
}


Let's try to compile it
$ gcc -Wall test.c
You should see some error saying undefined reference to tic and toc. This is because we have not told gcc to look for libtictoc library. 

Well, let's do it.
$ gcc -Wall -l tictoc test.c
The -l option tells gcc to search for library, and the proceeding string (tictoc) preceded by lib will be the name of the library. That means, -l tictoc is asking gcc to look for a library file named libtictoc within the default library folders. Since we have copied over libtictoc.a file into /usr/local/lib, which is one of the default library search folders, gcc will be able to locate it. To find out the default load library path is, look into /etc/ld.so.conf file.

Note that .a extension is used for static library whereas .so extension is used for dynamically linked library.

It should compile now. Let's run it and see if it actually works.
$ ./a.out
You wills see something like time elapsed 1s and 3s, just as you expected!

Sunday, March 20, 2016

How to Read CPU Temperature in Ubuntu 14.04 LTS

Install the necessary package
$ sudo apt-get install lm-sensors 

Start the sensors
$ sudo sensors-detect
$ sudo service kmod start

Print out the measurement
$ sensors

That's it!

How to Setup Personal Cloud Server on Ubuntu 14.04 LTS using OwnCloud

This post is based on https://youtu.be/aotBluDGAAE.

First, download the latest build of owncloud, which is 9.0.0 at the time of writing this post.
$ wget https://download.owncloud.org/community/owncloud-9.0.0.tar.bz2

Extract the file using tar
$ tar fxj owncloud-9.0.0.tar.bz2

Install necessary packages (^ key is not a mistake below)
$ sudo apt-get install lamp-server^ php5-gd php5-curl php5-intl php5-mcrypt php5-imagick -y

During the installation of SQL server, it will ask for the root password. Make a note of this password, as it will be used in the setup later on.

Upload the directory to the server
$ sudo cp -rfp owncloud /var/www/html/

Change the permission of the server
$ sudo chown -R www-data:www-data /var/www/html/owncloud

A security measure
$ sudo a2enmod rewrite

Modify the apache configuration file
$ sudo vim /etc/apache2/apache2.conf

Change AllowOverride option to All under <Directory /var/www/>

Restart the server.
$ sudo service apache2 restart

Open up a web browser, and go to the address: http://server_ip/owncloud
where server_ip is the IP address of the owncloud server you just setup

Setup the administrator. In the first box, choose owncloud admin username and password. In the second box, enter root as the username and SQL password from the previous step.

That's it! When you install the desktop or mobile client, make sure to enter the server address as http://server_ip/owncloud.



NOTE: if you have firewall setup, you may need to open up the TCP port 80.

Thursday, March 3, 2016

How to Boot into Console Mode in Ubuntu

If you want to change the default boot option of Ubuntu Desktop into a console mode, here is how:

1. Backup the grub file
$ sudo cp -n /etc/default/grub /etc/default/grub.bk

2. Open up the grub file
$ sudo vim /etc/default/grub

3. Modify the menu entries
a) Comment out GRUB_CMD_LINE_LINUX_DEFAULT="quiet splash"
b) Change GRUB_CMD_LINE_LINUX="" to GRUB_CMD_LINE_LINUX="text"
c) Uncomment GRUB_TERMINAL=console

When complete, the file should look something like below:
...
GRUB_DEFAULT=0
GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
#GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX="text"

# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"

# Uncomment to disable graphical terminal (grub-pc only)
GRUB_TERMINAL=console
...

4. Update grub
$ sudo update-grub

Only for Ubuntu 15.10 or up that uses systemd:
$ sudo systemctl enable multi-user.target --force
$ sudo systemctl set-default multi-user.target

5. Reboot and see if it works
$ sudo reboot

By the way, to start GUI, simply run the following command after logging into the console
$ sudo service lightdm start

Tuesday, March 1, 2016

How to Debug Remote using gdbserver

In this post, I will go through the method of debugging remotely using gdbserver. This is useful when you want to debug a program that constantly requires user's input. For example, consider the simple program test.c below:

#include <stdio.h>
int main (int argc, char** argv) {
    printf("input a positive number: ");
    int i;
    scanf ("%d", &i);
    for (; i>0; i--)
       printf("%d\n", i); 
return 0;
}

This program will require a user input and behave accordingly. Let's start debugging this remotely.

First, we need to compile it of course,
$ gcc -g test.c

Next, we need to install gdbserver
$ sudo apt-get install gdbserver -y

Let's run gdbserver and open up connection
$ gdbserver :1234 a.out 10
It should be waiting for connection to be made on port 1234. Don't forget the argument to the program, which is 10 in this case.

Now, we will open up another terminal and start gdb of a.out binary we just compiled
$ gdb -q

In the gdb prompt, run
(gdb) target remote :1234
(gdb) b test.c:7
(gdb) c

Now, you will see interactive gdb running on one of the terminal windows and the program running on the other!