<?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"
	>

<channel>
	<title>zeaster</title>
	<atom:link href="http://zeaster.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://zeaster.com/blog</link>
	<description>about blank</description>
	<pubDate>Wed, 14 May 2008 02:04:19 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>中国地震2008</title>
		<link>http://zeaster.com/blog/2008/05/13/earthquake2008/</link>
		<comments>http://zeaster.com/blog/2008/05/13/earthquake2008/#comments</comments>
		<pubDate>Tue, 13 May 2008 03:01:11 +0000</pubDate>
		<dc:creator>zeaster</dc:creator>
		
		<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://zeaster.com/blog/?p=107</guid>
		<description><![CDATA[默哀...
使用牛博网捐款救助灾区
详情请见
http://www.bullog.cn/blogs/liuyanban/archives/136782.aspx
向军人致敬！
空15军强行空降
http://blog.sina.com.cn/s/blog_4cdb2e8301009g42.html
]]></description>
			<content:encoded><![CDATA[<p>默哀...</p>
<p>使用<a href="http://www.bullog.cn/">牛博网</a>捐款救助灾区<br />
详情请见<br />
<a href="http://www.bullog.cn/blogs/liuyanban/archives/136782.aspx">http://www.bullog.cn/blogs/liuyanban/archives/136782.aspx</a></p>
<p>向军人致敬！<br />
空15军强行空降<br />
<a href="http://blog.sina.com.cn/s/blog_4cdb2e8301009g42.html">http://blog.sina.com.cn/s/blog_4cdb2e8301009g42.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://zeaster.com/blog/2008/05/13/earthquake2008/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Google Android Custom Widget RichEdit - 1</title>
		<link>http://zeaster.com/blog/2008/04/24/google-android-custom-widget-richedit-1/</link>
		<comments>http://zeaster.com/blog/2008/04/24/google-android-custom-widget-richedit-1/#comments</comments>
		<pubDate>Wed, 23 Apr 2008 17:28:17 +0000</pubDate>
		<dc:creator>zeaster</dc:creator>
		
		<category><![CDATA[blog]]></category>

		<category><![CDATA[google]]></category>

		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://zeaster.com/blog/?p=106</guid>
		<description><![CDATA[I developed two custom  widgets for ZInfo.
One is called RichText that can show links with custom display text, rather than the link itself.
The other is a more powerful dialog. It will be discussed later.
Android provides a widget called TextView with auto link feature.
That means you can show this:
This is http://zeaster.com/blog/
but, how to show this:
This [...]]]></description>
			<content:encoded><![CDATA[<p>I developed two custom  widgets for <a href="http://infosword.com/zinfo/">ZInfo</a>.</p>
<p>One is called RichText that can show links with custom display text, rather than the link itself.<br />
The other is a more powerful dialog. It will be discussed later.</p>
<p>Android provides a widget called TextView with auto link feature.<br />
That means you can show this:<br />
This is <a href="http://zeaster.com/blog/">http://zeaster.com/blog/</a></p>
<p>but, how to show this:<br />
This is <a href="http://zeaster.com/blog/">my blog</a>.</p>
<p>How to show a link with custom display text?<br />
RichText helps us in this way:<br />
<code><br />
RichText rt = (RichText) findViewById(R.id.rich_text);<br />
StringBuilder sb = new StringBuilder();<br />
sb.append("This is a demo about how to use RichText.\n");<br />
sb.append("a custom android widegt show links with custom display text, rather than the link itself.\n");<br />
sb.append("This is &lt;a href='http://zeaster.com/blog'&gt;my blog&lt;/a&gt;\n");<br />
sb.append("This is &lt;a href='http://infosword.com/zinfo'&gt;ZInfo&lt;/a&gt;\n");<br />
rt.setRichText(sb.toString());<br />
</code></p>
<p>With this code, you got:<br />
<img src="http://lh4.ggpht.com/yichao.zhang/SA9r6PZYGWI/AAAAAAAAAGo/mTDyAvex4MQ/device.png" alt="http://lh4.ggpht.com/yichao.zhang/SA9r6PZYGWI/AAAAAAAAAGo/mTDyAvex4MQ/device.png" /></p>
<p>SpannableString is used in RichText to show custom style.<br />
For more details, check its <a href="http://blogsync-java.googlecode.com/files/AndroidCustomWidget.tar.gz">source code</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://zeaster.com/blog/2008/04/24/google-android-custom-widget-richedit-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>ZInfo - Information sharing platfrom on Android</title>
		<link>http://zeaster.com/blog/2008/04/18/zinfo-information-sharing-platfrom-on-android/</link>
		<comments>http://zeaster.com/blog/2008/04/18/zinfo-information-sharing-platfrom-on-android/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 16:39:04 +0000</pubDate>
		<dc:creator>zeaster</dc:creator>
		
		<category><![CDATA[google]]></category>

		<category><![CDATA[mobile]]></category>

		<category><![CDATA[opensource]]></category>

		<guid isPermaLink="false">http://zeaster.com/blog/?p=104</guid>
		<description><![CDATA[ZInfo is finally released for Android Developer Challenge after our many hard working days.
It's an information sharing platform based on your contacts and location.
The video demo can be found at http://infosword.com/zinfo/video.html.
We gave a presentation about ZInfo on Beijing Open Party - Before the Rain.
It makes me the most excited that I meet a lot of [...]]]></description>
			<content:encoded><![CDATA[<p><a title="ZInfo" href="http://infosword.com/zinfo/">ZInfo</a> is finally released for <a title="Android Developer Challenge" href="http://code.google.com/android/adc.html">Android Developer Challenge</a> after our many hard working days.<span class="nfakPe"><br />
It's</span> an information sharing platform based on your contacts and location.<br />
The video demo can be found at <a href="http://infosword.com/zinfo/video.html" target="_blank">http://infosword.com/<span class="nfakPe">zinfo</span>/video.html</a>.</p>
<p>We gave a presentation about ZInfo on <a href="http://www.beijing-open-party.org/index.php/2008/04/07/beijing-open-partybefore-the-rain/">Beijing Open Party - Before the Rain</a>.<br />
It makes me the most excited that I meet a lot of open source followers.<br />
They are very friendly, full of passion, enjoy coding! I learned a lot from them.</p>
<p>Special thanks to cleverpig!<br />
He is so kind and want to sponsor us a server to host ZInfo.<br />
And he understands us fully when we decided to put off releasing publicly recently.</p>
<p>It's so great to meet you guys in the community!</p>
]]></content:encoded>
			<wfw:commentRss>http://zeaster.com/blog/2008/04/18/zinfo-information-sharing-platfrom-on-android/feed/</wfw:commentRss>
		</item>
		<item>
		<title>most geek wordpress theme</title>
		<link>http://zeaster.com/blog/2008/03/16/most-geek-wordpress-theme/</link>
		<comments>http://zeaster.com/blog/2008/03/16/most-geek-wordpress-theme/#comments</comments>
		<pubDate>Sun, 16 Mar 2008 02:28:31 +0000</pubDate>
		<dc:creator>zeaster</dc:creator>
		
		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://zeaster.com/blog/2008/03/16/most-geek-wordpress-theme/</guid>
		<description><![CDATA[Never been more glad to find such wonderful wordpress theme - wordpress cli
Have a try if you like unix.

]]></description>
			<content:encoded><![CDATA[<div class="post-content">Never been more glad to find such wonderful wordpress theme - <a href="http://code.google.com/p/wordpress-cli/">wordpress cli</a></p>
<p><a href="http://zeaster.com/blog/index.php?wptheme=CLI">Have a try</a> if you like unix.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://zeaster.com/blog/2008/03/16/most-geek-wordpress-theme/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Inconvenienced when using Contact Content Provider on Android</title>
		<link>http://zeaster.com/blog/2007/11/28/inconvenienced-when-using-contact-content-provider-on-android/</link>
		<comments>http://zeaster.com/blog/2007/11/28/inconvenienced-when-using-contact-content-provider-on-android/#comments</comments>
		<pubDate>Wed, 28 Nov 2007 06:17:00 +0000</pubDate>
		<dc:creator>zeaster</dc:creator>
		
		<category><![CDATA[google]]></category>

		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://zeaster.com/blog/2007/11/28/inconvenienced-when-using-contact-content-provider-on-android/</guid>
		<description><![CDATA[These days, I've been developing an application that reads and writes entries from/into Android Contacts.
Everything goes fine until I need to insert email entry into Android Contact by Contact Content Provider API.
This is how to insert a people or phone entry into contact (people, phones table):
getContentProvider().insert(People.CONTENT_URI, values);
getContentProvider().insert(Phones.CONTENT_URI, values);
That's fine according to
http://code.google.com/android/devel/data/contentproviders.html
However when I insert an [...]]]></description>
			<content:encoded><![CDATA[<p>These days, I've been developing an application that reads and writes entries from/into Android Contacts.<br />
Everything goes fine until I need to insert email entry into Android Contact by Contact Content Provider API.</p>
<p>This is how to insert a people or phone entry into contact (people, phones table):<br />
getContentProvider().insert(People.CONTENT_URI, values);<br />
getContentProvider().insert(Phones.CONTENT_URI, values);</p>
<p>That's fine according to<br />
http://code.google.com/android/devel/data/contentproviders.html</p>
<p>However when I insert an email entry into contact (in contact_methods table) using:<br />
ContentURI uri = getContentProvider().insert(ContactMethods.CONTENT_URI, values);</p>
<p>It just returns null, nothing inserted, and nothing shows up on logcat.<br />
Why? the link above says it should be fine!<br />
To find the answer, I post a thread in Google Group:<br />
http://groups.google.com/group/android-developers/browse_thread/thread/9ed4ff7fc1338b7c<br />
However no response.<br />
then I have been diving into build-in Contacts Application for 2 days to find how Google used their own api.<br />
Luckily, I got the key.<br />
see details on <a href="http://zeaster.com/blog/2007/11/28/how-to-decompile-dex-file-on-android/">my another post</a>:<br />
http://zeaster.com/blog/2007/11/28/how-to-decompile-dex-file-on-android/</p>
<p>You should insert an email like this:<br />
ContentURI uri = People.CONTENT_URI.addId(user_id).addPath("contact_methods");<br />
ContentValues values = ...<br />
uri = getContentResolver().insert(uri, values);</p>
<p>why? I guess Google should provide one same way to insert content.</p>
<p>That's the main inconvenience.<br />
I guess what's even worse is Google does not provide enough docs or log warnings for this tip.<br />
Here are the others:</p>
<p>2.<br />
when insert an email for a not-created-yet user id, It's still inserted successfully.<br />
when the user id created in the future, the user would have the email address.<br />
I guess Google should prevent this happen.<br />
Actually many checks Google need to do.That's really a beta SDK.</p>
<p>3.<br />
The content provider API is not Object-Oriented enough.<br />
I feel it tedious to use.</p>
<p>4.<br />
Maybe this is greedy.<br />
I hope there is API to manipulate database that's similar to ActiveRecord for Rails.<br />
Maybe I will implement one like that if time permits.</p>
]]></content:encoded>
			<wfw:commentRss>http://zeaster.com/blog/2007/11/28/inconvenienced-when-using-contact-content-provider-on-android/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to decompile .dex file on Android</title>
		<link>http://zeaster.com/blog/2007/11/28/how-to-decompile-dex-file-on-android/</link>
		<comments>http://zeaster.com/blog/2007/11/28/how-to-decompile-dex-file-on-android/#comments</comments>
		<pubDate>Wed, 28 Nov 2007 06:12:00 +0000</pubDate>
		<dc:creator>zeaster</dc:creator>
		
		<category><![CDATA[google]]></category>

		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://zeaster.com/blog/2007/11/28/how-to-decompile-dex-file-on-android/</guid>
		<description><![CDATA[Lucky to see the Google Android build-in Contacts is also developed by Android SDK.
This article will take it for example and discuss these How-To's:
1 How to find the Contacts App file on Google Android
2 How to find the Contacts App's classes.dex on Google Android
3 How to dump the Contacts App's classes
4 How to decompile the [...]]]></description>
			<content:encoded><![CDATA[<p>Lucky to see the Google Android build-in Contacts is also developed by Android SDK.<br />
This article will take it for example and discuss these How-To's:</p>
<p>1 How to find the Contacts App file on Google Android<br />
2 How to find the Contacts App's classes.dex on Google Android<br />
3 How to dump the Contacts App's classes<br />
4 How to decompile the dumped file</p>
<p>{<br />
Actually, I think the Contacts Content Provider that Google provides has some inconvenience to use.<br />
And I will post another blog to list what's inconvenience and request some improvement from Google.<br />
The blog link is <a href="http://zeaster.com/blog/2007/11/28/inconvenienced-when-using-contact-content-provider-on-android/">here</a>:<br />
http://zeaster.com/blog/2007/11/28/inconvenienced-when-using-contact-content-provider-on-android/<br />
}</p>
<p>1 How to find the Contacts App on Google Android<br />
Using adb tool</p>
<p>$ adb shell<br />
# cd /system/app<br />
cd /system/app<br />
# ls<br />
ls<br />
-rw-r--r-- root     root        25519 2007-11-14 20:40 ContactsProvider.apk<br />
-rw-r--r-- root     root         7544 2007-11-14 20:40 GoogleAppsProvider.apk<br />
-rw-r--r-- root     root        16198 2007-11-14 20:40 ImProvider.apk<br />
-rw-r--r-- root     root        20308 2007-11-14 20:40 MediaProvider.apk<br />
-rw-r--r-- root     root        21272 2007-11-14 20:40 TelephonyProvider.apk<br />
-rw-r--r-- root     root        11809 2007-11-14 20:40 SettingsProvider.apk<br />
-rw-r--r-- root     root       418688 2007-11-14 20:41 Browser.apk<br />
-rw-r--r-- root     root        68077 2007-11-14 20:41 Contacts.apk<br />
-rw-r--r-- root     root        96287 2007-11-14 20:41 Development.apk<br />
-rw-r--r-- root     root        44790 2007-11-14 20:41 GoogleApps.apk<br />
-rw-r--r-- root     root         8637 2007-11-14 20:41 Fallback.apk<br />
-rw-r--r-- root     root        99431 2007-11-14 20:41 Home.apk<br />
-rw-r--r-- root     root       171614 2007-11-14 20:41 Maps.apk<br />
-rw-r--r-- root     root       424601 2007-11-14 20:41 Phone.apk<br />
-rw-r--r-- root     root       192119 2007-11-14 20:41 XmppService.apk<br />
-rw-r--r-- root     root         6614 2007-11-14 20:41 XmppSettings.apk<br />
#</p>
<p>The Contacts.apk is the Contacts App and ContactsProvider.apk is the app that provides the Contact Content Provider for reading and writing "content://contacts/" resources.<br />
we can see many system apps developed by Android Java SDK are put here.<br />
However what is inside *.apk file. Actually it is a .zip file. It is easy to unzip and get the answer.<br />
take Contacts.apk for example, it contains:</p>
<p>META-INF\<br />
res\<br />
AndroidManifest.xml<br />
classes.dex<br />
resources.arsc</p>
<p>The classes.dex file contains all compiled Java code.</p>
<p>2 How to find the Contacts App's classes.dex on Google Android<br />
No need to unzip Contacts App's classes.dex file from Contacts.apk file.<br />
The Dalvik VM has a cached file for us. Go head to find it.</p>
<p>$ adb shell<br />
# cd /data/dalvik-cache<br />
cd /data/dalvik-cache<br />
# ls<br />
ls<br />
-rw-rw-rw- root     root        73852 2007-11-27 05:16 system@app@Contacts.apk@classes.dex<br />
-rw-rw-rw- app_0    app_0       64172 2007-11-27 05:17 system@app@ContactsProvider.apk@classes.dex<br />
-rw-rw-rw- root     root        15204 2007-11-27 05:17 system@framework@am.jar@classes.dex<br />
-rw-rw-rw- app_3    app_3        3012 2007-11-27 07:33 system@app@Fallback.apk@classes.dex<br />
-rw-rw-rw- root     root      7252804 2007-11-27 05:16 system@framework@core.jar@classes.dex<br />
....and many other cached files.</p>
<p>3 How to dump the Contacts App's classes<br />
Unfortunately the classes.dex is not a .jar file. It's Dalvik executable format that is optimized for efficient.<br />
so we can not pull the .class files as .jar format. However Google Android provides a tool named dexdump included in the emulator to dump .dex file. Here is how to use it.<br />
# dexdump<br />
dexdump: no file specified<br />
dexdump: [-f] [-h] dexfile...</p>
<p>-d : disassemble code sections<br />
-f : display summary information from file header<br />
-h : display file header details<br />
-C : decode (demangle) low-level symbol names<br />
-S : compute sizes only</p>
<p>Now we dump the system@app@Contacts.apk@classes.dex and system@app@ContactsProvider.apk@classes.dex.</p>
<p># dexdump -d -f -h -C system@app@Contacts.apk@classes.dex &gt;&gt; Contacts.apk.dump<br />
# dexdump -d -f -h -C system@app@ContactsProvider.apk@classes.dex &gt;&gt; ContactsProvider.apk.dump</p>
<p>and then pull it out.<br />
# exit<br />
$ adb pull /data/dalvik-cache/Contacts.apk.dump ~/android<br />
$ adb pull /data/dalvik-cache/ContactsProvider.apk.dump ~/android</p>
<p>Now we get the dumped files on ~/android folder.</p>
<p>4 How to decompile the dumped file<br />
.dex file is optimized, so we can not decompile it as normal .class file.<br />
Fortunately the dumped file is a bit readable for me.<br />
As it is too big to analyze all the code, so I just take "how to create a contact" for example.<br />
It's easy to get this info from the dumped file.<br />
It has these classes:<br />
...<br />
Class name        : 'com/google/android/contacts/AttachImage'<br />
Class name        : 'com/google/android/contacts/ContactEntryAdapter'<br />
Class name        : 'com/google/android/contacts/EditContactActivity'<br />
Class name        : 'com/google/android/contacts/EditContactActivity$EditEntry'<br />
...</p>
<p>The EditContactActivity class has a private void create() method.<br />
#3              : (in com/google/android/contacts/EditContactActivity)<br />
name          : 'create'<br />
type          : '()V'<br />
access        : 0x0002 (PRIVATE)</p>
<p>So all the code that create a contact is here from the dumped file, my comments inlined:<br />
// private void create()<br />
009b24:                                        |[009b24] com/google/android/contacts/EditContactActivity.create:()V</p>
<p>// ContentValues v9 = new ContentValues();<br />
009b28: 2109 3100                              |0000: new-instance v9, android/content/ContentValues // class@0031<br />
009b2c: 6f01 0f00 0900                         |0002: invoke-direct {v9}, android/content/ContentValues.<init>:()V // method@000f</init></p>
<p>// Entry v12 =  this.getCurrentEntry();<br />
009b32: f4fc a800                              |0005: +iget-object-quick v12, v15, [obj+00a8]</p>
<p>// int v11 = v12.lines<br />
009b36: f801 1500 0c00                         |0007: +invoke-virtual-quick {v12}, [0015] // vtable #0015<br />
009b3c: 0a0b                                   |000a: move-result v11</p>
<p>// int v5 = 0<br />
009b3e: 1205                                   |000b: const/4 v5, #int 0 // #0</p>
<p>// if v5 &gt;= v11 goto 0046<br />
009b40: 3ab5 3a00                              |000c: if-ge v5, v11, 0046 // +003a</p>
<p>// EditEntry v8 = (EditEntry)this.getCurrentEntry();<br />
009b44: f4fc a800                              |000e: +iget-object-quick v12, v15, [obj+00a8]<br />
009b48: f802 1a00 5c00                         |0010: +invoke-virtual-quick {v12, v5}, [001a] // vtable #001a<br />
009b4e: 0c0c                                   |0013: move-result-object v12<br />
009b50: 07c0                                   |0014: move-object v0, v12<br />
009b52: 1e00 3d00                              |0015: check-cast v0, com/google/android/contacts/EditContactActivity$EditEntry // class@003d<br />
009b56: 0708                                   |0017: move-object v8, v0</p>
<p>// int v12 = v8.kind // The Instance field kind is defined in its superclass Entry. see details in dumped Entry and EditEntry sections.<br />
009b58: f28c 1400                              |0018: +iget-quick v12, v8, [obj+0014]</p>
<p>// int v13 = -3  // PHOTO_KIND = -3 defined in v8's superclass Entry<br />
009b5c: 12dd                                   |001a: const/4 v13, #int -3 // #fd</p>
<p>// if v12 != v13 goto 0020  // a photo entry, goto 0020<br />
009b5e: 38dc 0500                              |001b: if-ne v12, v13, 0020 // +0005</p>
<p>// int v5++;<br />
009b62: d805 0501                              |001d: add-int/lit8 v5, v5, #int 1 // #01</p>
<p>// goto 000c<br />
009b66: 33ed                                   |001f: goto 000c // -0013</p>
<p>// String v7 = v8.getData();<br />
009b68: f801 0c00 0800                         |0020: +invoke-virtual-quick {v8}, [000c] // vtable #000c<br />
009b6e: 0c07                                   |0023: move-result-object v7</p>
<p>// boolean v12 = TextUtils.isEmpty(v7)<br />
009b70: 7001 4200 0700                         |0024: invoke-static {v7}, android/text/TextUtils.isEmpty:(Ljava/lang/CharSequence;)Z // method@0042<br />
009b76: 0a0c                                   |0027: move-result v12</p>
<p>if v12!=false/0 goto 0030<br />
009b78: 3e0c 0800                              |0028: if-nez v12, 0030 // +0008</p>
<p>// String v12 = v8.column  // The Instance field column is defined in EditEntry. see details in dumped EditEntry section.<br />
009b7c: f48c 2800                              |002a: +iget-object-quick v12, v8, [obj+0028]</p>
<p>// v9.put(v12,v7)  // v9 is a ContentValues, v12 is the column name, v7 is the value.<br />
009b80: f803 0b00 c907                         |002c: +invoke-virtual-quick {v9, v12, v7}, [000b] // vtable #000b</p>
<p>// goto 001d<br />
009b86: 33ee                                   |002f: goto 001d // -0012</p>
<p>// String v12 = v8.column  // The Instance field column is defined in EditEntry. see details in dumped EditEntry section.<br />
009b88: f48c 2800                              |0030: +iget-object-quick v12, v8, [obj+0028]</p>
<p>// String v13 = "name";<br />
009b8c: 180d 1c00                              |0032: const-string v13, "name" // string@001c</p>
<p>// boolean v12 = v12.equals(v13);<br />
009b90: ee02 0300 dc00                         |0034: +execute-inline {v12, v13}, java/lang/String.equals:(Ljava/lang/Object;)Z // inline #0003<br />
009b96: 0a0c                                   |0037: move-result v12</p>
<p>// if v12 != false/0, goto 001d<br />
009b98: 3d0c e5ff                              |0038: if-eqz v12, 001d // -001b</p>
<p>// String v12 = "EditContactActivity"<br />
009b9c: 180c 0100                              |003a: const-string v12, "EditContactActivity" // string@0001</p>
<p>// String v13 = "Name is required"<br />
009ba0: 180d 0200                              |003c: const-string v13, "Name is required" // string@0002</p>
<p>// Log.e(v12, v13);  //log info using android/util/Log<br />
009ba4: 7002 4700 dc00                         |003e: invoke-static {v12, v13}, android/util/Log.e:(Ljava/lang/String;Ljava/lang/String;)I // method@0047<br />
009baa: 0a0c                                   |0041: move-result v12</p>
<p>// call this.XXX()<br />
009bac: f801 8400 0f00                         |0042: +invoke-virtual-quick {v15}, [0084] // vtable #0084</p>
<p>// return void<br />
009bb2: 0e00                                   |0045: return-void</p>
<p>// ContentResolver v12 = this.getContentResolver();<br />
009bb4: f4fc a400                              |0046: +iget-object-quick v12, v15, [obj+00a4]</p>
<p>// CONTENT_URI v13 = People.CONTENT_URI;<br />
009bb8: 610d 0300                              |0048: sget-object v13, android/provider/Contacts$People.CONTENT_URI:Landroid/net/ContentURI; // field@0003</p>
<p>// CONTENT_URI v10 = v12.insert(v13, v9)   //  CONTENT_URI v10 = getContentResolver().insert(uri, values);<br />
// insert people into contacts<br />
009bbc: f803 1100 dc09                         |004a: +invoke-virtual-quick {v12, v13, v9}, [0011] // vtable #0011<br />
009bc2: 0c0a                                   |004d: move-result-object v10</p>
<p>// List v12 = this.mContactEntries<br />
009bc4: f4fc c000                       |004e: +iget-object-quick v12, v15, [obj+00c0]<br />
009bc8: 7001 8900 0c00             |0050: invoke-static {v12}, com/google/android/contacts/ContactEntryAdapter.countEntries:(Ljava/util/ArrayList;)I // method@0089<br />
009bce: 0a06                                   |0053: move-result v6</p>
<p>// int v5 = v11 //contact Entry Count<br />
009bd0: 01b5                                   |0054: move v5, v11</p>
<p>// if v5 &gt;= v6, goto 009e<br />
009bd2: 3a65 4900                              |0055: if-ge v5, v6, 009e // +0049</p>
<p>// List v12 = this.mContactEntries<br />
009bd6: f4fc c000                              |0057: +iget-object-quick v12, v15, [obj+00c0]</p>
<p>// EditEntry v8 = (EditEntry) getEntry(v12, v5);<br />
009bda: 7002 8b00 5c00                         |0059: invoke-static {v12, v5}, com/google/android/contacts/ContactEntryAdapter.getEntry:(Ljava/util/ArrayList;I)Lcom/google/android/contacts/ContactEntryAdapter$Entry; // method@008b<br />
009be0: 0c0c                                   |005c: move-result-object v12<br />
009be2: 07c0                                   |005d: move-object v0, v12<br />
009be4: 1e00 3d00                              |005e: check-cast v0, com/google/android/contacts/EditContactActivity$EditEntry // class@003d<br />
009be8: 0708                                   |0060: move-object v8, v0</p>
<p>// int v12 = v8.kind // The Instance field kind is defined in its superclass Entry. see details in dumped Entry and EditEntry sections.<br />
009bea: f28c 1400                              |0061: +iget-quick v12, v8, [obj+0014]</p>
<p>// int v13 = -1 // CONTACT_KIND = -1 defined in v8's superclass Entry<br />
009bee: 12fd                                   |0063: const/4 v13, #int -1 // #ff</p>
<p>// if v12 == v13 goto 007e<br />
009bf0: 37dc 1a00                              |0064: if-eq v12, v13, 007e // +001a</p>
<p>// v9.clear() // ContentValues.clear()<br />
009bf4: f801 1500 0900                         |0066: +invoke-virtual-quick {v9}, [0015] // vtable #0015</p>
<p>// boolean v12 = v8.toValues(v9) // boolean EditEnty.toValues(ContentValues cv)<br />
009bfa: f802 0d00 9800                         |0069: +invoke-virtual-quick {v8, v9}, [000d] // vtable #000d<br />
009c00: 0a0c                                   |006c: move-result v12</p>
<p>//if v12 !=false/0, goto 007b<br />
009c02: 3d0c 0e00                              |006d: if-eqz v12, 007b // +000e</p>
<p>// ContentResolver v12 = this.getContentResolver();<br />
009c06: f4fc a400                              |006f: +iget-object-quick v12, v15, [obj+00a4]</p>
<p>// String v13 = v8.contentDirectory<br />
009c0a: f48d 2c00                              |0071: +iget-object-quick v13, v8, [obj+002c]</p>
<p>// v10.addPath(v13);<br />
009c0e: f802 1800 da00                         |0073: +invoke-virtual-quick {v10, v13}, [0018] // vtable #0018<br />
009c14: 0c0d                                   |0076: move-result-object v13</p>
<p>// CONTENT_URI v12 = v12.insert(v13, v9)   //  CONTENT_URI v12 = getContentResolver().insert(uri, values);<br />
009c16: f803 1100 dc09                         |0077: +invoke-virtual-quick {v12, v13, v9}, [0011] // vtable #0011<br />
009c1c: 0c0c                                   |007a: move-result-object v12</p>
<p>// int v5++;<br />
009c1e: d805 0501                              |007b: add-int/lit8 v5, v5, #int 1 // #01</p>
<p>// goto 0055<br />
009c22: 33d8                                   |007d: goto 0055 // -0028</p>
<p>// String v7 = v8.getData();<br />
009c24: f801 0c00 0800                         |007e: +invoke-virtual-quick {v8}, [000c] // vtable #000c<br />
009c2a: 0c07                                   |0081: move-result-object v7</p>
<p>// v9.lines<br />
009c2c: f801 1500 0900                         |0082: +invoke-virtual-quick {v9}, [0015] // vtable #0015</p>
<p>// boolean v12 = TextUtils.isEmpty(v7)<br />
009c32: 7001 4200 0700                         |0085: invoke-static {v7}, android/text/TextUtils.isEmpty:(Ljava/lang/CharSequence;)Z // method@0042<br />
009c38: 0a0c                                   |0088: move-result v12</p>
<p>if v12!=false/0 goto 007b<br />
009c3a: 3e0c f2ff                              |0089: if-nez v12, 007b // -000e</p>
<p>// String v12 = v8.column  // The Instance field column is defined in EditEntry. see details in dumped EditEntry section.<br />
009c3e: f48c 2800                              |008b: +iget-object-quick v12, v8, [obj+0028]</p>
<p>// v9.put(v12,v7)  // v9 is a ContentValues, v12 is the column name, v7 is the value.<br />
009c42: f803 0b00 c907                         |008d: +invoke-virtual-quick {v9, v12, v7}, [000b] // vtable #000b</p>
<p>// ContentResolver v12 = this.getContentResolver();<br />
009c48: f4fc a400                              |0090: +iget-object-quick v12, v15, [obj+00a4]</p>
<p>// int v13 = 0<br />
009c4c: 120d                                   |0092: const/4 v13, #int 0 // #0</p>
<p>// int v14 = 0<br />
009c4e: 120e                                   |0093: const/4 v14, #int 0 // #0</p>
<p>009c50: 07c0                                   |0094: move-object v0, v12<br />
009c52: 07a1                                   |0095: move-object v1, v10<br />
009c54: 0792                                   |0096: move-object v2, v9<br />
009c56: 07d3                                   |0097: move-object v3, v13<br />
009c58: 07e4                                   |0098: move-object v4, v14</p>
<p>// int v12 = v12.update(v1,v2,v3,v4) // getContentResolver(),update(uri, values, null, null)<br />
// refer to this method, public final int update(ContentURI uri, ContentValues values, String where, String[] selectionArgs)<br />
009c5a: f905 1400 0000                         |0099: +invoke-virtual-quick/range {v0, v1, v2, v3, v4}, [0014] // vtable #0014<br />
009c60: 0a0c                                   |009c: move-result v12</p>
<p>// goto 007b<br />
009c62: 33de                                   |009d: goto 007b // -0022</p>
<p>// int v12 = 4<br />
009c64: 124c                                   |009e: const/4 v12, #int 4 // #4</p>
<p>009c66: f5fc c800                              |009f: +iput-quick v12, v15, [obj+00c8]<br />
009c6a: f7fa 9000                              |00a1: +iput-object-quick v10, v15, [obj+0090]</p>
<p>// int v12 = -1<br />
009c6e: 12fc                                   |00a3: const/4 v12, #int -1 // #ff<br />
009c70: f801 0700 0a00                         |00a4: +invoke-virtual-quick {v10}, [0007] // vtable #0007<br />
009c76: 0c0d                                   |00a7: move-result-object v13<br />
009c78: f803 7f00 cf0d                         |00a8: +invoke-virtual-quick {v15, v12, v13}, [007f] // vtable #007f</p>
<p>// goto 0045<br />
009c7e: 339a                                   |00ab: goto 0045 // -0066<br />
exceptions    : (none)<br />
positions     : 30<br />
0x0000 line=471<br />
.....<br />
0x00a3 line=515<br />
locals        : 10<br />
//the 10 local variables defined here<br />
0x0000 - 0x00ac reg=15 this Lcom/google/android/contacts/EditContactActivity;<br />
0x0002 - 0x00ac reg=9 values Landroid/content/ContentValues;<br />
0x000b - 0x00ac reg=11 contactEntryCount I<br />
0x000c - 0x00ac reg=5 i I<br />
0x0018 - 0x0045 reg=8 entry Lcom/google/android/contacts/EditContactActivity$EditEntry;<br />
0x0024 - 0x0045 reg=7 data Ljava/lang/String;<br />
0x004e - 0x00ac reg=10 contactUri Landroid/net/ContentURI;<br />
0x0054 - 0x00ac reg=6 entryCount I<br />
0x0061 - 0x009e reg=8 entry Lcom/google/android/contacts/EditContactActivity$EditEntry;<br />
0x0082 - 0x009e reg=7 data Ljava/lang/String;</p>
]]></content:encoded>
			<wfw:commentRss>http://zeaster.com/blog/2007/11/28/how-to-decompile-dex-file-on-android/feed/</wfw:commentRss>
		</item>
		<item>
		<title>blogsync FAQ</title>
		<link>http://zeaster.com/blog/2007/09/08/blogsync-faq/</link>
		<comments>http://zeaster.com/blog/2007/09/08/blogsync-faq/#comments</comments>
		<pubDate>Fri, 07 Sep 2007 20:12:00 +0000</pubDate>
		<dc:creator>zeaster</dc:creator>
		
		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://zeaster.com/blog/2007/09/08/blogsync-faq/</guid>
		<description><![CDATA[blogsync FAQ from http://code.google.com/p/blogsync-java/wiki/BlogsyncFAQ
what is blogsync?
it is used to import wordpress posts into blogger.
how to use it?

set jdk bin path in run.bat/run.sh
execute run.bat/run.sh

what is new in blogsync 0.3?
The comments can be imported from wordpress rss xml file to blogger site now. However it can not preserve the published time of the wordpress comments. so the [...]]]></description>
			<content:encoded><![CDATA[<p>blogsync FAQ from <a href="http://code.google.com/p/blogsync-java/wiki/BlogsyncFAQ">http://code.google.com/p/blogsync-java/wiki/BlogsyncFAQ</a></p>
<h3>what is blogsync?</h3>
<p>it is used to import wordpress posts into blogger.</p>
<h3>how to use it?</h3>
<ul>
<li>set jdk bin path in run.bat/run.sh</li>
<li>execute run.bat/run.sh</li>
</ul>
<h3>what is new in blogsync 0.3?</h3>
<p>The comments can be imported from wordpress rss xml file to blogger site now. However it can not preserve the published time of the wordpress comments. so the published time of your imported comments is just the time when you import.</p>
<h3>what is new in blogsync 0.2?</h3>
<p>add feature to import posts from exported wordpress rss xml file to blogger site.</p>
<h3>which jdk version do I need to run blogsync?</h3>
<p>You should use jdk1.5 or later.</p>
<h3>how to add jdk bin path in path environment?</h3>
<ul>
<li>windows
<ol>
<li>says your java.exe is in directory c:\jdk1.5.0\bin</li>
<li>set the following line in run.bat</li>
<pre class="prettyprint"><span class="pln">    set path</span><span class="pun">=</span><span class="pln">c</span><span class="pun">:</span><span class="pln">jdk1</span><span class="pun">.</span><span class="lit">5</span><span class="pun">.</span><span class="lit">0</span><span class="pun"></span><span class="pln">bin</span><span class="pun">;%</span><span class="pln">path</span><span class="pun">%</span></pre>
</ol>
</li>
<li>Mac or unix
<ol>
<li>says your java is in directory /path/to/your/java</li>
<li>set the following line in run.sh</li>
<pre class="prettyprint"><span class="pln">    </span><span class="kwd">export</span><span class="pln"> PATH</span><span class="pun">=</span><span class="str">/path/</span><span class="pln">to</span><span class="pun">/</span><span class="pln">your</span><span class="pun">/</span><span class="pln">java</span><span class="pun">:</span><span class="pln">$PATH</span></pre>
</ol>
</li>
</ul>
<h3>how do I know which version of jdk I am using?</h3>
<p>open a terminal, type "java -version". you should get something like this:</p>
<pre class="prettyprint"><span class="pln">java version </span><span class="str">"1.5.0_12"</span><span class="pln">
</span><span class="typ">Java</span><span class="pun">(</span><span class="pln">TM</span><span class="pun">)</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="typ">Runtime</span><span class="pln"> </span><span class="typ">Environment</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Standard</span><span class="pln"> </span><span class="typ">Edition</span><span class="pln"> </span><span class="pun">(</span><span class="pln">build </span><span class="lit">1</span><span class="pun">.</span><span class="lit">5</span><span class="pun">.</span><span class="lit">0_12</span><span class="pun">-</span><span class="pln">b04</span><span class="pun">)</span><span class="pln">
</span><span class="typ">Java</span><span class="pln"> </span><span class="typ">HotSpot</span><span class="pun">(</span><span class="pln">TM</span><span class="pun">)</span><span class="pln"> </span><span class="typ">Client</span><span class="pln"> VM </span><span class="pun">(</span><span class="pln">build </span><span class="lit">1</span><span class="pun">.</span><span class="lit">5</span><span class="pun">.</span><span class="lit">0_12</span><span class="pun">-</span><span class="pln">b04</span><span class="pun">,</span><span class="pln"> mixed mode</span><span class="pun">)</span></pre>
<h3>how to run run.bat/run.sh in command line?</h3>
<ul>
<li>windows</li>
<blockquote><p>open a command window, type:</p>
<pre class="prettyprint"><span class="pln">    cd e</span><span class="pun">:</span><span class="pln">path</span><span class="pun"></span><span class="pln">to</span><span class="pun"></span><span class="pln">your</span><span class="pun"></span><span class="pln">run</span><span class="pun">.</span><span class="pln">bat
    run</span><span class="pun">.</span><span class="pln">bat</span></pre>
</blockquote>
<li>Mac or unix</li>
<blockquote><p>open a terminal, type:</p>
<pre class="prettyprint"><span class="pln">    cd </span><span class="pun">/</span><span class="pln">path</span><span class="pun">/</span><span class="pln">to</span><span class="pun">/</span><span class="pln">your</span><span class="pun">/</span><span class="pln">run</span><span class="pun">.</span><span class="pln">sh
    sh run</span><span class="pun">.</span><span class="pln">sh</span></pre>
</blockquote>
</ul>
<h3>when run run.sh, it is opened by my editor, what should I do?</h3>
<p>please run run.sh in command line.</p>
<h3>after clicking on run.bat/run.sh, there was nothing happend, what should I do?</h3>
<p>run run.bat/run.sh in command line so that find what's going wrong in the terminal?</p>
<h3>It prompts "java: command not found", what's going wrong?</h3>
<p>java is not in your path, please add jdk bin path in your path environment.</p>
<h3>why do I get <tt>Exception in thread "main" java.lang.NoClassDefFoundError: org/easter/blogsync/BlogSync</tt>?</h3>
<p>if you are on Mac or unix, please make sure you have read permission on blogsync/build/blogsync.jar file if not, open a terminal and type:</p>
<pre class="prettyprint"><span class="pln">chmod </span><span class="lit">744</span><span class="pln"> </span><span class="pun">/</span><span class="pln">path</span><span class="pun">/</span><span class="pln">to</span><span class="pun">/</span><span class="pln">your</span><span class="pun">/</span><span class="pln">blogsync</span><span class="pun">/</span><span class="pln">build</span><span class="pun">/</span><span class="pln">blogsync</span><span class="pun">.</span><span class="pln">jar</span></pre>
<h3>why do I get <tt>Failed to create input stream: Server returned HTTP response code: 403 for URL: http://mydomain.com/wordpress/xmlrpc.php</tt>?</h3>
<ul>
<li>if you installed a plugin called Enforce www. Preference, it would affect the path to your xmlrpc.php file, so deactivated it first.</li>
<li>if you enabled mod_security on apache, it would block access to xmlrpc.php, so add this to your .htaccess file:</li>
<pre class="prettyprint"><span class="pln">    </span><span class="tag">&lt;Files </span><span class="atn">xmlrpc.php</span><span class="tag">&gt;</span><span class="pln">
      SecFilterInheritance Off
    </span><span class="tag">&lt;/Files&gt;</span></pre>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://zeaster.com/blog/2007/09/08/blogsync-faq/feed/</wfw:commentRss>
		</item>
		<item>
		<title>python script to email me the dynamic ip from tp-link router</title>
		<link>http://zeaster.com/blog/2007/09/05/python-script-to-email-me-the-dynamic-ip-from-tp-link-router/</link>
		<comments>http://zeaster.com/blog/2007/09/05/python-script-to-email-me-the-dynamic-ip-from-tp-link-router/#comments</comments>
		<pubDate>Tue, 04 Sep 2007 23:02:00 +0000</pubDate>
		<dc:creator>zeaster</dc:creator>
		
		<category><![CDATA[opensource]]></category>

		<guid isPermaLink="false">http://zeaster.com/blog/2007/09/05/python-script-to-email-me-the-dynamic-ip-from-tp-link-router/</guid>
		<description><![CDATA[At home, my boxes are connected to internet by Beijing ADSL.
when connected, Beijing ADSL gives me a dynamic ip and it changes about every 24 hours.
Before I get the dynamic ip by a service provided by oray.net.
However recently the service is broken.
So I have to write a python script to check the dynamic ip from [...]]]></description>
			<content:encoded><![CDATA[<p>At home, my boxes are connected to internet by Beijing ADSL.<br />
when connected, Beijing ADSL gives me a dynamic ip and it changes about every 24 hours.<br />
Before I get the dynamic ip by a service provided by oray.net.<br />
However recently the service is broken.<br />
So I have to write a python script to check the dynamic ip from my tp-link router every 3 minutes and if it changed, emails the new dynamic ip to my gmail.</p>
<p>I also write a bash script to run the above python script at boot on my gentoo linux.</p>
<p>The python script:</p>
<pre class="python">&nbsp;
<span style="color: #808080; font-style: italic;">#!/usr/bin/python</span>
&nbsp;
<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;">urllib2</span>
<span style="color: #ff7700;font-weight:bold;">import</span> libgmail
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">cookielib</span>
<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;">re</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">base64</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">socket</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">urlparse</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urlparse</span>
&nbsp;
nowip=<span style="color: #483d8b;">''</span>
logfile=<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/var/log/ipsender.log'</span>,<span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> log<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>:
 now=<span style="color: #dc143c;">time</span>.<span style="color: black;">strftime</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%Y-%m-%d %X'</span><span style="color: black;">&#41;</span>
 logfile.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s %sn'</span>%<span style="color: black;">&#40;</span>now,s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
 logfile.<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> gmailsender<span style="color: black;">&#40;</span>to_addr,subject,msg<span style="color: black;">&#41;</span>:
 username=<span style="color: #483d8b;">'xxx@gmail.com'</span>
 password=<span style="color: #483d8b;">'xxx'</span>
 ga=libgmail.<span style="color: black;">GmailAccount</span><span style="color: black;">&#40;</span>username,password<span style="color: black;">&#41;</span>
 ga.<span style="color: black;">login</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
 gmsg=libgmail.<span style="color: black;">GmailComposedMessage</span><span style="color: black;">&#40;</span>to_addr,subject,msg<span style="color: black;">&#41;</span>
 ga.<span style="color: black;">sendMessage</span><span style="color: black;">&#40;</span>gmsg<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> check<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
 <span style="color: #ff7700;font-weight:bold;">global</span> nowip
 timeout=<span style="color: #ff4500;">10</span>
 <span style="color: #dc143c;">socket</span>.<span style="color: black;">setdefaulttimeout</span><span style="color: black;">&#40;</span>timeout<span style="color: black;">&#41;</span>
 username = <span style="color: #483d8b;">'admin'</span>
 password = <span style="color: #483d8b;">'xxx'</span>
 <span style="color: #ff7700;font-weight:bold;">try</span>:
   theurl=<span style="color: #483d8b;">'http://192.168.1.1/userRpm/StatusRpm.htm'</span>
   req = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span>theurl<span style="color: black;">&#41;</span>
   base64string = <span style="color: #dc143c;">base64</span>.<span style="color: black;">encodestring</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s:%s'</span> % <span style="color: black;">&#40;</span>username, password<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:<span style="color: #ff4500;">-1</span><span style="color: black;">&#93;</span>
   authheader =  <span style="color: #483d8b;">&quot;Basic %s&quot;</span> % base64string
   req.<span style="color: black;">add_header</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Authorization&quot;</span>, authheader<span style="color: black;">&#41;</span>
   handle = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>
   <span style="color: #008000;">str</span>=handle.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
   ss=<span style="color: #483d8b;">'var wanPara = new Array'</span>
   start=<span style="color: #008000;">str</span>.<span style="color: black;">index</span><span style="color: black;">&#40;</span>ss<span style="color: black;">&#41;</span>+ss.<span style="color: #0000cd;">__len__</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
   end=<span style="color: #008000;">str</span>.<span style="color: black;">index</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">';'</span>,start<span style="color: black;">&#41;</span>
   s2=<span style="color: #008000;">str</span><span style="color: black;">&#91;</span>start:end<span style="color: black;">&#93;</span>
   log<span style="color: black;">&#40;</span>s2<span style="color: black;">&#41;</span>
   t=<span style="color: #008000;">eval</span><span style="color: black;">&#40;</span>s2<span style="color: black;">&#41;</span>
   log<span style="color: black;">&#40;</span>t<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
   handle.<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;">if</span> nowip!=t<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>:
     nowip=t<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>
     gmailsender<span style="color: black;">&#40;</span><span style="color: #483d8b;">'mygmail@gmail.com'</span>,<span style="color: #483d8b;">'ddnsip===%s'</span>%nowip,s2<span style="color: black;">&#41;</span>
     log<span style="color: black;">&#40;</span><span style="color: #483d8b;">'send %s successfully.'</span>%nowip<span style="color: black;">&#41;</span>
   <span style="color: #ff7700;font-weight:bold;">else</span>:
     log<span style="color: black;">&#40;</span><span style="color: #483d8b;">'ddnsip remains %s.'</span>%nowip<span style="color: black;">&#41;</span>
 <span style="color: #ff7700;font-weight:bold;">except</span>:
   log<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Unexpected error:'</span>, <span style="color: #dc143c;">sys</span>.<span style="color: black;">exc_info</span><span style="color: black;">&#40;</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: black;">&#41;</span>
&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;">while</span> <span style="color: #008000;">True</span>:
   check<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;">3</span>*<span style="color: #ff4500;">60</span><span style="color: black;">&#41;</span>
&nbsp;
main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>The bash script put in /etc/init.d/:</p>
<pre class="python">&nbsp;
<span style="color: #808080; font-style: italic;">#!/sbin/runscript</span>
<span style="color: #808080; font-style: italic;"># Copyright 1999-2004 Gentoo Foundation</span>
start<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>	<span style="color: black;">&#123;</span>
	ebegin <span style="color: #483d8b;">&quot;Starting ipsender&quot;</span>
	nohup python /home/zeaster/amp/ipsender.<span style="color: black;">py</span> &amp;gt;&amp;gt; /var/log/ipsender-nohup.<span style="color: black;">log</span>&amp;amp;
	eend $?
<span style="color: black;">&#125;</span>
stop<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>	<span style="color: black;">&#123;</span>
	ebegin <span style="color: #483d8b;">&quot;Stopping ipsender unsuccessfully&quot;</span>
	eend $?
<span style="color: black;">&#125;</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://zeaster.com/blog/2007/09/05/python-script-to-email-me-the-dynamic-ip-from-tp-link-router/feed/</wfw:commentRss>
		</item>
		<item>
		<title>wake-on-lan by python script</title>
		<link>http://zeaster.com/blog/2007/07/30/wake-on-lan-by-python-script/</link>
		<comments>http://zeaster.com/blog/2007/07/30/wake-on-lan-by-python-script/#comments</comments>
		<pubDate>Mon, 30 Jul 2007 03:23:00 +0000</pubDate>
		<dc:creator>zeaster</dc:creator>
		
		<category><![CDATA[opensource]]></category>

		<guid isPermaLink="false">http://zeaster.com/blog/2007/07/30/wake-on-lan-by-python-script/</guid>
		<description><![CDATA[How to wake up your computer on the LAN?
the answer is just to send a Magic Packet to your computer on port 7 or 9.
However when your computer is down, it has no ip, so send it to the broadcast ip
the following python script implements the above idea.
&#160;
&#160;
import struct, socket
&#160;
def wake_on_lan&#40;ether_addr, inet_addr&#41;:
  addr_byte=ether_addr.split&#40;':'&#41;
  [...]]]></description>
			<content:encoded><![CDATA[<p>How to wake up your computer on the LAN?<br />
the answer is just to send a Magic Packet to your computer on port 7 or 9.<br />
However when your computer is down, it has no ip, so send it to the broadcast ip<br />
the following python script implements the above idea.</p>
<pre class="python">&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">struct</span>, <span style="color: #dc143c;">socket</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> wake_on_lan<span style="color: black;">&#40;</span>ether_addr, inet_addr<span style="color: black;">&#41;</span>:
  addr_byte=ether_addr.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">':'</span><span style="color: black;">&#41;</span>
  hw_addr=<span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'BBBBBB'</span>,
    <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>,
    <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>,
    <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>,
    <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>,
    <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>,
    <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  msg=<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\x</span>ff'</span>*<span style="color: #ff4500;">6</span>+hw_addr*<span style="color: #ff4500;">16</span>
&nbsp;
  s=<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_DGRAM</span><span style="color: black;">&#41;</span>
  s.<span style="color: black;">setsockopt</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">SOL_SOCKET</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">SO_BROADCAST</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
  s.<span style="color: black;">sendto</span><span style="color: black;">&#40;</span>msg, <span style="color: black;">&#40;</span>inet_addr,<span style="color: #ff4500;">7</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  s.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
wake_on_lan<span style="color: black;">&#40;</span><span style="color: #483d8b;">'00:E0:4C:E1:D9:CC'</span>, <span style="color: #483d8b;">'192.168.1.255'</span><span style="color: black;">&#41;</span></pre>
<p>The code above is based on socket.SOCK_DGRAM to send UDP packet.<br />
How to create a UDP packet based on  raw  socket  in python?<br />
the project dpkt does an excellent job.<br />
the following example shows that:</p>
<pre class="python">&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">socket</span>
<span style="color: #ff7700;font-weight:bold;">from</span> dpkt <span style="color: #ff7700;font-weight:bold;">import</span> ethernet,udp,ip
<span style="color: #ff7700;font-weight:bold;">import</span> dpkt
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">struct</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">string</span>
&nbsp;
iface = <span style="color: #483d8b;">&quot;eth1&quot;</span>
mac   = <span style="color: #483d8b;">&quot;00:0E:35:AB:9B:40&quot;</span>
inet  = <span style="color: #483d8b;">&quot;192.168.1.6&quot;</span>
debug = <span style="color: #ff4500;">0</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> eth_aton<span style="color: black;">&#40;</span>buffer<span style="color: black;">&#41;</span>:
    addr =<span style="color: #483d8b;">''</span>
    temp = <span style="color: #dc143c;">string</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span>buffer,<span style="color: #483d8b;">':'</span><span style="color: black;">&#41;</span>
    buffer = <span style="color: #dc143c;">string</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>temp,<span style="color: #483d8b;">''</span><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;">0</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>buffer<span style="color: black;">&#41;</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>:
        addr = <span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>addr,<span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'B'</span>, <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>buffer<span style="color: black;">&#91;</span>i: i + <span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>, <span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>,<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> addr
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> buildUdp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    ether_addr=<span style="color: #483d8b;">'00:E0:4C:E1:D9:CD'</span>
    addr_byte=ether_addr.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">':'</span><span style="color: black;">&#41;</span>
    hw_addr=<span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'BBBBBB'</span>,
       <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>,
       <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>,
       <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>,
       <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>,
       <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>,
       <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>addr_byte<span style="color: black;">&#91;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#93;</span>,<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    msg=<span style="color: #483d8b;">'xff'</span>*<span style="color: #ff4500;">6</span>+hw_addr*<span style="color: #ff4500;">16</span>
&nbsp;
    udp_p = udp.<span style="color: black;">UDP</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    udp_p.<span style="color: black;">sport</span> = 0x8130
    udp_p.<span style="color: black;">dport</span> = <span style="color: #ff4500;">7</span>
    udp_p.<span style="color: black;">data</span> = msg
    udp_p.<span style="color: black;">ulen</span> += <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>udp_p.<span style="color: black;">data</span><span style="color: black;">&#41;</span>
&nbsp;
    ip_p = ip.<span style="color: black;">IP</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    ip_p.<span style="color: black;">src</span> = <span style="color: #dc143c;">socket</span>.<span style="color: black;">inet_aton</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'192.168.1.6'</span><span style="color: black;">&#41;</span>;
    ip_p.<span style="color: black;">dst</span> = <span style="color: #dc143c;">socket</span>.<span style="color: black;">inet_aton</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'192.168.1.255'</span><span style="color: black;">&#41;</span>;
    ip_p.<span style="color: black;">off</span> = 0x4000
    ip_p.<span style="color: black;">data</span> = udp_p
    ip_p.<span style="color: black;">p</span> = ip.<span style="color: black;">IP_PROTO_UDP</span>
    ip_p.<span style="color: #008000;">len</span> += <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>udp_p<span style="color: black;">&#41;</span>
&nbsp;
    packet = ethernet.<span style="color: black;">Ethernet</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    packet.<span style="color: black;">src</span> = eth_aton<span style="color: black;">&#40;</span>mac<span style="color: black;">&#41;</span>
    packet.<span style="color: black;">dst</span> = eth_aton<span style="color: black;">&#40;</span><span style="color: #483d8b;">'ff:ff:ff:ff:ff:ff'</span><span style="color: black;">&#41;</span>
    packet.<span style="color: black;">data</span> = ip_p
    packet.<span style="color: #008000;">type</span> = ethernet.<span style="color: black;">ETH_TYPE_IP</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> debug: <span style="color: #ff7700;font-weight:bold;">print</span> dpkt.<span style="color: black;">hexdump</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>packet<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> packet
&nbsp;
s = <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;">PF_PACKET</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">SOCK_RAW</span><span style="color: black;">&#41;</span>
s.<span style="color: black;">bind</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>iface,ethernet.<span style="color: black;">ETH_TYPE_IP</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
packet = buildUdp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
s.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>packet<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://zeaster.com/blog/2007/07/30/wake-on-lan-by-python-script/feed/</wfw:commentRss>
		</item>
		<item>
		<title>blogsync 0.3 released, comments can be imported.</title>
		<link>http://zeaster.com/blog/2007/06/01/blogsync-03-released-comments-can-be-imported/</link>
		<comments>http://zeaster.com/blog/2007/06/01/blogsync-03-released-comments-can-be-imported/#comments</comments>
		<pubDate>Fri, 01 Jun 2007 08:34:00 +0000</pubDate>
		<dc:creator>zeaster</dc:creator>
		
		<category><![CDATA[blog]]></category>

		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://zeaster.com/blog/2007/06/01/blogsync-03-released-comments-can-be-imported/</guid>
		<description><![CDATA[Firstly, the foregoing blogsync 2.0 should be blogsync 0.2. :-)blogsync is a tool that import your wordpress to blogger from rss xml file or online
Now it's blogsync 0.3 release. and it can import comments from exported wordpress rss xml file to blogger site.it can be downloaded from:http://code.google.com/p/blogsync-java/downloads/list
however it can not preserve the published time of [...]]]></description>
			<content:encoded><![CDATA[<p>Firstly, the foregoing blogsync 2.0 should be blogsync 0.2. :-)<br />blogsync is a tool that import your wordpress to blogger from rss xml file or online</p>
<p>Now it's blogsync 0.3 release. and it can import comments from exported wordpress rss xml file to blogger site.<br />it can be downloaded from:<br /><a href="http://code.google.com/p/blogsync-java/downloads/list">http://code.google.com/p/blogsync-java/downloads/list</a></p>
<p>however it can not preserve the published time of the original comments.<br />so the published time of your imported comment is just the time when you import.<br />more details can be found at<br /><a href="http://groups.google.com/group/bloggerDev/browse_thread/thread/15c9a45416305f99">http://groups.google.com/group/bloggerDev/browse_thread/thread/15c9a45416305f99</a></p>
]]></content:encoded>
			<wfw:commentRss>http://zeaster.com/blog/2007/06/01/blogsync-03-released-comments-can-be-imported/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
