7/31/07

My choice for music player on ubuntu.

Today I'm looking for mp3 player for my ubuntu. Feisty come with rhythmbox but after few months using I think it's time to try something better. Rhythmbox does not let me edit idv3 tags and [for me]it's hard to manage library so it's not acceptable. All I wants are

a) idv3 tags must editable. This is important for me because some of my mp3 collection don't have info in tags or some have a wrong info.

b) full support thai language.

c) gtk+ application will be good.
I found this blog [http://onlyubuntu.blogspot.com/2007/03/media-players-available-for-ubuntu.html] list some media players in ubuntu. I choose some to try[all are easy to install in Feisty just 'sudo aptitude install <packagename>']

Beep Media Player is like xmms. If I'm not wrong I think the project is stop now.

Amarok come with great interface, full of features but it's KDE app so it's need some other kde package to install and run.

Exaile, like KDE's Amarok but it's GTK+ and written in Python. It almost be my choice but it has a problem with my language e.g. the library manager can not add mp3 file to collection when artist and album tag are thai langauge.


At last Listen is my choice, interface just like other gtk apps, does everything amarok and exaile can do, idv3 tags editing, ipod management, information from wikipedia, lyrics search, webradio, lastfm, download album cover. Even I feel Amarok still better in editing multitrack tags, burning CD and browsing collection but listen does it's job and I try to avoid to use kde in gnome.

7/28/07

convert mp3 id3 tags to unicode.

The problem about playlist on media player are unreadable when it use thai character. This is caused by different encoding used in id3 tags and in media player. Id3 tags use cp874[don't know why] but in current linux distribution, player use unicode. This will not be a problem if tags are english characters that cp874 and unicode has the same value e.g. 'A' is '0x41' for cp874 and '0x0041' for unicode, but not for thai character.

To correct thai character in playlist. There is a script to convert 1-byte charsets to unicode[download] by Kopats Andrei.
Now what to do:
1. download the script. You'll get 'tag2utf.py'.
2. install requirement software

sudo apt-get install python-eyed3

3. in the script, looking for charsets = {'cp1251':'c','koi8-r':'k' } and replace with your language encoding[ for thai change it to charsets = {'tis-620':'t' } ]
Now we ready to convert mp3 tags. run script by 'tag2utf.py <mp3 dir>' it will convert id3 tags of all files in specify directory include sub directory. Below is the result.


resource [in thai]
http://wiki.ubuntuclub.com/wiki/Tag2utf
http://linuxtip.blogspot.com/2007/02/id3-tag-part-ii.html

7/25/07

uhh.. I got hacked

Yesterday, In the morning my boss tell me to looking at the router. It blinks like it'll going to blow up. Something in our network use almost 60% of my bandwidth. I look around and see that network light on the acient small box on the floor blinks too. It's a secondhand computer from japan and I almost forget it.

On that box,I install dapper server,postfix,courier,mysql and use it as a mail server with no firewall. poor me. :(

This is first time I got hacked(as I know hah ha). I've no idea what to do first. I go to check /var/log/auth.log and found many ssh attack. 'who' give me two users online, me and test1[the hacker]. 'top' show that user test1 run tons of ssh-scan process. I can't remember that did I create that test1 user myself or the hacker do a dictionary attack, found my password then create test1 user. What I do at that time is restart computer, delete test1 user then create a firewall.

Then I go to ubuntuforums and found this thread. It look like my case and from his .bash_history look like the hacker going to /var/tmp, download a file.tgz that contain hiden directory 1.user 2.user ssh-scan... So I go back to check my box and here is what i found on my email server.

pnix@xxx:~$ ls -a /var/tmp
. .. fast .PA PA.tgz
pnix@xxx:~$ ls -a /var/tmp/.PA
. 191.20.pscan.22 191.83.pscan.22 217.20.pscan.22 gen-pass.sh pass_file pscan2 ssh-scan vuln.txt
.. 191.21.pscan.22 217.10.pscan.22 common go.sh pico ss start
pnix@xxx:~$ ls -a /var/tmp/fast
. 1.user 3.user checkmech fast go LinkEvents m.help m.lev m.ses .m.set.swp src
.. 2.user Andy.seen configure genuser httpd Makefile mkindex m.pid m.set r Vipuletz.seen
pnix@xxx:~$

It's look almost the same files. On that thread many one said go to reinstall this box can't trust anymore. Yes, I agree but not now I will prepare the new one first with full secure as I can.

Since yesterday lunch until now there five or six attempts to attack my mail server. From many places include the test1 user[I know his ip address] but no success[my firewall's job not too bad]. :)

7/24/07

Manage services on ubuntu

To add/remove service in ubuntu. Manually you can put init script in /etc/init.d then create symbolic link from /etc/rc?.d/S[NN]name or K[NN]name to /etc/init.d/scriptname.[S for start and K for stop]
In ubuntu has a tool to manage init scripts call update-rc.d. For example if you want to start serviceA in runlevel 2 3 4 5 with sequence number 18 and stop in runlevel 0 1 6 with sequence number 99 use the command.[the scriptA must already create in /etc/init.d]

pnix@pnix-a7n:~$ sudo update-rc.d serviceA start 18 2 3 4 5 . stop 99 0 1 6


In redhat base linux, i use chkconfig do the same thing. For more detail try 'man chkconfig'.

7/22/07

Clean up your ubuntu box

After running the system for a long time. Today I found few things I should do to clean the box.

First clean the old package files in cache, When you do "sudo aptitude update|upgraed|install", the packages will be downloaded to your local disk[ locate at /var/cache/apt/archives/ ] then installed. If you try ls that directory you will see how many packages you've download. To prevent these cache from growing we should remove some outdated package by

pnix@pnix-a7n:~$ sudo apt-get autoclean
Password:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Del compizconfig-settings-manager 0.1.0+git20070717~3v1ubuntu0 [461kB]
Del libcompizconfig-backend-gconf 0.1+git20070709~3v1ubuntu0 [29.5kB]
.
.
Del libdecoration0 1:0.5.1+git20070706~3v1ubuntu1 [2401B]
pnix@pnix-a7n:~$


next install localepurge. [These package will remove all locale in your system except what you choose to keep]
pnix@pnix-a7n:~$ sudo aptitude install localepurge

it will open package configuration for select language you want to use on your system. I select all en,de,pt and th.

another thing is orphaned libraries[ the packages that no longer use]. To find orphaned packages we need a tool.
pnix@pnix-a7n:~$ sudo aptitude install deborphan

Now to use it, just type "deborphan" in terminal then orphaned packages will be listed and you can remove it with "aptitude purge <package>".
pnix@pnix-a7n:~$ deborphan
libglut3
pnix@pnix-a7n:~$ sudo aptitude purge libglut3
Password:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Reading extended state information
Initializing package states... Done
Building tag database... Done
The following packages will be REMOVED:
libglut3{p}
0 packages upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
Need to get 0B of archives. After unpacking 49.2kB will be freed.
Do you want to continue? [Y/n/?] y
Writing extended state information... Done
(Reading database ... 109118 files and directories currently installed.)
Removing libglut3 ...
localepurge: Disk space freed in /usr/share/locale: 21704K
localepurge: Disk space freed in /usr/share/man: 3168K

Total disk space freed by localepurge: 24872K

pnix@pnix-a7n:~$

or if you want one line command try this.
sudo deborphan | xargs sudo apt-get -y remove --purge

7/18/07

Directive tag in more details

From last post about tag in jsp. This post is about directive tag in more details. Directive tag can devide into three types e.g. page, include and taglib

<%@ directive attribute="value" %>

page directive: page directive will provide the information about the page for jsp engine to compile that page.
Below are some importance attributes of page directive :
language tells the engine about language that the page is using.
usage: <%@ page language="java" %>

extends tell jsp engine that this page will extend from specify class.
usage: <%@ page extends="test.myclass" %>

import used to import any class to use in our jsp page. We can use comma(,) to import more than one packages.
usage: <%@ page import="java.sql.*,mypackage.myclass" %>

session="true|false", default is true so jsp pages are session enable.
usage: <%@ page session="true" %>

buffer, control buffer usage for that jsp page.
usage: <%@ page buffer="none" %>

autoFlush="true|false", if true will automatic clear when buffer is full.
usage: <%@ page autoFlush="true" %>

isThreadSafe="true|false", if true, jsp engine will create new thread for every concurrent request.
usage: <%@ page isThreadSafe="true" %>

errorPage tell the server that which page to go when got un-handled exceptions in the page.
usage: <%@ page errorPage="error.jsp" %>

more than one directives can be used by separate by space.
usage: <%@ page language="java" session="true" contentType="text/html;charset=ISO-8859-1" %>

include directive: include is used to include content in another file into the jsp page. You can use it for header or footer of the page.
<% include file="file to include" %>

usage: <%@ include file="/header.jsp" %>

taglib directive:
next in jsp tag series

7/14/07

wine0.9.40 and utorrent1.7 on win2000 mode get black screen

Today I upgrade utorrent[sure on feisty] from 1.6 to 1.7 then restart utorrent. This upgrading cause unused parts of uTorrent's window are black. That's annoying me.


After some searching, look like it wine bug, I run with wine 0.9.40, the newest one. The black window area will happen when use in mode < winxp. So if you have the same problem, setting "windows version"[by run winecfg] to winxp will fix it.

7/11/07

JSP TAGS

JSP is the html page that add java code[called JSP tags] into it.
JSP tags can be devided into 6 different types. These are:
Comment tag use to add comment.

<% --comment here-- %> or <! --comment here-- >

Declarations tag use to define the variables,methods or classes to use in the JSP page.
<%!
Declaration1;
Declaration2;
%>

Scriplets tag use to insert java statements.
<%
Statement 1;
Statement 2;
Statement n;
%>

Expressions tag use to print out any data on the page. These data are automatically converted to string.
<%=[Value] or [Expression]%>

Directives tag is used for many purposes depend on directive and attribute in tag. there are three directives page, include and taglib.
<%@ directive attribute="value" %>

Action tag is use to transfer control to other server objects[ex. pages] or perform operations on other objects.
<jsp:action attributes />

action tag has three types e.g. include,forward and usebean.

7/8/07

Compiz Fusion on Fiesty

Two weeks ago, I read on ubuntuforums and found this thread about how to get compiz fusion work on ubuntu fiesty. It show you clearly step by step how to. Today I'm just decide to try and it's real amazing. 3D Cube and many effect feel smoother than the old compiz from repos.
It's work on my asus n6200td 128M card, my memory is 512M, athlon xp 1700+ and A7N8X-E mobo. Compiz fusion still development version but for me it's very very very stable. So I urge you to try it now.

Compiz Fusion is merging of compiz and beryl project. It's not on feisty repos yet but may be on Gutsy Gibbon.

Using HttpURLConnection

Usually when I want to make a request over network in java I familiar to use Socket class like this.

Socket theSock = new Socket(server,port);
PrintStream ps = new PrintStream(theSock.getOutputStream());

then uses ps.println() to send a request and uses theSock.getInputStream() to reciece response to see everything that sent over output stream. But this maybe not suitable for all situation.

Talking with web server will be done through HTTP message[request,response] that consists of header and body. So to make a post,get http request [with Socket class]
//Post
ps.println("POST uri HTTP/1.1");
ps.println("Content-Length: "+body.length());
ps.println("Content-Type: "+contenttype);
ps.println();
ps.println(body);

//or Get
ps.println("GET uri HTTP/1.1");
ps.println("Connection: Close");
ps.println();

and web server will responds with HTTP response like. Here's the example.
HTTP/1.1 200 OK
Date: Wed, 04 Jul 2007 10:14:54 GMT
.
Content-Length: 7
Connection: close
Content-Type: text/html

body

With this format it's hard to manage if we get the reponse via getInputStream() of Socket instance. How about Cookie or Session? or actual data in body. If the response is in xml format and we try to parse it like this
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(theSock.getInputStream());

It will throw "SAXException: Parsing Error : The root element is required in a well-formed document".
Instead of using using Socket class that saw only bits transfer over the network. HttpURLConnection class will alows us to read parameters in header and data in body. see the code.
//to make HTTP Post request with HttpURLConnection
URL url = new URL("http://server/uri");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();

then set some properties and make a request
conn.setRequestMethod("POST");
conn.setAllowUserInteraction(false); // no user interact [like pop up]
conn.setDoOutput(true); // want to send
conn.setRequestProperty( "Content-type", "text/xml" );
conn.setRequestProperty( "Content-length", Integer.toString(contentx.length()));
OutputStream ost = conn.getOutputStream();
PrintWriter pw = new PrintWriter(ost);
pw.print(body); // here we "send" our body!
pw.flush();
pw.close();

for Get Exam just change setRequestMethod to conn.setRequestMethod("GET").

To get body,cookie or other header parameter of HTTP response
int i=1;// this will print all header parameter
String hKey;
while ((hKey=conn.getHeaderFieldKey(i))!=null){
String hVal = conn.getHeaderField(i);
System.out.println(hKey+"="+hVal);
i++;
}
//and InputStream from here will be body
conn.getInputStream()


note: some time http get need to pass some parameter value, url to create in new URL("url") will end with something like field1=value1&field2=value2... This url must be encode with static method URLEncoder.encode(String) first.

7/2/07

3DES/Base64 encryption in java

Last week I need to post data in xml format to one server. For security reason one node[xml] require 3DES encryption and encode to Base64 before send. It's a good idea to encrypt sensitive data before store in database or transfer over internet but I'm not even know what 3DES is. After some search, I found that it's not too hard.

This post is about how i encrypt data in java. 3DES algorithm use symetric key[secret key] to encrypt or decrypt data. So..

First define a key [ length must be 24 bytes ]. I do this by getBytes() from random string.

byte [] seed_key = (new String("er48nsjhwlG593mjhgdb20ih")).getBytes()

create Cipher object
SecretKeySpec keySpec = new SecretKeySpec(seed_key,"TripleDES");
Cipher nCipher=Cipher.getInstance("TripleDES");
nCipher.init( Cipher.ENCRYPT_MODE, keySpec );

Cipher class provides the functionality of a cryptographic cipher for encryption and decryption. To create cipher object, pass transformation to getInstance method.
Transformation can be in form like "algorithm/mode/padding" or only "algorithm".
for 3DES, algorithm can be "DESede" or "TripleDES". In experiment both give me the same result so I specify only algorithm as "TripleDES".

Now encrypt plaintext and get our cipher bytes by
String plaintxt="My SECRET WORD";
byte[] cipherbyte = cipher.doFinal(plaintxt.getBytes());

From cipher bytes. Our text is encrypted. To be easy to manage[send over internet or store in db] I will transform it with Base64[package from commons codec]
String encodeTxt = new String(Base64.encodeBase64(rawbyte));

Now decryption is just reverse the things we do for encryption, getBytes() from encodeTxt, decode with Base64 class, and doFinal() will give you decrypt text.
Note that for decryption, cipher object will init in DECRYPT_MODE.
nCipher.init( Cipher.DECRYPT_MODE, keySpec );
byte [] encData = Base64.decodeBase64(encodeTxt.getBytes());
decryptedtxt = nCipher.doFinal(encData);