downloadI ran into a problem with Apache on Centos 6. For some time, I was the only person who had access to this particular machine so permissions were not a problem. However, now that somebody else is taking care of the website hosted there, they had troubles editing files that were uploaded via website and owned by apache. So I added the user to the apache group and put this line:

umask 002

into file:

/etc/sysconfig/httpd

That way, any file created by apache user was by default writable by the apache group so the given user would be able to work with those files. When I tried it out, however, it didn’t work, the user was not able to modify those files, to my frustration. Now, I was left with two options, either pull my hair off, or modify the httpd init script, neither of them much to my liking. Eventually, I found out that the solution was pretty easy – the PHP upload script was explicitly setting the permissions to 644 so members of apache group were not able to modify the file. When I modified the application and its chmod command, everything worked like a charm.

Update 17. 4. 2017

I came to face the same situation with nginx on Centos 7. The issue was basically the same, only the file where umask directive had to be placed to was different:

/lib/systemd/php-fpm.service

and umask had to be placed into the [Service] section:

[Service]
#other stuff here
UMask=0002
Tagged with: , , , ,

A funny thing happened to me the other day. Someone brought me a 4-bay Synology NAS which had been hit by ransomware called Synolocker. The usual scenario – the NAS was exposed to the internet, maybe not updated as regularly as it should have been, and eventually targeted by ransomware. The bright side was that the owner kept an offline copy of the data that was stored on the NAS, so no big harm done. I was only asked to restore the NAS to the original settings to get rid of the nasty piece of software and make the NAS usable again.

RAID 5

RAID 5

synolocker

The funny fact was that once I restored the operating system (thus removing the infected system) and was about to go and blank the encrypted volumes, I was surprised to find out that the data was still there, perfectly intact. This particular piece of ransomware was so “lazy” that it didn’t even bother to actually encrypt the data. It simply demanded ransom and waited for anyone who would panic enough to go and pay up.

Tagged with: ,

Yet another game from the 90’s that I wanted to tick off as done. Here are a few screenshots:

Tagged with: ,

nicubunu-RPG-map-symbols-stone-bridge-100pxI got a machine on which I wanted to try Centos 7 and KVM virtualization. As usual, I had to search for how to do a network bridge as it’s been quite long since I did it last time (on Centos 6). So these are the basic steps. First, dont’t forget to install bridge-utils while installing the KVM-related packages:

yum install qemu-kvm libvirt virt-install bridge-utils ifconfig bind-utils

Now, this was the default config file for the network interface:

# cat /etc/sysconfig/network-scripts/ifcfg-enp3s1 
TYPE=Ethernet
BOOTPROTO=dhcp
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
NAME=enp3s1
UUID=5435015d-7174-414a-9fa3-9b5ec715a054
DEVICE=enp3s1
ONBOOT=yes

I had to change it to point to a bridge interface called bridge0.

# cat /etc/sysconfig/network-scripts/ifcfg-enp3s1 
DEVICE="enp3s1"
ONBOOT="yes"
NM_CONTROLLED="no"
#TYPE=Ethernet
BRIDGE=bridge0
BOOTPROTO=static

And this is where the new network configuration goes. It’s probably worth mentioning that it’s been changed from DHPC to a static IP address:

# cat /etc/sysconfig/network-scripts/ifcfg-bridge0
DEVICE="bridge0"
ONBOOT="yes"
TYPE=Bridge
BOOTPROTO=static
IPADDR=192.168.0.103
NETMASK=255.255.255.0

and also that the GATEWAY has been moved to /etc/sysconfig/network.

# cat /etc/sysconfig/network
# Created by anaconda
GATEWAY=192.168.2.1

After

service network restart

you should be able to connect KVM VMs directly to the LAN.

Tagged with: , , ,

At home, I’ve been using rolling release of Debian for my desktop for quite some time. The good thing about it is that years go by and you need not worry about the end of life of this or that particular release. Sometimes, things can go awry, of course, but that happens quite rarely and running apt-get dist-upgrade usually takes care of the problem. Yesterday, however, I ran into a funny error message:

Errors were encountered while processing:
 systemd

I have to admit that as far as the current flamewars regarding systemd are concerned, I don’t feel my insight is deep enough to allow me to contribute to those discussions one way or the other, but in the light of the current spiteful debate, it was a really funny error message 🙂

screenshot-systemd

Tagged with: ,

kids helped a lot

kids helped a lot

I’ve been tinkering with my computers ever since the days of ZX Spectrum, more or less. In the last eight years or so, however, people would come to me with their broken laptops and computers every now and then. It didn’t happen too often to become a nuisance; instead, it was a welcome distraction from my regular daily tasks (with the exception, maybe, of the time when I had seven laptops at my office at once 🙂 ).

