Monday, July 7, 2014

Ubuntu Alarm Clock

I really like the old Ubuntu alarmclock instead of the new alarm-clock-applet. The reason is that alarmclock offers a way to save and load the alarm list which no other apps I know of can do. Today after rebooting, I couldn't see my alarms any more. After a few hours of try-and-error, I found the fix. It turned out that my alarmclock's config for some reason refused to open the app. So I moved ~/.config/alarmclock/alarms.conf to another folder, reinstalled alarmclock and reloaded my alarm list. Everything went to normal now, Hooray!

Tuesday, July 1, 2014

Adding another file type for ctags parsing

Normal ctags commands to support C++ parsing:

$ ctags -R --c++-kinds=+cdefglmnpstuvx --fields=+iaS --extra=+q

This will generate the ctags database from the following file types under the current directory:

 *.c++ *.cc *.cp *.cpp *.cxx *.h *.h++ *.hh *.hp *.hpp *.hxx *.C *.H

(From ctags --list-maps)

If another file type needs to be included for the parsing, for example you want to add *.inl file type to C++ language map, add the following line to ~/.ctags.

--langmap=c++:+.inl
 
To check:

$ ctags --list-maps | grep C++
C++      *.c++ *.cc *.cp *.cpp *.cxx *.h *.h++ *.hh *.hp *.hpp *.hxx *.C *.H *.inl

Run ctags again to regenerate the database with the support of *.inl files as well.

$ ctags -R --c++-kinds=+cdefglmnpstuvx --fields=+iaS --extra=+q


Tuesday, April 29, 2014

Using ipset

Finally got it to work. Nobody seems to have a complete and accurate solution for my case... So here it is.
 #include <iostream>  
 #include <thread>     // std::thread  
 #include <mutex>     // std::mutex  
 #include <assert.h>  
 extern "C" {  

 // Debian libipset libary is a C library. All the headers  
 // have to be enclosed in extern "C" brackets to have  
 // proper linkage  
 #include <libipset/session.h>      /* ipset_session_* */  
 #include <libipset/data.h>       /* enum ipset_data */  
 #include <libipset/parse.h>       /* ipset_parse_* */  
 #include <libipset/types.h>       /* struct ipset_type */  
 #include <libipset/ui.h>        /* core options, commands */  
 #include <libipset/utils.h>       /* STREQ */  
 }  
 // debian-ipset is not thread-safe. We're using  
 // a mutex to serialize the ipset calls.  
 std::mutex s_ipsetMutex;  
 // We're only adding a command/an element to the set,  
 // so the restore line no. remains 0  
 #define IPSET_SESSION_LINE_NO 0  
 int  
 ipsetAdd(std::string table, std::string set_type, uint32_t interval)  
 {  
  int32_t ret = 0;  
  const struct ipset_type *type = NULL;  
  enum ipset_cmd cmd = IPSET_CMD_ADD;  
  struct ipset_session *session;  
  // debian-ipset calls are not thread-safe. We're adding  
  // a mutex to serialize the calls.  
  s_ipsetMutex.lock();  
  ipset_load_types();  
  // Initialize an ipset session by allocating a session structure  
  // and filling out with the initialization data.  
  session = ipset_session_init(printf);  
  if (session == NULL)  
  {  
   printf("ipsetAdd: Cannot initialize ipset session for "  
     "set_type %s. aborting.\n", set_type.c_str());  
   ret = 1;  
  }  
  else  
  {  
   // Set session lineno to report parser errors correctly   
   ipset_session_lineno(session, IPSET_SESSION_LINE_NO);  
   // Parse string as a setname.  
   // The value is stored in the data blob of the session.  
   ret = ipset_parse_setname(session, IPSET_SETNAME, table.c_str());  
   if (ret == 0)  
   {  
    type = ipset_type_get(session, cmd);  
    if (!type)  
    {  
     printf("ipsetAdd: Failed to get the set type from Kernel "  
       "set_type=%s table=%s sess=%p cmd=%d\n", set_type.c_str(), table.c_str(),  
       session, cmd);  
     ret = 1;  
    }  
    else  
    {  
     // Parse string as a (multipart) element according to the settype.  
     // The value is stored in the data blob of the session.  
     ret = ipset_parse_elem(session, (ipset_opt)type->last_elem_optional,  
                 set_type.c_str());  
     if (ret == 0)  
     {  
      // Put a given kind of data into the data blob and mark the  
      // option kind as already set in the blob.  
      ret = ipset_data_set(ipset_session_data(session), IPSET_OPT_TIMEOUT, &interval);  
      if (!ret)  
      {  
       // Execute a command  
       ret = ipset_cmd(session, cmd, IPSET_SESSION_LINE_NO);  
       if (ret)  
       {  
        printf("ipsetAdd: WARNING: Failed to execute "  
          "IPSET_CMD_ADD command. ipset exists? ret=%d set_type=%s table=%s\n",  
          ret, set_type.c_str(), table.c_str());  
        // Not an error condition  
        ret = 0;  
       }  
      }  
      else  
      {  
       printf("ipsetAdd: Failed to set timeout option. "  
         "ret=%d set_type=%s table=%s\n", ret, set_type.c_str(), table.c_str());  
      }  
     }  
     else  
     {  
      printf("ipsetAdd: Failed to parse element. "  
        "ret=%d set_type=%s table=%s\n", ret, set_type.c_str(), table.c_str());  
     }  
    }  
   }  
   else  
   {  
    printf("ipsetAdd: Failed to parse setname. "  
      "ret=%d set_type=%s table=%s\n", ret, set_type.c_str(), table.c_str());  
   }  
   // Finish the ipset session  
   if (ipset_session_fini(session) != 0)  
   {  
    printf("ipsetAdd: Failed to destroy ipset "  
      "session. ret=%d set_type=%s table=%s\n", ret, set_type.c_str(),  
      table.c_str());  
   }  
  } // else of if (session == NULL)  
  s_ipsetMutex.unlock();  
  return ret;  
 }  
 int main()  
 {  
  ipsetAdd("my_ipset_table", "127.0.0.1,62142,127.0.0.1", 600);  
  return 0;  
 }  


