Sunday, May 07, 2017

readlink system call fails on other files besides symbolic links

I just write this post to remind myself that the readlink system call fails on non symbolic links. I was expecting that it would work on files and directories but it doesn't.

man 2 readlink says in one of the errno:

EINVAL The named file is not a symbolic link.

So the next step is to check if the path is a symbolic link or not. The first choice would be to use stat on the path, but stat will give you results from the dereferenced file, not the symbolic link. So using stat system call on a file will never tell you if the file is a symbolic link.

lstat()  is  identical  to  stat(), except that if pathname is a symbolic link, then it returns
       information about the link itself, not the file that it refers to.


There you have it for future reference:

std::string MountHandler::doReadlink(std::string const& path) {
    char buff[PATH_MAX];
    struct stat stat_buf = {};
    if (lstat(path.c_str(), &stat_buf) == -1)
        throw std::runtime_error(fmtString("Could not stat path %s. Errno: %s",
        path.c_str(), strerror(errno)));

    if (!S_ISLNK(stat_buf.st_mode))
        return path;

    ssize_t len = readlink(path.c_str(), buff, sizeof (buff) - 1);
    if (len == -1) {
        throw std::runtime_error(fmtString("Readlink failed on %s. errno %s",
            path.c_str(), strerror(errno)));
    }
    buff[len] = '\0';
    return std::string(buff);
}

Sunday, April 16, 2017

Breaking abstract class interface in C++

Today while working on some code I had the need to make a tiny-bit-small break on a contract from an abstract base class.

The case is that I had an abstract base class called Pin, that contracted 2 methods for subclasses. The problem is that the InputPin class while benefiting from other functionality provided by the class Pin, could not sensibly provide a setPinValue method. Imagine I am naive and will only inform this operation is impossible on runtime:

volatile bool pinA1 = false;

class Pin {
public:
 virtual void setPinValue(bool value) = 0;
 virtual bool getPinValue() const = 0;
 virtual ~Pin() {}
}

class InputPin : public Pin {
public:
 virtual void setPinValue(bool value) { throw std::runtime_error("Cannot set value on input pin"); }
 virtual bool getPinValue() const { return pinA1 };
}

class OutputPin : public Pin {
public:
 virtual void setPinValue(bool value) { pinA1 = true; }
 virtual bool getPinValue() const { return pinA1 };
} 

Then I set out to find if I could use the compiler for my help in such a case. As usual Stackoverflow had question and answer about it. The answered marked as right is the ideal answer: No you cannot delete Pure Virtual Methods, fix your design. A bit further down showed the real answer: You can achieve something similar but it is not advised:

class InputPin : public Pin {
public:
 virtual bool getPinValue() const { return pinA1 };
private: 
 virtual void setPinValue(bool value) { throw std::runtime_error("Cannot set value on input pin"); } 
}


Just encapsulate the breaking method in the private part of the class and no one will be able to use it. If the Older-You gets the idea of using it in some private part of your own implementation you still get the luxury of the exception

I like answers who say "You kind of can do it, but you shouldn't", because you get to learn the corner cases and tricks with which to shoot yourself in the foot some time later. I, like everyone else, like a corner trick to impress the girls. Of course some time later it bites me back, or just my Older-Me looks back with astonishment at such a pretentious idiot I was.

*EDIT* After thinking a bit more about it and talking with my friend about it, he came up with the idea that just hiding the method in a private part of the class is not enough to make it reachable. This is because if the class is called polymorphically the virtual dispatcher in run-time will still reach this hidden method.

The best way in the end is to make it private and do nothing.

TLDR; Redesign your architecture to not have broken interfaces.

Saturday, April 15, 2017

Firefox mouse-less addon workflow

Today I had some time to tweak my Firefox workspace and came up with an addon combo which might be useful for somebody. The combo's purpose is to enable internet navigation almost completely without mouse.

Normally I have many open tabs on Firefox, and when there were that many they become invisible and only reachable by some kind of scrolling. This sucked because I do not have the habit of being organized and grouping tabs by theme, although I should.

The scrolling problem is removed by accepting that the tab bar can be multi-row. There just happens to be a cool addon called Tabmix Plus which allows multi-row tabs. It brings lots of other functionality which I do not care. If anybody is interested I exported it's settings for further reference are available in this link. To import it just go to TabMix Plus's settings and import the file.

This enables me tab visibility and knowing where the Tab I wanted was relative to my current tab, I coudl use the Ctrl-PgDn/PgUp trick switch tabs. The thing is, I have normally 30 tabs or more. Going one-by-one until my desired tab took sweet time. Also along the way it loaded all the tabs that were just lazy loaded.

