Everything In Between

The brutally honest, first-person account of Meitar Moscovitz’s life.

Archive for March, 2008

Sharing your Windows XP Virtual Machine’s Internet connection with your Mac OS X host operating system using VMware Fusion

5 comments

In some situations, like the odd one I now find myself in, the only way to get Internet connectivity is to use a solution that requires a fair bit of maneuvering. In my situation, I have temporarily obtained a Vodafone 3G mobile card. Unfortunately, the Vodafone Mobile Connect software for Mac OS X as of this writing is obscenely poor. Of course, Vodafone’s software for Windows works without a hitch.

The only way I could get my Vodafone 3G card to work was to fire up a Windows XP guest inside of my MacBook Pro, using VMware Fusion. Connecting to the Internet with the 3G card using the Windows guest was smooth sailing, but that only provided the Internet connection to the Windows virtual machine. I wanted my Mac to be directly connected.

The solution is obvious, but a few gotchas really bit me hard. To get the Windows guest to share its Internet connection from the 3G card to my Mac, I would need to bridge VMware’s virtual ethernet adapter from the Windows guest to the Mac OS X host. Once bridged, both the Windows guest and the Mac OS X host would logically be on the same ethernet network segment. At this point, I can enable Windows XP’s built-in Internet Connection Sharing (stupidly dubbed “ICS” because everything needs a TLA) on the 3G connection so that Windows NATs it through to the bridged virtual ethernet card. Finally, I can connect to Vodafone’s 3G network, and all should be well.

Here’s the gotchas.

First, in order for VMware to actually initiate the network bridge when it starts up, it must detect that a physical link is active on your Mac. In other words, Mac OS X’s Network System Preferences pane must show you a yellow dot next to at least one physical networking device (probably either your “Built-in Ethernet” or your “AirPort” ports). VMware Fusion will give you no errors or warnings that a bridge is unavailable until you try to connect your virtual machine’s network while set to bridge, in which case VMware Fusion will complain with an error that reads: “The device on /dev/vmnet0 is not running.”

Obviously, if you have no other devices to connect to, you need to fake one. The easiest way to do this is to set up a Computer-to-Computer network using AirPort. Just go to your AirPort menu bar item and select “Create Network…” and create the network (preferably encrypted). If you check System Preferences now, you should see a that AirPort has a yellow dot next to it and reads as having a “Self-Assigned IP Address.” Now that you have a physical link on your AirPort card, you should be able to start the VMware Fusion virtual machine with bridged networking mode without incident.

However, if you do encounter the above error anyway, you need to restart the VMware network bridge. You can do this either by shutting down VMware completely (turn off your guest operating systems, and quit the VMware Fusion application), or you can run the following commands as an administrator in Terminal, which will stop any bridge currently running (or do nothing if no bridge is running) and then restart it, providing the output as shown:

sudo killall vmnet-bridge
sudo "/Library/Application Support/VMware Fusion/vmnet-bridge" -D vmnet0 ''
Entering event loop...
Examining network configuration...
Turning on bridge with host network interface en1...

Obviously, you may be asked for your password as you perform this procedure. Note that the trailing two apostrophes are single quotes with no space. This is (almost) how the VMware Fusion boot.sh script starts and stops the network bridge. Specifically, you’re telling the vmnet-bridge application to run in Debug mode and to bridge vmnet0 to whatever is the current primary networking interface. In the example output shown above, this is en1, or my AirPort card connected to the computer-to-computer network I created in the previous step.

Hopefully you won’t have to mess with the vmnet-bridge application, as this should happen on its own when you start up VMware Fusion if you have any physical link on a network device. Nevertheless, I’ve found this is sometimes unreliable, so just in case it doesn’t now you know how to bring up the bridge on your own. (Tip: once it’s up, you can CTRL-Z to pause it, re-start it with fg %1 and then quit Terminal if you like. The bridge will still be up.)

Now that the AirPort card has a physical link, and the VMware network bridge is running, the next step is to configure your virtual machine to use bridged networking. Just go to Virtual Machine → Network → Bridged as normal. Make sure Connected is also selected. Now start up your Windows guest.

Once Windows boots, go to the Network Connections window by selecting Start → Connections → Show all connections. At this point, your “Local Area Connection” in Windows probably has a warning sign on it and reads as having “Little or no connectivity.” It probably has a self-assigned IP address just like your AirPort card. That’s fine—as long as it’s not “unplugged,” we’re in good shape.