To build it:
$ g++ myipset.cpp -std=c++0x  -lipset -o myipset

Create your ipset first:
$ sudo ipset create my_ipset_table hash:ip,port,ip family inet maxelem 600000

Due to the fact that some of the ipset commands need special
capability to call or get valid return (e.g. ipset_type_get & ipset_cmd), you have to run it as root.
$ sudo myipset

To check it:
$ sudo ipset -l

Here is the C version of the same function:
 #include <stdio.h>  
 #include <pthread.h>       
 #include <assert.h>  
 #include <libipset/session.h>      /* ipset_session_* */  
 #include <libipset/data.h>       /* enum ipset_data */  
 #include <libipset/parse.h>       /* ipset_parse_* */  
 #include <libipset/types.h>       /* struct ipset_type */  
 #include <libipset/ui.h>        /* core options, commands */  
 #include <libipset/utils.h>       /* STREQ */  
 // debian-ipset is not thread-safe. We're using  
 // a mutex to serialize the ipset calls.  
 pthread_mutex_t s_ipsetMutex;  
 // We're only adding a command/an element to to the set,  
 // so the restore line no. remains 0  
 #define IPSET_SESSION_LINE_NO 0  
 int  
 ipsetAdd(char *table, char *set_type, uint32_t interval)  
 {  
  int32_t ret = 0;  
  const struct ipset_type *type = NULL;  
  enum ipset_cmd cmd = IPSET_CMD_ADD;  
  struct ipset_session *session;  
  // debian-ipset calls are not thread-safe. We're adding  
  // a mutex to serialize the calls.  
  pthread_mutex_lock(&s_ipsetMutex);  
  ipset_load_types();  
  // Initialize an ipset session by allocating a session structure  
  // and filling out with the initialization data.  
  session = ipset_session_init(printf);  
  if (session == NULL)  
  {  
   printf("ipsetAdd: Cannot initialize ipset session for "  
     "set_type %s. aborting.\n", set_type);  
   ret = 1;  
  }  
  else  
  {  
   // Set session lineno to report parser errors correctly   
   ipset_session_lineno(session, IPSET_SESSION_LINE_NO);  
   // Parse string as a setname.  
   // The value is stored in the data blob of the session.  
   ret = ipset_parse_setname(session, IPSET_SETNAME, table);  
   if (ret == 0)  
   {  
    type = ipset_type_get(session, cmd);  
    if (!type)  
    {  
     printf("ipsetAdd: Failed to get the set type from Kernel "  
       "set_type=%s table=%s sess=%p cmd=%d\n", set_type, table,  
       session, cmd);  
     ret = 1;  
    }  
    else  
    {  
     // Parse string as a (multipart) element according to the settype.  
     // The value is stored in the data blob of the session.  
     ret = ipset_parse_elem(session, (enum ipset_opt)type->last_elem_optional,  
                 set_type);  
     if (ret == 0)  
     {  
      // Put a given kind of data into the data blob and mark the  
      // option kind as already set in the blob.  
      ret = ipset_data_set(ipset_session_data(session), IPSET_OPT_TIMEOUT, &interval);  
      if (!ret)  
      {  
       // Execute a command  
       ret = ipset_cmd(session, cmd, IPSET_SESSION_LINE_NO);  
       if (ret)  
       {  
        printf("ipsetAdd: WARNING: Failed to execute "  
          "IPSET_CMD_ADD command. ipset exists? ret=%d set_type=%s table=%s\n",  
          ret, set_type, table);  
        // Not an error condition  
        ret = 0;  
       }  
      }  
      else  
      {  
       printf("ipsetAdd: Failed to set timeout option. "  
         "ret=%d set_type=%s table=%s\n", ret, set_type, table);  
      }  
     }  
     else  
     {  
      printf("ipsetAdd: Failed to parse element. "  
        "ret=%d set_type=%s table=%s\n", ret, set_type, table);  
     }  
    }  
   }  
   else  
   {  
    printf("ipsetAdd: Failed to parse setname. "  
      "ret=%d set_type=%s table=%s\n", ret, set_type, table);  
   }  
   // Finish the ipset session  
   if (ipset_session_fini(session) != 0)  
   {  
    printf("ipsetAdd: Failed to destroy ipset "  
      "session. ret=%d set_type=%s table=%s\n", ret, set_type,  
      table);  
   }  
  } // else of if (session == NULL)  
  pthread_mutex_unlock(&s_ipsetMutex);  
  return ret;  
 }  

