April 3rd, 2011 at 1:15 pm

User accounts and vsftpd

I think the following is a common setup these days: You have a webserver and host websites for a couple of friends. Your friends don’t need shell access, but they need FTP.

Now, vsftpd is the FTP server of choice for such a situation: It is light-weight, and as it relies on system features (namely PAM) for user authentication, it can be considered quite secure in regard to user management – as opposed to FTP servers that feature their own authentication layer. Vsftpd can, as most FTP servers, chroot users into their home directories, meaning they cannot access other parts of the server below their home directory.

In order to create a user account which can log in via FTP, but not SSH, you can use the following (as root):

useradd -d /path/to/website/document/root/ -s $(which nologin) username
passwd username

You can also switch the user’s shell later, if the account already exists:

usermod -s $(which nologin) username

The important thing is that the output of which nologin is a path to the nologin tool, which simply tells the authentication layer that it must not open an interactive shell, but issue an error and return a error code instead.

If you experience that a user gets an error from vsftpd if the shell is a normal interactive shell like /bin/bash, but they cannot log in if the shell is something like /usr/sbin/nologin, you must check if the correct path to the nologin tool is included in /etc/shells. If it’s not, you must add it here.

Now your users can enjoy the full comfort of an FTP server, and you don’t have to be afraid that their accounts can be misused to get shell access and snoop around on your server.

March 25th, 2011 at 12:03 pm

Bullshit versioning

Firefox 4 is great, no doubt.

However, one thing Firefox should definitely not take from Google is the versioning scheme: Mozilla promised to release four more major versions of Firefox in 2011.

Real vs. bullshit versioning

Why is this bad? Well, it’s not bad, but stupid. The most common technical software versioning schema is based on sequence based identifiers. A figure like 3.6.13 tells us something like: This is the third major version of this software’s architecture, there have been six minor versions with larger API changes within this major version, and this is the thirteenth update of the sixths minor version.

If you release version 3.6.17, it means there have been internal changes, not or barely visible to end users or third party developers (like plugin authors). If you release 3.7, it means that end users may experience smaller differences, and some plugin developers must adapt their code. If you release version 4, it means for end users that you will likely have a new look’n'feel – for third party developers it means that each of them must make sure that their addons still work with that release. Therefore, it’s a good idea for vendors with a vivid third party community to release preview versions like alphas, betas and RCs early and frequently.

So, a major version usually indicates a completely new software architecture – at least if you use versioning for technical and not for marketing reasons. So either Mozilla knows now that they will overthrow the entire architecture of Firefox four times in the current year. Or they move from real versioning to bullshit versioning, the way Google and Opera do it.

Why does marketing get to dictate the version numbers?

The question is: Why do they do this? In my opinion, there’s one large, yet two-fold problem:

  • 90 percent of desktop users are still left with an operating system that does not provide a sophisticated package management, and
  • the same 90 percent, or even more, are trained that you either pay for a new version or you get only bugfixes (if you’re lucky).

The combination of these problems has trained users to be unconcerned in regard to updates: If the version number doesn’t indicate that this release is nothing less than a revolution, it’s not worth taking the hassle of uninstalling the old one and installing the new one.

A trend?

Let’s hope that other projects don’t get inspired be such a stupid versioning policy. However, I’m not afraid that the lot of open source projects will feel the itch to switch to such a stupid versioning schema, because their target audience are not the people who decide in favour of a software because of the higher version number. The opposite is true: Smaller projects understand the benefit of releasing small increments very often, because this is the way to get a “flow” of attention and participation.

But, for example, I’m courious how this will affect the market of office applications, especially OpenOffice vs. LibreOffice. Will one weapon in their battle be the struggle for the higher version number?

March 25th, 2011 at 11:27 am

Firefor 4: Definitely faster

Wow, I just installed Firefox 4 – and it’s definetly much, much, much faster than my last 3.6.x install. In Google Maps, the tiles are loaded almost instantly. Other webpages I have visited so far have also a much better responsiveness.

The user interface of the new Firefox has been inspired a lot by Google’s Chrome/Chromium. For example, when you hover a link with your mouse, the URL is not shown as tooltip, but in the left bottom corner of the browser. This may seem irritating, if you usually like to know where you’re going next and have to go to a totally different area of your screen, and back. But it’s helpful for “rich” applications who want to display their own tooltips and other information in the context of the pointer.

