nemrod.se Various guides and experiments

Battery level logger


This is a shell script I wrote on and for a very old laptop (old as in it had a P1 processor) I had. I got the laptop and had heard that the battery was in a bad condition, but after using it for a bit I thought it wasn’t that shabby. To put it to the test I had two choices. Sit by the computer and time it, or write a shell script to log the battery level as it went. I obviously went with the shell script.

It has two modes, analyze mode and log mode. They’re called with ‘utp -a FILE’ and ‘utp -l FILE’ respectively. The log mode writes the time and the battery level, separated by a comma, to the specified file, sleeps for a second, and repeats. Here is more exactly what it writes:

echo "$(date +%T), $(apm | cut -d' ' -f5)" | tee -a $OPTARG

The analyze mode echoes the percent in tens (100-91%, 90-81% etc) and how long those percent took and finally a summary, from what percent it started from to at what percent the last logging took place and how long the whole thing took. Here is an example output (with a faked file so it doesn’t make much sense):

Percent:        Time:
100 - 91:       0m10s
90 - 81:        0m10s
80 - 71:        0m10s
70 - 61:        0m10s
60 - 51:        0m10s
50 - 41:        0m10s
40 - 31:        0m10s
30 - 21:        0m10s
20 - 11:        0m10s
10 - 01:        0m10s
The script was logging from 100% to 1% in 1 minutes.

It’s free as in free speech (and free beer) so you have no restrictions regarding usage or modifications to it, but it’s always nice to hear from anyone using what you make so feel free to post a comment or send me a mail. Any bug fixes, improvements or other additions would be neat to get so I can host the new version here. :)

utp shell script


Posted in Projects | Leave a comment

Password Generator


This is an extension for pure random password generation. You set a length between 5 and 20 characters, if you want it to contain upper-case, lower-case, numbers and special characters and click generate. Since I’m into the habit of wanting passwords that look good I’ve made it so you can choose to generate between 1 and 5 passwords in one go to make it easier to get those.

Now simply choose the prettiest of the generated passwords and you’re done! ;)

Extension information:

Extension:
Password Generator
Latest version:
v0.2
Download link:
Password Generator on the Chrome Web Store
Description:
Allows you to generate customisable secure passwords on the fly.
Browser compatibility:
Chrome build with browser action support
Features:
  • Password length between 5 and 20 characters
  • Generate between 1 and 5 passwords at a time
  • Choose to include or exclude uppercase characters, lowercase characters, numbers and special characters
  • Possibility to choose between 3 different themes, or make your own
Screenshots:
Password Generator dark theme

The extension open with the dark theme set.

Revision history:

Version 0.1 [05:13, 2009-12-13]:
Initial release.
Version 0.2 [11:48, 2009-12-20]:
Theme support, 3 themes to choose from.

Posted in Chrome Extensions | Leave a comment

Beautiful URLs with mod_rewrite and PHP


If you’re reading this you’re probably already well aware of the benefits of good URLs – usability, accessibility and for search engine optimization purposes. In this guide I’m going to explain how I went from example.com/?p=4&s=12 to nemrod.se/chrome-extensions/pagerank-display using mod_rewrite, PHP and MySQL in the background.

Necessary back-end changes

If your URLs contain the ID of things instead of the titles, you’re gonna have to do a lot more changes than just mod_rewriting. I don’t know how others have solved it, but the way I did it was by adding an extra field in my database called sanitized_title or sanitized_name etc. depending on what it is. I then wrote a quick function to sanitize the wanted field when adding new posts, pages or whatever it may be and then add it to the database along with the rest of the data. This is what my function looks like:

function sanitize($str) {
	$str = strtolower($str);
	$str = strip_tags($str);

	$str = preg_replace('/[^a-z0-9]+/i', ' ', $str);

	$str = preg_replace('/\s+/i', ' ', $str);
	$str = trim($str);

	$str = str_replace(' ', '-', $str);
	return $str;
}

It first converts the whole string to lower-case and strips it from HTML tags. It then uses regular expression replace to replace everything not a letter or a number with spaces. It then replaces all whitespace with a single space (if the string had “bla – bla bla” that would be three spaces – now it’s one) and trims whitespace from the beginning and end of the string. Lastly it replaces the spaces with dashes before returning the string.