Tuesday, April 15, 2014

Update Firefox on Ubuntu

For some strange reason, I couldn't open and see content of any of my yahoo mail using Firefox. I tried it on Chrome. It was working. So it must be something to do with Firefox + yahoo combination. Since I cannot fix yahoo from its setting (it doesn't even open), I in turn focused on fixing Firefox. Anyway I checked my add-ons and plug-ins and found nothing suspicious. So I decided to update my Firefox. I found the version from Help->About Firefox. The version was 20 and there was NO update button/link despite of all the articles on the net saying so. Next I ran

sudo apt-get update
sudo apt-get --purge --reinstall install firefox

Hoping the system will find the updates in the repositories and update Firefox for me. Nope. Firefox was not updated. So I had to do it manually. Here are the steps:

1. Get a Linux 64-bit copy from here and untar/uncompress it.

~/Downloads$ tar xvfj  firefox-28.0.tar.bz2
tar: Record size = 8 blocks
firefox/
firefox/libsoftokn3.so
firefox/chrome.manifest
firefox/mozilla-xremote-client
firefox/crashreporter.ini
firefox/libnspr4.so
firefox/updater
.
.
.

2. Backup your $HOME/.mozilla directory if you want to be careful.

$ cd; cp .mozilla .mozilla.bak
3. Close all Firefox instances.

4. Backup your firefox directory

$ sudo mv /usr/lib/firefox /usr/lib/firefox.bak
5. Move firefox directory you just uncompressed to /usr/lib

$ sudo mv ~/Downloads/firefox /usr/lib
6. Now give it a try by launching it from the launcher or command line.

$ /usr/bin/firefox &
7. One more step, the firefox.png file seems to be missing from the latest Firefox 28 package. You will see a big red cross if this is not done. So to properly show firefox icon in your launcher.

