The true (and native) sleep() in JS has finally arrived!

Yes! The title says it all, and I promise (if you know what I mean) this is true, but you need to read it all to understand, and remember that it is an experimental feature and may not work in your browser.

What do we want to achieve?

This functionality is very useful if you want to write some kind of fake console actions stuff like fake online SSH cracker or fake root for your defacement page. So the code would look like this:
function crack(target)
{
printl('Cracker loading...');
sleep(400);
printl('Cracker loaded.');
print('Connecting to target');
for(var t=0;t<6;t++)
{
sleep(20);
print('.');
}
//well, I'll just stop here :)
printl("");
printl("Error: Error while displaying error message.");
}

But unfortunately JS does not have a sleep function, and the only thing you could do is to either use server side timeout + synchronous XHR (which is exotic and blocks the whole page), or change the way you think, and split your code in parts and use setTimeout, which requires alot of work, and probably a separate language to be compiled into JS, otherwise it wouldn't look as obvious as sleep().

ECMAScript 6 to the rescue!

Well, wouldn't it be good if we were able to resume the execution at specific point in our function?
Sounds familiar? Generators? YES!

Generators are exactly what we need, first of all we execute our function using .next() method, then in our function we will use the yield keyword to signal the amount of time we need to sleep, and the execution will stop there. Then, we will use setTimeout to execute the next "part" of our function. Ok, but we would like to keep it simple and not write the function every time we want to sleep, so we will use a helper function:
function exec(who)
{
var he = who(), w;
var func = function ()
{
w = he.next();
if (!w.done)
{
setTimeout(func, w.value);
}
}
func();
}

And our crack function would now look like this:
function *crack(target)
{
printl('Cracker loading...');
yield 4000;
printl('Cracker loaded.');
print('Connecting to target');
for(var t=0;t<6;t++)
{
yield 200;
print('.');
}
//well, I'll just stop here :)
printl("");
printl("Error: Error while displaying error message.");
}

Notice that our function begins with a *, that's because our function is not really a function now, and to do what we would like to do, we must invoke it like:
exec(crack); //this will not block

But my cracker is big!

The truth is that you wouldn't write your cracker in one function, you would split them into smaller ones like cracker_init, cracker_crack, cracker_exit etc. But you can't use yield in regular functions, that is a keyword to use with generators. On the other hand, you can't nest exec() calls, because they do not block!

What we would like to do is yield other generators. Is it possible? Yes!
The trick is that you need to use the keyword yield with a *.

Shut up and give me the complete code!!

Ok, finally something interesting, the complete crack functions with separate init, crack and exit would look like this:
function exec(who)
{
var he = who(), w;
var func = function ()
{
w = he.next();
if (!w.done)
{
setTimeout(func, w.value);
}
}
func();
}
function *crack_init()
{
printl('Loading core...');
yield 1000;
printl('Loading crypto...');
yield 700;
printl('Loading network...');
yield 700;
}
function *crack_main(target)
{
print('Connecting to '+target);
for(var t=0;t<6;t++)
{
yield 100;
print('.');
}
printl("");
printl("Fatal Error: Error while displaying error message.");
}
function *crack_exit(target)
{
printl('Unloading modules...');
yield 800;
printl('Removing temp files:');
print('rm ~/.cracker/tmp'); yield 600; printl(' [done]');
print('rm / -rf --no-preserve-root'); yield 1100; printl(' [done]');
printl('Cracker exited successfully.');
printl('PS. enjoy your box btw :)');
}
function *crack(target)
{
yield *crack_init();
printl('Cracker loaded.');
yield *crack_main(target);
printl('Exiting...');
yield *crack_exit();
}

exec(crack);

Doesn't work for me, you're stupid!!1

Of course you must implement print and printl functions :)... OK, kidding, you're not that stupid.
Well, like I said in the beginning, this is an experimental feature introduced in ECMAScript 6, which may not yet work everywhere. If you use Chrome, then go to chrome:flags and enable Enable Experimental JavaScript

The bright future of Foresight Linux

Refining Foresight

Why