Read more ›

Tagged with:

120px-Official_gnu.svgGettext is a great way to localize and internationalize (simply put, to translate) your (web)applications. It’s especially useful when you’re building a multi-language application because you can separate the code from the translation process effectively.

  1. all strings that need to get translated have to be wrapped in _() function in the source code files:

    echo _('text to be translated');
  2. cd to the project directory and run in bash (this will go through all the php files in the current working directory):

    xgettext --from-code=UTF-8 -d projectname *.php
  3. to search for all php files in the project directory recursively, try this:

    find . -iname "*.php" | xargs xgettext --from-code=UTF-8 -d projectname

    If you need to omit a particular directory, use inverted grep like this:

     find . -iname "*.php" | grep -v "/omitted_directory/" | xargs xgettext --from-code=UTF-8 -d projectname
  4. The above mentioned commands will output a file named projectname.po, which can be translated using Poedit or Pootle. Poedit will generate binary file projectname.mo on save.
  5. To use this binary file, create another directory in your project folder (I’m using cz_CS locale identifier)

    ./translation/cs_CZ/LC_MESSAGES

    and copy the .mo file there.

  6. In your application, use the following:

    $languange = 'cs_CZ';
    putenv("LANG=$language");
    setlocale(LC_ALL, $language); 
    bindtextdomain("projectname", "./translation/"); 
    textdomain("projectname");
    bind_textdomain_codeset("projectname", 'UTF-8');

This will load the .mo file with translated strings and replace all the _() wrapped strings in there.

Tagged with: , ,

Some time ago, I started playing Lands of Lore. Then I took a short break (for about five years 🙂 ) and now I happened to stumble across the saved games so I decided to go on again this Xmas. Here come a few screenshots from the final stages of the game:

Tagged with: , ,

small_hAlthough jabber is my preferred IM protocol, sometimes I have to communicate with people who, for some reason, only use Skype. On Debian, that can be quite a problem, supposing you are not particularly keen on weed infestation of your system. One way to get Skype was to start a virtual machine with another operating system. That is a rather resource hungry solution for one application only, however. Last week I found a satisfactory solution – run Skype in a docker container. It was a double win as I finally discovered something to use docker for 🙂

The container keeps Skype away from my base operating system and at the same time it all takes less resources than a full VM. The fork of the original repo is here:
https://github.com/vex21/docker-skype

Funny things happen, though. Today, Microsoft announced they were going public with the web interface. Naturally, that is the best option they could provide.

Tagged with: ,

yii logoYii framework has a really nice CRUD generator that can speed up building back-end applications, which tend to be rather similar and therefore repetitive. If you prepare reasonable taxonomy of the underlying database tables, it also manages the page headers pretty well. If your table is called album, for instance, it will generate a page for editing albums with a header “Edit Album #1”, an index page called “List Albums” or the management page called “Manage Albums”. As you can see, it will even handle the plural forms. However, this works fine for English projects, but may not be desirable for other languages.

What I usually do is find the method called pluralize() in framework/gii/CCodeModel.php and basically disable the method by changing it like this:

public function pluralize($name)
	{
		return $name; # this disables the method no matter where it gets used
		$rules=array(
			'/(m)ove$/i' => '\1oves',
			'/(f)oot$/i' => '\1eet',
			'/(c)hild$/i' => '\1hildren',
			'/(h)uman$/i' => '\1umans',
			'/(m)an$/i' => '\1en',
			'/(s)taff$/i' => '\1taff',
			'/(t)ooth$/i' => '\1eeth',
			'/(p)erson$/i' => '\1eople',
			'/([m|l])ouse$/i' => '\1ice',
			'/(x|ch|ss|sh|us|as|is|os)$/i' => '\1es',
			'/([^aeiouy]|qu)y$/i' => '\1ies',
			'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
			'/(shea|lea|loa|thie)f$/i' => '\1ves',
			'/([ti])um$/i' => '\1a',
			'/(tomat|potat|ech|her|vet)o$/i' => '\1oes',
			'/(bu)s$/i' => '\1ses',
			'/(ax|test)is$/i' => '\1es',
			'/s$/' => 's',
		);
		foreach($rules as $rule=>$replacement)
		{
			if(preg_match($rule,$name))
				return preg_replace($rule,$replacement,$name);
		}
		return $name.'s';
	}

Another way of dealing with this is to remove the generated names based on the table names completely. You can edit the files like:

framework/gii/generators/crud/templates/default/admin.php
framework/gii/generators/crud/templates/default/create.php
framework/gii/generators/crud/templates/default/update.php
etc.

prior to making use of the CRUD generator, and change the H1 headers and the labels to something more generic (i.e. simply “Edit”, “View”, “Update row #1”).

Tagged with: , ,
Top