If your language has got any additional characters, such as the Swedish å, ä and ö you’re going to have to add them like this, preferably somewhere near the end:

	$str = str_replace('å', 'a', $str);
	$str = str_replace('ä', 'a', $str);
	$str = str_replace('ö', 'o', $str);

Modify the administration interface to add the sanitized string to the database, like this for example:

$title = mysql_real_escape_string($_POST['title']);
$sanitized_title = sanitize($_POST['title']);
mysql_query('INSERT INTO post (title, sanitized_title) VALUES (\'' . $title . '\', \'' . $sanitized_title . '\')');

If you’ve already got a large database without the sanitized field I suggest writing a PHP script that simply loops through all the records in the database, calls the sanitize function on the title, and updates the post. Something like this:

$result = mysql_query('SELECT * FROM post');
while($row = mysql_fetch_array($result))
	mysql_query('UPDATE post SET sanitized_title=' . sanitize($row['title']) . ' WHERE id=' . $row['id']);

Now all you have to do is change all the occurences of the ID in the code to the sanitized title. It’s usually pretty easy since it’s generated from the database, all you have to do is echo the sanitized_title column instead of the id one! After doing so your site should have URLs similar to example.com/index.php?p=chrome-extensions&s=pagerank-display. It’s not quite where we want to go, but the hardest part is over!

mod_rewrite and .htaccess

Now that we’re using the sanitized names in the PHP code, the rest is a breeze. All we have to do is make the URLs look pretty for the users with mod_rewrite, modify the PHP code to match, and we’re done!

The way I used to do my mod_rewrite was using a prefix. In other words, I rewrote the URLs so they looked like example.com/prefix/chrome-extensions/pagerank-display. The reason is because I didn’t know how to be able to go to other folders on the server, they would all be rewritten if I didn’t have that prefix! After getting the mission to rewrite the URLs on another site, the SEO (search engine optimisation) company I work at, I thought that there has to be a better way than using a prefix and went investigating. I remembered that WordPress had pretty URLs, and went looking in their .htaccess.

What I found was a pretty obvious solution, but something I hadn’t known could be done with .htaccess files before. What it does is check if the file or folder you’re trying to go to exists, and if not, it sends you to index.php. No more prefix yet it’s still possible to get to other files and folders on the server! :)

The code you put in .htaccess looks like this:

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php/$i [L,QSA]

What the lines do:

  • Activates the rewrite engine
  • Sets the rewrite base, i.e. where we’re doing the rewriting
  • Checks if the requested URL is a real file
  • Checks if the requested URL is a real folder
  • If it’s not, we attach the requested URL (the part after the domain name) to index.php, which then further processes the data

Now we’ve successfully sent the pretty URLs to index.php, now we just have to process it and change the links to match!

The PHP processing

If you go to nemrod.se/chrome-extensions/pagerank-display and chrome-extensions/pagerank-display isn’t a real file or folder the real URL after rewriting will be index.php/chrome-extensions/pagerank-display. The way I process this in PHP is by exploding the REQUEST_URI server variable over / and then setting the appropiate variables to their values. For nemrod.se, for example, the first variable is the page, and the second is the name of a post. This is how my code looks:

$uri = explode('/', $_SERVER['REQUEST_URI']);
if(sizeof($uri) > 1 && !empty($uri[1]))
	$page = $uri[1];
if(sizeof($uri) > 2 && !empty($uri[2]))
	$post = $uri[2];

If I echo the $page and $post variables after going to the above URL, they’ll be chrome-extensions and pagerank-display respectively. The rest is just your ordinary menu generation and stuff, if(!isset($page)) set $page to the first page in the menu generating loop, and so on.

No error 404?!

Yes, that’s right. If the file doesn’t exist you’ll be sent to index.php to do all the processing, so you won’t be getting any error 404! To fix this I added some PHP code to make sure the server returned a 404 if the URL really is a real 404. I’m sure there are a lot of ways to do it, but in my case I just set a variable to true ($e404 = true;) and if the page was really found when generating the menu etc. I simply set it to false. After the check is done I have an if statement like this:

if($e404)
	header('HTTP/1.0 404 Not Found');

Where the content of the page is supposed to be displayed I also have an if, but instead of sending another header I simply inform the visitor that the page he tried to access doesn’t exist. This also makes for an error 404 with easy access to your site, since it’ll be displayed right in the middle of it, with the menu accessible and everything. :)

A tip:

If you’ve got URLs with a lot of traffic you might want to do a 301 redirect to your new, pretty, URLs. One of my most visited URLs back when I used prefixes was nemrod.se/n/chrome_extensions/pagerank_display_v1.9. So as to not lose all that traffic this (along with some other URLs) was what I added to my .htaccess:

RewriteRule ^n/chrome_extensions/pagerank_display_v1.9[\/]?$ http://nemrod.se/chrome-extensions/pagerank-display [R=301,L]

There are more automated ways to do it, if you’re already using URLs like index.php?page=name&post=title you can use this, for example (untested):

RewriteRule ^index.php?page=(.*?)$ http://example.com/$1 [R=301,L]
RewriteRule ^index.php?page=(.*?)&post=(.*?)$ http://example.com/$1/$2 [R=301,L]

Posted in Guides | 9 Comments

Sending mail from outside your network


After having set up a mail server for the company I work at (I’m a technician at a SEO, PPC and web marketing company) we quickly came across a problem. One of our employees tried to send a mail through our server from outside our network, which resulted in an error.

The first problem I figured was because pretty much all ISPs in Sweden block port 25 (SMTP). It was quickly solved by routing incoming port 587 to internal port 25 on our server. Yup, it solved the problem. But only the first problem, because after we could actually connect to the server from outside the network we got another problem. An authentication problem. Duh, I should’ve known.

It’s supposed to block attempts to spam through our server from outside but I never considered the possibility that it’ll block legitimate mail as well. What I had to do was obviously set up some kind of authentication, and the way to do it is SASL. I use Dovecot on the server, so Dovecot SASL is what I’ll be using in this guide. If you followed my guide to Postfix+Dovecot your server should be compiled with support for it already.

First of all we need to enable it in Postfix. To do that simply add the following lines to your Postfix configuration (main.cf) some place appropriate:
broken_sasl_auth_clients = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes

You will also want to add permit_sasl_authenticated somewhere in the “smtpd_recipient_restrictions” list.

Next up is Dovecot, so open up your dovecot.conf. You can start by adding “login” to the mechanisms row, so it’ll look like this:
mechanisms = plain login

After that change the client path row to:
path = /var/spool/postfix/private/auth
I also changed both user and group to postfix instead of dovecot.

That should be all you need to do to enable SASL for your mail server, now all that’s left is to test it. Run the following four commands to completely stop and start the mail server:
postfix stop
pkill -9 dovecot
postfix start
dovecot

To test the SASL authentication the first thing we have to do is to base64-encode our username and password so we can send it to the server. Normally the mail client does this, but since we’re telneting we have to do it ourselves. Run the following command in the terminal:
perl -MMIME::Base64 -e ‘print encode_base64(“\000user\@domain.tld\000password”)’
AHVzZXJAZG9tYWluLnRsZABwYXNzd29yZA==
The string of random characters it returned is the base64-encoded version of “\0user@domain.tld\0password.”

Now let’s try authenticating ourselves when sending a mail through telnet!
telnet localhost 25
Trying 127.0.0.1…
Connected to localhost.
Escape character is ‘^]’.
220 server.domain.tld ESMTP Postfix

AUTH PLAIN AHVzZXJAZG9tYWluLnRsZABwYXNzd29yZA==
235 2.7.0 Authentication successful
From here on send a mail as usual, with “MAIL FROM”, “RCPT TO” and “DATA.”

That’s all there was to it – now you, like me and my company’s employees, should be able to send mail from outside the local network. ;)


Posted in Guides | Leave a comment

nmailadm – web interface for mail server administration


This is a mail administration interface that I made after I had set up my own Postfix+Dovecot+MySQL mail server. It’s a very rudimentary interface but it can add virtual domains, aliases and mailboxes – pretty much everything you need. That is, unless you’re interested in vacation responders and things like that.

It was made to work with my own mail database that I created, for specifications of that you can go to the guides section and read the mail server guide. It should be pretty easy for anyone familiar with PHP and MySQL to edit the source to work with a different database if you’ve got one and don’t want to change it.

It’s free as in free speech so you have no obligations regarding usage or modifications to it, but it’s always nice to hear from anyone using what you make so feel free to post a comment or send me a mail. Any bug fixes, improvements or other additions would be neat to get so I can host the new version here. :)

nmailadm v0.1


Posted in Projects | Leave a comment