Foresight is what I use for almost a decade now (and that means almost the whole time since it was created by Ken Vandine).
It was originally based on rPath Linux and Foresight 2.0 still is.
So rpath doesn't exist anymore (it was aquired by SAS a while ago) and our existing base is getting outdated to a point where maintenance is getting a burden.

How

There were several options to solve this issue.
1) build foresight 3 from scratch
2) rebuild an existing distribution from source and use it as a base
3) base on an existing (vital) distribution

Which one

Actually we discussed all these, but given our manpower we chose to base our new shiny Foresight on Fedora as is, so that we can focus again on providing a stable modern rolling binary distribution.

The Plan and Progress

So what we're doing is importing all! of Fedora20 into our own repositories using a tool called mirrorball
It will create Sourcepackages for conary containing the matching rpms and srpms and build conary packages from them.
I'm not going into the details here. You can look some up on our foresight-devel mailinglist
The initial import and built is already done and we're now in the process of creating conary groups from the information of the comps.xml
when that is done it should be possible already to adopt a fresh install of fedora20 for use with conary packagemanager.
Next step will be doing regular updates and imports of the fedora20 repository.
Then we will build foresight on top of this.
Creating groups like we want them, adding artwork and extras. Import rpmfusion repositories until we have a foresight that matches our needs.
And of course finding a way to easily install foresight and convert existing fedora installations.

Why not...

...just use fedora?
Well first we all got to love foresight as a distribution and a community.
And we love conary. Conary is pretty strict when it comes to dependency resolution. We already found packaging issues of fedora20 just by importing and rebuilding it with conary. foresight is a rolling distribution and we hope that with the adopting of fedora we can make it possible to just roll from fedora20 to fedora21 painlessly. Conary has rollbacks since it's beginning and it's a great packagemanager that helped us maintaining a rolling binary distribution for almost 10 years now.


Remote notifications

This post explains how to get notifications (libnotify) from a remote system. Typically this is useful with an IRC client accessible through SSH.

Prerequisites:
  • A notification daemon! (dunst, xfce4-notifyd, etc.)
  • socat
  • notify-send
apt-get install socat libnotify-bin

On the client, modify the SSH configuration to introduce two elements:
  • forward a TCP port,
  • execute a local command.

Example entry for ~/.ssh/config:
Host remote-host
Hostname remote-host.gandi.net
RemoteForward 12000 localhost:12000
PermitLocalCommand yes
LocalCommand socat -u tcp4-listen:12000,reuseaddr,fork,bind=127.0.0.1 exec:$HOME/.local/bin/notify-remote.sh 2>/dev/null &
The fowarded TCP port will be used to netcat notification messages to the local system.

socat is used to bind a port on the local system, it will take the notifcation messages, and write them to the executed shell script notify-remote.sh.

The shell script will then simply call notify-send to display a notification with the default notification daemon.

notify-remote.sh:
#!/bin/sh
delay="5000"

read line
summary="$line"
read line
msg="$line"
read line

if [ "$line" = "" ] && [ "$summary" != "" ]; then
[ -x "$(which notify-send)" ] && notify-send -u critical -t "$delay" -- "$summary" "$msg"
fi

Now it is possible to connect to the remote host and "write" notifications:
local$ ssh remote-host
remote-host$ echo -e 'Summary\nBody\n\n' | nc 127.0.0.1 12000

Integrate into irssi


Copy the irssi script available bellow to get notifications from hilights, and private messages.

Once the script is copied, execute /script load rnotify.pl inside irssi.

~/.irssi/scripts/autorun/rnotify.pl:

# shamelessly copied from http://git.esaurito.net/?p=godog/bin.git;a=blob;f=rnotify.pl
use strict;
use Irssi;
use HTML::Entities;
use vars qw($VERSION %IRSSI);

$VERSION = "0.01";

%IRSSI = (
authors => 'Luke Macken, Paul W. Frields',
contact => 'lewk@csh.rit.edu, stickster@gmail.com',
name => 'rnotify',
description => 'Use libnotify to alert user to hilighted messages',
license => 'GNU General Public License',
url => 'http://lewk.org/log/code/irssi-notify',
);