$ sudo cp /usr/lib/firefox.backup/icons/mozicon128.png \ 
/usr/lib/firefox/icons
8. Try yahoo mail again. It works!

9. Now you can delete all the backups if everything works as expected.

In a fairly good mode, so toss in a bonus tip - to open a file with the default application in command line:

xdg-open /usr/lib/firefox/mozicon128.png

Saturday, June 15, 2013

Frozen MacOS terminal due ssh session timeout

To get out of a frozen terminal due to ssh timeout. Type the following keys:

enter (return key) ~.

Add the following to your .ssh/config file. It sends a signal to the server every 240 seconds to keep the session.

Host *
  ServerAliveInterval 240

Reference: http://www.metachunk.com/blog/dealing-osx-terminal-ssh-timeouts-0

Monday, July 30, 2012

vim 7.x and matchit plugin

For a few months I have been trying to make my vim (7.2.330) in Ubuntu 10.04 work with matchit plugin. But it never wanted to cooperate. The matchit plugin works perfectly with my vim 6.4.6 by simply downloading/unzipping the match.zip from here and adding the following line to ~/.vimrc file.

:source {path_to_matchit_plugin}/matchit.vim

But for vim 7.x, the following line has be to added to ~/.vimrc as well:

:filetype plugin on

Friday, February 24, 2012

Mapping Your Domain Name to Work with Blogger

From GoDaddy support center: http://help.godaddy.com/article/5112#parking

You can establish a more professional identity for your Blogger® blog by configuring it to point to one of the domain names you registered through us. Instead of entering your Blogger URL to view your latest blog post, visitors enter your domain name's URL. For example, by mapping your coolexample.blogspot.com blog to your www.coolexample.com domain name, visitors focus solely on your domain name.
To point your Blogger blog to your domain name, you set up domain name mapping, which configures your blog settings and domain name. You update your settings in your Blogger account and our Domain Manager:
  1. Park the domain name you want to use with your Blogger account on our parked nameservers.
  2. Edit the www CNAME record for the domain name you want to use with your Blogger account. This update tells the Web browser to open your Blogger blog when visitors enter your domain name's URL in the browser address bar.
  3. Forward your domain name to use www. This step ensures your Blogger blog displays for visitors who go to your domain name with or without the www prefix. For example, it displays for visitors who entered both www.coolexample.com and coolexample.com.
  4. Configure your Blogger account to use your domain name.

To Park Your Domain Name

  1. Log in to your Account Manager.
  2. Next to Domains, click Launch.
  3. Select the domain name you want to use with your Blogger account, and then from the Nameservers, select Set Nameservers.
  4. Select I want to park my domains.
  5. Click OK.
  6. Click OK again.

To Edit Your CNAME Record

  1. Log in to your Account Manager.
  2. Next to Domains, click Launch.
  3. From the Tools menu, select DNS Manager. The DNS Dashboard displays.
  4. For the domain name you want to use with your Blogger account, click Edit Zone. The Zone File Editor displays.
  5. In the CNAME (Alias) section, click the www record.
  6. In the Points To field, type ghs.google.com.
  7. Click Save Zone File, and then click OK.

To Forward Your Domain Name

  1. Go to support.google.com.
  2. Click Host my blog on a URL that I already own.
  3. Follow the listed instructions.

To Configure Your Blogger Account

  1. Log in to your Blogger account.
  2. From the Settings tab, select Publishing.
  3. Click Custom Domain.
  4. In the Buy a domain for your blog section, click Switch to advanced settings.
  5. In the Your Domain field, enter your domain name. For example, enter www.coolexample.com.
  6. To specify another location in which to look for files, in the Use a missing files host? section, select Yes and enter the path. If not, select No.
  7. In the Word Verification field, enter the characters as they display in the image above the field.
  8. Click Save Settings.
Any DNS changes you make can take up to 48 hours to reflect on the Internet.
NOTE: As a courtesy, we provide information about how to use certain third-party products, but we do not endorse or directly support third-party products and we are not responsible for the functions or reliability of such products. Blogger® is a registered trademark of Google, Inc. All rights reserved.