The upper area of the the browser window looks cleaner, too: There are no more navigation buttons except back/forward. The home button has disappeared, which also makes sense: I guess that the majority of users wouldn’t even know what website is behind that button, because they have many favourites. The stop/reload button is now part of the address bar. I like that too, but only as the stop button is red while loading a page. It is important to give users the ability to stop the loading as soon as possible if they see that they’re on the wrong webpage.

All in all: The first impression of Firefox 4 is very great: Fast browsing and a modern UI.

March 15th, 2011 at 7:28 pm

Brückentechnologie?

Nicht, dass ich bisher an die Unbedenklichkeit der Kernkraft und die blumige Propaganda der Atomlobby geglaubt hätte. Aber was mir momentan besonders – in Bezug auf die deutschen Energiedebatten – auffällt: Plötzlich werden einfach so drei bis sieben Kernkraftwerke abgeschaltet. Schätzungsweise müssten die betreffenden Kraftwerke einen zweistelligen Prozentsatz des deutschen Energiebedarfs decken.

Aber wie kann das sein, dass man diese Kraftwerke einfach abschalten kann? Hieß es nicht immer, die Kraftwerke seien eine unverzichtbare „Brückentechnologie“? Waren die Kraftwerke nicht notwendig um die Grundversorgung gegenüber den ach so volatilen Erneuerbaren Energien sicherzustellen? Gab es nicht Propaganda-Artikel, die behaupteten, dass deutsche und europäische Stromnetz würden langsam an die Belastbarkeitsgrenze kommen, wenn noch mehr Windenergie eingespeist würde?

Wenn man problemlos sofort fünf Kraftwerke abschalten kann, sollte es doch eigentlich kein Problem sein, innerhalb weniger Jahre alle Kraftwerke abzuschalten? Gut, das wird natürlich nicht ganz so einfach; man kann nicht einfach die Anzahl der Windparks und Gezeitenkraftwerke vervielfachen. Aber die Notwendigkeit eines jahrzehntelangen Weiterbetriebes von Atomkraftwerken hat sich nunmehr erübrigt.

March 10th, 2011 at 11:08 pm

Batch processing files with YUI Compressor

The YUI Compressor is a phenomenal tool to minimize (and obfuscate, by the way) CSS and JavaScript code.

Here’s a little bash script that will batch-process all JS and CSS files in your project, while preserving a source copy of that file.

#!/bin/bash
 
JAVA="$(which java)"
BUILDDIR="$(pwd)"
YUIJAR="/path/to/yuicompressor-x.x.x.jar"
 
 
echo "Compressing JS and CSS:"
 
for TYPE in js css
do
	for FILENAME in $(find "$BUILDDIR" -iname "*.$TYPE" | sed -e "s|\.$TYPE$||g")
	do
		echo -n "compressing $FILENAME.$TYPE ... "
 
		mv "$FILENAME.$TYPE" "$FILENAME.src.$TYPE"
		$JAVA -jar $YUIJAR  --charset utf-8 --type "$TYPE" "$FILENAME.src.$TYPE" > "$FILENAME.$TYPE"
 
		if [ "$?" == '0' ]; then
			echo "success."
		else
			cp "$FILENAME.src.$TYPE" "$FILENAME.$TYPE"
			echo "ERROR: failed, using original."
		fi
	done
done
 
echo "done."

Note: You will usually first copy your application source to some sort of build target, and then apply this script. Elsewise, you will have to revert the actions of that script when you continue editing your code.

February 20th, 2011 at 11:16 am

Concurrency in a Bash script

How can you have concurrent “threads” in a Bash script, and at the same time have a flow control?

My problem was that I wanted to trigger database backups on remote servers via SSH. Not one after another, but at the same time.

Of course, “concurrency” itself is nothing special, you can background tasks and wait for all of them to finish.

# start two processes in the background and wait until the last one finishes
(sleep 4 ; echo 'done 1') & (sleep 2; echo 'done 2') & wait; echo "all done"

But there are a few problems:

  • The script can’t do anything until both tasks are finished,
  • You can not intervene if a task takes too long or goes crazy otherwise.

But this can be done within a shell script, completely without using wait:

#!/bin/bash
 
 
### config
 
# after $TIMEOUT seconds, the script will definitely abort
TIMEOUT=6
 
# check all $CYCLE seconds (increase, if checks are resource-greedy)
CYCLE=1
 
 
 
### program
 
ts()
{
	echo -n "$(date +%s)"
}
 
thread1()
{
	(sleep 4; echo "thread 1 finished") & PID_1=$!
}
 
thread2()
{
	(sleep 2; echo "thread 2 finished") & PID_2=$!
}
 
 
START="$(ts)"
 
thread1
thread2
 
