Posted on February 25, 2020
Well, anyone who has ever developed a C++ game or application with Gregorian to Jalali date conversion (or, vice versa) requirement is well aware of the hurdles of doing such a task. I, for one, have been maintaining my own cross-platform C++ library for almost two decades now, with occasional bugs coming up from time to time.
Recently, I have been playing with boost::locale (developed by Artyom Beilis and contributed to Boost project) a bit more in order to utilize it in a personal project called Barandazstorm, a home-grown social media analysis tool. Browsing the docs, I noticed the following example which does not even compile on my compiler:
boost::locale Gregorian to Hebrew date conversion example
// Create locales with Hebrew and Gregorian (default) calendars.
// Create a Gregorian date from fields
date_time greg(year(2010) + february() + day(5),l_gregorian);
// Assign a time point taken from the Gregorian date to date_time with
// the Hebrew calendar
// Now we can query the year.
std::cout <<"Hebrew year is "<< heb / year << std::endl;
So, I tried to make a guess and replaced the en_US.UTF-8@calendar=hebrew part with en_US.UTF-8@calendar=jalali which didn’t work. But, on the second try replacing that with en_US.UTF-8@calendar=persian actually worked! Which is sheer delight; due to the fact that now I found a solution to convert dates between both calendars as efortless as techonologies such as .NET in C++:
Two-way Gregorian / Jalali date conversion using boost::locale
* @author Mamadou Babaei <email@example.com>
* @version 0.1.0
* @section LICENSE
* (The MIT License)
* Copyright (c) 2020 Mamadou Babaei
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* @section DESCRIPTION
* Two-way Gregorian / Jalali date conversion using boost::locale example
std::locale locale_gregorian = generator("en_US.UTF-8");
std::locale locale_jalali = generator("en_US.UTF-8@calendar=persian");
boost::locale::date_time jalali(gregorian.time(), locale_jalali);
std::cout <<"Persian date is "<< jalali / boost::locale::period::year()
<<"/"<< std::setfill('0') << std::setw(2)
<< (jalali / boost::locale::period::month()) +1<<"/"<< std::setfill('0') << std::setw(2)
<< jalali / boost::locale::period::day()
std::locale locale_gregorian = generator("en_US.UTF-8");
std::locale locale_jalali = generator("en_US.UTF-8@calendar=persian");
boost::locale::date_time gregorian(jalali.time(), locale_gregorian);
std::cout <<"Gregorian date is "<< gregorian / boost::locale::period::year()
<<"/"<< std::setfill('0') << std::setw(2)
<< (gregorian / boost::locale::period::month()) +1<<"/"<< std::setfill('0') << std::setw(2)
<< gregorian / boost::locale::period::day()
On a side note, for the above code to work your boost::locale libraries has to be built with ICU support; otherwise boost::locale throws an exception. On most Linux or BSD distros this is the default when you install Boost libraries from your distro’s package manager. On Windows, it requires a bit of effort if you are trying to build Boost binaries yourself, which is another story for another time.
I did test the above code on FreeBSD, Linux, and Microsoft Windows, using MSVC, GCC, LLVM/Clang, and MinGW, and it’s working as expected on all of these platforms.
Posted on August 19, 2019
A few months back due to various changes in how Funtoo is being managed, I migrated back from Funtoo to Gentoo after almost a decade. After some time I realized my laptop randomly gets stuck on a blank screen and freezes just right before my login manager (SDDM) starts. I noticed the hard-disk LED is blinking and the system is actually not freezed and probably is working and stuck on something. Checking the system or Xorg logs did not reveal anything unusual.
I even posted my issue on the Gentoo Forums and when I thought the issue is gone I marked it as SOLVED (well, I don’t turn off this laptop or reboot too much). But, the problem came back and hunted me over again.
Finally, I decided to install JuiceSSH on my phone since I do not have access to another PC for the time being. When it did freeze, I did ssh into my Gentoo installation and noticed udevd’s CPU usage is at 100%. I looked up the forums to see if someone else having this issue or not. I cannot recall where on the forums I saw it, but it seems this was a known issue to some users with recent NVIDIA drivers and someone suggested blacklisting the NVIDIA drivers, so the kernel won’t load them at boot time as it is going to be loaded by X later on.
Well, I did the following changes in order to blacklist the NVIDIA modules, so the kernel won’t load them at boot itme:
Well, I haven’t played a multiplayer game in ages until recently, when my cool boss announced regular playtimes for all the employees in our company as a group activity in order to put the fun back into work. Since I’m a die-hard COD4 fan and I used to play Promod LIVE heavily with colleagues and friends, I proposed Call of Duty 4: Promod LIVE 220 which happened to be favored by everybody; except there was one issue: everyone uses Microsoft Windows while I’m developing UE4 games on a single-boot Funtoo Linux system.
Naturally, my first attempt was running it inside a Windows 7 virtual machine under VMWare Workstation for Linux which supports up to Direct3D 10 (the exact API used by COD4). Sadly, the experience was very poor and painful with lots of unbearable stuttering on my decent hardware. Thus, the last resort was running it under Wine, which I used to happily run many Windows applications and games under it for many years. Though, throughout those years I replaced almost every Windows application with an equivalent or an alternative Linux application until I gradually stopped using it. In the meanwhile, I also distanced myself from traditional desktop environments such as GNOME, KDE, Xfce, and LXDE, while experimenting with various window managers specially i3wm, which caught my attention for many good reasons. So, in the end I made up my mind and alienated myself from desktop environments once and for all.
Running a fully-fledged game engine such as Unreal Engine 4, I expected COD4, Wine, and i3 combination to work fine out of the box as it would under any other DE. Well, it turned out that I was too simple-minded about running a fullscreen game such as COD4 under Wine/i3wm. Hopefully, as the Wine FAQ states the workaround is super easy.
Here is the full guide on running COD4 v1.7 with Promod LIVE 2.20 on GNU/Linux.
Posted on April 29, 2016
Update 1 [2016/09/30]:A section has been added to the end of the article for dealing with major FreeBSD upgrades.
Update 2 [2016/09/30]:A section has been added to the end of the article for upgrading current installation of Discourse to newer versions.
Update 3 [2016/09/30]:A section has been added to the end of the article for installing Discourse under Ruby version managers which is required for dealing with newer versions of Discourse since the current system-wide version of Ruby on FreeBSD is 2.2.5p319.
Update 4 [2016/10/06]:I decided to get rid of Discourse on this blog for various reasons including negative feedback from my readers, performance issues, being a memory hog and not so easy on memory, difficult maintenance, dealing with building Ruby Gems which is a tedious task in case they fail to build and a bug that duplicates my posts and creates a new thread for each post which means it won’t show previous comments. Last but not least, in my estimation it’s too heavy for such a small task such as a comment system.As a result, this guide won’t be maintained anymore.
Well, when it comes to blog comment hosting services for static blogs, you will have a plethora of options such as SolidOpinion, Disqus, Livefyre, Google+ or Facebook comments, and many more. Unfortunately, such services has never been an option for me and I resisted them like forever. Yes, I’ve got one million reasons to believe and do so which demands another post of its own. So, I’ll avoid that argument for now.
This left me with two choices:
Operate my blogs without the comment section as I did for years
Since people asked me for a way to discuss their feedback on the website, this made the former choice a no go, anymore. So, in a search for the promised commenting system, I spent hours installing and trying every single FLOSS commenting system on GitHub. And everyone of them has had a big flaw that I could not tolerate. Finally, I came to the conclusion that I’m out of luck with that. Of course, I always had the option to write my own commenting system according to my own needs. As, I did with my own blog subscription system. But, due to the lack of time that was not an option either.
Despite many nice feature it provides, it has a few rough edges, too. I was able to conquer some and some couldn’t, yet. But it did not stop me from integrating it into my Hexo-based blogs after two weeks of testing it. So, there it is, from now on both this blog and my Farsi blog are discussion aware :).
OK, the main issue that many people face when they want to install Discourse in a platform other than GNU/Linux, is they get hit in the face by the reading this line in the official documentation:
Why do you only officially support Docker?
Hosting Rails applications is complicated. Even if you already have Postgres, Redis and Ruby installed on your server, you still need to worry about running and monitoring your Sidekiq and Rails processes. Additionally, our Docker install comes bundled with a web-based GUI that makes upgrading to new versions of Discourse as easy as clicking a button.
Yes, I know Ruby and Rails are crap and deploying Ruby on Rails apps are pain in the Butt. Do not worry! This was the first struggle with Discourse that I had since this blog runs on FreeBSD. And, FreeBSD support for Docker is experimental, yet. Fortunately, I used to deploy GitLab instances on FreeBSD for three years which was also RoR before I migrated to Gogs which kicks butt, anyway! That made it easy to figure out a simple way to deploy Discourse without Docker on FreeBSD.
Posted on August 25, 2015
Undeniably, flaming has been around since the dawn of the Internet age. And even worse, it has been on the rise ever since. Gazillions of flame wars on websites such as Slashdot or Reddit surely is enough proof, the greatest of which is the perennial debates between users of competing operating systems.
No doubt I’m a FLOSS enthusiast and advocate who considers free/libre/azad software superior to the proprietary ones, by all means possible. But like all software, the FLOSS ones have some shortcomings, too. So, the point is no one-hundred percent reliable software exists on this planet which means open source software may also suffer from bugs or security flaws as proprietary software do.
Today is Linux kernel birthday and many FLOSS enthusiast and advocates around the globe are going to celebrate it. I’m a diehard FreeBSD fan, but it won’t stop me from celebrating Linux birthday. In fact, I still use GNU/Linux for building native C/C++ libraries using Android NDK on a Slackware machine. In addition to that, I used to be a heavy Funtoo / Gentoo user. The thing is, I appreciate the tools I use, no matter what. So, I’m going to celebrate Linux birthday by telling you a story. A story that made an unforgettable trip even more memorable. Here’s the story of a GNU/Linux system in production which crashed in its hometown, Helsinki, Finland.
Posted on August 8, 2015
Update 1 [2016/09/23]:OmniBackup now officially supports GNU/Linux. More info…
Update 2 [2016/09/23]:Official documentation moved to GitHub which means this guide won’t be maintained anymore and maybe out of date or inaccurate.
A week ago was System Administrator Appreciation Day. It is celebrated on the last Friday in July and it has been celebrated since July 28, 2000. But, system administrators know not all days are like that day. They face many hard times and struggles during their careers and the worse of them all is either a security breech or data loss.
For so many years I’ve been writing and maintaining backup scripts on and on, for every single database I added, for every single directory with critical data, or any other service I was running on every new server I got my hands on. In the end, I found myself ended up in a pile of backup scripts and multitudinous cron entries which was a nightmare to keep track of. I even had to manage the schedule so that two backup scripts do not run at the same time. Even more, I had to manually track the backups to see whether they were successful or not. Also, someone has to manually delete the old ones to make rooms for the next ones.
Therefore, I came up with an elegant solution to replace the old process which I found exceptionally error-prone. An end to all my hardships which I call OmniBackup. At last, I’m able to confidently keep abreast of all the ever-growing data that I have to keep safe.
“So, what exactly is OmniBackup?” you may ask. “A fair question,” I would say. OmniBackup is a MIT licensedBash script which delivers the following set of features:
Configuration and customization of backup mechanism through JSON
Support for PostgreSQL backups as a whole or per database
Support for MariaDB and MySQL backups as a whole or per database
Support for filesystem backups with optional ability to follow symbolic links
Support for pluggable customized scripts to extend OmniBackup functionality beyond its original design which allows support for many different backup scenarios that has not been built into OmniBackup, yet
Backup file name tagging which allows including date or host name in the archive name
Online backup without a prerequisite to suspend any service
Support for customized backup tasks priority order
Support for multiple backup servers
Ability to always keep a copy of backups offline
Ability to keep a copy of backups offline if no backup server is available, or in case of an error such as a file transfer error
Secure file transfer through SSH / SCP protocol
LZMA2, gzip and bzip2 compression algorithms along with different compression levels to maintain a balance between speed and file size
Ability to preserve permissions inside backup files
Support for symmetric cryptography algorithms AES-128, AES-192 and AES-256 (a.k.a Rijndael or Advanced Encryption Standard)
Random passphrase generation for encrypted backups with variable length and patterns or a unique passphrase for all backups
Support for RSA signatures to verify the backup origin and integrity
Passphrase encryption using RSA public keys for individual backup servers
Backup integrity verification by offering hash algorithms such as MD4, MD5, MDC-2, RIPEMD160, SHA, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 and WHIRLPOOL
Optional Base64 encoding
System logs and a standalone log file including all details
Reporting through email to a list of recipients with ability to include passphrases
Customized mail subject for successful and failed backup operations
Disclaimer:Please be wary of the fact that this script has approximately 3.5 K lines of Bash code and devoured hell of a time from me to write and debug. You should also consider that this is my first heavy Bash experiment and I may not write quality code in the language since I’m a newcomer to Bash. I do not claim that OmniBackup is production ready, that’s why I did version the first release at 0.1.0. Also keep in mind that OmniBackup heavily relies on 3rd-party software which increases the chance for fatal bugs, therefore losing data. So, I provide OmniBackup without any warranties, guarantees or conditions, of any kind and I accept no liability or responsibility for any misuse or damage. Please use it at your own risk and remember you are solely responsible for any resulting damage or data loss.
Credits:Many thanks go to my fellow and long-time friend, Morteza Sabetraftar for his help and ideas without whom OmniBackup lacked features or quality. Another kudos goes to my brother Amir by releasing me from shopping, cooking and house-cleaning without even mentioning it, an invaluable and priceless assistance that encouraged me even more to use my best endeavours to get this task done.
Please, feel free to clone and modify it as you wish. Pull requests for new features, improvements or bug fixes are also very welcome.
There is an old saying that the only safe computer is one that’s disconnected from the network, turned off, and locked in an underground bunker—and even then you can’t be sure!
Since most of us can’t afford to keep our servers in an underground bunker, the least little thing that could have been done in order to keep their threat exposure at rock-bottom is protecting them by running a combination of a firewall and an intrusion prevention system or IPS (a.k.a intrusion detection and prevention systems or IDPS). Surely, that alone proved insufficient and other security measures and best practices should also be considered.