Archive for technology

So I use rsync to keep a remote directory up to date

On an older post about WinSCP Kamil Grabowski asked if I’d used rsync to keep remote files in sync.

I have, and use it more often than winscp or sshfs.

rsync is basically a smart copy utility – it can copy (sync) files between local or remote directories, and it will copy on the changed portions of files.

You can use it as a single invocation:

rsync -avr localdir remoteuser@remotehost:remotedir

You can also do it in a loop (but note that if you haven’t set up your SSH keys, you’ll be prompted for a password each time…):

while true; do rsync -avr localdir remoteuser@remotehost:remotedir; sleep 5; done

If you want it to not make a connection unless there are new files, you need to get a bit more complex:

set source=SOURCE_DIR
touch -t 197001010000 last # make a placeholder file as of 1970 so we can find newer files
while true
  if [ "`find $source -newer last -print`" ]
    touch last
    rsync -avrz $source $dest
    echo -ne .
  sleep 5

Comments (1)

So I Considered AppStore vs. Cydia

From ChaZg33k on So I Made My iPhone Say Hello, World…

Why would you want to use the App Store when you could submit to Cydia?

Hmm. Troll, or serious question? Guess I’ll respond as a serious question, because I have something serious to say.

Cydia is cool. But the AppStore reaches more iPhones (all jailbroken and all “stock” iPhones) – and most people I see with an iPhone don’t have it jailbroken (and yes, I’ve been asking – current ratio is about 10:1).

Also, there’s a strange behavior with iPhone users – they actually seem willing to PAY for software in the AppStore! <NY Times>.

Given the prevalence of Crackulous, I don’t know that the same holds true for many Cydia users (n.b., I use Cydia, but not Crackulous, and yes, I realize that there are fair use arguments for tools like that, and that the DMCA also has a few arguments to make).


P.S. Just about ready to submit my first app to the AppStore (nothing fancy, though it made me build infrastructure and experience for other projects I have going), then hoping to begin posting more about details, and should be following on with more interesting apps shortly!

Comments (1)

So I used sshfs to Mount a Remote Filesystem

This is the one Linux way to edit files remotely as if they were local. For a Windows approach, see my post on WinSCP. There’s also a Windows sshfs called Dokan SSHFS.

sshfs is a user-space Linux filesystem that makes an ssh connection look like a local filesystem.

It’s trivial to use:

  1. As root (or using sudo) add your user to the ‘fuse’ group:

    # adduser butler fuse
    Adding user `butler' to group `fuse' ...
    Adding user butler to group fuse

  2. Start a new shell as the desired user (to get the updated group list), make a mount point, and start sshfs. Note that sshfs will prompt you to accept the remote key (not shown) if this user hasn’t previously connected to this remote account.

    $ mkdir soi
    $ sshfs soi's password:
    $ ls soi/images
    changeDirectories.jpg keepRemoteSynced.jpg updatingFiles.jpg
    directoriesSynced.jpg session.jpg watchForChanges.jpg
    firstSession.jpg updateFiles.jpg

  3. Read and update files as if they were local – but with some transfer lag…

If you don’t want to deal with the lag every time you read or write the file, you’ll probably want to use scp or rsync to copy the files over when you need them on the remote machine – and you’ll probably want to use ssh-agent and ssh-add to set up key-based authentication, so you don’t have to type your password every time. You can even put the scp or rsync calls in your Makefile…

Comments (2)

So I used WinSCP to Keep a Remote Directory Up-to-Date

Mononofu reminded me I hadn’t talked about how to keep remote directories in sync. This is the windows version. For a Linux version, see my post on sshfs.

