I recently installed Audio Recorder which has a very cool feature: to automatically start recording Skype calls. So that I don't waste time or forget about it, I set Audio Recorder to automatically start when I log in. There is one downside: when Audio Recorder starts, it automatically starts Skype, which starts with its last online status. This is very annoying, as it shows me online in Skype right away I log in Ubuntu, even if I don't want to be online or I don't want to be visible.
After googleing a bit, I run into this Skype forum thread of users complaining about this feature (or lack of feature to set startup status). One of the posts explains how to manually change the SQLite database that Skype uses for accounts. I tested that and worked great so in order to integrate this into Audio Recorder, I wrote the following bash script located saved as ~/bin/skype:
#!/bin/bash
sqlite3 ~/.Skype/YOURSKYPEIDHERE/main.db 'UPDATE Accounts SET set_availability=6'
/usr/bin/skype $*
Note that ~/bin/skype has to be executable and ~/bin/ has to come in $PATH before /usr/bin for this to work.
A mix of how-tos, notes, and gotchas that I might need again sometime in the future.
Wednesday, July 2, 2014
Thursday, April 17, 2014
Udev tricks - How to toggle built-in wi-fi on/off
My Toshiba Satellite laptop has a RTL8192CE built-in wifi, which is a total joke. It only works if I'm within a few meters range of the router and without any big obstacles between. For example, if I'm in my home office I can't even use the router that is in the next room. All other devices in our house can connect and mark it as strong signal. If by any luck my laptop manages to connect, the connection is unusable, with network speeds of less than 1Mb/s and most of the packages failing their CRC checksum.
I googled and test various solutions. None of them worked. I found many others which have same problem. Different OSes, different laptop models, same card type, same problem. After loosing (in total) more than 3 days on this, I decided it's just not worth it and bought and Atheros external USB wifi dongle (model TL-WN721N). It works perfectly and without any problems.
The problem I had now is that when I plug the USB wifi, Network Manager in Ubuntu clutters its menu and dialog boxes with various options to select which wifi card to use. For example, when I want to connect to a hidden network, it asked me to select which card to use for connection. It also used to keep trying to reconnect to the home network on the faulty card (but that I fixed by deleting Wi-fi network settings). This is annoying and overall makes me waste a lot of time. Therefore, I read udev man pages to find out how can I disable the built-in wifi whenever I plug in the USB one. Eventually I came up with these rules:
SUBSYSTEM=="net", ACTION=="add", ENV{INTERFACE}=="wlan1", RUN+="/sbin/rmmod rtl8192ce"
SUBSYSTEM=="net", ACTION=="remove", ENV{INTERFACE}=="wlan1", RUN+="/sbin/modprobe --quiet rtl8192ce"
I googled and test various solutions. None of them worked. I found many others which have same problem. Different OSes, different laptop models, same card type, same problem. After loosing (in total) more than 3 days on this, I decided it's just not worth it and bought and Atheros external USB wifi dongle (model TL-WN721N). It works perfectly and without any problems.
The problem I had now is that when I plug the USB wifi, Network Manager in Ubuntu clutters its menu and dialog boxes with various options to select which wifi card to use. For example, when I want to connect to a hidden network, it asked me to select which card to use for connection. It also used to keep trying to reconnect to the home network on the faulty card (but that I fixed by deleting Wi-fi network settings). This is annoying and overall makes me waste a lot of time. Therefore, I read udev man pages to find out how can I disable the built-in wifi whenever I plug in the USB one. Eventually I came up with these rules:
SUBSYSTEM=="net", ACTION=="add", ENV{INTERFACE}=="wlan1", RUN+="/sbin/rmmod rtl8192ce"
SUBSYSTEM=="net", ACTION=="remove", ENV{INTERFACE}=="wlan1", RUN+="/sbin/modprobe --quiet rtl8192ce"
The major time waster was ENV{INTERFACE}=="wlan1" because NAME=="wlan1" works on add event, but not on remove. I also lost some valueable time trying to get it work with INTERFACE=="wlan1", before I actually understood that INTERFACE is not a property.
These rules go under: /etc/udev/rules.d/99-disable-builtin-wlan.rules.
Later on, I decided to do something similar for the built-in soundcard (for similar reasons). It took me some time to find out the proper commands to disabled it. First I tried to remove its modules (like i did with the wifi), but that option failed because they were always in use by PulseAudio. So I started to look into PulseAudio options. I found the pactl (and pacmd) which seemed to do what I needed. It took another 30 minutes of testing to find out how to use them for this task and another 15 minutes to find out that they don't work as root, but should be run as the current user. After that, writing the udev rules was a piece of cake:
SUBSYSTEM=="sound", ACTION=="add", ENV{ID_TYPE}=="audio", RUN+="/bin/su abautu -c '/usr/bin/pactl set-card-profile alsa_card.pci-0000_00_1b.0 off'"
SUBSYSTEM=="sound", ACTION=="remove", ENV{ID_TYPE}=="audio", RUN+="/bin/su abautu -c '/usr/bin/pactl set-card-profile alsa_card.pci-0000_00_1b.0 output:analog-stereo+input:analog-stereo'"
These rules go under: /etc/udev/rules.d/99-disable-builtin-wlan.rules.
Later on, I decided to do something similar for the built-in soundcard (for similar reasons). It took me some time to find out the proper commands to disabled it. First I tried to remove its modules (like i did with the wifi), but that option failed because they were always in use by PulseAudio. So I started to look into PulseAudio options. I found the pactl (and pacmd) which seemed to do what I needed. It took another 30 minutes of testing to find out how to use them for this task and another 15 minutes to find out that they don't work as root, but should be run as the current user. After that, writing the udev rules was a piece of cake:
SUBSYSTEM=="sound", ACTION=="add", ENV{ID_TYPE}=="audio", RUN+="/bin/su abautu -c '/usr/bin/pactl set-card-profile alsa_card.pci-0000_00_1b.0 off'"
SUBSYSTEM=="sound", ACTION=="remove", ENV{ID_TYPE}=="audio", RUN+="/bin/su abautu -c '/usr/bin/pactl set-card-profile alsa_card.pci-0000_00_1b.0 output:analog-stereo+input:analog-stereo'"
Note that you need to replace "su abautu" with your own username or it won't work.
Thursday, January 30, 2014
How to create ASCII armored signatures/encrypted files with Seahorse plugin
Recently I played looked into various Linux (Ubuntu) software that can digitally sign documents. After testing various software (open source and proprietary) and various signature options, I decided that Ubuntu's Seahorse best fits my needs. After installing the seahorse-plugins package, I was thrilled with the results with respect to flexibility, ease of use, and end results.
Only one thing was bugging me: when signing (or encrypting) a file, the result file was in binary format. It worked fine, but I just felt that an ASCII armored file would be better (for me). I tried to find some UI option to change that, but I didn't. I googled for this feature, but found nothing interesting (except for requests/forum posts of other people asking about this feature). In the end, I decided to download the source code and see how it works. After 15 minutes of searching through code, I found out what I needed. It's really easy.
To create ASCII armored signatures/encrypted files with Seahorse plugin (in Nautilus) I followed these steps:
1. open gconf-editor
2. navigate to /desktop/pgp/ascii_armor
3. enable the ascii_armor option
Once I found out what the option name was, googleing exactly that got me to this page: https://wiki.gnome.org/Apps/Seahorse/SpecialGconfKeys
Only one thing was bugging me: when signing (or encrypting) a file, the result file was in binary format. It worked fine, but I just felt that an ASCII armored file would be better (for me). I tried to find some UI option to change that, but I didn't. I googled for this feature, but found nothing interesting (except for requests/forum posts of other people asking about this feature). In the end, I decided to download the source code and see how it works. After 15 minutes of searching through code, I found out what I needed. It's really easy.
To create ASCII armored signatures/encrypted files with Seahorse plugin (in Nautilus) I followed these steps:
1. open gconf-editor
2. navigate to /desktop/pgp/ascii_armor
3. enable the ascii_armor option
Once I found out what the option name was, googleing exactly that got me to this page: https://wiki.gnome.org/Apps/Seahorse/SpecialGconfKeys
Saturday, November 9, 2013
Openssl - setting up a custom CA certificate, requesting and approving certificates with Subject Alternative Name (SAN)
I spent last couple of hours reading web resources, man pages and config files to get what I need: a custom CA setup that allows me to sign certificate request which include Subject Alternative Name (SAN) extensions.
First I edited /etc/ssl/openssl.cnf. In the CA_default section:
- I changed dir = ./demoCA to dir = /etc/ssl/demoCA (this is so that I can run openssl ca from any directory without entering full paths)
- I uncommented copy_extensions = copy (this is required so that I can include in certificates SANs from their certificate requests)
In the req section:
- I uncommented req_extensions = v3_req
In the v3_req section
- I added subjectAltName = $ENV::subjectAltName so that I can pass SAN content via environmental variables (I found this trick somewhere on the internet, in order to avoid writing them in config files).
Finally I ran following commands to create the required files:
Setup custom CA certificate
I started with the Ubuntu certificates guide. It explains how to setup the custom CA. I used the instructions in there, but I decided to use the default Ubuntu CA setup (which used /etc/ssl/demoCA directory).First I edited /etc/ssl/openssl.cnf. In the CA_default section:
- I changed dir = ./demoCA to dir = /etc/ssl/demoCA (this is so that I can run openssl ca from any directory without entering full paths)
- I uncommented copy_extensions = copy (this is required so that I can include in certificates SANs from their certificate requests)
In the req section:
- I uncommented req_extensions = v3_req
In the v3_req section
- I added subjectAltName = $ENV::subjectAltName so that I can pass SAN content via environmental variables (I found this trick somewhere on the internet, in order to avoid writing them in config files).
Finally I ran following commands to create the required files:
sudo mkdir /etc/ssl/demoCA cd /etc/ssl/demoCA sudo sh -c "echo '01' > serial" sudo touch index.txt sudo mkdir private newcerts sudo chown 700 private newcerts sudo openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 3650 -newkey rsa:2048
Create a certificate with SAN
As indicated in the Ubuntu docs (and lots of other places):
openssl genrsa -des3 -out server.key 2048 openssl rsa -in server.key -out server.key.insecure mv server.key server.key.secure mv server.key.insecure server.key env 'subjectAltName=DNS:testbox.local' openssl req -reqexts v3_req -new -key server.key -out server.csr openssl req -in server.csr -noout -text sudo env 'subjectAltName=DNS:testbox.local' openssl ca -in server.csr
The signed certificate will be saved in /etc/ssl/demoCA/newcerts/.
Saturday, July 6, 2013
Improving OpenVPN thoughput
I recently faced an unusual problem (for me): an OpenVPN connection going via TCP over a fast network, which had transfered speeds of less than 2KB/s. Although I tested some other options (compression on/off, UDP, etc), none of them proved significantly faster. Moreover, I has hoping to fix the problem with as few as possible changes to clients.
Some time ago, I red about optimizing OpenVPN over Gbit networks. That post covers optimizations related to CPU bottleneck (hardware SSL support, different ciphers, etc). This was certainly not the case for me, since boxes linked via OpenVPN were mostly idle. However, that post has a very brief and accurate explanation and statement about how OpenVPN works, i.e. the data flow between source and destination.
So based on that post, I decided to try mssfix 0 (ie. disable OpenVPN packet fragmenting and leave the kernel/driver do that) and to increase tun-mtu parameter to help test speed improvements. I increased it to 32000 and I got about 150KB/s speed, then to 48000 and I got about 250KB/s, then to 60000 and I got 300KB/s. I thought "what if ...?" and I raised it to 65500. Amazingly, I got average speeds of 1.25MB/s with top speeds above 2.5MB/s.
That was cool, but had one downside: the VPN connection become unstable, with the tun0 device disappearing from the server (probably because the process that managed it crashed).
Reading further in OpenVPN man page and other posts, I decided that I should try to use OpenVPN's mssfix feature. Default value is 1500, but OpenVPN automatically reduces that in order to allow for the SSL data overhead. I decided to be on the safe size and use mssfix 1440. Heuristically, I thought I should use a tun-mtu that is a multiple of that (to help split the data in even fully-filled packets). So I used tun-mtu 64800. With these two settings on, the server proved stable and average transfer speeds went to about 850KB/s (good enough for my needs).
I should not that these transfer speeds were obtained by applying the same settings:
Some time ago, I red about optimizing OpenVPN over Gbit networks. That post covers optimizations related to CPU bottleneck (hardware SSL support, different ciphers, etc). This was certainly not the case for me, since boxes linked via OpenVPN were mostly idle. However, that post has a very brief and accurate explanation and statement about how OpenVPN works, i.e. the data flow between source and destination.
So based on that post, I decided to try mssfix 0 (ie. disable OpenVPN packet fragmenting and leave the kernel/driver do that) and to increase tun-mtu parameter to help test speed improvements. I increased it to 32000 and I got about 150KB/s speed, then to 48000 and I got about 250KB/s, then to 60000 and I got 300KB/s. I thought "what if ...?" and I raised it to 65500. Amazingly, I got average speeds of 1.25MB/s with top speeds above 2.5MB/s.
That was cool, but had one downside: the VPN connection become unstable, with the tun0 device disappearing from the server (probably because the process that managed it crashed).
Reading further in OpenVPN man page and other posts, I decided that I should try to use OpenVPN's mssfix feature. Default value is 1500, but OpenVPN automatically reduces that in order to allow for the SSL data overhead. I decided to be on the safe size and use mssfix 1440. Heuristically, I thought I should use a tun-mtu that is a multiple of that (to help split the data in even fully-filled packets). So I used tun-mtu 64800. With these two settings on, the server proved stable and average transfer speeds went to about 850KB/s (good enough for my needs).
I should not that these transfer speeds were obtained by applying the same settings:
tun-mtu 64800in the client config. If no changes are applied to the client configs, the transfer speed will be still unacceptable low, but still higher than before (about 5KB/s).
mssfix 1440
Wednesday, January 9, 2013
Is there any design behind Python language?
I gave Python another try (fourth or so). In the past I found it to be a terrible designed language. Lots of things in the language itself felt like they were scraped from all other existing programming languages. And the worst part, that it didn't feel familiar at all, even if you know those languages.
This time I tried Python 3. I went with the Dive Into Python 3 book (ofcourse).
Some of the weirdest things I noticed while reading:
1. Python's goal was to be a programming language that is as easy to read as plain English, right? Then why use def instead of define, why use try...except instead of try...exception. I mean, unless you know what try...except does, you'll think it will try to do something, except some other thing.
2. You add items to lists using list method like a_list.insert(), or a_list.append(), but you delete them using del keywork (del a_list[0]). What is that?
3. You define tuples with (1, 2), but (1) is not a tuple because ( ) are used for math. You need to write (1,). Makes sense, but whoever added the tuples feature did not see this coming? Were they not enough symbols on the keyboard that they had to recycle ( )?
4. You define sets with {1, 2}, but {} is a dictionary. What? Yes, for empty sets you need set().
5. Printing an empty list shows [], an empty tuple shows (), an empty dict shows {}, but and empty set shows... set()? boooh!
6. Lists have extend() and append() methods, but sets have update() and add().
7. List don't have discard() method (i.e. like remove() but doesn't raise exception), but sets do. Logic for that is?
List goes on, but I got tired of keeping track. I finished reading the book eventually (quite fast I would say considering my "go away Python" bias) and I have to admin Python 3 is much better designed than 2.
However, it wasn't the language itself that got me hooked on the book, but it was the book itself. It's full of non-Python related technical info and generic programming tips. It ties well to other topics without going into much detail. I recommend reading it.
This time I tried Python 3. I went with the Dive Into Python 3 book (ofcourse).
Some of the weirdest things I noticed while reading:
1. Python's goal was to be a programming language that is as easy to read as plain English, right? Then why use def instead of define, why use try...except instead of try...exception. I mean, unless you know what try...except does, you'll think it will try to do something, except some other thing.
2. You add items to lists using list method like a_list.insert(), or a_list.append(), but you delete them using del keywork (del a_list[0]). What is that?
3. You define tuples with (1, 2), but (1) is not a tuple because ( ) are used for math. You need to write (1,). Makes sense, but whoever added the tuples feature did not see this coming? Were they not enough symbols on the keyboard that they had to recycle ( )?
4. You define sets with {1, 2}, but {} is a dictionary. What? Yes, for empty sets you need set().
5. Printing an empty list shows [], an empty tuple shows (), an empty dict shows {}, but and empty set shows... set()? boooh!
6. Lists have extend() and append() methods, but sets have update() and add().
7. List don't have discard() method (i.e. like remove() but doesn't raise exception), but sets do. Logic for that is?
List goes on, but I got tired of keeping track. I finished reading the book eventually (quite fast I would say considering my "go away Python" bias) and I have to admin Python 3 is much better designed than 2.
However, it wasn't the language itself that got me hooked on the book, but it was the book itself. It's full of non-Python related technical info and generic programming tips. It ties well to other topics without going into much detail. I recommend reading it.
Sunday, November 11, 2012
Using WebScarab with existing SSL certificate
I needed to monitor/debug some HTTP and HTTPS traffic to a site from a closed source software. I had access to the real SSL certificates and via some quick DNS rewrites I was able to fool the application that the site's IP is my local address. At this point all I needed was some kind of reverse proxy that allows me to log requests as they are forwarded to the real site. I can't use Wireshark because it doesn't decode HTTPS traffic. I could have used nginx (or other similar) but I wanted something more adapted to this task. While googling I run into fiddler (only for Windows), charlesproxy (commercial), paros and its succesor ZAP (good, but listens/forwards only to one port) and others. The one that seemed to offer most features was WebScarab.
WebScarap is a Java app (selfcontained jar) that allows you to monitor HTTPS requests via it's build-in proxy. In order to handle HTTPS traffic, in the proxy listener settings you need to enable a proxy listener that forwards traffic to a HTTPS server. Something like: address=127.0.0.1, port=443, and baseurl=https://example.com:443/.
By default, Webscarab will generate a self-signed SSL certificate for your setup. This means that browsers will complain about it and the application I was testing would refuse to use it. One can create a certs directory inside the webscarab application and put existing certficates inside that as described here. There are some things to be aware of:
After I got the jars, running ant still not finished successfully. The command that worked was: ant -lib lib build. That created a webscarab.jar file. Trying to run that jar directly (using following command) failed:
Update: After posting this, I found this discussion which points out that -jar and -classpath arguments are mutually exclusive. So I rewrote the first command to:
Update: After more poking around, I found out that I can avoid typing the long classpath by editing the manifest file inside the webscarab.jar (in META-INF/manifest.mf) and replace the current Class-Path entry with:
WebScarap is a Java app (selfcontained jar) that allows you to monitor HTTPS requests via it's build-in proxy. In order to handle HTTPS traffic, in the proxy listener settings you need to enable a proxy listener that forwards traffic to a HTTPS server. Something like: address=127.0.0.1, port=443, and baseurl=https://example.com:443/.
By default, Webscarab will generate a self-signed SSL certificate for your setup. This means that browsers will complain about it and the application I was testing would refuse to use it. One can create a certs directory inside the webscarab application and put existing certficates inside that as described here. There are some things to be aware of:
- If you're proxying requests on privileged ports (e.g. 80 or 443), you might need to start WebScarab as root (but you already knew that, right?)
- Most webserver certificates come in PEM format (.crt extension) with a key file. WebScarab nees a PKCS12 format (.p12 extension) file. You can convert them with openssl:
openssl pkcs12 -export -in example.com.crt -inkey example.com.key -certfile CertificationAuthority.crt -out example.com.p12
- When openssl asks you for a password for the .p12 file, you must enter the word password. This is hardcoded into WebScarab.
- The name of the .p12 file must match exactly the server name to which you are forwarding requests (as setup in the proxy listeners settings) and not the name of the server for which you are receiving requests (the two might be different). If you're forwarding to www1.example.com, then the name of the file must be www1.example.com.p12. I learned the hard way (i.e. reading webscarab code) that because I'm forwarding the requests to an IP address, the certificate file needs to be named as for that address. For example, if baseurl is https://192.168.1.1:443/ then the certificate file must be named 192.168.1.1.p12.
- Having a custom certificate inside the certs directory (as described in item 4) will NOT work (keep reading for a few solutions). :(
--- a/src/org/owasp/webscarab/plugin/proxy/Proxy.java
+++ b/src/org/owasp/webscarab/plugin/proxy/Proxy.java
@@ -476,7 +476,7 @@ public class Proxy implements Plugin {
SSLContext sslcontext = null;
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(is, _keystorepass);
- kmf = KeyManagerFactory.getInstance("X509");
+ kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, _keypassword);
sslcontext = SSLContext.getInstance("SSLv3");
sslcontext.init(kmf.getKeyManagers(), null, null);
Running ant build (or simply ant) to recompile webscarab failed due to many missing classes. I found out the some of the jar files that it needed to compile are not included in the git repo (maybe due to licensing terms or something). In particular, I needed to add the following jars into the lib directory (you can find them in the official webscarab jar or by googleing): bcprov-jdk15-1.45.jar, joda-time-1.6.2.jar, openid4java-nodeps-0.9.6.jar, xalan-2.7.1.jar.After I got the jars, running ant still not finished successfully. The command that worked was: ant -lib lib build. That created a webscarab.jar file. Trying to run that jar directly (using following command) failed:
java -cp .:lib/bcprov-jdk15-1.45.jar:lib/commons-logging-1.0.4.jar:lib/flex-messaging-remoting.jar:lib/jfreechart-1.0.13.jar:lib/openid4java-nodeps-0.9.6.jar:lib/bsf-2.3.0.jar:lib/concurrent.jar:lib/htmlparser.jar:lib/jhall-2.0_02.jar:lib/tagsoup-1.0rc2.jar:lib/bsh-2.0b1.jar:lib/flex-messaging-common.jar:lib/jcifs-1.3.14.jar:lib/joda-time-1.6.2.jar:lib/xalan-2.7.1.jar:lib/chardet.jar:lib/flex-messaging-core.jar:lib/jcommon-1.0.16.jar:lib/openamf.jar:lib/xmlsec-1.4.3.jar -jar webscarab.jarI don't know why it failed, maybe I'm missing something. However, I opened the build directory and tried to run this:
java -cp .:../lib/bcprov-jdk15-1.45.jar:../lib/commons-logging-1.0.4.jar:../lib/flex-messaging-remoting.jar:../lib/jfreechart-1.0.13.jar:../lib/openid4java-nodeps-0.9.6.jar:../lib/bsf-2.3.0.jar:../lib/concurrent.jar:../lib/htmlparser.jar:../lib/jhall-2.0_02.jar:../lib/tagsoup-1.0rc2.jar:../lib/bsh-2.0b1.jar:../lib/flex-messaging-common.jar:../lib/jcifs-1.3.14.jar:../lib/joda-time-1.6.2.jar:../lib/xalan-2.7.1.jar:../lib/chardet.jar:../lib/flex-messaging-core.jar:../lib/jcommon-1.0.16.jar:../lib/openamf.jar:../lib/xmlsec-1.4.3.jar org.owasp.webscarab.MainThis command finally worked (ran from inside the build directory).
Update: After posting this, I found this discussion which points out that -jar and -classpath arguments are mutually exclusive. So I rewrote the first command to:
java -cp .:lib/bcprov-jdk15-1.45.jar:lib/commons-logging-1.0.4.jar:lib/flex-messaging-remoting.jar:lib/jfreechart-1.0.13.jar:lib/openid4java-nodeps-0.9.6.jar:lib/bsf-2.3.0.jar:lib/concurrent.jar:lib/htmlparser.jar:lib/jhall-2.0_02.jar:lib/tagsoup-1.0rc2.jar:lib/bsh-2.0b1.jar:lib/flex-messaging-common.jar:lib/jcifs-1.3.14.jar:lib/joda-time-1.6.2.jar:lib/xalan-2.7.1.jar:lib/chardet.jar:lib/flex-messaging-core.jar:lib/jcommon-1.0.16.jar:lib/openamf.jar:lib/xmlsec-1.4.3.jar:webscarab.jar org.owasp.webscarab.MainThat means that I'm including the webscarab.jar in the classpath and explicitly naming the main class in command line. It worked like a charm!
Update: After more poking around, I found out that I can avoid typing the long classpath by editing the manifest file inside the webscarab.jar (in META-INF/manifest.mf) and replace the current Class-Path entry with:
Class-Path: lib/bcprov-jdk15-1.45.jar lib/commons-logging-1.0.4.jar lib/flex-messaging-remoting.jar lib/jfreechart-1.0.13.jar lib/openid4java-nodeps-0.9.6.jar lib/bsf-2.3.0.jar lib/concurrent.jar lib/htmlparser.jar lib/jhall-2.0_02.jar lib/tagsoup-1.0rc2.jar lib/bsh-2.0b1.jar lib/flex-messaging-common.jar lib/jcifs-1.3.14.jar lib/joda-time-1.6.2.jar lib/xalan-2.7.1.jar lib/chardet.jar lib/flex-messaging-core.jar lib/jcommon-1.0.16.jar lib/openamf.jar lib/xmlsec-1.4.3.jarAfter doing so, running WebScarab is (again) as easy as running:
java -jar webscarab.jar
Etichete:
certificate,
HTTPS,
java,
reverse-proxy,
ssl,
webscarab
Friday, November 2, 2012
Solr replication monitoring
I am using Solr replication on some projects for load balancing (not that Solr really needs that ;) ) and high-availability. Recently, due to a network problem, replication was stalled on one of the slave without me noticing it, so I wrote a small script to check the index version difference between master and slave and which admins can integrate with current monitoring system (nagios, zenoss, munin, whatever).
#!/bin/bash
if [ $# -lt 2 ]; then
echo Usage: `basename $0` SolrMasterIP[:port] SolrSlaveIP[:port] [AlertThreshold]
exit 1
fi
# read command params
MASTER=$1
SLAVE=$2
THRESHOLD=${3:-1}
# read index version from master and slave
MASTER_INDEX=`wget -qO - http://$1/solr/admin/replication/index.jsp | awk '/Index Version/ {print substr($3,0,length($3)-1)}'`
[ -z "$MASTER_INDEX" ] && echo Error reading Master index && exit 2
SLAVE_INDEX=`wget -qO - http://$2/solr/admin/replication/index.jsp | awk '/Index Version/ {print substr($3,0,length($3)-1)}'`
[ -z "$SLAVE_INDEX" ] && echo Error reading Master index && exit 3
# check if master-slave index difference is within acceptable threshold
let "$MASTER_INDEX - $SLAVE_INDEX < $THRESHOLD" && echo Slave index version \($SLAVE_INDEX\) is behind master \($MASTER_INDEX\) && exit 4
echo Slave index version \($SLAVE_INDEX\) is in sync with master \($MASTER_INDEX\)
Sunday, October 28, 2012
Speed up Ubuntu Quantal Quetzal
I recently upgraded my Ubuntu 12.04 Precise to Ubuntu 12.10. Overall, I didn't see much difference, probably because I didn't run/notice the bugs/limitations that were fixed in this new release. One thing that I (subjectively) noticed is that boot up and application startup is slower, with the UI experiencing occasional freezes. I guess these slowness/freezes were already in 12.04, but they become more obvious after the upgrade. To the point that they become frustrating. So I looked into some ways that might speed up the system (not minor or complete tweakings, but just a few to get over the current situation).
I didn't notice any major speedup on this either. It could be some, but bootup time is still several times more of the Ubuntu advertised "10 seconds bootup".
Although I installed it mostly for the "memory optimizations" promise, Prelink also seemed to help with speed. I'm not sure how much since I installed it after preload which already helped in that area.
Mount options
First thing I tried was adding nodiratime and noatime options to the mount options of / and /home partitions. To do that, just edit /etc/fstab and add these options alongside the existing ones. My fstab looks something like this now:
/dev/sda1 / ext4 nodiratime,noatime,errors=remount-ro 0 1 UUID=..... /home ext4 defaults,nodiratime,noatime 0 2
I didn't notice any major speedup after these changes, but they do seem common sense and lack of speedup might be due to my particular setup (some VMs I'm using).
Install ureadahead
Next I installed the ureadahead package which is supposed to lower boot up times. Install was easy:
sudo apt-get install ureadaheadAccording to what I read, on first run, ureadahead logs bootup files accesses and then aggregates these files into cached file that will be used in next bootups to speed things up. It also optimizes this cached file according to the type of disk that you have (SSD or HDD). After the system boots, ureadahead process seems to terminate and just gets out of the way.
I didn't notice any major speedup on this either. It could be some, but bootup time is still several times more of the Ubuntu advertised "10 seconds bootup".
Install preload
Preload is a daemon that logs statistics about programs usage and requirements and use these statistics to speed up programs startup. I guess this is what Windows has on by default in that prefetched folder. As mentioned in the man pages, the speed up is not immediately, because preload first needs to collect the stats and create some caches before it can use them. Even so, I did see programs starting faster pretty soon after installing preload. I just installed using:
sudo apt-get install preload
Install prelink
Preling is a tool that improves memory usage and load times by optimizing programs and libraries. Install it using:
sudo apt-get install prelinkAfter install, you need to start the optimization process. Before I did that, first I edited /etc/prelink.conf to include /opt directory in the optimization process because I have some custome software there. After that, just run
sudo prelink -avmRThe option v is for verbose so that you can see what's processing. You could remove that if you don't care. I guess I'll need to run such a command when I update/install new software, but that's not a big issue.
Although I installed it mostly for the "memory optimizations" promise, Prelink also seemed to help with speed. I'm not sure how much since I installed it after preload which already helped in that area.
Tuesday, November 29, 2011
Setup GeoIP for PHP5 on Ubuntu Server
I lost a few hours on this, although I done it sometime ago. To make sure I don't forget it again, here it is:
- Install geoip packages:
sudo apt-get install geoip-bin php5-geoip - Download GeoIP Lite version:
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz -O /tmp/GeoLiteCity.dat.gz - Unzip GeoIP Lite to /usr/share/GeoIP/GeoIPCity.dat (this is what I forgot: to rename the file):
sudo gunzip -c /tmp/GeoLiteCity.dat.gz > /usr/share/GeoIP/GeoIPCity.dat - Reload apache
sudo /etc/init.d/apache2 reload
Thursday, August 5, 2010
Elegant SEF columns layout
I found this somewhere (I can't remember where). I'm not using it now, but it's good to know.
The CSS is
The CSS is
/* @begin columns/sidebars (fixed L,R; liquid C) */and the HTML (in a Drupal theme) is:
.columns-both, .columns-left {
padding-left: 200px; /* LC width */
}
.columns-both, .columns-right {
padding-right: 150px; /* RC fullwidth + CC padding */
}
.columns-container .column-main, .columns-container .column-left, .columns-container .column-right {
position: relative;
float: left;
}
.columns-container .column-main {
width: 100%;
}
.columns-container .column-left {
width: 190px; /* LC width */
left: -200px; /* LC fullwidth + CC padding */
margin-left: -100%;
}
.columns-container .column-right {
width: 140px; /* RC width */
margin-right: -150px; /* RC fullwidth + CC padding */
}
/*** IE6 Fix ***/
* html .columns-container .column-left {
left: 150px; /* RC fullwidth */
}
/* @end columns/sidebars (fixed L,R; liquid C) */
Tuesday, July 6, 2010
Working out OpenVPN with Network Manager in Lucid Lynx
For two years now, I've used OpenVPN to connect to a server where I upload some of the stuff I work on. Until now I always started OpenVPN from the terminal, because I didn't manage to get it working from the Network Manager in the last 4 Ubuntu versions.
Last weekend, I had some spare time and I installed Lucid Lynx on my laptop. I tried (again) to get OpenVPN working with Network Manager. As usually it failed, although I was pretty sure everything I did was correct.
So I decided to import my existing openvpn configuration file and export it back to see if there's something different. After doing this, I've noticed a few difference, but most of them were just due to syntax. However, two lines looked more interesting:
Last weekend, I had some spare time and I installed Lucid Lynx on my laptop. I tried (again) to get OpenVPN working with Network Manager. As usually it failed, although I was pretty sure everything I did was correct.
So I decided to import my existing openvpn configuration file and export it back to see if there's something different. After doing this, I've noticed a few difference, but most of them were just due to syntax. However, two lines looked more interesting:
user openvpnI've checked and saw that with these lines in the configuration file, the openvpn connection failed to start even from the terminal. Therefore, I did the following:
group openvpn
- create the openvpn group as a system group using
groupadd -r openvpn
- assign the openvpn group to the directory (and files) that holds my openvpn key and certificates (mine and server's):
chgrp -R openvpn openvpn_folder
- assign group read permissions to the openvpn settings directory and remove permissions for others:
chmod g+r,o-rwx openvpn_folder
Monday, May 24, 2010
Matlab 7 startup problem
Recently I had to install Matlab 7 on a Dell Inspiron 1501 laptop running Windows XP SP3. Everything went OK during installation. However, Matlab failed to start: it started, showed the splash screen, show the full application window, and as soon as the prompt was about to appear, all windows closes.
After some googleing I found out that this is caused by Matlab 7 using the wrong version of the Blas library (http://www.mathkb.com/Uwe/Forum.aspx/matlab/12542/MATLAB-7-R14-crashing). Dell Inspiron 1501 has an AMD Athlon processor.
The solution was quite easy (considering how much time I lost to find it): add the environmental variable BLAS_VERSION with the value atlas_Athlon.dll.
After some googleing I found out that this is caused by Matlab 7 using the wrong version of the Blas library (http://www.mathkb.com/Uwe/Forum.aspx/matlab/12542/MATLAB-7-R14-crashing). Dell Inspiron 1501 has an AMD Athlon processor.
The solution was quite easy (considering how much time I lost to find it): add the environmental variable BLAS_VERSION with the value atlas_Athlon.dll.
Tuesday, May 4, 2010
Manually setup the Broadcom wireless card firmware on Dell Inspiron 1501
These steps summarize the information presented here: http://wireless.kernel.org/en/users/Drivers/b43#devicefirmware.
- Download and extract the b43-fwcutter.
- Download and extract the Broadcom drivers.
- Compile the b43-fwcutter
- Run the b43-fwcutter to extract the firmware
cd /tmp
wget http://bu3sch.de/b43/fwcutter/b43-fwcutter-013.tar.bz2 wget http://mirror2.openwrt.org/sources/broadcom-wl-4.150.10.5.tar.bz2
tar xjf b43-fwcutter-013.tar.bz2 tar xjf broadcom-wl-4.150.10.5.tar.bz2 cd b43-fwcutter-013 make cd ..
b43-fwcutter-013/b43-fwcutter -w /lib/firmware broadcom-wl-4.150.10.5/driver/wl_apsta_mimo.o
Monday, May 3, 2010
Customizing Moodle login instructions on a per language basis
Today I installed another language in one of my Moodle sites. On this occasion I noticed that the login instructions that I setup in the Moodle admin settings are being displayed in Romanian whatever language the user selects.
More precisely, in order to tell users to check their spam/bulk folder for the registration email that the site sends, I frequently customize the auth_instructions setting on the /admin/settings.php?section=manageauths page. In it, I copy the original message, which I get from the HTML source of the login page, and then I customize it to suit my needs.
When I setup a custom message, the original message is no longer displayed; which is very well. The problem is that when a user switches to another language (e.g. English), the customized message still appears (in Romanian). In order to fix this "problem", I removed the customized message from the site setting (ie. leaving it blank) and I moved it in the moodle.php language file for Romanian. This is quite easy to do: just go to /admin/lang.php?mode=compare¤tfile=moodle.php¤tstr=loginsteps#loginsteps and paste the HTML for your message (the one you had customized before in the site setting).
Note: If you did not apply the patch I describe in Click-to-translate feature for Moodle then loading the string editing page will take some time. Be patient!
More precisely, in order to tell users to check their spam/bulk folder for the registration email that the site sends, I frequently customize the auth_instructions setting on the /admin/settings.php?section=manageauths page. In it, I copy the original message, which I get from the HTML source of the login page, and then I customize it to suit my needs.
When I setup a custom message, the original message is no longer displayed; which is very well. The problem is that when a user switches to another language (e.g. English), the customized message still appears (in Romanian). In order to fix this "problem", I removed the customized message from the site setting (ie. leaving it blank) and I moved it in the moodle.php language file for Romanian. This is quite easy to do: just go to /admin/lang.php?mode=compare¤tfile=moodle.php¤tstr=loginsteps#loginsteps and paste the HTML for your message (the one you had customized before in the site setting).
Note: If you did not apply the patch I describe in Click-to-translate feature for Moodle then loading the string editing page will take some time. Be patient!
Thursday, April 29, 2010
Sharing Powerpoint course content
In the last couple of months I looked into solutions for sharing my course presentations (PowerPoint files) with others. My main goal would be to provide an experience as close as possible to the actual in-class courses for people that missed courses. This means that I would like the course content to be available to others as a full-length presentation with an audio narration.
The easiest way to do it with PowerPoint is to record the audio using the Record Narration feature. The problem with sharing PowerPoint files with narration are multiple. I have some solutions to these problems, but they lead into other problems.
The first major problem comes from PowerPoint itself: it can record narrations only in PCM format. That means that an audio narration (recorded with mono, 16 bit, 22KHz quality) takes about 150MB/hour (about 352Kbps). As a solution, I can link the audio narration file (instead of embedding it into PowerPoint) and compressed later as an MP3. Compressing it with FFmpeg is a painless process (just run one command) and takes only a few minutes. Compressed as an MP3 at 8Kbps, I will get around 3,5MB/hour for the narration which is quite ok. The problem that shows up in this case is that the file are linked (so I have to handle all of them with the main ppt file), and even worse, the PowerPoint stores the absolute path to the file (so moving the ppt file to another is very difficult if you want to keep the narration working).
The second major problem is that students must have PowerPoint (full version or viewer-only) installed and they need to download the file in order to view it. To make things more complicated, if the narration is linked it will not work unless the files are save in the same folder (i.e. same disk, path, folder name) as it was when narration was recorded. A MAJOR blocker. Combined, these two problems, put the ppt file sharing solution out of the game. I'll prepare the course in PowerPoint, but I need another method to share it using Moodle.
Due to certain restrictions (I won't go into details), I can not use presentations or videos sharing services with public access (like slideshare.com or youtube.com).
The solution I'm looking into for my problem is share the presentations as Flash content, so I'm looking into different PowerPoint to Flash converting solutions. To sum up my requirements, I want the solution to have the following features:
The easiest way to do it with PowerPoint is to record the audio using the Record Narration feature. The problem with sharing PowerPoint files with narration are multiple. I have some solutions to these problems, but they lead into other problems.
The first major problem comes from PowerPoint itself: it can record narrations only in PCM format. That means that an audio narration (recorded with mono, 16 bit, 22KHz quality) takes about 150MB/hour (about 352Kbps). As a solution, I can link the audio narration file (instead of embedding it into PowerPoint) and compressed later as an MP3. Compressing it with FFmpeg is a painless process (just run one command) and takes only a few minutes. Compressed as an MP3 at 8Kbps, I will get around 3,5MB/hour for the narration which is quite ok. The problem that shows up in this case is that the file are linked (so I have to handle all of them with the main ppt file), and even worse, the PowerPoint stores the absolute path to the file (so moving the ppt file to another is very difficult if you want to keep the narration working).
The second major problem is that students must have PowerPoint (full version or viewer-only) installed and they need to download the file in order to view it. To make things more complicated, if the narration is linked it will not work unless the files are save in the same folder (i.e. same disk, path, folder name) as it was when narration was recorded. A MAJOR blocker. Combined, these two problems, put the ppt file sharing solution out of the game. I'll prepare the course in PowerPoint, but I need another method to share it using Moodle.
Due to certain restrictions (I won't go into details), I can not use presentations or videos sharing services with public access (like slideshare.com or youtube.com).
The solution I'm looking into for my problem is share the presentations as Flash content, so I'm looking into different PowerPoint to Flash converting solutions. To sum up my requirements, I want the solution to have the following features:
- small file output (I guess that means Flash with MP3 sound files)
- easy to publish in Moodle (i.e. a single swf file to upload instead of a bunch of different files)
- easy to create (i.e. click a few programs to transform from PowerPoint to Flash; as few as possible command line typing)
- free/unexpensive as in open source, freeware or adware (but with a decent sized banner and without affecting usability)
- fast conversion from ppt to swf (or batch conversion)
- (optional) as many features as possible (some feature examples are slide notes, slide thumbnails, different controls, search in slides, narrator information)
Sunday, March 21, 2010
Click-to-translate feature for Moodle
Lately I tried to improve the quality of my university's Moodle platform. Among other things (i.e. upgrades, new backup setups, new theme, etc) I also wanted to improve the quality of the Romanian translations. The Romanian language pack of Moodle 1.9 its quite good from the student/user point of view, but it still has some problems:
Even if you can guess the correct ad-litteram translation of a string, you could always benefit from knowing in what context it is used. This way, you can provide a better semantic translation.
In order to have this context information available, I patched Moodle to save the get_string results and send them to the browser (for user which have language editing capabilities). Then, using a simple JQuery/JavaScript script (sorry again for JQuery, I just found it much more pleasant than YUI) when the user performs a proper action (right-click while holding down Control), I display a list of the strings matching the element under the current mouse position. In this list, the user can click the string she/he wants to change/translate. A frame specific to that string is displayed where the user can edit the translation source and save it. The changes required patching lib/moodlelib.php (where get_string is) and lib/weblib.php (where the page footer is generated).
Initially, I wanted to do this a fully AJAX process (similar to Google's "suggest a better translation"), but I had to replicate a lot of the admin/lang.php content. This is not good, especially for future updates. Thus, I decided to open a frame with the translation editing form. The problem with this approach is that some translation files are just big and take very long to show up (frequently freezing Firefox for 5-10 seconds). Therefore, I patched admin/lang.php so that I can provide a particular string and it will display/edit only that string (loading/saving is very fast this way). Of course, the automatic translation feature using Google Language API is still in place and working fine.
Except for the new JavaScript for the editing console (which is about 80 lines of code, including many comments), the other changes are minor, allowing this feature to work with different Moodle versions.
Let's take now an example. Consider my local Moodle sandbox. As you can notice, the "Please register you site..." is not translated.
I'm an administrator, so I have language editing capabilities. When I right-click on that text (or an area that includes it, like a div, table cell, etc), I get a list of translatable string inside the HTML element I clicked. I go and click on the proper text:
Next, a frame loads displaying the editing form only for the pleaseregister string from the admin.php language file (which is currently untranslated in Romanian):
Taking advantage of the Google translation feature, I click on the English version of the text (on the left) in order to get it translated automatically into Romanian.
After making sure the translation is ok (and it was in this case), I can save it. Sometimes the Google translation needs a bit of work, but it's still a much better starting point than starting from zero.
If I would not patched admin/lang.php in order to display only the string I want to edit, then editing admin.php would mean to load a long form (which completely hangs Firefox for 10 seconds) and then scroll down to about 80% of the page or search for the string I wanted.
- the string for administrator/teacher views, reports, forms are not fully translated; I understand why: there little to gain in usability from translating them as many administrators use the English language (including me)
- new strings are not translated yet (maybe they are in CVS, but I did not look there)
- bugs
Even if you can guess the correct ad-litteram translation of a string, you could always benefit from knowing in what context it is used. This way, you can provide a better semantic translation.
In order to have this context information available, I patched Moodle to save the get_string results and send them to the browser (for user which have language editing capabilities). Then, using a simple JQuery/JavaScript script (sorry again for JQuery, I just found it much more pleasant than YUI) when the user performs a proper action (right-click while holding down Control), I display a list of the strings matching the element under the current mouse position. In this list, the user can click the string she/he wants to change/translate. A frame specific to that string is displayed where the user can edit the translation source and save it. The changes required patching lib/moodlelib.php (where get_string is) and lib/weblib.php (where the page footer is generated).
Initially, I wanted to do this a fully AJAX process (similar to Google's "suggest a better translation"), but I had to replicate a lot of the admin/lang.php content. This is not good, especially for future updates. Thus, I decided to open a frame with the translation editing form. The problem with this approach is that some translation files are just big and take very long to show up (frequently freezing Firefox for 5-10 seconds). Therefore, I patched admin/lang.php so that I can provide a particular string and it will display/edit only that string (loading/saving is very fast this way). Of course, the automatic translation feature using Google Language API is still in place and working fine.
Except for the new JavaScript for the editing console (which is about 80 lines of code, including many comments), the other changes are minor, allowing this feature to work with different Moodle versions.
Let's take now an example. Consider my local Moodle sandbox. As you can notice, the "Please register you site..." is not translated.
I'm an administrator, so I have language editing capabilities. When I right-click on that text (or an area that includes it, like a div, table cell, etc), I get a list of translatable string inside the HTML element I clicked. I go and click on the proper text:
Next, a frame loads displaying the editing form only for the pleaseregister string from the admin.php language file (which is currently untranslated in Romanian):
Taking advantage of the Google translation feature, I click on the English version of the text (on the left) in order to get it translated automatically into Romanian.
After making sure the translation is ok (and it was in this case), I can save it. Sometimes the Google translation needs a bit of work, but it's still a much better starting point than starting from zero.
If I would not patched admin/lang.php in order to display only the string I want to edit, then editing admin.php would mean to load a long form (which completely hangs Firefox for 10 seconds) and then scroll down to about 80% of the page or search for the string I wanted.
Sunday, February 14, 2010
Automatic translation for Moodle UI strings with Google Translation API
Today I installed a fresh copy of Moodle 1.9. I'm reviewing it in order to upgrade our university's site (from Moodle 1.8) and another site (using Moodle 1.6). As always, I started going through all it's settings, looking for new features or things that changed. When I reached the Language section, I installed the Romanian language, just to make sure installation is working. However, I noticed that the Romanian language pack is missing 26.7% of strings (2672 to be more precise). Some translated string are also a bit weird.
I remembered that about two years ago, I patched Drupal in order to get automatic translation using Google Translate. At that time, Google translate did not provide any web services API, nor AJAX, and the translation of text containing HTML tags was very poor. The patch was doing simple HTTP requests, parsing of the HTTP response, some simple cleanup and in the end, it stored the translation into the Drupal locale messages.
Google Translate nowadays has much more languages than it used to backthen is AJAX based and offers web services, too. I was wondering how does it handle HTML tags and how hard would be to get it into the Moodle language editor. After 2 hours of coding and reading its API, I came up with this (sorry for JQuery, I know Moodle likes YUI):
I remembered that about two years ago, I patched Drupal in order to get automatic translation using Google Translate. At that time, Google translate did not provide any web services API, nor AJAX, and the translation of text containing HTML tags was very poor. The patch was doing simple HTTP requests, parsing of the HTTP response, some simple cleanup and in the end, it stored the translation into the Drupal locale messages.
Google Translate nowadays has much more languages than it used to backthen is AJAX based and offers web services, too. I was wondering how does it handle HTML tags and how hard would be to get it into the Moodle language editor. After 2 hours of coding and reading its API, I came up with this (sorry for JQuery, I know Moodle likes YUI):
$translang = preg_replace('/_.*/', '', $currentlang);
echo '
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("language", "1")
google.load("jquery", "1.4.1")
</script>
<script type="text/javascript">
$(document).ready(function() {
$("form .translator .stren").click(function() {
var src = $(this);
var dst = $("[name=\'stringXXX" + this.id + "\']")
var tokens = [];
var text = src.text().replace(/\$a(->\w*)?/g, function(match) {
return "TK" + (tokens.push(match)-1);
});
google.language.translate(text, "en", "' . $translang .'", function(result) {
if (!result.error) {
dst.text(result.translation.replace(/TK\d+/g, function(match) {
return tokens[match.substring(2)];
})).css("background-color", "yellow")
}
})
})
});
</script>';
This will allow a translator to click on any string in the Language editing section and get a Google translation for that string. The translation is saved in the corresponding textarea (which is marked with yellow). You can then check, edit, undo, or save these changes.
Thursday, January 28, 2010
Thunderbird beats Evolution
I recently decided to get my email stored locally in case my internet connection fails and I need them. I used to have them save in Outlook Express (for backup purposes), but I dropped this habbit when I start forwarding everything to Gmail.
I decided to give Evolution a shot and see how it's doing these days. This is mainly because of it's "great integration with Gnome". The overall interface it's not very impressive, and looks like it's an old application. I could have gone along with it, no problem, but something else was a show stopper: I use POP3 and all email clients I used allowed me to "delete email on server when deleted from Inbox". Guess what? Evolution does not have this (again, for POP). It's either "delete emails when retrieving" or "delete after X days". It seems that this feature was requested back in Evolution 1.0 but it was never implemented. I search a lot on forums for an explanation and I found two Evolution developers (back in a 2003 thread):
I decided to give Evolution a shot and see how it's doing these days. This is mainly because of it's "great integration with Gnome". The overall interface it's not very impressive, and looks like it's an old application. I could have gone along with it, no problem, but something else was a show stopper: I use POP3 and all email clients I used allowed me to "delete email on server when deleted from Inbox". Guess what? Evolution does not have this (again, for POP). It's either "delete emails when retrieving" or "delete after X days". It seems that this feature was requested back in Evolution 1.0 but it was never implemented. I search a lot on forums for an explanation and I found two Evolution developers (back in a 2003 thread):
- this feature is a POP hack and will not be implemented
- Evolution is targeted more to enterprise users which use IMAP
- is it "hack" to use two POP commands to get a feature implemented? I guess no, since all other clients are doing it. Or maybe, they are all hackers, and Evolution developers are the real-deal.
- then why "force" it into my new Ubuntu desktop install (like that other half application that tries to replace Pidgin)?
Friday, January 22, 2010
Hiding Tight VNC tray icon
As stated in the TightVNC FAQ, in order to hide the tray icon of the server, you need to add/set in the registry the DWORD DisableTrayIcon entry to 1 inside the HKLM\SOFTWARE\ORL\WinVNC3 container.
A .reg file that does this automatically is this:
A .reg file that does this automatically is this:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\ORL\WinVNC3]
"DisableTrayIcon"=dword:00000001
Subscribe to:
Posts (Atom)





