## TIL: How to find if a number is power of 2

Take the number and take the number - 1, perform a binary and (`&`) operation on the two numbers. If the result is 0 then the number is the power of 2.

``````number != 0 && (number & (number - 1)) == 0
``````

Let's see some numbers which are power of 2 and their binary representation (padded with 0 for easer reading):

``````2  00010
4  00100
8  01000
16 10000

``````

Let's see the numbers - 1 and their binary representation (padded with 0 for easer reading):

``````1  00001
3  00011
7  00111
15 01111
``````

An `&` (and) operation will give 1 for a digit if both of digits are 1.

For example

``````4: 00100
3: 00011
--------
&: 00000
``````

Which will end up in 0, because a number which is the power of 2 only the first digit will be 1 and when we substitute 1 from the same number, we will get a number where all digits are 1 (except the first of the original number). So in the and we will &-ing 0 to 1 in every digit.

But on the other hand, if we substitute 1 from a non-power of 2, at least the first digit will always be 1 for both numbers, so &-ing them will always return a non 0 number:

``````3: 00011
2: 00010
--------
&: 00010
``````

Which is 2

``````6: 00110
5: 00101
--------
&: 00100
``````

Which is 4, so it's definetly not 0. So they are not power of 2.

Originally I found it in the Plan9 source code

## TIL: RBL DNS Query

Today I learned how to query if an address is on an rbl list.

Reverse the octets of the IP address: `1.2.3.4` becomes `4.3.2.1` Then append the domain name given by the DNSBL service (`dnsbl.example.com`) Then look up of this domain's A record.

`host 4.3.2.1.dnsbl.example.com`

If the IP is listed, it will return an address, or it will return an NXDOMAIN if the IP is not listed. The exact meaning of the address can be different at each provider.

Based on the knowledge I created a small program to check if a address is listed on a blacklist: DNSBL Check

From Wikipedia

## A service to share secrets securely

I built a simple program to share sensitive data securely

In the last few months I've been working on a service, which helps to share data securely. The service called sekret.link.

I wanted to practice Golang and Angular and it was a good candidate for that.

Imagine that a new colleague joined to the company, there are bunch of things she will need to have access, like WiFi, database, internal site or whatever. You know the password or you generate the password and you will need to send it to her on Slack or e-mail. You can send it as a simple message, but that will mean that Slack or her e-mail provider can read the information. What is worse that then this information won't be deleted automatically. If someone breaks into her account now can discover these secret informations and the company will be in a pretty bad situation.

The service what I created tries to help on these issues. You send the sensitive information to the service and it will store it encrypted. It returns an URL which can be used to decrypt the information. After the secret has been read it also destroyed and there is no way to restore it.