So, to work on files locally on Windows, but have them automatically copied to a remote directory, use WinSCP.

  1. Download WinSCP 4.17 and install it
  2. Run WinSCP
  3. Enter info to connect to the remote host (like your iphone)Session parameters
  4. On your first connect, WinSCP won’t recognize the key of the remote system, so just accept it. If you see this prompt later, it either means your remote system got a new key (e.g., reflashed the phone and re-jailbroke it), or somebody could be trying to intercept your communications. Prompt to accept remote host key
  5. Change directories to the local and remote directories you want to keep synced. Change directories
  6. Choose Commands | Keep Remote Directory up to Date (Ctrl-U). Keep Remote Directory up to Date (Ctrl-U)
  7. Choose options for synchronization, and do a full synchronization to get things started. Watch for changes
  8. Make changes to the files on your local machine. Update local files
  9. WinSCP notices the changes and pushes them to the remote machine. Updating files
  10. The directories are kept in sync. Directories synced

Comments (5)

So I wonder which is more open? G1 or iPhone

At first blush, the G1 is obviously more open than the iPhone – open source platform, open SDK from day 1, and you can install software from anywhere just by selecting a menu option.

But this software runs in a Java sandbox. You don’t appear to have access to the operating system outside the sandbox.

And I have a jailbroken iPhone. I can ssh into my phone. I can use the phone without a SIM card (G1 goes into “emergency calls only” mode). I can modify startup scripts. I can write applications to do anything on the phone. I can change anything I want to on the phone, as a Simple Matter Of Programming. Is the G1 that open? Not the Android platform – the actual, G1 device in my hands…

Of course, as a platform, Android is much more open than iPhone OS. But the actual device? So far, I’m saying a jailbroken iPhone…

Leave a Comment

So I Compared a T-Mobile G1 vs an iPhone

