Show current GIT branch in TCCFriday, May 3. 2013
I'm getting more and more familiar with the GIT workflow, which goes kinda like this:
git checkout -b topicbranchX Unfortunately this means that you'll end up with a bunch of branches (which you can delete once they get pulled into origin/master) but I keep forgetting what branch I currently have checked out. I've seen bash prompts that show the current branch and I decided to do something similar for TCC/LE. /*
@cl "/Tp%~f0" /nologo /GS- /link /SUBSYSTEM:console /nodefaultlib /entry:_main kernel32.lib
@goto :EOF
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
const WCHAR root[] = L"..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\.git\\HEAD";
int __stdcall _main() {
int offset = sizeof(root)/2 - 10;
while (offset >= 0) {
HANDLE h = CreateFileW(root + offset, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (h != INVALID_HANDLE_VALUE) {
char buf[64];
DWORD read = 0;
if (ReadFile(h, buf, sizeof(buf), &read, NULL) && read > 16) {
DWORD off = 0;
DWORD len = 7; // show 7 hex digits
if ((int&)buf[0] == ':fer') {
off = 16; // skip ref: refs/heads/
len = read - off ; // keep LF
}
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf + off, len, NULL, NULL);
}
return 13 - offset / 3;
}
offset -= 3;
}
return 0;
}What's fun about this file is that you can save it as "gb.cmd". When you then enter "gb" on the command line, it will actually invoke the C compiler (remember to run vcvars32) to generate the gb.exe. Next time, the exe will be invoked instead. This is the final prompt: prompt %%@exec[@gb.exe]$e[1m$P$e[0m$_$+$g Interview with Shanghai TVTuesday, February 19. 2013
A few weeks ago I got interviewed by Shanghai TV about the Shanghai hackerspace 新车间 (XinCheJian) that I'm part of. In the interview I demonstrate one of the hacks I did, using a TP-Link router to open the machine room.
(No, that's not actually the password for our machine room.) @GBlock also has a video on the hack on his Vimeo page. Set IE10 InPrivate as defaultWednesday, January 2. 2013
Do this by adding "-private" to the shortcut in the taskbar. Right-click on the IE logo in the taskbar. Then, right-click on "Internet Explorer" and click "Properties". In the properties dialog, add a space and then -private to the end of the Target. OK.
If IE is not currently running, right-clicking the IE logo in the task bar and selecting "Open new tab" opens a new, non-InPrivate, tab. ![]()
Google sabotaging Windows Phone clients?Tuesday, January 1. 2013
(Disclaimer: I'm a Software Engineer for Microsoft China. In this blog I express my personal opinion and none of this constitutes the official nor unofficial opinion of Microsoft.)
UPDATE: this issue also hit The Verge. The information in this thread also confirms that Google tests for "Windows Phone", as opposed to testing for specific browser capabilities. Gizmodo also posted the story. I make no secret of the fact that, while I like my (Microsoft sponsored) Windows Phone, I miss Google Maps. For me, Google Maps was the killer app for Android. And the experience is great, even in China, with vector maps, buildings, public transport, subway exits, real-time traffic, latitude. But Google Maps wasn't enough to keep me on Android. I thought the Windows Phone experience was better overall and I ended up using by Nokia Lumia 800 over my HTC Desire S. For maps, I keep switching between Nokia Maps and GMaps Pro, an unofficial Google Maps client for WP. And occasionally I'd simply go to maps.google.com with IE. Well, I used to, anyway. Lately (as of a few months ago) opening maps.google.com on my WinPhone simply redirects me to Google Search. Even the Chinese site, ditu.google.com, no longer opens on my WinPhone. Switching IE from Mobile to Desktop mode also doesn't fix the issue, and I keep getting redirected to a regular search page (under the maps.google.com domain, but it's still regular search, without maps.) My first thought was that the IE browser on WP7.5 "Mango" was simply not supported by Google. So I fired up the WP8 emulator to check whether Google Maps would open on the mobile version of IE10. Sure enough, it didn't. However, this time switching IE to Desktop mode did solve the problem and I got the regular desktop experience, albeit on a small screen. That's suspicious, I thought, since the browser is exactly the same, whether I use mobile mode or desktop mode. I figure I'd manually try the different User-Agents to see what would happen:
Interestingly, as soon as a device identifies itself as a Windows Phone (or WP7) it gets redirected. In other cases it gets the actual Google Maps page. As a test I wanted to replace the User-Agent from my WP7 device with the one from an Android device. Here's how: sudo apt-get privoxyAdd this to the end: {+hide-user-agent{Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus One Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1)}}Change listen-address to listen on a public IP: sudo vi /etc/privoxy/configOn the WP device, change the proxy for your current WLAN profile to point to your instance of Privoxy. Et voilà, you got Google Maps on WP7, albeit a little flaky. It might be that Google preferred WP user to have no experience to them having a flaky one, but that still doesn't explain why it's redirecting WP8 IE when in Mobile mode. Now here's what's interesting. As soon as I add "Windows Phone" to the User-Agent, the page no longer loads and I get redirected again. Clearly there's some regex magic at work on Google's end. As much as I agree with Hanlon's razor "Never attribute to malice that which is adequately explained by stupidity," this does reek of Google being disingenuous and blocking the competition from their platform's killing app. And it's not as-if they haven't done shit like this before. Oh, and Happy New Year! "Do no evil"Saturday, August 11. 2012
(Cross-posted from my Facebook profile)
Smart, but disingenuous, ad served by Google. Mentions other browsers but links to the Chrome homepage. The site this ad got served on worked just fine in IE. Dirty trick.
Finally: unbound + dnsmasqMonday, June 25. 2012
I've been using unbound as my only DNS server for over a year now. It's a recursive and caching DNS server with DNSSEC (a.o.) support.
This is particularly interesting for people living in China: the GFW's first line of defense (if you can call it that) is spoofing DNS. If you use the DNS server provided by any of the Chinese ISPs, you're unlikely to get any meaningful IP for domain such as facebook or twitter. But if you go through the whole recursive query yourself (ie. ask the root-servers for "com", ask the .com servers for "facebook" and ask the facebook servers for "www") then you will get an IP, which you can potentially verify using DNSSEC. Because facebook and others constantly add new servers to their datacenters, with new IPs, it's likely that once you get the right IP, you can actually connect to the server, without the need for VPN. Unbound is easy to setup. For me, "opkg install unbound" was half the battle. The other half involved editing /etc/unbound/unbound.conf. For a detailed walk through, check this great site [calomel.org]. Here's my current unbound.conf: server: All this was working fine, but the problem was that local names in my LAN no longer got resolved. Unbound doesn't no anything about DHCP and it won't accept DNS registrations from local machines. Dnsmasq does know about local names, since it's the one handing out the IPs in the first place. Ideally, I use both DNS servers: unbound for external queries and dnsmasq for internal (and internal only!) queries. Most of the time I query external names, so I'd tried to get Unbound to forward local queries to Dnsmasq. I configured Unbound to use port 53 and Dnsmasq to use port 533. Then, I added a forward-zone to unbound.conf: forward-zone: This was supposed to forward all queries in the "lan" domain (the local domain, as configured in dnsmasq/dhcp) to the dnsmasq server listening on port 533. Unfortunately, this didn't work. No queries got forwarded, even though a lookup for a local name did get suffixed with ".lan" by the clients. So I flipped it around: dnsmasq on port 53, unbound on 533. Add the following to /etc/config/dhcp: option 'nonegcache' '1'This works: I can successfully ping my local computers and NAS, while still having other queries resolved (recursively) by unbound. I used dns_verify.sh to check my setup: root@OpenWrt:~# ./dns_verify.shBy the way, the script needs dig, which you can get by doing "opkg install bind-dig". Real life exampleSaturday, February 11. 2012
I never found the need to study those common unix utilities like sed, awk, xargs. Even my knowledge of grep didn't go further than blah | grep foo. Until yesterday, when I needed to accomplish a task that just happened to involve all of these utilities:
grep ppp /proc/net/dev | sed "s/:/ /" | awk '($2+$10>1000000000){print $1}' | xargs --max-args=1 --no-run-if-empty ppp-off First, grep filters all lines from /proc/net/dev that contain ppp. Then, sed changes the colon into a space using the regex s/:/ /. Next, awk parses the values of the 2nd and 10th column [bytes sent and received] and if the sum exceeds 1GB it prints the value in the first column [the interface]. Finally, xargs invokes ppp-off for every interface returned. Why I needed this is left as an exercise to the reader. Modern COM Programming in DTuesday, January 24. 2012
I finally got around to asking for permission to share the slides of a tech talk I did more than a year ago: Modern COM Programming in D
In the slides I explain how I've made a projection for COM into D, which allows you to use COM objects without the usual hassle of refcount/QueryInterface/HRESULT/BSTR/etc... Sharing the code will be hard (mostly because of the shape it's in) but the slides basically contain all you need. Actually, D has progressed a lot since, so a rewrite might be in order anyway. UPDATE: Add your comments below or on Reddit. import std.stdio, comxml;
void main()
{
// Create a new empty document
auto doc = XmlDocument();
// Load an XML document from an inline string
doc.LoadXml("
Server-side email filteringTuesday, January 24. 2012
I hate etc/ and everything in it, but I realize it might not be etc/'s fault. The fault might lie with Google and Bing: most of the results I get are people asking the same question on some forum. These threads often end without any answer. Or worse, wrong information. About half the threads eventually end up with the members discussing a complete different issue. Anyway, I figured it out. The following example assumes you're using the maildir format for your mailbox.
As you can see, the rules in .procmailrc use regular expressions to find the right mail. Each rule starts with colon-zero-colon (see man procmailrc for more options), followed by a line with the regular expression. Here, ^ means beginning of the line. Note that dots must be escaped with a backslash. A wildcard would be written as .* The next line describes what to do when the regular expression is matched. In this case we want procmail to deliver the mail to a folder called SomeFolder. (If you're using mbox instead of maildir this would be a filename rather than a folder name.) Add as many rules as you want, separating them with an empty line. OpenWRT on Netgear WNDR3700, IPv6 edition!Wednesday, June 8. 2011
Happy IPv6 day everyone!
Here's how I went about it:
FaceboocSaturday, February 19. 2011
Nice IP address they got, by the way:
TCP [2002:74e2:70fd:e472::3]:3405 [2620:0:1cfe:face:b00c::3]:443 ESTABLISHED New sport: extreme hot-pluggingSaturday, February 19. 2011
I was bored so I tried pulling out the harddisk of my laptop while it was running. Windows (7) kept running and didn't crash. Of course, I couldn't actually open any programs, but it didn't lock up. I put the harddisk back in and after a while the programs that I had tried to open all opened up at once. Pretty impressive
I tried to same trick on Ubuntu 10.4. As soon as I pulled out the harddisk, the gnome UI died. The taskbars disappeared. My console window stayed open however, and 'top' (started before I pulled the HDD out) kept running as well. Once I exited 'top' the system was pretty useless, of course. I put the HDD back in, but that didn't do much. Ubuntu didn't seem to be able to recover the way Windows did. I also was unable to login from a new tty. Shouting Winamp to IcecastSunday, February 13. 2011
Did I mention how great the Squeezebox Boom sounds? Well, it sounds great.
I have bought Shukar Collective's latest album, Rromatek, on Amazon today. (Amazon MP3s can only be bought from the US; nothing a VPN can't solve.) Once the download finished I listened to the CD on my laptop, but my Dell has terrible speakers. I immediately wished I could listen to the CD from the Squeezebox instead. The solution I came up with was to hook my Winamp up to the Icecast server on my NAS. Turns out that's harder than you'd think. There's a Winamp DSP plugin that does just that (Oddcast aka Edcast), but it was abandoned, apparently because of "legal reasons". Luckily, Icecast now accepts Shoutcast clients, but the protocol used by Icecast is not the same as the one from Shoutcast and the Shoutcast Source Plugin (get it here) doesn't understand Icecast. Fortunately, since version 2.2, Icecast can handle Shoutcast sources, by adding a single line to your <listen-socket> section in icecast.xml: <shoutcast-mount>/strm<shoutcast-mount>I wanted a new mount for my Winamp, not to interfere with the one from Ices, so it became:
<listen-socket>
<port>8000</port>
<shoutcast-mount>/winamp</shoutcast-mount>
</listen-socket>
<mount>
<mount-name>/winamp</mount-name>
</mount>
In Winamp, go to Preferences, Plugins, DSP/Effects and configure the SHOUTcast Source DSP. Check "Use SHOUTcast v1 mode (for legacy servers)". Disable "Make this server public" on the Yellowpages tab. Select an audio format on the Encoder tab. Press connect, and we're done. Squeezebox Boom + Icecast = WinThursday, February 10. 2011
Been to Hong Kong for Chinese New Year and one of the gadgets I bought there was a Logitech Squeezebox Boom (1880HK$). I had heard about the Squeezebox line before, but had never actually seen one. I have looked on taobao.com but there were only few sellers and (hence?) more expensive than abroad. (There's one seller that seems to have quite a supply and selling them at half the market price, but that's just too shady.)
After the initial setup I was shown the main menu. Because I was using mysqueezebox.com (as opposed to my own server) I could only choose "Internet Radio". However, it was a very extensive list of well known radio stations, and in about 10 minutes I was listening to Studio Brussels! The quality was really good, and definitely better than the Creative D100 speakers I had bought 1 month earlier. But still no access to my own music collection. Second surprise: the Squeezebox does not understand UPnP or DLNA. I thought that was a major bummer. It would have allowed me to simply hook it up to my Buffalo LinkStation Live's Twinkymedia Server. It seemed I had to install a Squeezebox Server. Squeezebox Server was installable on my Linkstation using: ipkg install squeezecenterThat went well (albeit it was a somewhat older version), but it was immediately apparent that the 64Mb RAM of the Linkstation were not enough for the hefty perl + mysql Squeezecenter. The NAS was constantly swapping and became unresponsive. What I basically wanted was simple: when I still had my original Xbox with XBMC, I had made a startup script that immediately started Party Mode as soon as the XBox was turned on. Filling the room with music was a simple act of pressing a button. Most of the time I didn't care about which CD was playing. (Without Party Mode I would spend minutes figuring out what music I felt like listening and usually ending up with one of my favorites, never choosing 90% of the music I actually had.) I had heard about Icecast before. It's a music (media, to be more exact) streamer, similar to shoutcast. It was easily installed on my NAS using ipkg install icecast. Icecast itself is just the streaming server, it doesn't actually read music itself, but needs a Icecast Source to provide it with the bits. That job is done by Ices, also installable using ipkg install Ices0(Apparently nobody has built Ices2 for the ARM yet?) The input for Ices is a text file with the playlist. Because Ices0 (as opposed to Ices2) only understand MP3, I had to make a playlist with only my MP3s, skipping Flac and Ogg: find /mnt/disk1/share/music -name \*.mp3 > playlist.txt Icecast and Ices could now be started with: /opt/bin/icecast -c /opt/etc/icecast.xml -bI could now connect to my own radio station from Winamp! I then proceeded to add the URL to my Favorites on mysqueezebox.com but it wouldn't work. The Squeezebox cannot play streams on the LAN because the server (and in this case, mysqueezebox.com) must be able to access the stream, for some metadata I presume. The solution was easy: open a random port on the router and forward the traffic to the Icecast server: success! One caveat though: the LinkStation would be constantly streaming music, even when nobody was listening, causing non-stop churning of the harddisk. I wanted to started Ices when the first listener connected and to stop it once the last listener went away. That could be done by adding an authentication section to icecast.xml: <authentication type="url"> <option name="listener_add" value="http://localhost:8081/icecast.php"/> <option name="listener_remove" value="http://localhost:8081/icecast.php"/> <option name="auth_header" value="icecast-auth-user: 1"/> </authentication>With these settings, the Icecast server would contact the mentioned URLs when a listener (dis)connected. In the PHP file I could then start/stop the Ices server: <?
$action = $_POST['action'];
$mount = $_POST['mount'];
header("icecast-auth-user: 1");
function store($c)
{
$file = fopen("/tmp/count", "c+");
$count = fgets($file);
if ($count !== false)
rewind($file);
else
$count = 0;
$count = intval($count) + intval($c);
fputs($file, $count."\n");
fclose($file);
return $count;
}
function start_ices()
{
$array = array();
exec("ps", $array);
foreach($array as $line)
if (strpos($line, "/opt/bin/ices") !== false)
return;
exec("/opt/bin/ices -c /opt/etc/ices.conf.dist -B");
sleep(1);//echo $i;
}
function stop_ices()
{
exec("kill `cat /opt/var/log/icecast/ices.pid`");
}
if ($action == "listener_add" && $mount == "strm" && store(1) == 1)
start_ices();
if ($action == "listener_remove" && $mount == "strm" && store(-1) == 0)
stop_ices();
?>Success.
I can't believe how hard it is to create a global setting in PHP. I needed an atomic increment/decrement for the user count. The store($) function basically serves as a global InterlockedAdd, loading a integer from a tempfile, adding a value to it, writing the result back to the file and returning it to the caller. Please let me know if there's a easier way to accomplice that.
What's your mean?Friday, January 28. 2011
老外苦学汉语十年,到中国参加汉语等级考试,试题如下:
请解释下文中每个“意思”的意思— 阿呆给领导送红包时,两人的对话颇有意思。 领导:“你这是什么意思?” 阿呆:“没什么意思,意思意思。” 领导:“你这就不够意思了。” 阿呆:“小意思,小意思。” 领导:“你这人真有意思。” 阿呆:“其实也没有别的意思。” 领导:“那我就不好意思了。” 阿呆:“是我不好意思。” 老外泪流满面,交白卷回国了。 Chinese to English translation Foreigners learn Chinese bitter years, to China to participate in Chinese language level test, questions are as follows: Please explain below each "meaning" means — Dumb bribe the leaders, the two men rather meaningful dialogue. Leadership: "What do you mean? " Dumb: "no meaning, meaning mean. " Leadership: "You mean this is not enough. " Dumb: "a mere trifle, a mere trifle. " Leadership: "You are so interesting. " Dumb: "In fact, no other meaning. " Leadership: "Then I was embarrassed. "** Dumb: "I am sorry. " Foreigners in tears, has done nothing back home. ** "不好意思" means "I'm embarrassed", but it's also said when accepting a gift. Lǎowài kǔxué hànyǔ shí nián, dào zhōngguó cānjiā hànyǔ děngjí kǎoshì, shìtí rúxià: Qǐng jiěshì xià wénzhōng měi gè “yìsi” de yìsi— Ādāi gěi lǐngdǎo sòng hóngbāo shí, liǎng rén de duìhuà pō yǒuyìsi. Lǐngdǎo:“Nǐ zhè shì shénme yìsi?” Ādāi:“Méishénme yìsi, yìsi yìsi.” Lǐngdǎo:“Nǐ zhè jiù bùgòu yìsi le.” Ādāi:“Xiǎoyìsi, xiǎoyìsi.” Lǐngdǎo:“Nǐ zhè rén zhēn yǒuyìsi.” Ādāi:“Qíshí yě méiyǒu bié de yìsi.” Lǐngdǎo:“Nà wǒ jiù bù hǎoyìsi le.” Ādāi:“Shì wǒ bù hǎoyìsi.” Lǎowài lèi liú mǎnmiàn, jiāobáijuàn huíguó le.
(Page 1 of 9, totaling 126 entries)
» next page
Competition entry by David Cummins powered by Serendipity v1.0 |
QuicksearchMy Favorites
CategoriesTimezones
Blog Administration |