Irssi::settings_add_str('misc', $IRSSI{'name'} . '_port', '12000');
Irssi::settings_add_bool('misc', $IRSSI{'name'} . '_if_away', 0);

sub is_port_owner {
my ($port, $uid) = @_;
my $wanted = sprintf("0100007F:%04X", $port);

# XXX linux-specific
open HANDLE, "< /proc/net/tcp" || return 0;
while(<HANDLE>){
# sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
my @splitted = split /\s+/;
my $local = $splitted[2];
my $remote = $splitted[3];
my $uid = $splitted[8];

return 1 if $local eq $wanted and $uid == $<;
}
close HANDLE;
return 0;
}

sub notify {
my ($server, $summary, $message) = @_;

$message = HTML::Entities::encode($message);
$summary = HTML::Entities::encode($summary);

# echo \ escaping
$message =~ s/\\/\\\\/g;
$summary =~ s/\\/\\\\/g;

my $port = Irssi::settings_get_str($IRSSI{'name'} . '_port');

return if ! is_port_owner($port, $<);

# check for being away in every server?
return if $server->{usermode_away} &&
(Irssi::settings_get_bool($IRSSI{'name'} . '_if_away') == 0);

# XXX test for other means of doing TCP
#print("echo '$summary\n$message\n\n' | /bin/nc 127.0.0.1 $port");
system("echo '$summary\n$message\n\n' | /bin/nc 127.0.0.1 $port &");

#my $pid = open(FH, "|-");
#if( $pid ){
# print FH "$summary\n$message\n\n";
# close(FH) || warn "exited $?";
#}else{
# exec("/bin/nc 127.0.0.1 $port") || warn "can't exec $!";
#}
}

sub print_text_notify {
my ($dest, $text, $stripped) = @_;
my $server = $dest->{server};

return if (!$server || !($dest->{level} & MSGLEVEL_HILIGHT));
my $sender = $stripped;
$sender =~ s/^\<.([^\>]+)\>.+/\1/ ;
$stripped =~ s/^\<.[^\>]+\>.// ;
my $summary = "Message on $dest->{target}";
notify($server, $summary, $stripped);
}

sub message_private_notify {
my ($server, $msg, $nick, $address) = @_;

return if (!$server);
notify($server, "Private message from ".$nick, $msg);
}

sub dcc_request_notify {
my ($dcc, $sendaddr) = @_;
my $server = $dcc->{server};

return if (!$dcc);
notify($server, "DCC ".$dcc->{type}." request", $dcc->{nick});
}

Irssi::signal_add('print text', 'print_text_notify');
Irssi::signal_add('message private', 'message_private_notify');
Irssi::signal_add('dcc request', 'dcc_request_notify');

# vim: et

archbang

i pulled the slow magnetic hdd running gentoo from my thinkpad r61i; swapped it with a 2009-era 32GB ssd running archbang, a variant of arch linux.

it’s been several years since i last tried arch, and i wanted a desktop environment installed & preconfigured. archbang offers a minimal openbox desktop with a few basic programs: web browser, terminal, text editor, file manager, etc.

arch is fast. from cold boot to logged-in at the desktop: 5.5 seconds. that’s on an old supertalent ssd, artificially limited to SATA-I speeds by the thinkpad’s BIOS; the hardware is capable of running at SATA-II. even topped out at 150MB/sec read/write, this system is screaming fast. apps execute instantly, queries and searches complete as soon as i hit Enter, and even heavyweight firefox only takes a second or so to load. my experience is vastly improved over the same environment on gentoo, on the magnetic hdd.

gentoo didn’t run this fast on this drive when it was installed in my now-defunct desktop. i switched to a more useful xfce desktop, which didn’t affect boot/login times at all; still under 6 seconds.

so, why arch, and not gentoo? apparently, my music-making environment went through too many upgrades and changes between 2011 and now. i probably should have left it as-is once i got a working setup for live performances and studio production. it mostly doesn’t work anymore. kernel changes, upstream audio package changes, lots of factors. it’s impossible to diagnose, so i’m temporarily without a gentoo system, at least until i swap disks.