No one else will have access to the decryption key. It isn't saved, it isn't logged can not be guessed. The web client (which is visible at https://sekret.link) is even encrypting the data before sending it, so the unencrypted data never left your browser.

As the main purpose of the application is to protect privacy and keep secret hidden from unauthorized third parties I made it as secure as possible:

• The decryption key is random and long enough to be secure
• The decryption key is only known by the user who created the secret
• No external scripts included to the site
• No tracking scripts included to the site, it's not tracking even internally
• It doesn't use any cookies
• Both the frontend application and the server code are Open Source
• It has an API, so if you don't trust in the frontend application you can create your own

There were (are) several challenges I needed to solve. I wanted to make it secure as possible, as usable as possible and as developer friendly as possible.

The very first version had no UI, and I only wanted to be able to use it with `curl`. For example `curl -d 'secret message' https://sekret.link/api/` will return the link what you can send to your friend right away. However, it's simple and good, already has one issue: many applications, like Slack and other services fetches the pasted URLs to create some kind of preview. It means two very bad things: this application will read the secret will also be destroyed, so the real recipient will not be able to read it. That's why I needed to create the frontend application.

I plan to write some more about the challenges, like how I utilized the go interfaces, how I got some hard time with the Angular routing. How I made it work when JavaScript is turned off in the browser and I have some other stories.

Footnote: the idea is not new, there are several other services like that, for example Privnote, what I used before I created this service.

## Set default sound level of FiiO K1 on plug

FiiO K1 became very silent recently when you plug it in on Ubuntu for some reason.

To fix it add an UDEV rule:

/etc/udev/rules.d/71-fiio-k1.rules

``````SUBSYSTEMS=="usb", ACTION=="add|change", ATTRS{manufacturer}=="FiiO", ATTRS{product}=="FiiO USB DAC K1", RUN+="/home/ajnasz/bin/init-fiio-k1.sh"
``````

And create the shelscript which set the volume whenever you plug the DAC:

/home/ajnasz/bin/init-fiio-k1.sh

``````#!/bin/sh

CARD_ID="\$(aplay -l | grep "FiiO.*K1" | cut -d ' ' -f 2 | tr -d ':')"

if [ -z "\$CARD_ID" ];then
return
fi

amixer -c "\$CARD_ID" sset PCM 90%
``````

## ThinkPad T510 Xorg NVidia config

To enable screen backlight brightness adjustment, create the following file and restart the X server

## DBus Error - xinitrc

I tried to use Spotify dbus interface to play/pause tracks, found a nice shell script but it did not work, but instead I got this error message:

Error org.freedesktop.DBus.Error.ServiceUnknown: The name org.mpris.MediaPlayer2.spotify was not provided by any .service files

Turned out that the issue is probably with my X11 session initialization.

Note: At the very least, ensure that the last if block in `/etc/X11/xinit/xinitrc` is present in your `~/.xinitrc` file to ensure that the scripts in `/etc/X11/xinit/xinitrc.d` are sourced.

So, I tried to source the /etc/X11/Xsession before I start the window manager:

``````. /etc/X11/Xsession
exec i3
``````

Called `startx` but no luck, X did not start. The following error was in the `~/.xsession-errors`:

dbus-update-activation-environment: warning: error sending to systemd: org.freedesktop.DBus.Error.InvalidArgs: Invalid environment assignments

I had no clue what would that mean, however after some `echo` based debugging in `/etc/X11/Xsession` I could confirm that the files from `/etc/X11/Xsession.d` were sourced and the last file which was sourced is `/etc/X11/Xsession.d/99x11-common_start`. That file is a one liner:

``````exec \$STARTUP
``````

I guessed that `\$STARTUP` is undefined. Checked where it would be defined and I found `/etc/X11/Xsession.d/50x11-common_determine-startup`

If no X session startup program was passed to the Xsession script as an argument (e.g., by the display manager), or if that program was not executable, fall back to looking for a user's custom X session script, if allowed by the options file.

That means I can define it somehow, so I tried by setting it in my:

``````export STARTUP=i3
. /etc/X11/Xsession
``````

Then everything looks good. Some magic happens in those files (probably in /etc/X11/Xsession.d/20dbus_xdg-runtime) what I didn't tried to figure out yet.

## Hűtés csere

Legutóbb írtam, hogy RAM-ot vettem a 8 éves notebookba, ami nem pont olyan, mint amilyet szerettem volna, de azért végül megtartottam. Abban a cikkben írtam azt is, hogy némi FAN ERROR-ral üzenetet is kaptam a csere után, ami végül elmúlt. Sajnos nem múlt el, hanem állandóvá vált. Így használhatatlan lett szegény gép. Az interneten írták, hogy nem egyedi a gond és a legjobb megoldás a csere. Szétnéztem ebay-en, majd rendeltem is egy vadonatújnak mondottat. Ez volt 2019. március 3-án, a érkezése március 19 és április 17 között várható. Másnap útnak indult Kínából, egy héttel később pedig elégedetten láttam, hogy már Magyarországon volt a csomag. Nagyjából fél nappal később, március 13-án pedig le is szállt vele repülő Ferihegyen. Abban is bíztam, hogy a Magyar Posta a nagy nemzeti ünnep előtt kiszállítja. Ez sajnos nem sikerült. Viszont legalább a megadott legkésőbbi érkezéshez képest csupán egy nap késéssel, április 18-án csütörtökön már itt is volt a postai értesítő, hogy csomagom jött külföldről. Remélem nem túl költséges a csomagok tárolása.

Így, hogy már meg is jött a hűtő (réz borda és ventilátor), ma már időm is volt rá, hogy megpróbáljam beszerelni. Két youtube videó támogatásával nekiálltam kicsavarozni az összes csavart a laptop aljáról, és nagy nehezen a régi ventit is sikerült kivenni. Itt jegyezném meg, hogy a WD-40 nagyon jó csavarlazító és emellett remélem a gépben kárt nem tesz. Letisztítottam a korábbi hővezető pasztákat, aztán kicsi feszegetéssel betettem az új hútőt, ami csak minimálisan különbözik a régitől. Egy leszorító rögzítés van másképp megoldva meg a hátsó borda szélesebb egy fél centivel, de volt neki hely amit most rendesen kitölt. Összeszereltem félig, és bekapcsoltam, nem is sípolt, csak nem tudott bootolni, mivel az SSD-t kifelejtettem. Azt is bepattintottam, és láttam a még nem visszaszerelt billentyűzet helyén, hogy milyen szépen forog az a darab műanyag, ami ventilátor néven kerül forgalmazásba. Pár perc után minden megmaradt csavarnak megtaláltam a helyét, összepattintottam a műanyagokat és immáron az új hűtő halk surrogása felett írom ezt a rövid cikket. Tudom, hogy nagyon régi gép ez már, de 0.1-es load és 1.8G használt memória mellett szerintem elciripel még egy darabig.

## Sikerült-e RAM-ot rendelni?

Karácsonykor bevásároltam udemy-n tanfolyamból, többek között vettem kubernetest is. Amikor 3 VM-et futtattam miatta, akkor kezdett a napokban 8-ik évébe lépő Lenovo T510-ben lévő 4GB memória kevés lenni. Mivel 8 év az mégis csak nyolc év, akku sem a régi, a ventillátor is hangos, meg különben is, de elkezdtem nézegetni, hogy ha új gépet szeretnék, akkor miből lehet válogatni a piacon. Kínálat az van, meg áruk is és akkor még bele sem gondoltam, hogy vajon miféle minőséget gyárthatnak mostanság. A notebook vásárlás helyett úgy gondoltam, először megpróbálok javítani a jelenlegin. Anno az SSD egy nagyon jó beruházás volt, gyakorlatilag amiatt nincs igazán szükségem a mai napig sem újabb számítóra, mi baj lehet? Gőzöm sincs a mai és a 8 évvel ezelőtti hardveriparról. Nem tudom, hogy mi-mivel kompatibilis, hogyan adja a legjobb teljesítményt, csupán halovány emlékeim vannak régebbről, hogy az azonos típusú RAM-ok jó hatással vannak egymásra. Azt nem tudom a mai napig sem, hogy mennyire kell azonosnak lenni.

Nem akartam kockáztatni, igyekeztem detto ugyanolyan RAM-ot beszerezni.

``````\$ sudo dmidecode -t 17

[sudo] password for ajnasz:
# dmidecode 3.0
Getting SMBIOS data from sysfs.
SMBIOS 2.6 present.

Handle 0x002B, DMI type 17, 28 bytes
Memory Device
Array Handle: 0x002A
Error Information Handle: No Error
Total Width: 64 bits
Data Width: 64 bits
Size: 4096 MB
Form Factor: SODIMM
Set: None
Locator: DIMM 1
Bank Locator: Bank 0/1
Type: DDR3
Type Detail: Synchronous
Speed: 1334 MHz
Serial Number: 5A48C2FE
Asset Tag: 1104
Part Number: HMT351S6BFR8C-H9
Rank: Unknown
``````

Nem eltéveszthető a Part Number: HMT351S6BFR8C-H9 rész, erre kerestem, és Amazonon találtam.

Meg is rendeltem, hosszas utazás után ma érkezett meg, hazaérvén néhány csavartekerés után rögvest be is pattintottam a gép aljába. Indítás után Fan error hibaüzenet fogadott, ami arra ösztönzött, hogy még jobban szétszedjem és kicsit megtakarítsam a gépet. Kiporoltam a ventit, összeraktam és már majdnem egyből jó is lett, kicsit a seggére kellett verni, de elindult.

Boot után a free -h hihetetlen magas számokat produkált, tehát a RAM működik. Gyanútlanul kiadtam a fenti `dmidecode -t 17` commandot, amikor is! (csak az új RAM adatait mutatom):

``````Handle 0x002C, DMI type 17, 28 bytes
Memory Device
Array Handle: 0x002A
Error Information Handle: No Error
Total Width: 64 bits
Data Width: 64 bits
Size: 4096 MB
Form Factor: SODIMM
Set: None
Locator: DIMM 2
Bank Locator: Bank 2/3
Type: DDR3
Type Detail: Synchronous
Speed: 1600 MHz
Serial Number: 41CA7A57
Asset Tag: 1245
Part Number: HMT351S6CFR8C-PB
Rank: Unknown
``````

Jól észrevehető különbség a Part Number és a Speed.

Sikerült-e RAM-ot rendelni? Igen. Azt kaptam, amit rendeltem? Nem.

Viszont ez már így marad, az biztos.

## pomodoro.sh

Letöltés

A pomodoro egy módszer, ami segíthet az idő hatékonyabb kihasználásában. Irodai, kreatív munka során különösen hasznos lehet. A lényege, hogy a munkákat rövidebb - alapvetően 25 perces - szakaszokra bontva végezzük el, minden szakasz között rövidebb szünetet tartva. A legfontosabb, hogy egy pomodoro menetben kizárólag az adott feladattal foglalkozzunk. A kizárólag főleg azt jelenti, hogy nem olvasunk e-mailt, mi nem kapcsolódik a témához, nem chat-elünk, nem szólunk senkihez, nem kalandozunk feladataink véget nem érő listájában, hanem csak azt az egy kiválasztott munkát végezzük. Ha letelt az idő, akkor pedig dobjunk el mindent, akkor muszáj bármi mást csinálni, e-mailezni, kismacskát simogatni is. A koncentrált munkavégzés miatt a produktivitásunk hatalmasat nőhet, a szünetek pedig megakadályozzák, hogy idő előtt elfáradjunk.

Mondanom sem kell, a legnehezebb figyelmen kívül hagyni azt a rengeteg ingert. Chat, e-mail, kolléga a másik asztalnál nem ismer viccet.

Természetesen a nagy analóg csörgőóra mellett rengeteg program létezik, ami mást sem tesz, mint visszaszámol, esetleg letilt értesítéseket. Éppen ilyen természetes, hogy nekem egyik sem felel meg tökéletesen és különben is egy igazán egyszerű igényről van szó, amit élvezet mégegyszer megoldani.

Volt nekem erre már IRC/Slack botom (https://github.com/Ajnasz/hubot-pomodoro). Ezekről gyakran lemaradtam, mert az irc másik tmux sessionben fut és hangot sem ad. Hónapokkal ezelőtt kezdtem el csinálni az egyszerűbb megoldást, amit shellben meg tudok pattintani.

``````sleep 10 && aplay /usr/share/sounds/purple/alert.wav
``````

10 másodperc után egy hangfile lejátszása. A tmux is kiemeli az ablakot, mert változás történt.

``````sleep \$(echo "1 * 5" | bc) && aplay /usr/share/sounds/purple/alert.wav
``````

Itt azt próbáltam, hogy milyen volna `bc` paranccsal lehetne kiszámolni, hogy meddig tartson a sleep.

``````sleep \$((25 * 60)) && aplay /usr/share/sounds/purple/alert.wav
``````

Látszik, hogy mennyivel szebb, ha a `bc` sincs bevonva.

``````i=0;while [ \$i -lt \$((1 * 1)) ];do sleep 1; i=\$((\$i + 1)); echo \$i;done; aplay /usr/share/sounds/purple/alert.wav
``````

Na itt már látszik, hogy nem fog egy sorban megállni. Csak illene tudni, hogy mennyi idő telt el. Egymás alá írogatja a másodperceket.

``````i=0;while [ \$i -lt \$((1 * 5)) ];do sleep 1; i=\$((\$i + 1)); echo -n "\r\$i";done;echo; aplay /usr/share/sounds/purple/alert.wav
``````

Itt pedig az utolsó egy soros, ahol helyben frissítjük a kiírt eltelt időt.

Nagyjából ezután került be minden egy file-ba és lett a neve pomodoro.sh.

Ha pedig már shell script, akkor igyekeztem mindent konfigurálhatóvá tenni. A minden kimerült abban, hogy lehessen másik hangot játszani és tetszőleges időt beállítani. Aztán, ahogy az evolúció megkívánta, a desktop notification is megjelent, hogy már nagyon biztosan lássam, ha véget ért a pomodoro session. Ezzel kapcsolatos, hogy notification daemonként a dunstot használom, majd a `notify-send`-et is lecseréltem `dunstify`-ra.

Ez volt a pont, ami után már hetekig hozzá sem kellett nyúlni a scripthez, nem volt ötletem, amitől még fantasztikusabb lehetne. Viszont felismertem, hogy Slack üzenetek még mindig csak jönnek és jönnek, én meg nézem őket, ami a fókusz elvesztésével jár. Nosza, több se kellett, feltúrtam a Slack API dokumentációját, hogy megtudjam, miképpen lehetne scriptből roppant elfoglalttá beállítani magam. Így történt az, hogy a ha van `SLACK_TOKEN`, akkor a pomodoro menet kezdetekor beállítja a "ne zavarj" státuszt és még egy pofás paradicsom ikont is elhelyez a nevünk mellé, a session végén ezeket természetesen törli. Sőt, újabban nem csak törli, hanem visszaállítja a korábban beállítottra.

Korábban egy gistbe küldtem a változásokat, de a projekt érettsége nyomán úgy döntöttem, hogy egy saját Github repositoryt is megérdemel.

## Raspberry Pi külső drive kernel panic

Ha a Raspberryn a root partíció egy külső (USB) drive-on van, akkor ügyelni kell arra, hogy a `/boot/cmdline.txt`-ben, a root értéke `PARTUUID` formában legyen megadva, nem pedig `/dev/sda1` vagy hasonló módon. Ellenkező esetben Kernel Panic - not syncing: VFS: Unable to mount root fs on unknown-block... és ehhez hasonló hibaüzenet várhat, legkésőbb akkor, amikor egy reboot paranccsal szeretnéd újraindítani a gépet.

A `PARTUUID` a `sudo blkid` paranccsal kinyerhető, valami ehhez hasonló lesz az output: