Ben Kreeger

Getting MobileTerminal for iOS to recognize your .bashrc

This little bit goes hand in hand with this post (in fact, I’ve updated that post with this information, too). This post assumes you’ve got a basic working knowledge of bash and a way to edit text files on your jailbroken iOS device; if you’ve already got a .bashrc file, it’s likely you meet these requirements.

So you’ve got a .bashrc file created in your /var/mobile home directory, but it doesn’t load in MobileTerminal unless you source it. That’s not a bad one to fix. Here’s how.

Create a .bash_profile file inside your /var/mobile directory, and stick in this line of text.

source ~/.bashrc

Now we’ll need to create a file at /etc/shells (after you login as root).

su root
sudo touch /etc/shells

Now we’ll need to edit the contents of that file with the following. Again, edit it using the same method you modified the .bashrc file above.

/bin/sh
/bin/bash

Now, ensure this new file is owned by root:wheel (do this as root, again).

chown root:wheel /etc/shells

Then, you’ll need to edit the /etc/master.passwd file (make sure you’re still logged in as root). You’ll see two lines, one beginning with mobile, one beginning with root. Each one ends with :/bin/sh. Change this to read :/bin/bash.

Now the next time you fire up MobileTerminal, you ought to have your .bashrc file loaded.

Posted

Record Store Day 2011: the bounty.

Record Store Day 2011: the bounty.

Unfortunately I missed out on the sold-out Foo Fighters' Medium Rare, but I picked up Wasting Light anyway. I also grabbed a copy of the Mumford/Marling/Dharohar EP, which actually was a RSD exclusive. I've never been to a Record Store Day, but the turnout was very impressive. Can't wait until next year!

Posted

The best part of warmer weather.

Photo1
Posted

Troubles with WCF REST? Me too, but that's just because I'm a dope.

I’m posting this here because I had this AWESOME writeup ready to post on StackOverflow, but then I realized my problem right before I hit “Post.” So here it is for those it may help.

I had been pulling my hair out using WCF to implement a RESTful API that sends/receives JSON. I had a GET call that works like a charm. I had got a POST request that’s kicking me where it hurts. When I try to run a .NET console app that tries posting JSON to it, it sent me back an error 400: bad request. I couldn’t seem to find why.

Here’s the ServiceContract, interface and implementation.

[ServiceContract]
public interface ILeadResource : IResource
{   
    [OperationContract]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest,
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json,
               UriTemplate = "/")]
    string Post(LeadContract lead);
}

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class LeadResource : ILeadResource
{
    public string Post(LeadContract lead)
    {
        return string.Format("Hello, your lead's name is {0}.", lead.FirstName);
    }
}

I’m rockin' a really simple DataContract at least to start out with. Here’s that.

[DataContract]
public class LeadContract
{
    public LeadContract(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    [DataMember]
    public string FirstName { get; set; }

    [DataMember]
    public string LastName { get; set; }
}

And here’s my web.config, where applicable. I’m using a custom basic auth backend, FYI.

And in a nutshell, here’s how I’m calling it, just from a console app.

var result = string.Empty;
var authString = "username:P@SSW0RD";
var baseUrl = "https://localhost/api/leadresource.svc/leads/";

// I'm using a self-signed cert locally.
ServicePointManager.ServerCertificateValidationCallback =
    new RemoteCertificateValidationCallback(delegate { return true; });

Console.WriteLine("Now posting.");
var request = WebRequest.Create(baseUrl + "/") as HttpWebRequest;
if (request != null)
{
    request.Method = "POST";
    request.ContentType = "application/json; charset=utf-8";
    request.Headers = new WebHeaderCollection
                  {
                      // For basic authentication.
                      {"Authorization", string.Format("Basic {0}",
                          Convert.ToBase64String(Encoding.UTF8.GetBytes(authString)))}
                  };

    // Make data, stick it in the stream.
    var data = @"{""lead""{""FirstName"":""Releasethe"",""LastName"":""Kraken""}}";
    var bytes = Encoding.UTF8.GetBytes(data);
    request.ContentLength = bytes.Length;
    var postStream = request.GetRequestStream();
    postStream.Write(bytes, 0, bytes.Length);
    postStream.Close();

    var response = request.GetResponse(); // I get my error 400 here, naturally.
    var stream = response.GetResponseStream();
    if (stream != null)
    {
        var reader = new StreamReader(stream);
        result = reader.ReadToEnd();
        reader.Close();
    }
    Console.WriteLine(result);
}

Once I had lost about 95% of the hair on my scalp, I figured out it was just malformed JSON. I had tried so many damned ways of composing that JSON before finally getting it right. This last final blow was me missing the colon after “lead”.

var data = @"{""lead"":{""FirstName"":""Releasethe"",""LastName"":""Kraken""}}";

I hope my wife thinks I look alright with male pattern baldness.

Posted

Textastic + git: a match made in jailbreaker nerd heaven

The problem domain

I’m absolutely loving Textastic. It’s a text editor for the iPad with syntax highlighting and a lot of those other niceties you’d like to have in a text editor. It’s no TextMate (or Sublime Text), but if I’m editing code on the go, it’s a godsend. The developer is very active in adding new features and correcting any existing problems, too; it’s $10 well spent for me. There is one feature that may or may not be in the works for Textastic, though, that I’ve been jonesing to have. And that’s version control support. I’d love the ability to make clones of my github repos inside Textastic’s working directory, edit my code, and then commit it (and push it). I was feeling exceptionally bold and nerdy yesterday, so I took this roadblock and faced it head-on to roll my own solution. Here’s what I did, translated into what you can do.

The jailbreak

Textastic runs on the iPad. If you have a 1st-generation iPad running on iOS 4.3.1, that’s a prime candidate for jailbreaking! Skip over to the iPhone Dev Team’s blog and download the latest copy of redsn0w and a copy of the iPad 4.3.1 IPSW package (used by redsn0w), and follow redsn0w’s directions (they’re very easy to follow). Mere minutes later, you’ll be rockin' with Cydia on your iPad’s SpringBoard. Moving on…

The packages

In order to do some of the necessary stuff ahead, you’ll need to search for and download a few packages from Cydia. Queue up and install the following:

  • Core Utilities (coreutils)
  • less
  • OpenSSH
  • OpenSSL
  • iFile (it’s a store package, $5 I believe; it’s indispensable for browsing the iPad’s file system, but if your iPad is connected to a computer you can also use other tools, like funbox)
  • Safari Download Manager (again, a commercial package, but you can simply download the files on a computer and use something like funbox, if you prefer)
  • git

There’s one more you have to download, but you can’t seem to do it from Cydia. Get the latest build of MobileTerminal, found here. If you’re doing it on your iPad, and you’ve got iFile/Safari Download Manager installed, you can simply tap the link to the latest version, download it into iFile on your iPad, and install it using iFile’s built-in DEB package installer. Otherwise, you’ll have to download the .deb file to your computer and use funbox to install it to your connected iPad.

The configuration

There are a few things we’ll need to do to make this easy on ourselves, and the first step is to setup a .bashrc file in our /var/mobile/ directory, and define an alias into Textastic’s Documents directory (it’s a lengthy path). If you’ve got iFile, fire it up and create a file named .bashrc in the /var/mobile/ directory (make sure you have iFile’s “Show hidden files” setting on, otherwise you won’t be able to see it after you create it). You can then tap that file and open it in iFile’s build in text viewer/editor. (If you’ve got funbox, you can create this on your computer as a text file and then transfer it over to the /var/mobile directory, all using funbox). The file really just needs the line below; if you happen to already have a .bashrc file, just add this somewhere. This will allow you to fire up MobileTerminal and just type in textastic, hit enter, and be placed right where you need to be to get to all of Textastic’s documents.

alias textastic='cd /var/mobile/Applications/62EBB0B3-5DCC-437A-A6B4-E764EE458579/Documents'

Now that we’ve got our alias, it’s time to make sure MobileTerminal reads this .bashrc file when it launches. Create a .bash_profile file inside your /var/mobile directory, and stick in this line of text.

source ~/.bashrc

Now we’ll need to create a file at /etc/shells (after you login as root).

su root
sudo touch /etc/shells

Now we’ll need to edit the contents of that file with the following. Again, edit it using the same method you modified the .bashrc file above.

/bin/sh
/bin/bash

Now, ensure this new file is owned by root:wheel (do this as root, again).

chown root:wheel /etc/shells

Then, you’ll need to edit the /etc/master.passwd file (make sure you’re still logged in as root). You’ll see two lines, one beginning with mobile, one beginning with root. Each one ends with :/bin/sh. Change this to read :/bin/bash.

Now the next time you fire up MobileTerminal, you ought to have your .bashrc file loaded.

Explanation:
All the applications (App Store apps, that is) are stored in the /var/mobile/Applications directory, but they’re not easily identifiable because each application’s folder is named after the app’s GUID. This is another place where iFile comes in great handy; it has a setting that’ll translate all the GUID-looking folder names in that Applications directory into the actual app names, making it much easier to find Textastic. Textastic’s GUID is part of that path shown above; I won’t bother with repeating it again!

The action

Now comes the fun part. Launch MobileTerminal to get started. In the examples below, each line of code is a new prompt. You’ll have access to that alias we set up. Type it in, then hit enter.

textastic

Now you’ll be in the directory where Textastic stores its documents. I’ve created a new git folder for all my repos, to keep them separate from anything else I might create in Textastic.

mkdir git
mkdir awesomesauce && cd awesomesauce
git init

Voila! Now you have a git repo inside of Textastic. Fire up Textastic and you’ll see your git folder in all its glory. Edit code in your new project, then when you need to commit, switch back to MobileTerminal, jump into the directory where your code is, and run your git commands.

. ./.bashrc
textastic
cd git/awesomesauce
git status

The only limitation I’ve found right now is that git add -i doesn’t work; I’m likely missing some dependency it requires, and I have no idea what that is.

The nice

Of course, you can have git with github too. Just follow github’s directions on setting up your credentials locally.

git config --global user.name "Firstname Lastname"
git config --global user.email "email@domain.com"
git config --global github.user username
git config --global github.token 0123456789yourf0123456789token

Also, since you have ssh installed, you need to generate your private/public key pair to use in your exchanges with github. Just follow the prompts after typing…

ssh-keygen

You’ll need to grab the contents of the id_rsa.pub file in /var/mobile/.ssh/ and paste them in your github account dashboard. Again, you can do this using iFile, or if you’ve got your iPad connected to your computer, use something like funbox.

The closing

Anyway, hope this helps you all! It seems like a rather lengthy setup, but apart from installing a few packages, creating a file, and running a couple of terminal commands, it’s actually not too bad, and you only have to set it up once. Let me know if you have any questions!

Posted

Password secrecy.

Posted

Customizing Rdio's background art

I'm a sucker for customization, so I've downloaded a nifty extension for Chrome called Personalized Web that lets you inject custom HTML, JS, or CSS in a pages targeted by regular expressions. In other words, it lets you tweak the pages you view in various ways.

Custom rdio background 

What I've done is set a custom background to Rdio that's only visible by my computer, of course, but it's still great to change the scenery every now and then. Since Personalized Web lets you import rules in JSON format, you can find my rule for doing so right here, or embedded below. Just get the raw version of that file, copy it, and paste it in the "Load Dump" dialog window under Personalized Web's settings.

I'm also running a local web server on my machine to server up the file (if you've got a web host, you can throw your image up there and point the script to it), thus the reference to localhost.

Posted

Already installed Windows 7 SP1, but still need to install RSAT?

I wiped my computer a month or so ago and hopped right up to Windows 7 Service Pack 1, and then figured I’d install Remote Server Admin Tools. So I downloaded the package that’s out there on the Intarweb only to find out that the currently released package for RSAT only works for Windows 7 RTM (i.e., not service pack 1).

"This update is not applicable to your computer."

Microsoft has announced that April is their target date for releasing a downloadable package that installs RSAT on Win7 SP1. I needed it badly for work, but I didn’t want to go through the hassles of uninstalling SP1 just to install RSAT and then reinstall SP1.

Fear not… this is much quicker and cleaner. This post has some awesome sauce instructions on how to get it working. Like a charm, I might add. Thank you, mysterious stranger.

Posted

Aardvark?

Aardvark?

If this is what an aardvark looks like, I do not want to visit a zoo ever again.

Posted

Apple's iOS subscription model may be that final straw for me.

Typically when I post stuff, it’s either things that I’m passionate about, or it’s poop jokes. I don’t aim for the middle. And I’m shooting high with this one (I may throw in a poop joke or two, however). It’s something that has me a little steamed up. It’s about what Apple is beginning to do with their in-app purchase model and charging subscriptions in apps.

I’ll preface this all with a love-letter background. I’ve been an iPhone user for well over three years now. I’ve been a Mac user for longer than that. I’ll be one of the firs to profess my love for the Apple-branded gadgets I own. They’re fantastic pieces of hardware. I still can’t imagine buying a new computer that isn’t a Mac. My next phone, however, may not be an iPhone. Here’s why.

Apple has introduced new rules into their App Store that require app developers who post apps that operate on a subscription model to offer in-app subscriptions while removing all references to outside-sold subscriptions for the app. They’re not mandating total removal of those outside subscriptions; they’re just saying the user can’t know about them. This in-app subscription nets Apple 30% of each subscription. This affects a number of the apps I use on my iPhone and my iPad, as well as some I probably don’t quite realize.

The first and foremost of which is Rdio: streaming music service. It’s subscription based. I pay $10 to Rdio every month so I can listen to unlimited music from my desktop or from my smartphone. I’ve ditched my local iTunes library in favor of this service; it’s the greatest thing since sliced bread. I don’t work for Rdio (I know a few people that do, but I certainly do not speak for them). I don’t know how much they make off of my monthly fee, but it can’t be very much. They have to pay oodles of money to music distribution firms, to artists, to record labels, to licensing companies, etc. in order to provide the service they do. Their profit margin certainly can’t be over 30%. If new subscribers come to their service via an iPhone app (which I imagine tons will, in addition to the tons that already have), if they’re not aware of the subscription service through Rdio’s website, they’ll be paying 30% of Rdio’s money to Apple, and Rdio’s ability to turn any sort of a profit begins to diminish. Quickly. They’d be losing money on each new subscriber. As a user, this isn’t good. Rdio’s options would be to a) lose money for each new customer, b) pull out of the App Store (and lose a good portion of business), or c) wait for Apple’s rules to change regarding subscriptions.

The second of which is Netflix, streaming movie/television service extraordinaire. They operate on a very similar subscription model to Rdio. Again, they’d surely be losing money if Apple took 30%. And that’s not 30% of the profit. That’s money off the entire transaction. The most these companies lose off the top of the transactions now are credit card fees, which are typically 2-4%.

The third is Amazon Kindle, which I use to read books between my iOS devices and my Kindle. Apple won’t let them offer their subscriptions without having that equal-price in-app subscription where they lose 30%, and rumblings are abound on the web (so take these with a grain of salt) that their out-of-app book purchases from Amazon’s Kindle Store would be in trouble on iOS devices, too (meaning Apple would mandate they offer in-app book purchases where, again, Apple takes 30%).

Other services that could be affected include Instapaper’s upcoming subscription-based service that allows access to the new Instapaper API, for third-party client access. There’s also Dropbox, which offers subscriptions for more space every month. There’s Evernote, which offers the same, but with bandwidth and features. Those are all the ones I use that could be impacted. Hell, losing Rdio alone is a deal-breaker for me. One that I haven’t used is MLB’s MLB.tv app, where users subscribe and watch live streaming baseball. Presumably, Spotify will be affected. Rhapsody is also affected; they’ve even issued a statement regarding the brou-ha-ha stating that it’s “economically untenable” and they’ll either be pulling out of the App Store or investigating legal channels; either way, they’re not playing. Here’s the bit that everybody else is posting.

Our philosophy is simple too – an Apple-imposed arrangement that requires us to pay 30 percent of our revenue to Apple, in addition to content fees that we pay to the music labels, publishers and artists, is economically untenable. The bottom line is we would not be able to offer our service through the iTunes store if subjected to Apple’s 30 percent monthly fee vs. a typical 2.5 percent credit card fee.

I could understand this model in terms of newspapers and magazines and such. But certainly not with services that have a profit margin that’s already less than 30% due to their industry (streaming movies and music, especially). If these services pull out of the App Store, come June 30th I’ll be pulling out as well (and I’ll likely be taking my business to the Android Marketplace). These services that I consume on a daily basis are greater than just one or two devices I consume them on (a device that has fantastic software and hardware otherwise, sadly). Apple’s new subscription model is nothing but crap, in my opinion. It certainly smells like it.

There, I’ve thrown in a poop joke.

Posted