I’ll continue to update this as I continue to learn about both phones, but I’ll start with some first impressions.

  • The G1 is noticeably bigger, but not bad.

    It’s bigger than the iPhone, bigger than my RAZR VR3, thinner than my wife’s old T-Mobile Wing, but way smaller than my Zaurus c860. It fits in a shirt pocket or pants pocket (though my wife is concerned about it being tight in her jeans pockets).

    It meets my size criteria, though I’d like it to be smaller – I forget the iPhone is in my pocket, not likely to forget the G1.

  • The bend of the G1 isn’t bad. I was really concerned from the pictures of the bent-up bottom of the phone, but you don’t notice it, it isn’t bad to hold either in portrait or landscape. Not a problem.
  • The iPhone screen is noticeably larger, and a bluer white. The G1 screen is brighter, and a bit warmer (more yellow) white.
  • Android needs a review of “small screen” mentality. Apple got this right (very right) in that whatever application is presenting content to the user gets the whole screen. Smaller-than-screen windows should be rare, and only for very small announcements.

    There are lots of places Android uses sub-screen windows, often presenting large amounts of content without making full use of the available screen real estate. This is present in basic functionality – like the Applications tab not using the whole screen – and applications using dialog boxes.

    You can really see this by going into the Settings|About section – all the Legal documents are presented in a centered dialog box, appearing over the background window, even though they have pages and pages of content. If you open the DMCA info, you get a web page that is scrolled horizontally half off this tiny dialog box because of navigation controls on the left side (but they’re not even visible because the page is scrolled down past them). Really obnoxious. Kudos to Apple.

    Oh, and one more example: setting up a Wireless access code. the G1 pops up a dialog box (again, smaller than screen size) for you to enter your key. And you have to open the keyboard, rotating to landscape mode, to enter it, because there is no onscreen touch keyboard. Then you type the key, and there is a half-exposed control at the bottom of the dialog box. If you scroll the dialog box up a bit, you can see that it is a checkbox to display the key as you’re typing it. If the dialog took advantage of the whole screen, you wouldn’t need to scroll to see this option.

  • Android is much less aware of its device than the iPhone is. No, I’m not trying to anthropomorphize the phones.

    When you tip the iphone, it (usually) rotates to landscape. Touch is integrated throughout the iPhone system, to go back, to select options, etc. You always interact by touching the screen.

    I haven’t found anything on the G1 that recognizes when I’m holding it landscape unless I open the keyboard. Then everything is landscape, even if I’m still holding the phone vertically. The only way to rotate the browser to landscape/wide-screen viewing is to open the keyboard.

    With Android, you go to the home screen by pushing the off-center home button. You get menus by pressing the menu button. You go back by pressing the back button. These functions are never presented on screen for a touch. I find myself constantly wondering, “How to I get back to that last window? Oh, yeah, the button”, whereas with the iPhone, it’s presented where your focus is, on the screen. I’m always forgetting what functions need the menu button, which need home, and which need back.

    Now, I realize that onscreen controls cost screen real estate (not as much as the “dialog boxes” do, though!). Maybe I’ll remember the G1 controls more naturally later, but for now, the physical buttons aren’t helping usability.

    And sometimes, things you really should be able to touch can’t be selected by touch – in the google legal information, you can’t touch-to-select a link until you’ve touched the trackball, then you can touch to select.

  • Apple’s browser is easier to use. The zoom & scroll is easier than the G1, thanks to the multitouch interface. Android could do better than its clunky buttons even without a touch screen, but for now it’s clunky.
  • To take a screenshot on an iPhone: hold down the “sleep” button and press and release the “home” button. It saves the screenshot to the Photos directory.

    To take a screenshot on the G1: connect the G1 via USB, install the SDK, run DDMS, select your handset, and press Ctrl-S, then save the image. ( *sigh*

Comments (4)

So I had to force reset my iPhone (force shutdown/poweroff)

If your phone locks up, is unresponsive, and won’t go to sleep, etc., you probably need to reset it by forcing a shutdown. This happens occasionally with stock or jailbroken iphones, original and 3G. This crash may occur more frequently in low disk space conditions.

This isn’t a painful procedure and doesn’t lose your data – it just takes a minute.

Hold down the “home” and “sleep” buttons for several seconds (about 10). You may see the “Slide to poweroff” screen appear. The screen may go black. Don’t let go until you see the apple logo (or pineapple logo for jailbroken phones). Let go and wait a minute, and your phone will boot up normally.


Leave a Comment

So I Found Ways to Develop for iPhone

To develop for the iPhone, you have a few choices:

Web applications


  • choose your tools, choose your development platform
  • can make it available to non-iPhone users
  • requires connectivity


  • requires a hosting provider
  • limited to safari interface (i.e., tap, rotate, two-finger scroll, pinch zooming, no accelerometer, little iphone glitz)

Toolkits available:

Additional tools/techniques:

  • Web clip bookmark icon create an icon for use in the home screen (hit + in Safari, then “Add to home screen”)
  • Data links allow you to encapsulate webapp and state in the URL. Provides a mechanism to save a “bookmarklet” (“webclip”) that encapsulates the application. If we can also sync back to the online application, that would complete the round-trip.
  • iPhone in Action book has discussion of tradeoffs of web vs native applications

Native applications via the Apple SDK


  • best tools available, including the simulator
  • access to all documented iPhone SDK features
  • publish your application in the AppStore
  • lots of books published or being written


  • iPhone only
  • Limitations on application functionality from iPhone SDK agreement (no interpreters, no plugins, …)
  • Requires Apple approval of application for listing in AppStore
  • Requires signing a non-disclosure agreement (NDA)NDA lifted!
  • requires Mac OS X as development platform

Toolkits available:

Native applications via the open source tools


  • no NDA to sign
  • develop on your platform of choice
  • full access to anything the community has discovered
  • (possibly more than the documented SDK)
  • you can even develop ON the iPhone


Toolkits available:

So, there you have it. Three options.

What will you do?

Comments (1)

So I Don’t Like System.Net.HttpListener

…or at least, I disagree with a design choice made in a class it uses – System.Net.EndPointManager

Backstory (Exposition)

I’ve been doing some work with the generally excellent Dekiwiki. It’s a descendant of MediaWiki, of WikipediA fame. (Does anyone actually capitalize the “A” in WikipediA? I just noticed it on the logo on their website. Really. Never saw it before. Anyway, back to our, umm, backstory…)

Dekiwiki provides some neat extension capabilities, and a useful REST API, and a really cool web service framework. Oh, and it comes with a wiki, too.

Inciting Incident

But I noticed that the dekiwiki API process (running in mono) listens on all interfaces of its port – not just localhost:

netstat -anp | grep 8081
tcp 0 0* LISTEN 31194/mono

Well, that was disturbing, because it means people from the Internet (you know, “bad guys”) can connect to this internal process.


There’s a configuration value that looks like it should limit it, in /etc/dekiwiki/

# Port the API listens on

# hostname to listen on

Rising Action

But it doesn’t.

Digging into the code (gotta love open source…), I found that it was just using the HttpListener class from Mono. HttpListener delegates to EndPointManager, which includes this code:

// Always listens on all the interfaces, no matter the host name/ip used.
EndPointListener epl = GetEPListener (IPAddress.Any, lp.Port, listener, lp.Secure);


And sure enough, some experimentation with IronPython and .Net on Windows

    from System.Net import *
    l.Prefixes.Add( "http://localhost:8080/" )

showed that Microsoft works the same way.

netstatp -an | grep -B2 8080
[TCP] ipy.exe:3656



I can understand why – Microsoft wants the HttpListener class to work like virtual hosts in an HTTP 1.1 environment, so you can distinguish URL requests for different web applications by hostname, but that doesn’t mean the “bind sockets only to the appropriate interface” principle isn’t valuable, too.

But at least if you request something over that socket from an external host, you won’t match the specified URL prefix, so you’ll get an error. That’s something anyway. And you can always set up firewall rules to block the port…


Comments (1)

So I Installed git and git-svn on Cygwin

Sometime I’ll have to tell you about why I chose git.

Installing on cygwin wasn’t too bad. Had a few problems, though.

A little background

  • git is an open source, distributed version control system, originally created by Linus Torvalds, and greatly enhanced by the open source community.
  • svn or Subversion is an open source, centralized version control system.
  • git-svn is a git command to let you use the distributed functionality of git, and interact with the centralized world of subversion.

Cygwin setup

Running cygwin’s setup program gives you a GUI package installer. I like to use the xmission mirror, both because it is geographically close by, and because it is fast.

After all the preliminaries, click the “View” button to get an alphabetical list of packages, and expand the window so you can see a bit more. (I’m SO grateful cygwin finally made the window expandable, that I feel a bit guilty complaining that the initial window size is still too small…)

You’ll need at least the git, gitk, perl, and subversion-perl packages, and there’s lots of other good stuff there, too – like a full X-Windows system.

These required packages will also install a lot of other dependencies, so be prepared to wait a bit while it downloads and installs everything.


I also needed to download from CPAN into my c:/cygwin/lib/perl5/site_perl/5.10/ directory. (Thanks, Martin Carpella!)

Run git-svn

After everything is installed, you should be able to run git-svn. Note that there are two ways to run git-svn:

  1. git svn runs the wrapper program (git) which spawns the svn submodule
  2. git-svn runs the svn submodule directly

The installation process put git in /bin and git-svn in /usr/sbin/git-core/. I didn’t want to add that directory to my path, so I just run git svn.

Using git-svn

Andy Delcambre describes a basic workflow to use git-svn. There’s a more detailed description on

Some Problems

  • subversion-perl or perl not installed. Use the cygwin setup program.
    git: 'svn' is not a git-command. See 'git --help'.
  • Perl not found or not installed (I reinstalled perl using the cygwin setup program):
    /usr/sbin/git-core/git-svn: /usr/bin/perl: bad interpreter: No such file or directory
  • Need to download, or need to place it in the @INC path:
    Can't locate in @INC (@INC contains: /usr/lib/perl5/site_perl/5.10 /usr/lib/perl5/5.10/i686-cygwin /usr/lib/perl5/5.10 /usr/lib/perl5/site_perl/5.10/i686-cygwin /usr/lib/perl5/vendor_perl/5.10/i686-cygwin /usr/lib/perl5/vendor_perl/5.10 /usr/lib/perl5/site_perl/5.8 /usr/lib/perl5/vendor_perl/5.8 .) at /usr/lib/perl5/vendor_perl/5.10/ line 100.

Leave a Comment