while [ 1 ];
do
	PID_1_DONE="$(ps -p $PID_1 >/dev/null; echo $?)"
	PID_2_DONE="$(ps -p $PID_2 >/dev/null; echo $?)"
 
	[[ "$PID_1_DONE" != "0" && "$PID_2_DONE" != "0" ]] && \
		echo "everything finished successfully." && \
		exit 0
 
	NOW="$(ts)"
	DIFF="$[ $NOW - $START ]"
 
	echo $DIFF
 
	if [[ $DIFF -gt $TIMEOUT ]]; then
		echo "something went wrong, shutting down."
		kill $PID_1 >/dev/null 2>&1 || kill -9 $PID_1 >/dev/null 2>&1
		kill $PID_2 >/dev/null 2>&1 || kill -9 $PID_2 >/dev/null 2>&1
		exit 1
	fi
 
	sleep $CYCLE
done

What do we see here?

  • Both threads are started from a dedicated function in a subshell, and return their process ID to the environment of the script.
  • A while loop will run continuously, until either both subshell processes are finished, or until a given timeout is reached.

Of course, instead of a timeout, you can also define other break/exit conditions.

March 10th, 2009 at 5:29 pm

JavaScript printf()

The printf function is known in many programming languages. It allows to replace a certain pattern in a string with other strings.

Here’s a little printf() for JavaScript. It can’t do very much; in fact, it only can replace the placeholder %s multiple times.

var printf = function(string)
{
	if (arguments.length < 2) { return string; }
		for (var i=1; i<arguments.length; i++)
		{ string = string.replace(/%s/, arguments[i]); }
	return string;
}

Although it’s not too advanced, it can be helpful if want to produce something as a pagination:

var pagination = '';
var numpages = 5;
 
for (var page=1; page<=numpages; page++)
{
	pagination += printf('Page %s of %s', page, numpages);
}
February 24th, 2009 at 8:48 pm

Implementing PHP functions in JavaScript

There are some handy functions in PHP you would sometimes like to have in JavaScript, too. Why not reimplement them? It’s not hard. Take for example in_array() and explode():

function explode(delim, val_to_split)
{
	return (val_to_split.indexOf(delim))
		? val_to_split.split(delim)
		: [val_to_split];
}
 
function in_array(needle, haystack)
{
	hlength = haystack.length;
	for (var i=0; i<length; i++)
		{ if (needle == haystack[i])
			{ return true; } }
	return false;
}

Hint: On many pages of PHP functions, there are comments which describe how to reimplement a function (e.g. PHP 4 implementations of PHP 5 functions) — in PHP though, but it’s easy to adapt them for JavaScript.

December 11th, 2008 at 10:28 am

Lightweight JSON fetcher (3rd party capable!)

JSON is a great data transfer format, especially for AJAX style applications (much better than XML for that purpose). Fetching JSON from your server is usually not a big deal these days, since all common browsers provide the XMLHttpRequest.

But: It can be a big problem to fetch data from a third party server, due to the Same Origin Policy. Imagine you want to provide a service where people simply need to include a JS file from your server to make great things happen on their own sites. Fetching JSON with your script via XMLHttpRequest (even from your own server) will not work.

However, there’s a great workaround, which I first saw at Jeffrey Sambells’ site. His solution is more generic, as it’s able to load any JavaScript (not only JSON data) dynamically. Also, it’s compatible with the XMLHttpRequest functions. I just needed something to fetch my JSON, and I don’t need all of the XMLHttpRequest. Yet I do want to use AJAX indicators and error handling. So I used his code and taylored a lightweight JSON fetcher. If compressed with a JavaScript packer, it is as tiny as 1.4 kB.

The client side

Here’s the code for the fetcher. Save it as request.js or something and have it loaded with your other JS. You can also insert into other JS files.

/*
	XssJsonFetch
	(C) 2008 Alex Günsche
	Available under the MIT license
 
	based on XssHttpRequest (c) 2005 Jeffrey Sambells <info@jeffreysambells.com>
	see info and terms of use: http://jeffreysambells.com/posts/2006/03/06/centralized_ajax_services/
*/
 
var XhrCount = 0;
var XhrWatchList = [];
reqjson = [];
 
var Xhr = function() {
	this.ins = ++XhrCount;
	this.u;
	this.so;
	this.w;
	this.wc = 0;
	this.to = 5;
	this.responseText = null;
	this.status = null;
	this.readyState = 0;
};
 
Xhr.prototype.onerror = function() {};
Xhr.prototype.onload = function() {};
 
Xhr.prototype.srs = function(a) {
	if (this.readyState < a || a == 0) {
		this.readyState = a;
 
		if (this.readyState == 2)
		{
			this.srs(3);
			if(typeof reqjson[this.ins] != 'undefined')
			{
				var re = reqjson[this.ins];
 
				// this is more secure, but sometimes fails on complex objects
				//re = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test( re.replace(/"(\\.|[^"\\])*"/g, ''))) && re || false;
 
				re = re || false;
 
				this.responseText = re;
				this.status = (re) ? 'ok' : 'string error';
   			}
			else
			{
				this.status = 'noresult';
				this.onerror();
			}
 
			this.so.parentNode.removeChild(this.so);
			reqjson = [];
			this.srs(4);
			this.onload();
		}
	}
};
 
Xhr.prototype.load = function(u)
{
	this.u = u;
	this.so = document.createElement('script');
	this.so.id = 'reqjson'+this.ins;
	this.so.charset = 'utf-8';
 
	this.srs(1);
	this.so.type = 'text/javascript';
	this.so.src = this.u + (this.u.indexOf('?') != -1 ? '&': '?') + 'jsonvar=reqjson' + this.ins;
	this.so = document.getElementsByTagName('head')[0].appendChild(this.so);
	XhrWatchList[this.ins] = this;
	this.w = setInterval('XhrWatchList[' + this.ins + '].wl()', 50);
};
 
Xhr.prototype.wl = function()
{
	this.wc++;
	if (typeof reqjson[this.ins] != 'undefined')
	{
		clearInterval(this.w);
		this.srs(2);
	}
	else if ( this.wc >= (this.to*20) )
	{
		clearInterval(this.w);
		this.status = 'timeout';
		this.onerror();
	}
};

The server side

Of course, you need a part on the server to generate the dynamic parts. In this example, we simply output the date, but it can be any data that is expressible with a JSON string (and that’s a lot). Save it as ajax.php in the same directory on the server.

<?php
	header("Expires: Mon, 01 Jan 2000 05:00:00 GMT");
	header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
	header("Cache-Control: no-cache, must-revalidate");
	header("Pragma: no-cache");
	header("Content-Type: text/javascript");
 
	// $results could as well be an array or any type of a scalar
	// if you use an array, be sure that the keys and structure match what your JS expects
	$results = date('d.m.Y H:i:s');
 
	$json = json_encode($results);
 
	$reqvar = preg_match('|^reqjson[0-9]+$|', $_GET['jsonvar'])
		? 'reqjson['.str_replace('reqjson', '', $_GET['jsonvar']).']'
		: 'reqjson[0]';
 
	echo "$reqvar = $json;";
?>

… and a demo

A little demo to show you the integration into your own project. Save it as demo.html in the same directory as the other two, then load it in your browser.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	<script type="text/javascript" src="request.js"></script>
	<style type='text/css'>
		#main { border: 1px solid #888; padding: 10px; margin: 50px auto; width: 30em; }
		#dynfield { color: #090; }
		#button { border: 1px outset #888; padding: 3px; background: #eee; cursor: pointer; }
	</style>
	<script type='text/javascript'>/* <![CDATA[ */
	window.onload = function()
	{
		var $ = function(el) { return document.getElementById(el); };
 
		// the event to trigger the request
		$('button').onclick = function()
		{
			// if you use an indicator, make it appear here
 
			// any URL, relative or absolute, with parameters or without, even from a third-party server
			var url = "ajax.php";
 
			var http = new Xhr;
			http.load(url);
 
			http.onload = function()
			{
				// hide your indicator
 
				// here happens everything you need to perform with your fetched JSON
				var serverdate = http.responseText;
				if (serverdate) { $('dynfield').firstChild.data = serverdate; }
			};
 
			http.onerror = function() {
				// some error handling (and hide indicator)
				alert('Error: ' + http.status);
			};
		};
	};
	/* ]]> */</script>
	<title>AJAX demo</title>
</head>
<body>
	<div id='main'>
		<p>The server date is: <strong id="dynfield"> </strong></p>
		<p><span id="button">retrieve</span></p>
	</div>
</body>
</html>
November 30th, 2008 at 5:18 pm

eee-control for Gentoo

Eee-control is a nice tool to control various features of an EeePC, such as certain hardware (Bluetooth, WLAN, etc.) as well as power management. Installing this package on a Gentoo system takes some work, but I’ve created an ebuild that takes care of the most. Please have a look at the dedicated page which contains a link to the ebuild as well as full documentation on how to get eee-control running on Gentoo.