Single Instance Script on NAS4Free

Great thing about NAS4Free is the opportunity to do really powerful scripting. You can do automation scripts on par with full-blown *nix distributions. Better still, you can even configure them to run at desired times giving you full hand-off experience.

With all that power and possibility of scripts running left and right, it pays off to do some sanity checking. Most common one is disabling multiple instances (particularly important for backup script).

Since NAS4Free is FreeBSD-based, some things might be a bit different than your everyday Linux but rough code would be:

SCRIPT_NAME=`basename $0`
PID_FILE="/var/tmp/.$SCRIPT_NAME.pid"
PID_LAST=`cat $PID_FILE 2> /dev/null`
if [ -n "$PID_LAST" ]; then
    PID_ACTIVE=`ps $PID_LAST | grep "^$PID_LAST" | grep "${SCRIPT_NAME}\$"`
    if [ -n "$PID_ACTIVE" ]; then
        echo "ERROR: Script is already running!" >&2
        exit 255
    fi
fi
echo $$ > $PID_FILE


# DO SOMETHING USEFUL


rm $PID_FILE

When script is started for first time, process identifier (PID) is written to /var/tmp/.script.sh.pid (where script.sh is name of our script). This is followed by some useful action (insert your code here). When the job is done, /var/tmp/.script.sh.pid is simply removed and everything is fresh for a new start.

If we start second instance of script before first one has completed, script will find its temporary file. While it might stop with an error at this point, I prefer it to run additional check. Previous script might have crashed and thus temporary file might be just a leftover and there is nothing really running.

So it reads content of a temporary file in order to find previously used PID. That PID is then found in the list of processes and compared against a script name (maybe some other script is running under same PID - rare but happens). If process with same number and name is found, script throws an error and exits.

Simple and works 99% of time.

Script does have some issues. You cannot have two scripts with same name using the same trick because temporary file is based on a name only. Similar problem might be a false positive if another script with same name accidentally gets same PID as our previously running script (although this is highly unlikely). Solution for both would be using realpath command and basing temporary file and PID search on it.

Another issue might be how easy is to trick script into a parallel execution. Just remove temporary PID file and script will be no wiser. And there is no real way around this. Intention of this code is to prevent accidental parallel execution - if user wants to shoot at his foot, he will do it.

You can really make this as complicated or as simple as you wish. I found my sweet spot in the code above.

[2018-07-22: NAS4Free has been renamed to XigmaNAS as of July 2018]

Blackmailing Bastards

With a new year there came a bit of change from my domain registrar. Their post is Croatian-only but this is the gist of it: there are new TLDs available (.app, .shop, etc.), e-mail address verification is required, and free whois privacy is gone.

For those not aware, each website must have name, address and similar personal stuff filled upon registration. Companies usually have no issues with this but for individuals this is really inconvenient because everyone on Internet suddenly knows your home address. To alleviate this issue, domain registrars are usually satisfied if they have your information and whois gets filled with alternate data (usually their address). And everybody is happy.

Starting this year Plus hosting will start charging additional 40 HRK (+ tax) for this service.

Just to make it clear, I am not blaming them for this increase. For last 8 years they have given me the best service I could imagine and their response time was remarkable (immediate response for non-urgent queries even on Christmas). Their web packages are competitive, servers are good and there is really almost nothing I would change.

Their top registrar (OpenSRS) decided to start charging for privacy and they really had no other choice than to forward that cost to their customers. Since they are really small company, swallowing the price increase themselves is probably not a realistic expectation.

And don’t be mistaken, this is pure blackmail by OpenSRS. Since your registrar is usually also your web hosting provider, you got domain for free. Going anywhere else for domain (and leaving web service where it is) would cost you around $10 which is exactly how much they charge you for privacy. Since cost is the same, most users won’t bother with transfer and they will just pay the ransom. It is essentially the same business model patent trolls use - make it cheaper/simpler to settle than to fight.

As for my site, I haven’t decided what to do. Simplest solution of paying the cost increase just seems wrong. Moving away from Plus hosting is not something I am even seriously considering because that would be punishing them for something outside of their control. And having domain with one registrar while web hosting is at other’s would be annoying any time when there is a DNS issue and two companies start playing troubleshooting ping-pong.

I already contacted Plus about this and they assure me that my private address won’t be visible. If true it will alleviate my biggest complain. However, whether that is true or not is another matter. I am sure that guys at Plus believe it to be so but OpenSRS clearly lists address among the fields that are exposed. Time will tell.

Whatever decision might be, I have another few months to figure it out. Maybe OpenSRS idiots will smarten by then…

Why HP, Why?

Illustration

Due to my Intel NUC needs I got myself a new 802.11ac wireless card (Intel 7260). Since NUC didn’t really need AC, I decided to put new card into wife’s aging HP mini and take its N wireless. My hope was that newer card would improve wireless range just a bit and thus I would gain her eternal gratitude. That was the plan at least.