Next, select whatever other connection you want to share the Internet from (in my case, the 3G modem, but it could also just be any other connection in the window), right-click it and select Properties. Go to the Advanced tab and make sure “Allow other network users to connect through this computer’s Internet connection” is checked. The other boxes won’t matter.

What this does is turns on Windows’ own NAT service that configures the one connection (the one your sharing) as the WAN side of (yet another) virtual networking device and the Local Area Connection (the one we’ve bridged to our AirPort or Built-in Ethernet card on our Mac) as the LAN side. Hit OK as many times as is necessary to close the network connection properties windows and wait a few moments. Sometimes this can take up to 30 seconds or so, but eventually you’ll see Windows announce that “Local Area Connection is now connected.” If you inspect it, you’ll see that the IP address configuration has been automatically assigned as a “Manual Configuration” with the address of 192.168.0.1, a subnet mask of 255.255.255.0, and no default gateway.

As a last step, now we can actually connect to the Internet using whatever service we have. In my case, this is when I hit the “connect” button on my Vodafone Mobile Connect software. Once the connection is established and the Windows XP virtual machine can see Internet, it takes up to another minute or two (or three) for the Mac’s connection to get an IP address from the Windows guest, but it invariably works.

If the Windows side of things is giving you any trouble, the most reliable solution I’ve found is to simply disable, then re-enable whatever connection isn’t behaving as desired. If after all of this your Mac still doesn’t get an IP address from the Windows XP guest, disconnect and then re-connect the virtual machine’s ethernet card (by toggling the “Connected” menu item in the Virtual Machine → Network menu). Also, of course, be doubly sure that your AirPort is set to “Use DHCP.”

Phew! So simple…and yet so much harder than it had to be. I found the following two PDF documents very helpful in understanding all of this. You might too:

  1. VMware Fusion Network Settings — a super-brief, but excellent introduction to VMware’s network setting internals. It’s also a PDF download attached to the linked forum thread.
  2. Share Windows XP Guest Internet Connection with OS X Host HOWTO — This basically describes the same thing this post does, but it does so using absolute step-by-step instructions. It’s also a PDF download attached to the linked forum thread.

Written by Meitar

March 31st, 2008 at 4:06 am

HowTo: Use git for personal development when everyone else is using Subversion (part 2)

leave a comment

When we left off, you had just finished transforming a remote Subversion repository into a git repository and optimizing it to save you some space. Now that you have a git repository, what do you do?

First things first. Once you have an idea of what work you want to do, you should give yourself a space to do this work without disturbing anybody else’s work. Do this by making a new, personal branch. Unlike Subversion and some other centralized version control systems, git makes it possible to do make all kinds of changes to your repository, including making branches, and even save those changes without having to republish everything back to the central repository server at each step. In other words, if you thought Subversion branches were “cheap,” you’ll love git’s branches.

Also unlike Subversion, which stores its branches in completely separate pathnames, git keeps all branches in the same filesystem tree separated only with metadata (in .git/refs/remotes for remote branches and in .git/refs/heads for local branches, to be a bit more precise), so you don’t have to create lots of different directories for all your branches (unless you want to). With no branches defined, you’re working in the “master branch,” or “the trunk” by default.

git branch
* master

By saying git branch you ask git to print a list of all (local) branches. The one with the asterisk marks the current branch, the one you’re using at the moment you run the command. Since there are no branches, you’re currently in the “master” branch. But we don’t want to make changes here, we want to make changes in our own private branch, so we’ll make a new one.

git checkout -b new_branch_name

This will create a new branch with the name new_branch_name and immediately switch to it. Notice that you’ve made absolutely no changes to the filesystem itself; only the git metadata has been altered. Saying git branch again will show you the change:

git branch
  master
* new_branch_name

Also note that since we haven’t comitted any changes, we don’t need a commit message (or “log message”) for creating this branch. We’ll add one later, when we need it. Now go ahead and write some code in your new branch. At any time, you can create a new branch in the same way you added the first. Each new branch is created at the HEAD (“latest”) revision of whatever branch you’re currently working in.

git checkout -b another_branch
Switched to a new branch "another_branch"
git branch
  master
  new_branch_name
