<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>G-Loaded Journal &#187; Programming</title>
	<atom:link href="http://www.g-loaded.eu/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.g-loaded.eu</link>
	<description>An open-source software and technology related journal</description>
	<lastBuildDate>Fri, 11 May 2012 13:37:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
		<item>
		<title>Forking Apache-licensed software on Github and Bitbucket</title>
		<link>http://www.g-loaded.eu/2011/03/01/forking-apache-licensed-software-on-github-and-bitbucket/</link>
		<comments>http://www.g-loaded.eu/2011/03/01/forking-apache-licensed-software-on-github-and-bitbucket/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 16:05:36 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Legal]]></category>
		<category><![CDATA[License]]></category>

		<guid isPermaLink="false">http://www.g-loaded.eu/?p=2163</guid>
		<description><![CDATA[This post tries to investigate whether creating forks of software, that has been released under the terms of the Apache license, on Bitbucket or Github using a name identical to the name of the original project or a name that contains the name of the original project violates the Apache license or not. Whenever I [...]]]></description>
			<content:encoded><![CDATA[<p>This post tries to investigate whether creating forks of software, that has been released under the terms of the <strong>Apache license</strong>, on Bitbucket or Github using a name identical to the name of the original project or a name that contains the name of the original project violates the Apache license or not.</p>
<p>Whenever I release code to the public, I license it under the terms of the <a href="http://www.apache.org/licenses/LICENSE-2.0.txt">Apache license version 2</a>. I find this license to be very liberal, while at the same time it provides sensible terms about the use of copyright, patents, trademarks and names of the original work to those who are interested in building upon it. Below, there is an abstract of the license terms, paragraph 6:<br />
<span id="more-2163"></span></p>
<blockquote><p>
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
</p></blockquote>
<p>Social coding sites, like <a href="https://bitbucket.org">Bitbucket</a> and <a href="https://github.com">Github</a> permit forking the original project and use an identical name for the fork. In regard to the license term above, the following question is raised:</p>
<p>- <em>If the original project is licensed under an Apache license, do such public forks violate the license terms?</em></p>
<p>Well, I am not a lawyer, but if you want my personal opinion, then yes, such public forks violate the license of the original project and the developers who build upon code, that has been licensed under the Apache license, should use a different name for their fork. Both Bitbucket and Github offer the option to use a custom name when forking. Moreover, Bitbucket offers the option to the original developer to not allow public forks of the original project.</p>
<p>On the other hand, I think <strong>temporary public forks</strong> of Apache-licensed software, which are solely created in order to commit custom changes and then place a pull request on the original project, should not raise any issues, but only if the public fork is deleted or hidden after the author of the original project has pulled the changeset. But what happens in the case that the pull request is rejected? In this case, I guess the fork should be either renamed or deleted.</p>
<p>The only reason I write all these is to raise awareness about this potential issue and possibly start a constructive discussion. Also, as someone who frequently uses the Apache license, I&#8217;d like to know whether any of the questions raised in this post are valid or not.</p>
<p>You feedback is welcome.</p>
<p class="cc-block"><em><a href="http://www.g-loaded.eu/2011/03/01/forking-apache-licensed-software-on-github-and-bitbucket/">Forking Apache-licensed software on Github and Bitbucket</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>.</p>
<h4>Related Articles</h4>

<ul><li><a href="http://www.g-loaded.eu/2007/07/29/best-practices-of-software-licensing/" rel="bookmark">Best Practices of Software Licensing</a></li>
<li><a href="http://www.g-loaded.eu/2009/01/31/microsoft-releases-part-of-web-sandbox-code-under-the-apache-license/" rel="bookmark">Microsoft releases part of Web Sandbox code under the Apache License</a></li>
<li><a href="http://www.g-loaded.eu/2007/11/14/mod_gnutls-binary-for-apache/" rel="bookmark">mod_gnutls binary for Apache</a></li>
<li><a href="http://www.g-loaded.eu/2011/11/28/speed-up-apache-by-including-htaccess-files-into-httpd-conf/" rel="bookmark">Speed up Apache by including htaccess files into httpd.conf</a></li>
<li><a href="http://www.g-loaded.eu/2010/04/16/software-that-detects-violations-of-open-source-licenses/" rel="bookmark">Software that detects violations of open source licenses</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2011/03/01/forking-apache-licensed-software-on-github-and-bitbucket/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>rsapiget downloads files using the new Rapidshare API</title>
		<link>http://www.g-loaded.eu/2010/10/04/rsapiget-download-rapidshare-api/</link>
		<comments>http://www.g-loaded.eu/2010/10/04/rsapiget-download-rapidshare-api/#comments</comments>
		<pubDate>Mon, 04 Oct 2010 16:28:36 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Filesharing]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[rsapiget]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://www.g-loaded.eu/?p=1951</guid>
		<description><![CDATA[It was brought to my attention by a message in our forums that the download methods described in the &#8220;Use wget or curl to download from RapidShare Premium&#8221; article are no longer valid. Rapidshare has introduced a new API for account and file management. After a quick read of the Rapidshare API documentation, it was [...]]]></description>
			<content:encoded><![CDATA[<p>It was brought to my attention by a message in our forums that the download methods described in the &#8220;<a href="http://www.g-loaded.eu/2007/09/15/use-wget-or-curl-to-download-from-rapidshare-premium/">Use wget or curl to download from RapidShare Premium</a>&#8221; article are no longer valid. <strong>Rapidshare</strong> has introduced a new API for account and file management. After a quick read of the <a href="http://images.rapidshare.com/apidoc.txt">Rapidshare API documentation</a>, it was quite clear that the download methods that use regular cookies are not supported any more. I decided to spend some time with this API and try to write a Python script that can download files both as a free and a registered Pro user. I hereby publish this simple rapidshare client. I wrote this merely as an exercise and to compensate for the outdated information in that old article. I do not have a Rapidshare Pro account at this time and I&#8217;d say that I use such file-hosting services very rarely. So, the client has not been tested with a pro account. If you are a pro user, your feedback is welcome.</p>
<p><strong>Update</strong>: Thanks to <em>sharkic</em>&#8216;s feedback, this guide has now been improved by providing complete instructions on how to use <strong>wget</strong> and <strong>curl</strong> with the Rapidshare API. See the new sections <strong>at the end of the article</strong>.<br />
<span id="more-1951"></span></p>
<h4>The python implementation of a Rapidshare downloader</h4>
<p>Instead of writing a wrapper script around <a href="http://www.gnu.org/software/wget/">wget</a> or <a href="http://curl.haxx.se/">curl</a>, I decided to go ahead with a pure Python Rapishare downloader, which works with both free and pro accounts. The script is called <strong>rsapiget</strong>.</p>
<p>Here is the code:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#! /usr/bin/env python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#  rsapiget - A simple command-line downloader that supports the Rapidshare API.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#  Homepage: http://www.g-loaded.eu/rsapiget-download-rapidshare-api/</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#  Copyright (c) 2010 George Notaras, G-Loaded.eu, CodeTRAX.org</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#  Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span>
<span style="color: #808080; font-style: italic;">#  you may not use this file except in compliance with the License.</span>
<span style="color: #808080; font-style: italic;">#  You may obtain a copy of the License at</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#      http://www.apache.org/licenses/LICENSE-2.0</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#  Unless required by applicable law or agreed to in writing, software</span>
<span style="color: #808080; font-style: italic;">#  distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span>
<span style="color: #808080; font-style: italic;">#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
<span style="color: #808080; font-style: italic;">#  See the License for the specific language governing permissions and</span>
<span style="color: #808080; font-style: italic;">#  limitations under the License.</span>
<span style="color: #808080; font-style: italic;">#</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Configuration BEGIN</span>
LOGIN = <span style="color: #483d8b;">''</span>
PASSWORD = <span style="color: #483d8b;">''</span>
USE_SSL = <span style="color: #008000;">False</span>
VERIFY_MD5SUM = <span style="color: #008000;">False</span>
<span style="color: #808080; font-style: italic;"># Configuration END</span>
&nbsp;
__version__ = <span style="color: #483d8b;">'0.1.0'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">subprocess</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
<span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> hashlib
    <span style="color: #dc143c;">md5</span> = hashlib.<span style="color: #dc143c;">md5</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ImportError</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">md5</span>
    <span style="color: #dc143c;">md5</span> = <span style="color: #dc143c;">md5</span>.<span style="color: #dc143c;">new</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> info<span style="color: black;">&#40;</span>msg<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #66cc66;">%</span> msg<span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> error<span style="color: black;">&#40;</span>msg<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #66cc66;">%</span> msg<span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> transfer_progress<span style="color: black;">&#40;</span>blocks_transfered, block_size, file_size<span style="color: black;">&#41;</span>:
    percent = <span style="color: #008000;">float</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>blocks_transfered <span style="color: #66cc66;">*</span> block_size <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span> / file_size<span style="color: black;">&#41;</span>
    progress = <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>blocks_transfered <span style="color: #66cc66;">*</span> block_size / <span style="color: #ff4500;">1024</span><span style="color: black;">&#41;</span>
    downspeed = <span style="color: black;">&#40;</span><span style="color: #008000;">float</span><span style="color: black;">&#40;</span>blocks_transfered <span style="color: #66cc66;">*</span> block_size<span style="color: black;">&#41;</span> / <span style="color: #008000;">float</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - starttime<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> / <span style="color: #ff4500;">1024</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Complete: %.0f%% - Downloaded: %.2fKb - Speed: %.3fkb/s<span style="color: #000099; font-weight: bold;">\r</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>percent, progress, downspeed<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> download<span style="color: black;">&#40;</span>source, target<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">global</span> starttime
    starttime = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    filename, headers = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlretrieve</span><span style="color: black;">&#40;</span>source, target, transfer_progress<span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Complete: 100%<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> ss <span style="color: #ff7700;font-weight:bold;">in</span> headers:
        <span style="color: #ff7700;font-weight:bold;">if</span> ss.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == <span style="color: #483d8b;">&quot;content-disposition&quot;</span>:
            filename = headers<span style="color: black;">&#91;</span>ss<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>headers<span style="color: black;">&#91;</span>ss<span style="color: black;">&#93;</span>.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;filename=&quot;</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">9</span>:<span style="color: black;">&#93;</span>  <span style="color: #808080; font-style: italic;"># 9 is len(&quot;filename=&quot;)=9</span>
    <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlcleanup</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>     <span style="color: #808080; font-style: italic;"># Clear the cache</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> filename
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> verify_file<span style="color: black;">&#40;</span>remote_md5sum, filename<span style="color: black;">&#41;</span>:
    f = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>filename, <span style="color: #483d8b;">&quot;rb&quot;</span><span style="color: black;">&#41;</span>
    m = <span style="color: #dc143c;">md5</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        block = f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">32384</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> block:
            <span style="color: #ff7700;font-weight:bold;">break</span>
        m.<span style="color: black;">update</span><span style="color: black;">&#40;</span>block<span style="color: black;">&#41;</span>
    md5sum = m.<span style="color: black;">hexdigest</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> md5sum == remote_md5sum
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">2</span>:
        error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Need Rapidshare link as argument'</span><span style="color: black;">&#41;</span>
&nbsp;
    file_link = <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        rapidshare_com, files, fileid, filename = file_link.<span style="color: black;">rsplit</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">4</span>:<span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
        error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Invalid Rapidshare link'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> rapidshare_com.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'rapidshare.com'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">or</span> files <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">'files'</span>:
        error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Invalid Rapidshare link'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> USE_SSL:
        proto = <span style="color: #483d8b;">'https'</span>
        info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'SSL is enabled'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        proto = <span style="color: #483d8b;">'http'</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> VERIFY_MD5SUM:
        info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'MD5 sum verification is enabled'</span><span style="color: black;">&#41;</span>
&nbsp;
    info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Downloading: %s'</span> <span style="color: #66cc66;">%</span> file_link<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> filename.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.html'</span><span style="color: black;">&#41;</span>:
        target_filename = filename<span style="color: black;">&#91;</span>:-<span style="color: #ff4500;">5</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        target_filename = filename
    info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Save file as: %s'</span> <span style="color: #66cc66;">%</span> target_filename<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># API parameters</span>
&nbsp;
    params = <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'sub'</span>: <span style="color: #483d8b;">'download_v1'</span>,
        <span style="color: #483d8b;">'fileid'</span>: fileid,
        <span style="color: #483d8b;">'filename'</span>: filename,
        <span style="color: #483d8b;">'try'</span>: <span style="color: #483d8b;">'1'</span>,
        <span style="color: #483d8b;">'withmd5hex'</span>: <span style="color: #483d8b;">'0'</span>,
        <span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> VERIFY_MD5SUM:
        params.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
            <span style="color: #483d8b;">'withmd5hex'</span>: <span style="color: #483d8b;">'1'</span>,
            <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> LOGIN <span style="color: #ff7700;font-weight:bold;">and</span> PASSWORD:
        params.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
            <span style="color: #483d8b;">'login'</span>: LOGIN,
            <span style="color: #483d8b;">'password'</span>: PASSWORD,
            <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
&nbsp;
    params_string = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span>params<span style="color: black;">&#41;</span>
&nbsp;
    api_url = <span style="color: #483d8b;">'%s://api.rapidshare.com/cgi-bin/rsapi.cgi'</span> <span style="color: #66cc66;">%</span> proto
&nbsp;
    <span style="color: #808080; font-style: italic;"># Get the first error response</span>
    conn = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s?%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>api_url, params_string<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    data = conn.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;">#print data</span>
    conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Parse response</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        key, value = data.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">':'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
        error<span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        server, dlauth, countdown, remote_md5sum = value.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">','</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
        error<span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Wait for n seconds (free accounts only)</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>countdown<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">for</span> t <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>countdown<span style="color: black;">&#41;</span>, <span style="color: #ff4500;">0</span>, -<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>:
            <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Waiting for %s seconds...<span style="color: #000099; font-weight: bold;">\r</span>'</span> <span style="color: #66cc66;">%</span> t<span style="color: black;">&#41;</span>
            <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Waited for %s seconds. Proceeding with file download...'</span> <span style="color: #66cc66;">%</span> countdown<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># API parameters for file download</span>
&nbsp;
    dl_params = <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'sub'</span>: <span style="color: #483d8b;">'download_v1'</span>,
        <span style="color: #483d8b;">'fileid'</span>: fileid,
        <span style="color: #483d8b;">'filename'</span>: filename,
        <span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> LOGIN <span style="color: #ff7700;font-weight:bold;">and</span> PASSWORD:
        dl_params.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
            <span style="color: #483d8b;">'login'</span>: LOGIN,
            <span style="color: #483d8b;">'password'</span>: PASSWORD,
            <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        dl_params.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
            <span style="color: #483d8b;">'dlauth'</span>: dlauth,
            <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
&nbsp;
    dl_params_string = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span>dl_params<span style="color: black;">&#41;</span>
&nbsp;
    download_link = <span style="color: #483d8b;">'%s://%s/cgi-bin/rsapi.cgi?%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>proto, server, dl_params_string<span style="color: black;">&#41;</span>
&nbsp;
    downloaded_filename = download<span style="color: black;">&#40;</span>download_link, target_filename<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> VERIFY_MD5SUM:
        <span style="color: #ff7700;font-weight:bold;">if</span> remote_md5sum.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == <span style="color: #483d8b;">'not found'</span>:
            info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Remote MD5 sum is not available. Skipping MD5 sum verification...'</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> downloaded_filename:
            <span style="color: #ff7700;font-weight:bold;">if</span> verify_file<span style="color: black;">&#40;</span>remote_md5sum.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, downloaded_filename<span style="color: black;">&#41;</span>:
                info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Downloaded and verified %s'</span> <span style="color: #66cc66;">%</span> downloaded_filename<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'The downloaded file could not be verified'</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Will not verify. File not found: %s'</span> <span style="color: #66cc66;">%</span> downloaded_filename<span style="color: black;">&#41;</span>
&nbsp;
    info<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Operation Complete'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">KeyboardInterrupt</span>:
        error<span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>Aborted'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Save the code in a file called: <strong>rsapiget.py</strong></p>
<p>Usage is very simple:</p>
<pre class="console">
python rsapiget.py &lt;rapidshare_link&gt;
</pre>
<p>There are some configuration options at the top of the script you may need to check out:</p>
<ul>
<li><strong>LOGIN</strong>, <strong>PASSWORD</strong>: If you are a registered Pro user, set your username and password here. Being a pro user you will never have to wait for the download to start. Otherwise leave blank.</li>
<li><strong>USE_SSL</strong>: Set to <em>True</em> to force the client to communicate with the rapidshare servers over an encrypted connection. Note that, according to the docs, this is more expensive in terms of Rapidshare points, so it is disabled by default.</li>
<li><strong>VERIFY_MD5SUM</strong>: If this is set to <em>True</em>, the downloaded file&#8217;s integrity will be verified. The docs say that this results in more API calls than not using md5 verification, so this is disabled by default as well.</li>
</ul>
<p>Although the old article has a small download server implementation in BASH, I haven&#8217;t tested whether the latter works with this client or not.</p>
<p>Please note that this script is <em>work in progress</em> and I might update the code in the following days. So, <strong>check back often for updates</strong>.</p>
<h4>Download from Rapidshare API using wget</h4>
<p>All credit for this method goes to <strong>sharkic</strong> (see comments).</p>
<p>I admit that when I was checking out the API, I had completely overlooked the <em>withcookie</em> option of the <em>getaccountdetails_v1</em> subroutine. Also, I was not aware that it is now possible for free users to have an account with Rapidshare.</p>
<p>So, to sum <em>sharkic</em>&#8216;s feedback up, here is how it is done. The following information requires that you have signed up with Rapidshare. Of course downloading files using wget and the following instructions requires a Rapidshare Pro account.</p>
<p>First, <strong>save the cookie data</strong>. This has to be done <strong>once</strong>:</p>
<pre class="console">
wget -q -O - \
    --post-data="sub=getaccountdetails_v1&#038;withcookie=1&#038;login=LOGIN&#038;password=PASSWORD" \
    https://api.rapidshare.com/cgi-bin/rsapi.cgi \
    | grep cookie | cut -d '=' -f 2 > .rapidshare_cookie
</pre>
<p>Substitute LOGIN and PASSWORD with your Rapidshare account&#8217;s username and password.</p>
<p>Now, you can download files using:</p>
<pre class="console">
wget --no-cookies --header="Cookie: enc=`cat .rapidshare_cookie`" http://rapidshare.com/files/XXXXXXXX/test.zip
</pre>
<h4>Download from Rapidshare API using curl</h4>
<p>The <strong>curl</strong> method is a derivative of the wget method. First save the cookie with:</p>
<pre class="console">
curl --data "sub=getaccountdetails_v1&#038;withcookie=1&#038;login=LOGIN&#038;password=PASSWORD" \
    https://api.rapidshare.com/cgi-bin/rsapi.cgi \
    | grep cookie | cut -d '=' -f 2 > .rapidshare_cookie
</pre>
<p>Substitute LOGIN and PASSWORD with your Rapidshare account&#8217;s username and password.</p>
<p>Now, you can download files using:</p>
<pre class="console">
curl -L -O --cookie "enc=`cat .rapidshare_cookie`" http://rapidshare.com/files/XXXXXXXX/test.zip
</pre>
<p>Enjoy! Your feedback is welcome.</p>
<p class="cc-block"><em><a href="http://www.g-loaded.eu/2010/10/04/rsapiget-download-rapidshare-api/">rsapiget downloads files using the new Rapidshare API</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>.</p>
<h4>Related Articles</h4>

<ul><li><a href="http://www.g-loaded.eu/2007/09/15/use-wget-or-curl-to-download-from-rapidshare-premium/" rel="bookmark">Use wget or curl to download from RapidShare Premium</a></li>
<li><a href="http://www.g-loaded.eu/2008/12/18/using-the-mod_dav_svn-svnparentpath-directive-with-multiple-authz-files/" rel="bookmark">Using the mod_dav_svn SVNParentPath directive with multiple authz files</a></li>
<li><a href="http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/" rel="bookmark">Descramble Passwords from gftp Bookmarks using Python</a></li>
<li><a href="http://www.g-loaded.eu/2012/03/26/restore-original-configuration-files-from-rpm-packages/" rel="bookmark">Restore original configuration files from RPM packages</a></li>
<li><a href="http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/" rel="bookmark">VeriTAR &#8211; Verify checksums of files within a TAR archive</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2010/10/04/rsapiget-download-rapidshare-api/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>PHP Interactive Interpreter</title>
		<link>http://www.g-loaded.eu/2010/04/13/php-interactive-interpreter/</link>
		<comments>http://www.g-loaded.eu/2010/04/13/php-interactive-interpreter/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 13:16:42 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://www.g-loaded.eu/?p=1157</guid>
		<description><![CDATA[The PHP interpreter supports running it in interactive mode by using the --interactive (short equivalent: -a) command-line switch. Running an interactive PHP shell can be useful when you need to quickly try code snippets. But, for this mode to be fully functional, PHP has to be compiled with readline support. Unfortunately, on CentOS PHP has [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://php.net">PHP</a> interpreter supports running it in interactive mode by using the <code>--interactive</code> (short equivalent: <code>-a</code>) command-line switch. Running an interactive PHP shell can be useful when you need to quickly try code snippets. But, for this mode to be fully functional, PHP has to be compiled with <strong>readline</strong> support. Unfortunately, on <strong>CentOS</strong> PHP has not been compiled this way.<br />
<span id="more-1157"></span><br />
You can check the PHP compile-time configuration switches, by invoking the following command:</p>
<pre class="console">
php --info | grep -i 'configure command'
</pre>
<p>While searching for a solution about this, I ran across an interesting project, <a href="http://david.acz.org/phpa/">phpa</a>. From the developer:</p>
<blockquote><p>
phpa is an interactive command line shell for PHP.</p>
<p>It is a replacement for the interactive mode of the PHP interpreter (php -a), hence the name.</p>
<p>This software is public domain.
</p></blockquote>
<p>Before using it, make sure <strong>php-readline</strong> is installed:</p>
<pre class="console">
yum install php-readline
</pre>
<p>I downloaded <strong>phpa</strong> and set the <strong>executable</strong> bit as shown below:</p>
<pre class="console">
wget -O - http://david.acz.org/phpa/phpa.txt > ~/bin/phpa
chmod +x ~/bin/phpa
</pre>
<p>I also had to fix the bad <a href="http://en.wikipedia.org/wiki/Shebang_(Unix)">shebang</a>:</p>
<pre class="console">
sed -i 's#/usr/local/bin/php#/usr/bin/php#' ~/bin/phpa
</pre>
<p>Finally, an interactive PHP shell! Now running code snippets from the <a href="http://php.net/manual/en/index.php">PHP manual</a> is fun:</p>
<pre class="console">
[rocky@arena ~]$ phpa
PHP 5.1.6 (cli) (Jan 13 2010 17:05:38) [Linux]
>>> $arr = array("somearray" => array(6 => 5, 13 => 9, "a" => 42));
>>>
>>> echo $arr["somearray"][6];    // 5
5
>>> echo $arr["somearray"][13];   // 9
9
>>> echo $arr["somearray"]["a"];  // 42
42
>>>
</pre>
<p>Enjoy your new PHP interactive interpreter!</p>
<p class="cc-block"><em><a href="http://www.g-loaded.eu/2010/04/13/php-interactive-interpreter/">PHP Interactive Interpreter</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>.</p>
<h4>Related Articles</h4>

  <p>No related articles.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2010/04/13/php-interactive-interpreter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>From Subversion to Mercurial</title>
		<link>http://www.g-loaded.eu/2010/04/08/from-subversion-to-mercurial/</link>
		<comments>http://www.g-loaded.eu/2010/04/08/from-subversion-to-mercurial/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 12:33:59 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Maintenance]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://www.g-loaded.eu/?p=1693</guid>
		<description><![CDATA[I&#8217;ve been using the Subversion version control system during the last 2-3 years. Although a VCS has never been a top priority for me, it seems there is always room for version control. I ended up using it for almost everything, from simple to more complex scripts and even system configuration files in some cases. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using the <a href="http://subversion.tigris.org/">Subversion</a> <em>version control system</em> during the last 2-3 years. Although a <em>VCS</em> has never been a top priority for me, it seems there is always room for version control. I ended up using it for almost everything, from simple to more complex scripts and even system configuration files in some cases. A few weeks ago I decided to switch to <a href="http://mercurial.selenic.com/">Mercurial</a>. I had read about Mercurial for the first time in some mailing list messages written by <a href="http://keramida.wordpress.com">Giorgos Keramidas</a> and also in several <a href="http://keramida.wordpress.com/tag/mercurial/">posts about Mercurial</a> on his blog, but it was only a few months ago when I started experimenting with it for real. Although I use many of its features, my general use of version control systems is rather basic, so do not expect any sophisticated reasons why I have decided to switch:<br />
<span id="more-1693"></span></p>
<ol>
<li>It&#8217;s open-source software, written in <a href="http://python.org">Python</a>. This is very important for me as there is not much room in my head right now for other programming languages.</li>
<li>Easily extensible. If I ever need a special feature I will have the opportunity to implement it by writing a Python extension.</li>
<li>I got rid of those <code>.svn</code> directories.</li>
<li>I can use <a href="http://code.google.com/p/modwsgi/">mod_wsgi</a> and all its good features to provide repository access over HTTP/HTTPS.</li>
<li>I find the concept of a &#8220;<strong>distributed version control system</strong>&#8221; to be real progress in the VCS area.</li>
</ol>
<p>Truth is I will not stop using Subversion, but I will definitely choose Mercurial instead of SVN for any new project I start.</p>
<p class="cc-block"><em><a href="http://www.g-loaded.eu/2010/04/08/from-subversion-to-mercurial/">From Subversion to Mercurial</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>.</p>
<h4>Related Articles</h4>

<ul><li><a href="http://www.g-loaded.eu/2006/09/12/setting-up-subversion-and-websvn/" rel="bookmark">Setting up Subversion and WebSVN</a></li>
<li><a href="http://www.g-loaded.eu/2010/04/12/a-change-of-plans-regarding-a-web-based-vcs-manager/" rel="bookmark">A change of plans regarding a web-based VCS manager</a></li>
<li><a href="http://www.g-loaded.eu/2009/09/21/redmine/" rel="bookmark">Redmine</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2010/04/08/from-subversion-to-mercurial/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Python SSH Server for UNIX Systems using Twisted.conch</title>
		<link>http://www.g-loaded.eu/2010/03/26/python-ssh-server-unix-twisted-conch/</link>
		<comments>http://www.g-loaded.eu/2010/03/26/python-ssh-server-unix-twisted-conch/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 20:27:00 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Administration]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Remote]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Twisted]]></category>

		<guid isPermaLink="false">http://www.g-loaded.eu/?p=1572</guid>
		<description><![CDATA[I can still recall the excitement of the first time I tried to access and administer a remote system using SSH. Accessing my shell at a remote machine securely, being able to do local and remote port forwarding in order to access remote services through encrypted tunnels, X forwarding, secure file transfers using scp or [...]]]></description>
			<content:encoded><![CDATA[<p>I can still recall the excitement of the first time I tried to access and administer a remote system using <strong>SSH</strong>. Accessing my shell at a remote machine securely, being able to do local and remote port forwarding in order to access remote services through encrypted tunnels, X forwarding, secure file transfers using <em>scp</em> or <em>sftp</em>, <a href="http://www.g-loaded.eu/2005/11/10/ssh-with-keys/">authentication using public key infrastructure</a> are just a few of the features that justify the excitement of the first time. The only <em>Secure Shell</em> server implementation I had used all that time was the <a href="http://www.openssh.com/">OpenSSH</a> server. Although this is an open-source project, the fact that it is written in C makes it extremely difficult for me to have fun with it by making any modifications in order to implement even simple things like command filtering. This is because I have never programmed in <strong>C</strong> and do not intend to learn how to do it in the foreseeable future. So what I&#8217;ve been looking for today was a server implementation of the <strong>SSH2 protocol</strong> written in <a href="http://python.org">Python</a>. Unfortunately, there is no such project ready for immediate use. I had to hack my own! After several hours of trial and error, having written dozens of sample scripts for testing, I finally created a minimal project, called <strong>RapidSSH</strong>, in order to demonstrate how to create a fully functional SSH server with just a few lines of Python code by using <em>Twisted.conch</em>, part of the <a href="http://twistedmatrix.com">Twisted Framework</a>. Read on&#8230;<br />
<span id="more-1572"></span><br />
At first, I tried to experiment with the <a href="http://twistedmatrix.com/documents/current/conch/examples/sshsimpleserver.py">sshsimpleserver.py</a> example script that exists on the Twisted homepage. But, soon I realized that this script is there just to give an idea about how to use <code>Twisted.conch</code> and also provide a sensible starting point for your own implementations. That script was not even close in having the functionality I had in mind. After spending some time examining the Twisted source code, I found a fantastic, but completely undocumented, module: <a href="http://twistedmatrix.com/trac/browser/trunk/twisted/conch/unix.py">twisted.conch.unix</a>. Having gained some experience by my experimentation with <code>sshsimpleserver.py</code> I managed to easily put the pieces together and come up with the SSH server implementation as shown below.</p>
<p>But first, let&#8217;s install some <strong>dependencies</strong>. I assume that you will try the code on a machine aimed for testing, so I won&#8217;t be using the system&#8217;s package manager but instead use <strong>easy_install</strong> to install the needed Python modules. Other commands like <em>pip</em> could be used as well. If you do not want to mess with your system-wide python installation, just use <strong>virtualenv</strong> and <strong>pip</strong>, but I won&#8217;t go into the details about how to use these tools in the current document.</p>
<p>Install the needed dependencies:</p>
<pre class="console">
easy_install pycrypto
easy_install pyasn1
easy_install pam
easy_install twisted
</pre>
<p>Make sure you have <strong>gcc</strong> installed, because it will be needed to complete the installation of Twisted and PyCrypto.</p>
<p>I have created a project for this code at <strong>Bitbucket</strong>, called <a href="http://bitbucket.org/gnotaras/rapidssh/">RapidSSH</a>. This will make it easier to share code and ideas about SSH server implementations in Python using Twisted.</p>
<p>Filename: <code>scripts/rapidsshd_unix.py</code></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># This file is part of rapidssh - http://bitbucket.org/gnotaras/rapidssh/</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># rapidssh - A set of Secure Shell (SSH) server implementations in Python</span>
<span style="color: #808080; font-style: italic;">#            using Twisted.conch, part of the Twisted Framework.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># Copyright (c) 2010 George Notaras - http://www.g-loaded.eu</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># Permission is hereby granted, free of charge, to any person obtaining a copy</span>
<span style="color: #808080; font-style: italic;"># of this software and associated documentation files (the &quot;Software&quot;), to deal</span>
<span style="color: #808080; font-style: italic;"># in the Software without restriction, including without limitation the rights</span>
<span style="color: #808080; font-style: italic;"># to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span>
<span style="color: #808080; font-style: italic;"># copies of the Software, and to permit persons to whom the Software is</span>
<span style="color: #808080; font-style: italic;"># furnished to do so, subject to the following conditions:</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># The above copyright notice and this permission notice shall be included in</span>
<span style="color: #808080; font-style: italic;"># all copies or substantial portions of the Software.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span>
<span style="color: #808080; font-style: italic;"># IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span>
<span style="color: #808080; font-style: italic;"># FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE</span>
<span style="color: #808080; font-style: italic;"># AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span>
<span style="color: #808080; font-style: italic;"># LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span>
<span style="color: #808080; font-style: italic;"># OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN</span>
<span style="color: #808080; font-style: italic;"># THE SOFTWARE.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># Initially based on the sshsimpleserver.py kindly published by:</span>
<span style="color: #808080; font-style: italic;"># Twisted Matrix Laboratories - http://twistedmatrix.com</span>
<span style="color: #808080; font-style: italic;">#</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> pam
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">conch</span>.<span style="color: black;">unix</span> <span style="color: #ff7700;font-weight:bold;">import</span> UnixSSHRealm
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">cred</span> <span style="color: #ff7700;font-weight:bold;">import</span> portal
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">cred</span>.<span style="color: black;">credentials</span> <span style="color: #ff7700;font-weight:bold;">import</span> IUsernamePassword
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">cred</span>.<span style="color: black;">checkers</span> <span style="color: #ff7700;font-weight:bold;">import</span> ICredentialsChecker
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">cred</span>.<span style="color: black;">error</span> <span style="color: #ff7700;font-weight:bold;">import</span> UnauthorizedLogin
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">conch</span>.<span style="color: black;">checkers</span> <span style="color: #ff7700;font-weight:bold;">import</span> SSHPublicKeyDatabase
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">conch</span>.<span style="color: black;">ssh</span> <span style="color: #ff7700;font-weight:bold;">import</span> factory, userauth, connection, keys, session
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">internet</span> <span style="color: #ff7700;font-weight:bold;">import</span> reactor, defer
<span style="color: #ff7700;font-weight:bold;">from</span> zope.<span style="color: black;">interface</span> <span style="color: #ff7700;font-weight:bold;">import</span> implements
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">python</span> <span style="color: #ff7700;font-weight:bold;">import</span> log
&nbsp;
<span style="color: #808080; font-style: italic;"># Logging</span>
<span style="color: #808080; font-style: italic;"># Currently logging to STDERR</span>
log.<span style="color: black;">startLogging</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Server-side public and private keys. These are the keys found in</span>
<span style="color: #808080; font-style: italic;"># sshsimpleserver.py. Make sure you generate your own using ssh-keygen!</span>
&nbsp;
publicKey = <span style="color: #483d8b;">'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEArzJx8OYOnJmzf4tfBEvLi8DVPrJ3/c9k2I/Az64fxjHf9imyRJbixtQhlH9lfNjUIx+4LmrJH5QNRsFporcHDKOTwTTYLh5KmRpslkYHRivcJSkbh/C+BR3utDS555mV'</span>
&nbsp;
privateKey = <span style="color: #483d8b;">&quot;&quot;&quot;-----BEGIN RSA PRIVATE KEY-----
MIIByAIBAAJhAK8ycfDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW
4sbUIZR/ZXzY1CMfuC5qyR+UDUbBaaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fw
vgUd7rQ0ueeZlQIBIwJgbh+1VZfr7WftK5lu7MHtqE1S1vPWZQYE3+VUn8yJADyb
Z4fsZaCrzW9lkIqXkE3GIY+ojdhZhkO1gbG0118sIgphwSWKRxK0mvh6ERxKqIt1
xJEJO74EykXZV4oNJ8sjAjEA3J9r2ZghVhGN6V8DnQrTk24Td0E8hU8AcP0FVP+8
PQm/g/aXf2QQkQT+omdHVEJrAjEAy0pL0EBH6EVS98evDCBtQw22OZT52qXlAwZ2
gyTriKFVoqjeEjt3SZKKqXHSApP/AjBLpF99zcJJZRq2abgYlf9lv1chkrWqDHUu
DZttmYJeEfiFBBavVYIF1dOlZT0G8jMCMBc7sOSZodFnAiryP+Qg9otSBjJ3bQML
pSTqy7c3a2AScC/YyOwkDaICHnnD3XyjMwIxALRzl0tQEKMXs6hH8ToUdlLROCrP
EhQ0wahUTCk1gKA4uPD6TMTChavbh4K63OvbKg==
-----END RSA PRIVATE KEY-----&quot;&quot;&quot;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> PamPasswordDatabase:
    <span style="color: #483d8b;">&quot;&quot;&quot;Authentication/authorization backend using the 'login' PAM service&quot;&quot;&quot;</span>
    credentialInterfaces = IUsernamePassword,
    implements<span style="color: black;">&#40;</span>ICredentialsChecker<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> requestAvatarId<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, credentials<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> pam.<span style="color: black;">authenticate</span><span style="color: black;">&#40;</span>credentials.<span style="color: black;">username</span>, credentials.<span style="color: black;">password</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> defer.<span style="color: black;">succeed</span><span style="color: black;">&#40;</span>credentials.<span style="color: black;">username</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> defer.<span style="color: black;">fail</span><span style="color: black;">&#40;</span>UnauthorizedLogin<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;invalid password&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> UnixSSHdFactory<span style="color: black;">&#40;</span>factory.<span style="color: black;">SSHFactory</span><span style="color: black;">&#41;</span>:
    publicKeys = <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'ssh-rsa'</span>: keys.<span style="color: black;">Key</span>.<span style="color: black;">fromString</span><span style="color: black;">&#40;</span>data=publicKey<span style="color: black;">&#41;</span>
    <span style="color: black;">&#125;</span>
    privateKeys = <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'ssh-rsa'</span>: keys.<span style="color: black;">Key</span>.<span style="color: black;">fromString</span><span style="color: black;">&#40;</span>data=privateKey<span style="color: black;">&#41;</span>
    <span style="color: black;">&#125;</span>
    services = <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'ssh-userauth'</span>: userauth.<span style="color: black;">SSHUserAuthServer</span>,
        <span style="color: #483d8b;">'ssh-connection'</span>: connection.<span style="color: black;">SSHConnection</span>
    <span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Components have already been registered in twisted.conch.unix</span>
&nbsp;
portal = portal.<span style="color: black;">Portal</span><span style="color: black;">&#40;</span>UnixSSHRealm<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
portal.<span style="color: black;">registerChecker</span><span style="color: black;">&#40;</span>PamPasswordDatabase<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>   <span style="color: #808080; font-style: italic;"># Supports PAM</span>
portal.<span style="color: black;">registerChecker</span><span style="color: black;">&#40;</span>SSHPublicKeyDatabase<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;"># Supports PKI</span>
UnixSSHdFactory.<span style="color: black;">portal</span> = portal
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    reactor.<span style="color: black;">listenTCP</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5022</span>, UnixSSHdFactory<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    reactor.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Some notes:</p>
<ul>
<li>The server uses the very same public and private keys as found in the <code>sshsimpleserver.py</code> script. Make sure you generate new keys using <strong>ssh-keygen</strong> if you plan to run this on a public server (although this not recommended).</li>
<li>Twisted included a module for PAM authentication, <code>twisted.cred.pamauth</code>, but unfortunately I could not locate one of its dependencies to make it work. So, I used the excellent <a href="http://atlee.ca/software/pam/">python-pam</a> to create a custom PAM authenticator class.</li>
<li>I can guess what you might thought when you read about this code:<br />
<blockquote>Python is a cross-platform programming language. Twisted runs on Windows. So, is this a solution for running a SSH server on Win32?</p></blockquote>
<p> Well, at the moment it won&#8217;t run because internally it uses some Python modules that are available on UNIX platforms only. But, I intend to investigate the possibility of running this on <strong>Windows</strong> since I already need something like that.</li>
</ul>
<p>We can now enjoy our Python SSH server. Run as root:</p>
<pre class="console">
python scripts/rapidsshd_unix.py
</pre>
<p>From another machine, connect to the server using an <em>ssh client</em>:</p>
<pre class="console">
ssh -p 5022 rocky@arena
</pre>
<p>If you have deployed your public key in the <code>~/.ssh/authorized_keys</code> file on the remote machine (<em>arena</em>), you should be able to authenticate using the public key:</p>
<pre class="console">
ssh -p 5022 -i /path/to/private.key rocky@arena
</pre>
<p>You should get output like the following on the server:</p>
<pre class="console">
[root@arena ~]# python ssh.py
2010-03-26 21:30:05+0000 [-] Log opened.
2010-03-26 21:30:05+0000 [-] __main__.UnixSSHdFactory starting on 5022
2010-03-26 21:30:05+0000 [-] Starting factory <__main__.UnixSSHdFactory instance at 0xb7a0b0cc>
2010-03-26 21:30:13+0000 [__main__.UnixSSHdFactory] disabling diffie-hellman-group-exchange because we cannot find moduli file
2010-03-26 21:30:13+0000 [SSHServerTransport,0,192.168.0.172] kex alg, key alg: diffie-hellman-group1-sha1 ssh-rsa
2010-03-26 21:30:13+0000 [SSHServerTransport,0,192.168.0.172] outgoing: aes256-ctr hmac-sha1 none
2010-03-26 21:30:13+0000 [SSHServerTransport,0,192.168.0.172] incoming: aes256-ctr hmac-sha1 none
2010-03-26 21:30:14+0000 [SSHServerTransport,0,192.168.0.172] NEW KEYS
2010-03-26 21:30:14+0000 [SSHServerTransport,0,192.168.0.172] starting service ssh-userauth
2010-03-26 21:30:17+0000 [SSHService ssh-userauth on SSHServerTransport,0,192.168.0.172] rocky trying auth none
2010-03-26 21:30:17+0000 [SSHService ssh-userauth on SSHServerTransport,0,192.168.0.172] rocky trying auth publickey
2010-03-26 21:30:17+0000 [SSHService ssh-userauth on SSHServerTransport,0,192.168.0.172] rocky trying auth publickey
2010-03-26 21:30:17+0000 [SSHService ssh-userauth on SSHServerTransport,0,192.168.0.172] rocky authenticated with publickey
2010-03-26 21:30:17+0000 [SSHService ssh-userauth on SSHServerTransport,0,192.168.0.172] starting service ssh-connection
2010-03-26 21:30:17+0000 [SSHService ssh-connection on SSHServerTransport,0,192.168.0.172] got channel session request
2010-03-26 21:30:17+0000 [SSHChannel session (0) on SSHService ssh-connection on SSHServerTransport,0,192.168.0.172] channel open
2010-03-26 21:30:17+0000 [SSHChannel session (0) on SSHService ssh-connection on SSHServerTransport,0,192.168.0.172] pty request: xterm (24L, 80L, 0L, 0L)
2010-03-26 21:30:17+0000 [SSHChannel session (0) on SSHService ssh-connection on SSHServerTransport,0,192.168.0.172] getting shell
</pre>
<p>This first release of the <a href="http://bitbucket.org/gnotaras/rapidssh/">RapidSSH</a> project exists solely for demonstration purposes. Don&#8217;t get fooled by the small amount of code. Information about how to put the pieces together is scarce and it required a lot trial&#038;error and source code reading. The above implementation contains none of the customizations I had in mind. These will be done as soon as I find some time to do so. Until then it will be nice to hear about your experiences or implementations you have worked on.</p>
<p class="cc-block"><em><a href="http://www.g-loaded.eu/2010/03/26/python-ssh-server-unix-twisted-conch/">Python SSH Server for UNIX Systems using Twisted.conch</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>.</p>
<h4>Related Articles</h4>

<ul><li><a href="http://www.g-loaded.eu/2006/05/17/epiphany-python-console-open-new-tab/" rel="bookmark">Epiphany Python Console &#8211; Open New Tab</a></li>
<li><a href="http://www.g-loaded.eu/2007/01/31/python-irc-bot/" rel="bookmark">Python IRC Bot</a></li>
<li><a href="http://www.g-loaded.eu/2006/04/07/python-crash-course/" rel="bookmark">Python Crash Course</a></li>
<li><a href="http://www.g-loaded.eu/2005/11/10/configure-vnc-server-in-fedora/" rel="bookmark">Set up the VNC Server in Fedora</a></li>
<li><a href="http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/" rel="bookmark">Descramble Passwords from gftp Bookmarks using Python</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2010/03/26/python-ssh-server-unix-twisted-conch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>ping.py &#8211; Python Implementation of the ping command</title>
		<link>http://www.g-loaded.eu/2009/10/30/python-ping/</link>
		<comments>http://www.g-loaded.eu/2009/10/30/python-ping/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 18:54:18 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://www.g-loaded.eu/?p=1408</guid>
		<description><![CDATA[I&#8217;ve been looking for a pure python implementation of the ping command. Now that I found one, I am not sure if I want to use it, as it has a restriction: only privileged users can ping other hosts. I&#8217;ve used the ping command successfully as a normal user on all operating systems I have [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been looking for a pure python implementation of the <strong>ping</strong> command. Now that I found one, I am not sure if I want to use it, as it has a <em>restriction</em>: only privileged users can ping other hosts. I&#8217;ve used the ping command successfully as a normal user on all operating systems I have tried and never had an issue. Currently, I do not have the time to investigate this limitation, but, judging by the exception I get, it has to do with the creation of the socket through which the ICMP packet is sent. The normal user does not have the required privileges to create this socket.</p>
<p>[This post has been updated]<br />
<span id="more-1408"></span><br />
[<strong>Update #1</strong>]: This limitation also exists on the <strong>ping</strong> command, which runs with <strong>setuid</strong> access rights. (Thanks <a href="http://www.sakana.fr/blog/">Stephane</a>)</p>
<p>[<strong>Update #2</strong>]: After <a href="http://cdhallman.blogspot.com">Chris Hallman</a> reported that the original code actually works on Windows only, I made some changes to it and publish the updated code below.</p>
<p>The following code is a pure <strong>Python</strong> implementation of the <strong>ping</strong> command. I originally found it in the <a href="http://trac.pylucid.net/browser/CodeSnippets/ping.py">source code tree of pylucid</a> in a subdirectory where the developers keep various code snippets.</p>
<p>I had originally tested the code under Microsoft Windows as this was the OS I had available at the moment.  Chris Hallman noticed that the code does not work under GNU/Linux. After spending some hours trying to figure out what was wrong it, I realized that the part of the code that caused the failure on Linux was the use of the <code>time.clock()</code> function instead of <code>time.time()</code>. The <code>clock()</code> method works <a href="http://docs.python.org/library/time.html#time.clock">differently</a> under Windows and Linux.</p>
<p>I fixed the 2007 implementation and hereby publish the updated code(as <a href="http://www.g-loaded.eu/2009/10/30/python-ping/">python-ping</a>). Feel free to test it and report any issues.</p>
<p>Needed: test on Solaris.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;&quot;
    A pure python ping implementation using raw socket.
&nbsp;
&nbsp;
    Note that ICMP messages can only be sent from processes running as root.
&nbsp;
&nbsp;
    Derived from ping.c distributed in Linux's netkit. That code is
    copyright (c) 1989 by The Regents of the University of California.
    That code is in turn derived from code written by Mike Muuss of the
    US Army Ballistic Research Laboratory in December, 1983 and
    placed in the public domain. They have my thanks.
&nbsp;
    Bugs are naturally mine. I'd be glad to hear about them. There are
    certainly word - size dependenceies here.
&nbsp;
    Copyright (c) Matthew Dixon Cowles, &lt;http://www.visi.com/~mdc/&gt;.
    Distributable under the terms of the GNU General Public License
    version 2. Provided with no warranties of any sort.
&nbsp;
    Original Version from Matthew Dixon Cowles:
      -&gt; ftp://ftp.visi.com/users/mdc/ping.py
&nbsp;
    Rewrite by Jens Diemer:
      -&gt; http://www.python-forum.de/post-69122.html#69122
&nbsp;
    Rewrite by George Notaras:
      -&gt; http://www.g-loaded.eu/2009/10/30/python-ping/
&nbsp;
    Revision history
    ~~~~~~~~~~~~~~~~
&nbsp;
    November 8, 2009
    ----------------
    Improved compatibility with GNU/Linux systems.
&nbsp;
    Fixes by:
     * George Notaras -- http://www.g-loaded.eu
    Reported by:
     * Chris Hallman -- http://cdhallman.blogspot.com
&nbsp;
    Changes in this release:
     - Re-use time.time() instead of time.clock(). The 2007 implementation
       worked only under Microsoft Windows. Failed on GNU/Linux.
       time.clock() behaves differently under the two OSes[1].
&nbsp;
    [1] http://docs.python.org/library/time.html#time.clock
&nbsp;
    May 30, 2007
    ------------
    little rewrite by Jens Diemer:
     -  change socket asterisk import to a normal import
     -  replace time.time() with time.clock()
     -  delete &quot;return None&quot; (or change to &quot;return&quot; only)
     -  in checksum() rename &quot;str&quot; to &quot;source_string&quot;
&nbsp;
    November 22, 1997
    -----------------
    Initial hack. Doesn't do much, but rather than try to guess
    what features I (or others) will want in the future, I've only
    put in what I need now.
&nbsp;
    December 16, 1997
    -----------------
    For some reason, the checksum bytes are in the wrong order when
    this is run under Solaris 2.X for SPARC but it works right under
    Linux x86. Since I don't know just what's wrong, I'll swap the
    bytes always and then do an htons().
&nbsp;
    December 4, 2000
    ----------------
    Changed the struct.pack() calls to pack the checksum and ID as
    unsigned. My thanks to Jerome Poincheval for the fix.
&nbsp;
&nbsp;
    Last commit info:
    ~~~~~~~~~~~~~~~~~
    $LastChangedDate: $
    $Rev: $
    $Author: $
&quot;&quot;&quot;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span>, <span style="color: #dc143c;">socket</span>, <span style="color: #dc143c;">struct</span>, <span style="color: #dc143c;">select</span>, <span style="color: #dc143c;">time</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># From /usr/include/linux/icmp.h; your milage may vary.</span>
ICMP_ECHO_REQUEST = <span style="color: #ff4500;">8</span> <span style="color: #808080; font-style: italic;"># Seems to be the same on Solaris.</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> checksum<span style="color: black;">&#40;</span>source_string<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    I'm not too confident that this is right but testing seems
    to suggest that it gives the same answers as in_cksum in ping.c
    &quot;&quot;&quot;</span>
    <span style="color: #008000;">sum</span> = <span style="color: #ff4500;">0</span>
    countTo = <span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>source_string<span style="color: black;">&#41;</span>/<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span>
    count = <span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> count<span style="color: #66cc66;">&lt;</span>countTo:
        thisVal = <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>source_string<span style="color: black;">&#91;</span>count + <span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">256</span> + <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>source_string<span style="color: black;">&#91;</span>count<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">sum</span> = <span style="color: #008000;">sum</span> + thisVal
        <span style="color: #008000;">sum</span> = <span style="color: #008000;">sum</span> <span style="color: #66cc66;">&amp;</span> 0xffffffff <span style="color: #808080; font-style: italic;"># Necessary?</span>
        count = count + <span style="color: #ff4500;">2</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> countTo<span style="color: #66cc66;">&lt;</span>len<span style="color: black;">&#40;</span>source_string<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">sum</span> = <span style="color: #008000;">sum</span> + <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>source_string<span style="color: black;">&#91;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>source_string<span style="color: black;">&#41;</span> - <span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">sum</span> = <span style="color: #008000;">sum</span> <span style="color: #66cc66;">&amp;</span> 0xffffffff <span style="color: #808080; font-style: italic;"># Necessary?</span>
&nbsp;
    <span style="color: #008000;">sum</span> = <span style="color: black;">&#40;</span><span style="color: #008000;">sum</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>  +  <span style="color: black;">&#40;</span><span style="color: #008000;">sum</span> <span style="color: #66cc66;">&amp;</span> 0xffff<span style="color: black;">&#41;</span>
    <span style="color: #008000;">sum</span> = <span style="color: #008000;">sum</span> + <span style="color: black;">&#40;</span><span style="color: #008000;">sum</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>
    answer = ~<span style="color: #008000;">sum</span>
    answer = answer <span style="color: #66cc66;">&amp;</span> 0xffff
&nbsp;
    <span style="color: #808080; font-style: italic;"># Swap bytes. Bugger me if I know why.</span>
    answer = answer <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #ff4500;">8</span> | <span style="color: black;">&#40;</span>answer <span style="color: #66cc66;">&lt;&lt;</span> <span style="color: #ff4500;">8</span> <span style="color: #66cc66;">&amp;</span> 0xff00<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> answer
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> receive_one_ping<span style="color: black;">&#40;</span>my_socket, ID, timeout<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    receive the ping from the socket.
    &quot;&quot;&quot;</span>
    timeLeft = timeout
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        startedSelect = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        whatReady = <span style="color: #dc143c;">select</span>.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>my_socket<span style="color: black;">&#93;</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, timeLeft<span style="color: black;">&#41;</span>
        howLongInSelect = <span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - startedSelect<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> whatReady<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>: <span style="color: #808080; font-style: italic;"># Timeout</span>
            <span style="color: #ff7700;font-weight:bold;">return</span>
&nbsp;
        timeReceived = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        recPacket, addr = my_socket.<span style="color: black;">recvfrom</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1024</span><span style="color: black;">&#41;</span>
        icmpHeader = recPacket<span style="color: black;">&#91;</span><span style="color: #ff4500;">20</span>:<span style="color: #ff4500;">28</span><span style="color: black;">&#93;</span>
        <span style="color: #008000;">type</span>, <span style="color: #dc143c;">code</span>, checksum, packetID, sequence = <span style="color: #dc143c;">struct</span>.<span style="color: black;">unpack</span><span style="color: black;">&#40;</span>
            <span style="color: #483d8b;">&quot;bbHHh&quot;</span>, icmpHeader
        <span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> packetID == ID:
            bytesInDouble = <span style="color: #dc143c;">struct</span>.<span style="color: black;">calcsize</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;d&quot;</span><span style="color: black;">&#41;</span>
            timeSent = <span style="color: #dc143c;">struct</span>.<span style="color: black;">unpack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;d&quot;</span>, recPacket<span style="color: black;">&#91;</span><span style="color: #ff4500;">28</span>:<span style="color: #ff4500;">28</span> + bytesInDouble<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> timeReceived - timeSent
&nbsp;
        timeLeft = timeLeft - howLongInSelect
        <span style="color: #ff7700;font-weight:bold;">if</span> timeLeft <span style="color: #66cc66;">&lt;</span>= <span style="color: #ff4500;">0</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> send_one_ping<span style="color: black;">&#40;</span>my_socket, dest_addr, ID<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    Send one ping to the given &gt;dest_addr&lt;.
    &quot;&quot;&quot;</span>
    dest_addr  =  <span style="color: #dc143c;">socket</span>.<span style="color: black;">gethostbyname</span><span style="color: black;">&#40;</span>dest_addr<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header is type (8), code (8), checksum (16), id (16), sequence (16)</span>
    my_checksum = <span style="color: #ff4500;">0</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Make a dummy heder with a 0 checksum.</span>
    header = <span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;bbHHh&quot;</span>, ICMP_ECHO_REQUEST, <span style="color: #ff4500;">0</span>, my_checksum, ID, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    bytesInDouble = <span style="color: #dc143c;">struct</span>.<span style="color: black;">calcsize</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;d&quot;</span><span style="color: black;">&#41;</span>
    data = <span style="color: black;">&#40;</span><span style="color: #ff4500;">192</span> - bytesInDouble<span style="color: black;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #483d8b;">&quot;Q&quot;</span>
    data = <span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;d&quot;</span>, <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> + data
&nbsp;
    <span style="color: #808080; font-style: italic;"># Calculate the checksum on the data and the dummy header.</span>
    my_checksum = checksum<span style="color: black;">&#40;</span>header + data<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Now that we have the right checksum, we put that in. It's just easier</span>
    <span style="color: #808080; font-style: italic;"># to make up a new header than to stuff it into the dummy.</span>
    header = <span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span>
        <span style="color: #483d8b;">&quot;bbHHh&quot;</span>, ICMP_ECHO_REQUEST, <span style="color: #ff4500;">0</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">htons</span><span style="color: black;">&#40;</span>my_checksum<span style="color: black;">&#41;</span>, ID, <span style="color: #ff4500;">1</span>
    <span style="color: black;">&#41;</span>
    packet = header + data
    my_socket.<span style="color: black;">sendto</span><span style="color: black;">&#40;</span>packet, <span style="color: black;">&#40;</span>dest_addr, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># Don't know about the 1</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> do_one<span style="color: black;">&#40;</span>dest_addr, timeout<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    Returns either the delay (in seconds) or none on timeout.
    &quot;&quot;&quot;</span>
    icmp = <span style="color: #dc143c;">socket</span>.<span style="color: black;">getprotobyname</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;icmp&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        my_socket = <span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">AF_INET</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">SOCK_RAW</span>, icmp<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #dc143c;">socket</span>.<span style="color: black;">error</span>, <span style="color: black;">&#40;</span><span style="color: #dc143c;">errno</span>, msg<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">errno</span> == <span style="color: #ff4500;">1</span>:
            <span style="color: #808080; font-style: italic;"># Operation not permitted</span>
            msg = msg + <span style="color: black;">&#40;</span>
                <span style="color: #483d8b;">&quot; - Note that ICMP messages can only be sent from processes&quot;</span>
                <span style="color: #483d8b;">&quot; running as root.&quot;</span>
            <span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #dc143c;">socket</span>.<span style="color: black;">error</span><span style="color: black;">&#40;</span>msg<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #808080; font-style: italic;"># raise the original error</span>
&nbsp;
    my_ID = <span style="color: #dc143c;">os</span>.<span style="color: black;">getpid</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span> 0xFFFF
&nbsp;
    send_one_ping<span style="color: black;">&#40;</span>my_socket, dest_addr, my_ID<span style="color: black;">&#41;</span>
    delay = receive_one_ping<span style="color: black;">&#40;</span>my_socket, my_ID, timeout<span style="color: black;">&#41;</span>
&nbsp;
    my_socket.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> delay
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> verbose_ping<span style="color: black;">&#40;</span>dest_addr, timeout = <span style="color: #ff4500;">2</span>, count = <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    Send &gt;count&lt; ping to &gt;dest_addr&lt; with the given &gt;timeout&lt; and display
    the result.
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span>count<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;ping %s...&quot;</span> <span style="color: #66cc66;">%</span> dest_addr,
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            delay  =  do_one<span style="color: black;">&#40;</span>dest_addr, timeout<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #dc143c;">socket</span>.<span style="color: black;">gaierror</span>, e:
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;failed. (socket error: '%s')&quot;</span> <span style="color: #66cc66;">%</span> e<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
            <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> delay  ==  <span style="color: #008000;">None</span>:
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;failed. (timeout within %ssec.)&quot;</span> <span style="color: #66cc66;">%</span> timeout
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            delay  =  delay <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">1000</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;get ping in %0.4fms&quot;</span> <span style="color: #66cc66;">%</span> delay
    <span style="color: #ff7700;font-weight:bold;">print</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    verbose_ping<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;heise.de&quot;</span><span style="color: black;">&#41;</span>
    verbose_ping<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;google.com&quot;</span><span style="color: black;">&#41;</span>
    verbose_ping<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;a-test-url-taht-is-not-available.com&quot;</span><span style="color: black;">&#41;</span>
    verbose_ping<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;192.168.1.1&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>I decided not to publish the updated code on <a href="http://www.codetrax.org">CodeTRAX</a>, where I normally publish any programming-related stuff, but leave it on <a href="http://www.g-loaded.eu">G-Loaded</a> instead.</p>
<p class="cc-block"><em><a href="http://www.g-loaded.eu/2009/10/30/python-ping/">ping.py &#8211; Python Implementation of the ping command</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>.</p>
<h4>Related Articles</h4>

<ul><li><a href="http://www.g-loaded.eu/2006/05/06/sockets-programming-in-python/" rel="bookmark">Sockets Programming In Python</a></li>
<li><a href="http://www.g-loaded.eu/2007/01/31/python-irc-bot/" rel="bookmark">Python IRC Bot</a></li>
<li><a href="http://www.g-loaded.eu/2006/04/07/python-crash-course/" rel="bookmark">Python Crash Course</a></li>
<li><a href="http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/" rel="bookmark">Descramble Passwords from gftp Bookmarks using Python</a></li>
<li><a href="http://www.g-loaded.eu/2006/05/17/epiphany-python-console-open-new-tab/" rel="bookmark">Epiphany Python Console &#8211; Open New Tab</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2009/10/30/python-ping/feed/</wfw:commentRss>
		<slash:comments>45</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Descramble Passwords from gftp Bookmarks using Python</title>
		<link>http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/</link>
		<comments>http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/#comments</comments>
		<pubDate>Thu, 07 May 2009 07:21:56 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://www.g-loaded.eu/?p=1119</guid>
		<description><![CDATA[If you check the file where gftp keeps its bookmarks, you will notice that passwords are not stored in clear text. Instead, gftp has used an algorithm to scramble them. I cannot recall if it was one or two years ago when I had decided to write a script to convert the bookmarks from the [...]]]></description>
			<content:encoded><![CDATA[<p>If you check the file where <a href="http://gftp.seul.org/">gftp</a> keeps its bookmarks, you will notice that passwords are not stored in <em>clear text</em>. Instead, gftp has used an algorithm to <em>scramble</em> them. I cannot recall if it was one or two years ago when I had decided to write a script to convert the bookmarks from the gftp format to the FileZilla format, but I do recall that I had to descramble the passwords from the gftp bookmarks and the C code of that password descrambling algorithm had given me a hard time, because I had to port it to Python, since Python was the programming language I intended to use for my bookmark converter. At that time, I happened to hang out at <em>#python</em>, so I had asked for some help there and a kind fellow pythonista had saved the day.<br />
<span id="more-1119"></span><br />
The <strong>original password descrambling algorithm</strong> in C as found in the gftp sources at that time (<em>gftp-2.0.18/lib/misc.c</em>):</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">&nbsp;
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span>
gftp_descramble_password <span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>password<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>passwordpos<span style="color: #339933;">;</span>
  <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>newstr<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>newpos<span style="color: #339933;">;</span>
  <span style="color: #993333;">int</span> error<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>password <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'$'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>g_strdup <span style="color: #009900;">&#40;</span>password<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  passwordpos <span style="color: #339933;">=</span> password <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
  newstr <span style="color: #339933;">=</span> g_malloc <span style="color: #009900;">&#40;</span>strlen <span style="color: #009900;">&#40;</span>passwordpos<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  newpos <span style="color: #339933;">=</span> newstr<span style="color: #339933;">;</span>
&nbsp;
  error <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>passwordpos <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>passwordpos <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>passwordpos <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0xc3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #208080;">0x41</span> <span style="color: #339933;">||</span>
          <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span>passwordpos <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0xc3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #208080;">0x41</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
          error <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
          <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #339933;">*</span>newpos<span style="color: #339933;">++</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>passwordpos <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x3c</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;&lt;</span> <span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span>
                  <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span>passwordpos <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x3c</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;&gt;</span> <span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      passwordpos <span style="color: #339933;">+=</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>error<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      g_free <span style="color: #009900;">&#40;</span>newstr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>g_strdup <span style="color: #009900;">&#40;</span>password<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #339933;">*</span>newpos <span style="color: #339933;">=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>newstr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The following is the Python port of the above code. The person who did the porting wished to remain nameless. The exact answer I got when I had asked about how I should give him credit for the code was:</p>
<blockquote><p>
please don&#8217;t attach my name to it. it&#8217;s horrible, awful code. Consider it public domain, do with it as you wish.
</p></blockquote>
<p>Python port:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> gftp_descrable_password<span style="color: black;">&#40;</span>password<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;gftp password descrambler
&nbsp;
    This code has been released in the Public Domain by the original author.
&nbsp;
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> password.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'$'</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> password
    newpassword = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    pwdparts = <span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #008000;">ord</span>, password<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>pwdparts<span style="color: black;">&#41;</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>pwdparts<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span> <span style="color: #66cc66;">&amp;</span> 0xc3<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= 0x41 <span style="color: #ff7700;font-weight:bold;">or</span>
            <span style="color: black;">&#40;</span>pwdparts<span style="color: black;">&#91;</span>i+<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">&amp;</span> 0xc3<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= 0x41<span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> password
        newpassword.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #008000;">chr</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>pwdparts<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span> <span style="color: #66cc66;">&amp;</span> 0x3c<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&lt;&lt;</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span> +
                               <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>pwdparts<span style="color: black;">&#91;</span>i+<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">&amp;</span> 0x3c<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;&quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>newpassword<span style="color: black;">&#41;</span></pre></div></div>

<p>The only thing I have added to the above code is the <em>docstring</em> so that the function can be reused without licensing issues.</p>
<p>The above snippet has not been thoroughly tested, but it seems to work fine.</p>
<p>As for the bookmark converter, I am not interested in doing it any more.</p>
<p class="cc-block"><em><a href="http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/">Descramble Passwords from gftp Bookmarks using Python</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>.</p>
<h4>Related Articles</h4>

<ul><li><a href="http://www.g-loaded.eu/2006/04/07/python-crash-course/" rel="bookmark">Python Crash Course</a></li>
<li><a href="http://www.g-loaded.eu/2010/03/26/python-ssh-server-unix-twisted-conch/" rel="bookmark">Python SSH Server for UNIX Systems using Twisted.conch</a></li>
<li><a href="http://www.g-loaded.eu/2009/10/30/python-ping/" rel="bookmark">ping.py &#8211; Python Implementation of the ping command</a></li>
<li><a href="http://www.g-loaded.eu/2006/05/06/sockets-programming-in-python/" rel="bookmark">Sockets Programming In Python</a></li>
<li><a href="http://www.g-loaded.eu/2006/05/17/epiphany-python-console-open-new-tab/" rel="bookmark">Epiphany Python Console &#8211; Open New Tab</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2009/05/07/descramble-passwords-from-gftp-bookmarks-using-python/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Drupal Tip: List a node&#8217;s taxonomy terms inside a Block</title>
		<link>http://www.g-loaded.eu/2009/05/07/drupal-tip-list-a-nodes-taxonomy-terms-inside-a-block/</link>
		<comments>http://www.g-loaded.eu/2009/05/07/drupal-tip-list-a-nodes-taxonomy-terms-inside-a-block/#comments</comments>
		<pubDate>Thu, 07 May 2009 01:38:48 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Applications]]></category>
		<category><![CDATA[Customization]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Taxonomy]]></category>

		<guid isPermaLink="false">http://www.g-loaded.eu/?p=1097</guid>
		<description><![CDATA[It&#8217;s been several months since the last time I had done any coding on Drupal. Although many people might find it trivial, here is a PHP snippet to enter in a custom block, so that the taxonomy terms of the currently displayed node are printed as an unordered list inside that block. Also, each list [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been several months since the last time I had done any coding on <a href="http://drupal.org">Drupal</a>. Although many people might find it trivial, here is a PHP snippet to enter in a custom block, so that the <strong>taxonomy terms</strong> of the currently displayed node are printed as an unordered <strong>list</strong> inside that block. Also, each list item will be a <strong>link</strong> pointing to the relevant term page.<br />
<span id="more-1097"></span><br />
First of all, in order to be able to include PHP code, which will be evaluated, inside your posts, it is required to activate the <strong>PHP Filter</strong> module. Double check at <code>admin/settings/filters</code> that only trusted roles can use the PHP filter, otherwise your web site could be at risk. By default, only the administrator can use this filter.</p>
<p>To create the custom block, go to <code>admin/build/block/add</code> and enter a <strong>description</strong> and a <strong>title</strong> for your custom block. Paste the following code on the <strong>body</strong> textarea:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
 * Prints an unordered list of the terms (as links) that are
 * associated to the currently displayed node.
 */</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> arg<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'node'</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">is_numeric</span><span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$node</span> <span style="color: #339933;">=</span> node_load<span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>module_exists<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'taxonomy'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$terms</span> <span style="color: #339933;">=</span> taxonomy_link<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'taxonomy terms'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">print</span> theme<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'links'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$terms</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'class'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'node-terms'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">'No associated categories.'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Make sure you select the <strong>PHP filter</strong> from the list of the <em>input filters</em>. Also, set the rest of the settings according to your needs and save the custom block.</p>
<p>Your new block should be available in the block list in <code>admin/build/block</code> and you should be able to use it straight away.</p>
<p>Now to some technical details about <strong>arg(0)</strong> and <strong>arg(1)</strong>, which probably seem a bit cryptic to a user that is not experienced with Drupal (like me). Assume we have the following <strong>URL</strong> to a node: <code>www.example.org/node/23</code>, which means that the <strong>path</strong> to the page is <code>/node/23</code>. Well, <em>arg(0)</em> is the <code>node</code> part and <em>arg(1)</em> is the second part; <code>23</code> that is. Read about the <a href="http://api.drupal.org/api/function/arg">arg()</a> function.</p>
<p>This should explain the following part of the snippet above:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> arg<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'node'</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">is_numeric</span><span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$node</span> <span style="color: #339933;">=</span> node_load<span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#91;</span><span style="color: #339933;">...</span><span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>I give some emphasis on this as it is a snippet you will use quite often in order to use any of the node object&#8217;s properties inside a block.</p>
<p class="cc-block"><em><a href="http://www.g-loaded.eu/2009/05/07/drupal-tip-list-a-nodes-taxonomy-terms-inside-a-block/">Drupal Tip: List a node&#8217;s taxonomy terms inside a Block</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>.</p>
<h4>Related Articles</h4>

<ul><li><a href="http://www.g-loaded.eu/2009/01/04/always-use-a-block-device-label-or-its-uuid-in-fstab/" rel="bookmark">Always use a block device label or its UUID in fstab</a></li>
<li><a href="http://www.g-loaded.eu/2008/11/27/getting-my-hands-on-drupal/" rel="bookmark">Getting my hands on Drupal</a></li>
<li><a href="http://www.g-loaded.eu/2005/11/10/add-files-to-totem-playing-list-from-nautilus/" rel="bookmark">Add files to Totem playing list from Nautilus</a></li>
<li><a href="http://www.g-loaded.eu/2007/08/20/mailing-list-manager/" rel="bookmark">Mailing List Manager</a></li>
<li><a href="http://www.g-loaded.eu/2007/11/04/backslashes-inside-pre-html-tags-in-wordpress/" rel="bookmark">Backslashes inside pre HTML tags in WordPress</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2009/05/07/drupal-tip-list-a-nodes-taxonomy-terms-inside-a-block/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Using the mod_dav_svn SVNParentPath directive with multiple authz files</title>
		<link>http://www.g-loaded.eu/2008/12/18/using-the-mod_dav_svn-svnparentpath-directive-with-multiple-authz-files/</link>
		<comments>http://www.g-loaded.eu/2008/12/18/using-the-mod_dav_svn-svnparentpath-directive-with-multiple-authz-files/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 03:02:50 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://www.g-loaded.eu/?p=805</guid>
		<description><![CDATA[I&#8217;ve been using the mod_dav_svn module for Apache, part of the subversion distribution package, in order to make several SVN repositories available over the HTTP protocol for quite some time now. More specifically, I use a multi-repository setup under the same virtualhost by using the SVNParentPath directive of mod_dav_svn. Also, the authorization policy is enforced [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using the <strong>mod_dav_svn</strong> module for <a href="http://httpd.apache.org/">Apache</a>, part of the <a href="http://subversion.tigris.org/">subversion</a> distribution package, in order to make several <em>SVN repositories</em> available over the HTTP protocol for quite some time now. More specifically, I use a <em>multi-repository</em> setup under the same virtualhost by using the <code>SVNParentPath</code> directive of <em>mod_dav_svn</em>. Also, the <strong>authorization policy</strong> is enforced by <strong>mod_authz_svn</strong> by using one general <em>authz</em> file (<code>AuthzSVNAccessFile</code>) containing the <em>policy rules</em>. In case the user is not authorized to access the resource, basic HTTP authentication is used to finally grant or deny access to the user. Everything works as expected, but let&#8217;s see if this is practical too&#8230;<br />
<span id="more-805"></span><br />
It is obvious that using such a setup, all <a href="http://subversion.tigris.org/">subversion</a> repositories share the same authz file. This is fine in most circumstances, but it presumes that one person or a small team of administrators will practically be able to manage the authorization policy inside the authz file, unless you grant read/write access to everyone, which is not very likely. And this is where problems begin to arise. What happens if there are 1000 development teams and thousands of requests to the admin team asking for modifications on the authz file? This is almost chaos. On the other hand, suppose that each SVN repository belongs to a development team which wishes to manage its repo&#8217;s authorization policy itself. What can be done in such a case? Unfortunately, nothing that will not require some coding. mod_authz_svn cannot handle multiple authorization files when a multi-repository configuration (<code>SVNParentPath</code>) is used.</p>
<p>One way to resolve the issue mentioned above is to inject our own authorization code into the relevant phase of the HTTP request processing. What this authorization code is going to do is to dynamically construct the path to the requested repository&#8217;s authz file, parse the authz file, determine the level of access the user may get in accordance to the HTTP request type and, finally, return an OK or an error code back to Apache.</p>
<p>Tonight I&#8217;ve spent several hours on this. Although, the appropriate approach would be to patch mod_authz_svn, I am not that excited about such an approach as I would need several days of hard work to modify an existing apache module. Instead, I have almost finished an <strong>authorization handler</strong> and an <strong>authz file parser</strong> (only basic syntax is supported), both written in python, which can be used by apache with the help of <a href="http://www.modpython.org/">mod_python</a>.</p>
<p>This is not finished yet. As you might have assumed I need this piece of code for <a href="http://www.codetrax.org/projects/project-codetrax">Project CodeTRAX</a>. Although, I had decided not to release anything related to that project until it is finished, I might make an exception and release this piece of python code in order to get some valuable feedback about if and how secure it is.</p>
<p class="cc-block"><em><a href="http://www.g-loaded.eu/2008/12/18/using-the-mod_dav_svn-svnparentpath-directive-with-multiple-authz-files/">Using the mod_dav_svn SVNParentPath directive with multiple authz files</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>.</p>
<h4>Related Articles</h4>

<ul><li><a href="http://www.g-loaded.eu/2009/10/05/strange-mod_dav_svn-error/" rel="bookmark">Strange mod_dav_svn error</a></li>
<li><a href="http://www.g-loaded.eu/2005/10/03/search-a-string-in-multiple-files/" rel="bookmark">Search for a string in multiple files</a></li>
<li><a href="http://www.g-loaded.eu/2010/10/04/rsapiget-download-rapidshare-api/" rel="bookmark">rsapiget downloads files using the new Rapidshare API</a></li>
<li><a href="http://www.g-loaded.eu/2011/11/28/speed-up-apache-by-including-htaccess-files-into-httpd-conf/" rel="bookmark">Speed up Apache by including htaccess files into httpd.conf</a></li>
<li><a href="http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/" rel="bookmark">VeriTAR &#8211; Verify checksums of files within a TAR archive</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2008/12/18/using-the-mod_dav_svn-svnparentpath-directive-with-multiple-authz-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>delayed-shutdown initscript</title>
		<link>http://www.g-loaded.eu/2008/11/28/delayed-shutdown-initscript/</link>
		<comments>http://www.g-loaded.eu/2008/11/28/delayed-shutdown-initscript/#comments</comments>
		<pubDate>Fri, 28 Nov 2008 00:36:42 +0000</pubDate>
		<dc:creator>George Notaras</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Administration]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.g-loaded.eu/?p=684</guid>
		<description><![CDATA[delayed-shutdown is an initscript that delays the shutdown (runlevel 0) or reboot (runlevel 6) procedure as long as a pre-defined lock file exists. The goal is to create a mechanism, which can be used by programs that perform critical operations that must not be interrupted, in order to delay system shutdown until these programs have [...]]]></description>
			<content:encoded><![CDATA[<p><strong>delayed-shutdown</strong> is an initscript that delays the shutdown (runlevel 0) or reboot (runlevel 6) procedure as long as a pre-defined <strong>lock</strong> file exists. The goal is to create a mechanism, which can be used by programs that perform critical operations that must not be interrupted, in order to delay system shutdown until these programs have finished their job. The whole concept is very simple: the program, for instance a backup script, creates a pre-defined lockfile at a pre-defined location (<em>lock is acquired</em>). If a shutdown or reboot is initiated while the script is still active, <strong>delayed-shutdown</strong> checks for the existence of the lockfile and, if it finds it, it delays the system shutdown/reboot while it periodically continues to check for the existence of the lockfile. Whenever the backup script finishes its operation and deletes the lockfile (<em>lock is released</em>), <strong>delayed-shutdown</strong> lets the system go down.</p>
<p><strong>Note</strong>: in a previous post I had tried to <a href="http://www.g-loaded.eu/2008/11/26/using-a-switch-to-prevent-system-shutdownrebootsuspend/">implement a shutdown/reboot/suspend prevention switch</a> using various <em>inefficient methods</em>. After receiving some pointers from members of the Linux-Greek-Users mailing list, I studied the initscript mechanism and wrote this solution. It has been tested on Fedora only and is <strong>released for Fedora and RedHat based linux distributions</strong>. I would appreciate feedback about its compatibility with <strong>Debian</strong> or <strong>Gentoo</strong> based systems.<br />
<span id="more-684"></span></p>
<h4>Manual Installation</h4>
<p>As user &#8216;<strong>root</strong>&#8216; follow the instructions to install the file in your <em>initscripts directory</em>:</p>
<pre class="console">
cp delayed-shutdown /etc/init.d/
chmod +x /etc/init.d/delayed-shutdown
</pre>
<p>For RedHat and relatives run:</p>
<pre class="console">
chkconfig --add delayed-shutdown
</pre>
<p>For Debian and relatives run:</p>
<pre class="console">
update-rc.d delayed-shutdown defaults
</pre>
<h4>Manual De-installation</h4>
<p>If for any reason you need to remove &#8216;delayed-shutdown&#8217; from your system do the following:</p>
<p>For RedHat and relatives run:</p>
<pre class="console">
chkconfig --del delayed-shutdown
</pre>
<p>For Debian and relatives run:</p>
<pre class="console">
update-rc.d -f delayed-shutdown remove
</pre>
<p>Delete the initscript:</p>
<pre class="console">
rm /etc/init.d/delayed-shutdown
</pre>
<h4>Usage</h4>
<p>In order to delay the shutdown process until your software finishes its operation, you should create the no-shutdown lock file:</p>
<pre class="codesnp">
/var/lock/noshutdown.lock
</pre>
<p>Then let your software do its job and, when finished, delete the no-shutdown lock file. In case of a script that would be:</p>
<pre class="codesnp">
lockfile /var/lock/noshutdown.lock
... [script is working] ...
rm -f /var/lock/noshutdown.lock
</pre>
<h4>Test</h4>
<p>A test script, test.sh, is included in the distribution package. In order perform a test, do the following:</p>
<ul>
<li>Make sure you have installed the <strong>delayed-shutdown</strong> initscript as described in the &#8220;installation section.</li>
<li>Run test.sh: <strong>./test.sh &#038;</strong></li>
<li>Reboot or shutdown the machine</li>
</ul>
<p><code>Test.sh</code> will acquire the lock, sleep in the background for 90 seconds and then release the lock. The shutdown/reboot procedure will continue after the lock has been released.</p>
<h4>Download</h4>
<p>All versions of the software, including the latest stable release, are available from the development web site&#8217;s <a href="http://www.codetrax.org/projects/delayed-shutdown/files">download area</a>.</p>
<h4>Misc</h4>
<p>The initscript <em>delayed-shutdown</em> is released under the terms of the MIT license.</p>
<p class="cc-block"><em><a href="http://www.g-loaded.eu/2008/11/28/delayed-shutdown-initscript/">delayed-shutdown initscript</a></em>, unless otherwise expressly stated, is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>.</p>
<h4>Related Articles</h4>

<ul><li><a href="http://www.g-loaded.eu/2008/11/26/using-a-switch-to-prevent-system-shutdownrebootsuspend/" rel="bookmark">Using a switch to prevent system shutdown/reboot/suspend</a></li>
<li><a href="http://www.g-loaded.eu/2009/10/08/redmine-deployment-delayed/" rel="bookmark">Redmine deployment delayed</a></li>
<li><a href="http://www.g-loaded.eu/2009/10/30/selinux-setenforce-mode/" rel="bookmark">Using setenforce to switch SELinux mode wisely</a></li>
<li><a href="http://www.g-loaded.eu/2007/02/12/lock-out-a-user-after-n-failed-login-attempts/" rel="bookmark">Lock out a user after N failed login attempts</a></li>
<li><a href="http://www.g-loaded.eu/2009/02/01/xen-domu-using-dynamic-ip-and-hostname/" rel="bookmark">Xen DomU using dynamic IP and hostname</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.g-loaded.eu/2008/11/28/delayed-shutdown-initscript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Object Caching 1961/2072 objects using apc

Served from: www.g-loaded.eu @ 2012-05-17 04:00:27 -->