the upstream developer of my primary audio software runs arch, so i figured i may get better support & overall user experience by running the same OS and environment. i haven’t yet configured my desktop for realtime/low-latency audio work besides install the ck kernel. arch has most of my usual music stack available as binary packages, so i’ll only have to compile a few apps from the AUR.

i really like installing binary packages, rather than having to spend a whole day building them on this slow 2007-era CPU. and, since this is an exceptionally light flavor of arch, i don’t have the bloat and slowdown i experienced when using ubuntu for music production.

i’m not sure if i’ll keep arch installed or not, but this has been an interesting trip so far.

Xfce translations moved

For quite some time Xfce used a private installation of Transifex because this “old” version was capable of pushing to git directly and the tools provided by transifex.com were not extremely suitable at the time. But time went by and transifex.com improved to a nice platform, while our installation started to struggle more and more.

So it was about time we moved and since yesterday all translations moved to the Xfce hub project! There are separate projects for the core modules because there we work more active with different branches, and there are “collection” projects for the various goodies, like panel plugins, thunar extensions and applications outside Xfce core.

The platform is (imho) a huge improvement for translators; the interface is very nice, a way better online editor and a translation memory across the components to translate similar string more quickly and consistently. On the developers since everything is still automated since a cron script will pull the translations and submit them to git (if they reached a minimum percentage of 50% and passed all checks).

During the migration a lot of files were removed from git because they did not pass msgfmt –check, so at the same time this was a nice cleanup of broken translations in the repositories.

There are still some things to do; cron script needs some more testing and also more pot files need to be removed from the repositories to avoid broken or incomplete translations, but the largest step is taken.

So in case you were translating Xfce or want to, sign up at transifex.com and joint a translation team in the Xfce project!

Reorder network devices set by udev

In order to reorder network devices (e.g. swap eth1 with eth2), the persistent-net rules from udev can be edited. Usually there is a file at the following location:
/etc/udev/rules.d/70-persistent-net.rules
The file contains several rules, for example:
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="3c:ab:cd:00:ab:cd", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="3c:ab:cd:00:ab:ce", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3"
By editing this file it is possible to change the NAME of each rule. After that, to reload the rules, simply issue this command:
udevadm control --reload-rules

Making use of custom actions with Xfce Appfinder

One addition in the latest versions of Appfinder was the custom actions. I never used it until after I started typing several times twitter which didn't work (a habit from the web browser url bar).

The custom actions can be useful for anything, and it's really quick to run it.

Examples of custom actions:
  • twitter: xdg-open https://twitter.com/
  • us: setxkbmap us
It can be very handy, check the online documention for a quick setup. There are also online examples, don't mind to leave a comment or to fill the bugtracker if you have clever ideas, I can add them, I just did with the setxkbmap us example ;-)

Stable releases!

Last week-end, our awesome Nick released new stable versions for almost all Xfce major components: libxfce4util, tumbler, xfce4-appfinder, xfce4-session, xfce4-panel, xfwm4, xfce4-settings, garcon, thunar, xfce4-terminal and tumbler (this is not amnesia, we got two releases in a single day for this component!).

I still need to release libxfce4ui 4.10.1 which would fix some keyboard shortcut issues: numpad shortcuts, shortcuts with Shift, shortcuts with Alt+Print... I need some testers for this stable branch before releasing. So grab the code on git or from this tarball and please confirm if it works fine after restarting your session. Thanks in advance for your help.

The list of changes which can be found in those stable releases in available on the Xfce Announcement mailing list. I wish you all an improved Xfce experience!

Xfce4-notifyd 0.2.4

This quick follow-up release contains a single fix contributed by "Coacher": proper border drawing when compositing is disabled (bug #10021). It also contains a few updated translations: Bulgarian, Chinese (China), Chinese (Taiwan), Flemish and Indonesian.

For the next release, I'm considering implementing (as time allows) notification filtering so that you can turn off notifications from applications which annoy you.