* another_branch

To switch back to any other branch, simply git checkout that branch again:

git checkout master
Switched to branch "master"

If you want to delete a branch you don’t like, that’s easy too:

git branch -d another_branch
Deleted branch another_branch.

Keep in mind that throughout all of these branch creation and deletion actions, the only thing that’s being altered is the git metadata. That’s why it’s so cheap to create new branches. If you ever have a new idea you’re working on, it’s recommended that you create a branch for it, even if that branch is so short-lived it never gets published.

So you have a new local branch, and you’ve been working as you normally do for a few minutes, creating files, editting them, and so on. Running git status now will ask git to show you the changes you’ve made to your filesystem. If you’ve created any files in new directories that git doesn’t know about, it will simply report that directory. If you’ve made new files in directories git does know about, it will list all those files explicitly.

git status
# On branch cartoon_contests
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#	sites/default/modules/cartoon_contests/
#	sites/default/modules/factiva/.factiva.module.swp
#	sites/default/modules/testfile
#	sites/default/settings.php
nothing added to commit but untracked files present (use "git add" to track)

In the above sample output, I’m working on a new Drupal module for a web site. I’ve created a new directory, sites/default/modules/cartoon_contests/ (note the trailing slash), and I have several untracked files. One is my vim swap file for a different module, .factiva.module.swp, one’s an unimportant testfile, and the last is the Drupal configuration file, settings.php.

The only thing I want to commit is the new cartoon_contests directory, and all the files within it. Like Subversion, I have to tell git that I want to track this directory, which is done simply by saying git add cartoon_contests. Unlike Subversion, future invocations of git status let me see everything that git is going to go in the next commit.

git status
# On branch cartoon_contests
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#	new file:   sites/default/modules/cartoon_contests/cartoon_contests.info
#	new file:   sites/default/modules/cartoon_contests/cartoon_contests.module
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#	sites/default/modules/factiva/.factiva.module.swp
#	sites/default/modules/testfile
#	sites/default/settings.php

The “Changes to be committed” section of the output is called the staging area, or the index. In this way, I can prepare all the changes I want to commit before I do so, making sure they’re perfect before I actually commit them to the git repository. At any time before I commit, I can make additional modifications, such as git adding more files or directories, git reseting to unstage all (or some) of my changes, etc. git help reset also has a number of handy explanations with examples for different things you might need to do at this point.

If you were using svn:ignore, equivalent functionality exists in git. Simply append file glob patterns, one per line, to the $GIT_DIR/info/exclude file in your git repository. Like so:

echo -e "*.swp\nsites/default/settings.php" >> .git/info/exclude ; git status
# On branch cartoon_contests
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#	new file:   sites/default/modules/cartoon_contests/cartoon_contests.info
#	new file:   sites/default/modules/cartoon_contests/cartoon_contests.module
#

If you’ve got many of these, you can use git svn show-ignore >> .git/info/exclude to search through your old Subversion repository and look for any and all ignores, automatically adding them to git’s exclude list. (Checkout Tsuna’s blog entry on learning git for more tips like this.)

Finally, after you’ve done some of your work and you’ve finished staging your changes, you’re ready to commit them to the repository. On the other hand, if you hate what you’ve done and want to undo it all, you can say git reset --hard HEAD to throw away all your local changes. To throw away changes to just a single file, just checkout that file again by saying git checkout filename. This is the equivalent of Subversions svn revert filename command.

Before you actually make your first commit, however, you should properly introduce yourself to git. You don’t have to do this because git will try to figure out who you are by itself (details explained in detail here), but you probably should at least create global defaults for your user (which git will store in ~/.gitconfig). If you want to, you can also create per-repository defaults (which git will store in .git/config), or even system-wide defaults for all users of this computer (which git will store in /etc/gitconfig). To do so, say this:

git config --global user.name "Your Full Name"
git config --global user.email "you@example.com"

This will create the file ~/.gitconfig if it doesn’t alreay exist and will write your name into it. You can also just edit the file directly yourself instead of using git config commands.

Like Subversion, committing will create a saved, fixed point-in-time that marks the changes you have made to your files. Like branches, commits are also very cheap in git, so go ahead and commit at any time you like. Remember to stage your files (by git adding them), and then just git commit.

git add filepattern
git commit -m "My very frst git commit!"
Created commit ef483c1: My very frst git commit!
 5 files changed, 58 insertions(+), 12 deletions(-)

If you forget to specify a commit log message (-m "log message") on the command line, or if you want to enter a multi-line commit log, git will prompt you for it in your favorite $EDITOR. You can view a history, including all the log messages, for your project with git log. You can even the view logs in a number of pretty formats. Check git help log for more information.

If you want to change anything about the commit you just made, such as the author, you can just run git commit again with the --amend flag added to the command. Notice the typo in the commit log? Fixing it is really easy:

git commit --amend -m "My very first git commit!"
Created commit 88602f6: My very first git commit!
 5 files changed, 58 insertions(+), 12 deletions(-)

Finally, with your new code commited to your local git branch, it’s time to share that code with your colleagues who are (for some inexplicable reason) still using Subversion. This is also extremely simple. Just say git svn dcommit. (That’s right, dcommit, not just commit. I don’t know why….)

Not sharing your changes via Subversion, but with a patch instead? git diff -p will generate patches for you. See git help diff-files and look for the “GENERATING PATCHES WITH -P” section.

If you found this helpful, you may also enjoy an alternative tour for beginners from Carl Worth.

Written by Meitar

March 28th, 2008 at 3:20 am

Posted in HOWTO, Mac OS X, Programming, Unix/Linux

Tagged with

HowTo: Use git for personal development when everyone else is using Subversion (part 1)

3 comments

Let’s just jump into it.

Using Mac OS X, first make sure you have the git core installed as well as the git-svn components. Unlike other version control systems, git is not one monolithic program but a collection of smaller utilities, and the Subversion conduits are a subset of these utilities. The git-Subversion utilities themselves depend on having the Perl::Subversion bindings installed for Perl 5.

For the lazy MacPorts user, simply run:

sudo port install git-core +svn

This will install the git-core, the git-svn packages, as well as all the documentation for git and any required dependencies you don’t already have. Note that the documentation (man pages) is installed in /opt/local/man, which may not be in your default $MANPATH, so be sure to add that directory if man git returns a “No manual entry for git” error.

Alternatively, if you don’t want to use MacPorts, you can download a pre-compiled Mac OS X binary that includes git, the git docs, and the git-svn package from the git web site that comes complete with a standard GUI installation procedure.

Next, initialize a new git repository that tracks a remote Subversion one. This allows you to work privately using git, but to collaborate with other people who are using Subversion. Running

git svn init svn://my.svn.server/path/to/svn/repo workingcopy

will give you an empty git working copy named workingcopy configured to use the remote Subversion repository at svn://my.svn.server/path/to/svn/repo. This step is analogous to the need to run svnadmin create repo_db, to initialize a new repository database (where all the file versioning information will be stored). Unlike Subversion, git’s distributed database means that the working copy itself is also the location of the repository database, so there’s no need to deal with two filesystem paths anymore.

Next, change directory to your working copy, and run

cd workingcopy
git svn fetch

to populate your new, empty git working copy (and repository) with all the files from the remote Subversion repository.

Now that you have filled your git repository with a lot of data, if you want to, you can now also save a significant chunk of disk space by repacking that data into a more single, efficient, native packed git archive format (a .pack file). The git-repack -a command is used to do this, and its manual page says:

Instead of incrementally packing the unpacked objects, pack everything referenced into a single pack. Especially useful when packing a repository that is used for private development and there is no need to worry about people fetching via dumb protocols from it.

According to some sources, this can turn a 353MB Subversion repository into 31MB of git pack. Say:

git repack -a -d -f
Generating pack...
Counting objects: 284
Done counting 4475 objects.
Deltifying 4475 objects...
 100% (4475/4475) done
Writing 4475 objects...
 100% (4475/4475) done
Total 4475 (delta 1876), reused 0 (delta 0)
Pack pack-a115c320ff9c9968248bd250bdfea3110d0f0c1a created.
Removing unused objects 100%...
Done.

to perform the compression. For even greater savings, increase the compression by stipulating a high --window option, such as git repack -a -d -f --window=100. (--window defaults to 10—the higher the window, the harder git-repack will try to compress your stuff.) This turned a 36MB Subversion repository in one of my projects to a 20MB git pack. As always, your mileage may vary.

Congratulations, you have transformed your old Subversion repository to a git repository. All that’s left to do now is to get to the coding. Perhaps start by making a local (cheaper than cheap!) git branch….

That was easy, right? Most things in git are, in fact, that easy. If you’ve never used other version control systems before, be grateful. If you have, you can breathe a sigh of relief. Still not convinced? Don’t take my word for it…ask Linus Torvalds (or Randall Schwartz).

Written by Meitar

March 26th, 2008 at 1:54 am

Posted in HOWTO, Mac OS X, Programming, Unix/Linux

Tagged with

Mac OS X Desktop Background sets without iPhoto Albums

leave a comment

One of the pleasures of using Mac OS X is that Apple’s often-elegant UI makes the easy things easy and gracefully reveals the complexity of any complicated tasks you may wish to perform. Except when you want to do something out of the ordinary, of course, in which case things get complicated a bit more quicky. Thankfully, Apple doesn’t seem to go to any great lengths to cripple users, and this comes in handy time and time again.

While playing with my Desktop Backgrounds (computer “wallpapers”) the other day, I ran into an issue like this. I wanted to make sets of wallpaper images that overlapped one another. This is easily doable with Apple’s iPhoto, since all iPhoto albums appear as Desktop Background sets by default. I could simply put together a bunch of iPhoto Albums containing the images I wanted, including overlapping images, and be done with it. iPhoto takes care not to duplicate the photo into every album so space on my hard drive would not have been wasted.

But what if I didn’t want to use iPhoto? If I just have a bunch of image files on my disk in folders, how can I make overlapping sets? The solution is as simple as a Unix symbolic link—with a catch: only a symbolic link with an absolute path would work.

At first, I tried to simply use a standard Mac OS X “alias,” but that didn’t work. My MacBook Pro wouldn’t follow the alias file to the original file when trying to display the wallpaper. Then I tried a simple symlink from one file to another, but again it didn’t work.

Luckily, then I tried dragging the file into my terminal window, which automatically listed the full POSIX pathname of my image. This, surprisingly, worked. So it turns out that the Desktop & Screen Saver System Preference pane requires an absolute path to be specified if it’s to follow symlinks for creating wallpaper sets organized by folders. Go figure.

Written by Meitar

March 22nd, 2008 at 11:24 pm

Things different about Australia

5 comments

By way of example, I am being completely devoured by mosquitos sitting on a bench somewhere in Newtown, a suburb of Sydney. I’m leeching wifi in quite literally the only freely open, non-commercial wifi spot I’ve been able to find in the entire city after searching for such a spot for more than a week. Turns out, Internet access here is obscenely expensive—even by American standards—which partially explains the lack of free, open Wi-Fi.

Leeching this wifi is incredibly uncouth, I know, but I justify my behavior with the fact that I absolutely must ensure that my finances are in order in time for things like rent payments and every other opportunity to use the Internet—my only means of banking at this point—have been unavailable. Indeed, even the most common “free hotspot” service in this city, uConnect, provided by Unwired, shuts off at 7 PM. In fact, most of the city shuts off relatively early, save for nightspots and pubs.

The University of Sydney campus is, for the most part, closed on weekends. Those of you familiar with New York’s collegiate services would be appalled at the notion of something like your college library being closed at anything other than normal 9-5 business hours, but that seems the norm here. Similarly, back to the Internet access frustrations, all (and I mean every) bit of bandwidth you use on the University’s network is monitored and, ultimately, limited. The University has a Squid HTTP proxy set up which you must use to get anywhere on the Internet, but each account has a bandwidth cap of 2 MB per day, barring cache hits, of course. Beyond that, and you pay by the megabyte.

All Internet access, it seems, has bandwidth caps like this. There’s a veritable alphabet soup of ISPs that provide similar services, most over ADSL technology, since cable is hard to come by. Very frustrating, as I’ve never before had to think about how and where my bandwidth is being spent.

In any event, aside from the Internet access woes which were sadly unexpected, there are a number of other things about Sydney that are very different that New York City.

In restaurants, water is either self-serve or comes in bottles instead of being poured into glasses. This is a great idea, because it means I’m much more likely to actually have water when I want it. Also, waiters and waitresses expect no tip, so your bill is all you pay. This has two side effects, one rather nifty, and the other very uncool.