I knew that there was a shortcut to go directly to a tab number. The problem is that this shortcut only goes up to the 9th tab. I found a very basic, but functional plugin to allow me to go to any tab number, "GoTo Tab Number". The plugin is very basic and with Ctrl-Shift-O I am able to raise an ugly dialog to write the tab number. Even so yet another problem came up: How do I know the tab number in 30 tabs?

I found yet another slightly abandoned addon caled "TabNumber". This one, I felt I had to modify it as the position of the numbers overlaying the tab just looked out of place. It took me quite long to adjust and find what I was comfortable with. This was because my addon development workflow to reload the changes was quite shitty:
  • Make changes to the extracted .xpi.
  • Zip the plugin contents into a xpi.
  • Copy the plugin to the where Firefox expected it.
In the end it worked and I created a repository in github to store it. I tried to contact the author about it and if he wants he can publish my changes although I doubt he will. The changes are GPL because the license is GPL. To install it, as stated in the README:
  • git clone https://github.com/ptsneves/TagNumber
  • cd TagNumber
  • zip -x "TagNumbersPTSN.xpi" -r "TagNumbersPTSN.xpi" .
  • Install the .xpi manually on Firefox.
For the navigation the VimFX plugin makes the honors. Very clean and I have yet to have any annoyance with it. My favourite and most used functionality is the F key to get a key combination for each possible link. When you type the appropriate key combination, firefox follows the link.

Normal Ctrl-LeftArrow allows to return to the previous page, and O allows the address bar to get focus with all current content selected. This way you can just start typing and what was there gets deleted automatically if you do not care about it. The Address bar also works as a search bar which makes it basically the only text are you need.

libpurple for facebook chat

Nowadays I use Facebook's messenger for about everything, to the point that even in the phone It has mostly replaced the SMS.
With this in mind, I would like a client for Linux that would natively connect to the Facebook Messanger. The intent is that I am not distracted by other Facebook content while doing more serious stuff. Also the web interface of messenger is bloody heavy.

Some time ago I used the facebook client of Thunderbird but it has since stopped working. I tried following the bugzilla ticket with no success. I even offered myself to pay to the author of the patch mentioned in the bugzilla ticket but when I made the offer I stopped getting any replies. I would have done it myself but....javascript... is definitely not the language I master. I feel Javascript is script kiddie language so it makes the will to dive into the code even lower. I am full of shit of course.

Sad, I went around for some more time using the web client of messenger until I found that there is a library, which makes Pidgin messenger compatible with Facebook's messenger. There is even an (outdated) Debian repository which makes the library installation painless (instructions here).

I used the library in the repository for some time but unfortunately it is not updated very often and recently the library broke with the error:
 
 Null value for $.viewer.message_threads.sync_sequence_id #306

For some weeks I was "sad" again as I did not want or know how to integrate the library build from source in my Ubuntu machine. This weekend I finally got some more time and bit the bullet, going on to find a fix for the problem. I found the solution thanks to the fast response from dequis and now leave here the instructions so that I can also remember when the time comes to update it again.

The following instructions to build dequis libpurple facebook plugin:

  • git clone https://github.com/dequis/purple-facebook.git
  • cd purple-facebook
  • sudo apt-get install libpurple-dev libjson-glib-dev mercurial
  • ./autogen.sh
  • make
  • mkdir -p ~/.purple/plugin
  • cp pidgin/libpurple/protocols/facebook/.libs/libfacebook.so ~/.purple/plugins
I know there is a possibility to generate the debian packages, and it is probably as easy as, the previous steps, but I do not want to maintain any debian packages. Because of this  the library is now in an obscure part of my HOME directory which pidgin picks up, hihi.

Ok, ok. While I was writing this post I found it stupid to not write how to generate the debian package and gave it a try. Say you love me in the comments if it was useful: 

  • git clone https://github.com/dequis/purple-facebook.git
  • cd purple-facebook 
  • debuild -b -uc -us
  • cd ../
  • sudo dpkg -i purple-facebook_0.0.0-1_amd64.deb

Now I have a confession to make. I don't like Pidgin because it is slightly ugly. I use thunderbird and enjoy it, so my secret is that I would like to use this plugin for thunderbird. I set out to search a plugin for Thunderbird which would enable compatibility with libpurple and found an old plugin called "Additional Protocols for Thunderbird".
I tried to install it but it fails the compatibility check of my current Thunderbird. I even tried to be too clever, and downloaded an extension to Disable Compatibility check, but I couldn't understand if the plugin was broken or if I did not know how to use it.

Enjoy