As it is always the case with small machines, replacing anything is not really straightforward and some disassembly is required. In this case it was just removal of keyboard and new card went in even a bit easier than expected. After a bit of fidgeting with keyboard’s plastic tabs on reassembly I was ready to get into Windows.

Seconds later I was greeted with:

104 Unsupported wireless network device detected.
System Halted. Remove device and restart.

Yep, dear HP decided in their eternal wisdom to forbid wireless replacement. And I cannot imagine any other reason for this other than a case of pure assholeism.

It is definitely not for money. Not only that wireless cards almost never fail but their low cost would anyhow ensure that HP would see little to no profit on any exchange. Even worse, you can plugin another card that is same Broadcom chipset and it works. That means that they didn’t force anybody into using HP replacement services.

They also didn’t do it to force you into using HP upgrade - there is no such thing nor it was ever available. Maybe there were some plans but I doubt that because card was not really positioned to be user-replaceable.

Saving grace would be if they did it for compatibility. Maybe their testing discovered some bug on other cards so they decided to nip it in the bud. If this is really the case (no matter how unlikely it is) than it is pure laziness of engineering team. They decided to solve technical problem with a software block. And someone higher up decided to cover this up and not document such incompatibility anywhere. But I really doubt that.

Most likely story is that some “smart” manager overheard engineers speaking about difficult to replace wireless card. On that he said “We have it replaceable? We don’t have that on list of features. Disable it.” Engineer shrug and did as it was told. And now, years after that moment of stupidity, we have machine that cannot be upgraded. Not for technical reason, but for pure politics.

QText 3.60

It has been a long hiatus but time has come to have new QText out.

Most notable change will be for double-click. While it behaves a bit different than notepad does, it is more in sync with what you would expect a bit more modern program to do. Of course shortcuts follow the same behavior and whole thing should be a bit more natural for heavy keyboard user.

And that is pretty much single big change for it. Everything is same as it was with quite some bug-fixing compared to previous version. Program is a bit more friendly to new users (some balloon hints and similar nice touches); there are some high-DPI changes (no longer toolbar hunting on very high resolution screens, e.g. > 200 dpi); and lot of similar changes that you probably won’t even notice.

As always, upgrade is available directly through application, or you can download it from these pages.

Enjoy.

Scaling Toolstrip Images With DPI

Cheapest way to make high-DPI application is just to specify it as such in manifest and let font auto-sizing do the magic. Final result is more than acceptable and it definitely beats blurred fonts you would have without it.

However, this method doesn’t scale toolstrip icons (usually 16x16 pixels). They remain at same pixel size as before. If your monitor is 192 DPI, icons will look half their size. As monitors get higher and higher DPI situation just gets worse. Only proper solution would be to check system DPI and load higher resolution icons.

However, cheating a bit is ok too. Instead of having multiple sets of icons with different resolution each, we can resize ones that we already have. Yes, result will be a bit ugly, but not worse than Windows built-in scaling would do. All that can be achieved by having simple code in form constructor:

internal partial class MyForm : Form {
    public FilesEditForm(TabFiles tabFiles) {
        InitializeComponent();
        this.Font = SystemFonts.MessageBoxFont;

        using (var g = this.CreateGraphics()) {
            var scale = Math.Max(g.DpiX, g.DpiY) / 96.0;
            var newScale = ((int)Math.Floor(scale * 100) / 50 * 50) / 100.0;
            if (newScale > 1) {
                var newWidth = (int)(mnu.ImageScalingSize.Width * newScale);
                var newHeight = (int)(mnu.ImageScalingSize.Height * newScale);
                mnu.ImageScalingSize = new Size(newWidth, newHeight);
                mnu.AutoSize = false; //because sometime it is needed
            }
        }
    }
}

First variable simply contains scaling factor current monitor has compared to standard 96 DPI one. For example, 120 DPI monitor would cause variable’s value to be 1.25.

Next we try to determine how much we should magnify icons. In order to avoid unnecessary small adjustments, new scale is then calculated and rounded to .5 increments. If scale factor is 1.25, it will round-down to 1; scale of 1.6 will round-down to 1.5; scale of 2.2 will round-down to 2 and so on.

Check is made whether there is scaling to be done and, if needed, we simply calculate new image width and height using current size as a template. Assuming that icons were 16x16, scale factor of 1.5 would cause them to be 24x24.

Latest order of business is to turn off auto size. On most forms this step might be skipped without any issue. However, some stubborn forms will have their menu stay the same size as long as AutoSize is turned on (at least on .NET Framework 2.0). If you are on latest framework and/or your forms don’t misbehave, you can skip it safely.

PS: To have .25 increments, just swap 50 for 25; to have only whole number increments, swap 50 for 100.