First, because your waiter isn’t your personal server for the meal, any and all waiters will wait on you at your behest. None of this, “I’ll call your waiter” non-sense. Makes restaurants seem much more cohesive, egalitarian—a theme in this country. Secondly, because wait staff get no tips, they get paid much better than they do in the states, which in turn raises prices for the meals. This goes so far as to change the prices on menus during “public holidays,” when—presumably—wait staff get paid time and a half. Menus often say “surcharge applies on public holidays and weekends” to indicate this.

And speaking of menus, there’s a whole different language for coffee here than in the states. Regular coffees as we know them in NYC are called “long blacks” here. Contrast this with a “short black,” or single espresso. “Flat whites” are lattes served in coffee cups, whereas “lattes” are lattes served in regular water glasses. Why the distinction? I have no idea.

Some things are the same. Mochas, for instance, are coffee with chocolate. (So are the “stop” buttons on the public transit busses, but I digress.) Other coffee slang bits sound way too Starbucks-ese for me to like them, such as “Vienna long black,” which just means a long black (regular) coffee with whip cream on top.

If you order any coffee, don’t expect a refill—there’s no such thing as free refills here. In fact, everything, even the tiniest bit of luxury, is charged here. It costs you 10 cents per printed (B&W) page at the University of Sydney computer labs to print anything (but pages here are not the normal 8-and-a-half-by-11 that you’re used to in the States). If you want hot water at the showers after taking a swim at Bondi Beach, for example, then you drop a 20 cent coin into the shower stall. Say you want some condiments for your fish and chips, like ketchup? That’ll cost you 80 cents in addition to the price of your food. Tartar sauce is more expensive, at $1.10 per several-ounce dish.

Food in general is obscenely expensive, and at first I thought it was just me, but after talking to locals it seems everyone’s noticed the price increase. The past 7 summers in Australia have been very dry, so dry that the drought caused harvest yields to decrease dramatically, raising food prices by more than 30% in the past several years. Couple this rising inflation concerns, weakening U.S. Dollar strength, and what I’m left with as an International traveller is the grim prospect of paying almost $15.00 (USD!) for a bacon and egg breakfast with a single, non-refillable coffee at any decent café.

Similarly expensive are spirits and liquor, which in addition to being taxed at 10% like everything else under Australia’s national “Goods and Services Tax” (GST), have an additional tax associated with them dependent on their alcohol content. This means my favorite liquor, Tequila, costs about $70 AUD for a 750 ml bottle of Cuervo. Forget the really good stuff like 1800 Resposado or Patron, which are upwards of $100 for the same amount. Sigh.

As a result of all of this, my money is not going nearly as far as I would have hoped. I am looking forward to having an actual apartment—with an actual kitchen—because at least when that happens I can stop paying exorbitant prices for food. It’s nearly impossible to cook in the hostels Sara and I have been staying at because they’re simply uncomfortable, not private, and not very well-equipped. And to top it all off, I think my hostel’s bed is giving me allergies.

I have a job offer, assuming I can get permission to work from the New South Wales government. Ironically, permission to work is also something I have to pay for—how crazy is that?—so I’ve had to rush to set up bank accounts as soon as I got into the country. The banks, for what it’s worth, are surprisingly good even though everyone here says they are terrible thieves. This makes me think no one from this country would be able to put up with any bank from the States.

The best thing about my bank is that it has CSV, QIF, and MNX download options for every single data table presented on their web site. This is, interestingly, the biggest selling point for me but something no one at the bank had any clue about. It’s not mentioned in their marketing material, their sales staff had never heard of it, and the only reason I knew it existed was because I saw a screenshot with the words “export data” on the corner. I took a chance and set up my account with them based on this screen shot and it looks like it payed off. Machine-readable financial interchange, baby!

Conclusions? This country is in what I consider to be the bronze age when it comes to technology. Only the elite technophiles—looked down upon as “tall poppies” here, rather a bad thing what with the whole egalitarian society thing—even know their way about anything other than a web browser or Microsoft Office. That being said, everyone knows how to lock their wifi, even if they don’t know how to change the channel so that they can actually broadcast that signal more than 10 feet in any direction.

Written by Meitar

March 2nd, 2008 at 4:50 am

Posted in Crosspost, Personal