Reverse SSH Tunnel

Just finished playing around with reverse SSH tunnels with my buddy jkit so I figured I’d write this stuff down before I forgot.

ssh -nNT -R 1199:localhost:22 remotehost.com

This command looks pretty confusing if it’s the first time you’re seeing it (at least it did to me), but an intuitive way to phrase it would be: map port 1199 to localhost:22 on remotehost.com.

What’s the use case? For one, this command would allow you to SSH into a machine that is on a network behind a firewall or a router that you don’t have configuration access to. For example, if you’re on your laptop at a random cafe and you want to share a screen session on localhost, the other person would need SSH access.

What the above command would do is allow that person to SSH into your laptop from remotehost.com like so:

ssh -p1199 localhost

If you’re interested in other interesting use cases, check out localtunnel!

Positioning Schemes

There are three positioning schemes, and they are:

  • Floats
  • Absolute positioning
  • Normal flow

Floated content is defined as any element that has a CSS float property of ‘left’ or ‘right’. Note that these values may be inherited with the ‘inherit’ value.

Absolutely positioned elements consist of any element that has a CSS position property of either ‘absolute’ or ‘fixed’. That’s it.

Everything else falls under the category of ‘normal flow’. To be more specific, this category consists of any block that participates in the inline formatting or block formatting contexts, or any block that is positioned relatively. The spec also mentions boxes with the ‘run-in’ display property.

It’s worth mentioning that an element with the display property of ‘inline-block’ falls under the block formatting context.

Positioning schemes are not to be confused with the CSS position property.

Closure Pattern

Here’s a common closure pattern that I’ve been seeing a lot:

(function (window, document, undefined) {
/***
- undefined, unlike null or window, is not a reserved word and can be redefined. By redefining undefined with an undefined value, we can be sure that it is what we expect it to be.
- The local definition of these variables allows for a minor performance improvement where the scope chain does not have to be traversed when looking up their values.
- These variables can also be obfuscated when compressed (e.g., because window is a local variable in this scope, all occurrences of it may be replaced by a single letter variable name).
***/
})(this, document);

Crockford on CSS

I find within the community of people who use CSS great affection for it. They’re totally invested in CSS, they love it. They can’t imagine any other way of doing formatting in a document. It’s it. It’s sort of like watching an episode of Cops where the cops come in and break up the family dispute, and there’s this “CSS ain’t bad, you just don’t understand it like I do. I know it hurts me, but I make mistakes, I’m wrong.” CSS is awful, and it amazes me the way people get invested in it. It’s like once you figure it out, kind of go “oh, OK, I see how I might be able to make it work,” then you flip from hating it to loving it, and despising anybody who hasn’t gone through what you’ve gone through. It doesn’t make sense to me.

Avoiding Perl Capture Variables

In a recent conversation with an acquaintance of mine, he pointed out that Perl is very hard to read. I initially took offense as I loved the language during the relatively short time I coded in it, but I quickly realized that he was right. At the cost of flexibility, Perl tends to encourage unreadable code. You basically have to learn how to code Perl in such a way that others can clearly understand what’s going on, and to this end, Perl Best Practices by Damian Conway was an awesome book. I think that the challenge of coding Perl in a readable fashion made me a better programmer because it forced me to try and see my code from a different perspective.

Anyway, here’s one technique that I used to when dealing with regexes that captured matches. Needless to say, Perl’s capture variables are non-semantic, and convey nothing but the order of the captured matches. Here’s an example:

my $string = "eugene kashida tyler kashida";
my $re     = /(eugene)[\s\w]+(tyler)/xms;

$string =~ $re;

At this point, you can access the captured values from the capture buffers $1 and $2 respectively. If you wanted to improve readability and reduce the possibility of introducing bugs, you should immediately unpack these values into variables with meaningful names:

my ($dad, $son) = ($1, $2);

Here's a technique that lets you skip the handling of the numbered variables completely:

my ($dad, $son) = $string =~ $re;

If a regex match is executed in a list context, a successful match returns a list of captured strings. It's helpful to note that this also avoids the problem where if the match fails, the numbered capture variables contain values from the last successful match. Regardless of the way you approach it, you should always be checking that the match was successful.

Ah, Perl! How I miss you so!

The Factory/Constructor Pattern

Code your constructors defensively by checking whether or not it was called with the new operator:


function Circle (color, radius) {
    if (! (this instanceof arguments.callee)) {
        return new arguments.callee(color, radius);
    }

    this.color  = color;
    this.radius = radius;
}

Source

Image Formats on the Web

Differences between image formats never really mattered to me. People tend not to care about the characteristics of TIFF and JPEG unless it makes a difference in their lives. For some, the catalyst to learn is a hobby or a career in photography or design. For me, it was when I started web development.

My whole team was relatively new to the “view source” side of things, as we came from a background of Perl and the command line. Thank goodness for the UED folk over at Yahoo! or we would have had no choice but to create sites that resembled ASCII art. I had a healthy interest in the design side of things, so I ended up tackling Photoshop often, getting my ass handed back to me on a platter on quite a few occasions. One thing that perplexed me were the choices I was told to make when I hit “save as.” Here are my findings from back then. I hope it helps someone out.

Lossless vs. Lossy Compression

In simple terms, lossless compression means that you can compress and decompress an image without losing any information, and lossy compression means that once you compress an image, you can never get the original image back. PNG and GIF fall under the former category, and JPEG falls under the latter.

When to use What

Although they are digital, “real world” images can be considered to have analog traits as they consist of smooth, soft gradients. By “real world,” I mean any image that was recorded by a camera. What lossy compressions aim to do is to reduce the information of an image just enough so that human perception cannot detect any changes. Given this goal, a lot of information can be discarded as our visual perception isn’t as up to par as you would think. Therefore, real world images should be saved as JPEG. I am not aware of other lossy formats, but this seems to be the de facto standard.

Images with sharp edges on the other hand, are the ideal candidates for lossless compression formats. Logos, text, and bullets fall under this category. It makes sense if you think about it–in order to display sharp lines after compression, each pixel needs to remain the same color as it originally was. The most popular lossless formats on the web are GIF (“jiff”)and PNG (“ping”).

GIF or PNG?

One of the main arguments for PNG used to be that GIF was patented and PNG wasn’t; however, the patents on GIF have long since expired. There still remains an important difference: PNG supports alpha transparency and GIF doesn’t. Actually, this statement is not completely true unless you’re dropping IE6 support. Sadly, IE6 is still categorized as an A-Grade browser, and most websites will still need to accomodate it’s limitations. In addition, PNG8 doesn’t actually have an alpha channel, but Fireworks has the ability to simulate alpha transparency using semi-transparent color chips.

Although IE6 doesn’t support alpha transparency by default, you can use the AlphaImageLoader filter or TwinHelix’s iepngfix (a script that applies the filter to multiple images) with PNG24+ images to get near-native PNG support. Please be conservative in the use of this miracle filter, as it does not do it’s magic for free–it causes a linear degradation of page performance on the user’s browser. Your average IE6 user is most likely on an older machine, which will have a harder time processing the AlphaImageLoader filter(s), so you might consider the option of gracefully degrading the image quality for IE6 using Fireworks PNG files instead.

Carriage Returns vs Line Feeds

My first job out of school was to maintain and add to an ETL-style feed processing platform written in Perl. It’s basic function was to take a data source, apply a series of transformations to it, and then spit it back out–usually in a different format such as XML or an SQLite flat file.

A problem that I often encountered when simultaneously working in a UNIX environment and dealing with data sources that were compiled by Excel users, had to do with newline representation. Without getting into the origins of the divergence, an application can basically choose to represent the newline as either a line feed (\n), a carriage return (\r), or a combination of the two (\r\n) control characters. In this case, UNIX does the line feed, and Windows does a carriage return followed by a line feed.

This was why when I opened up a CSV file in Vim, I would occasionally see something that looked like:

hello world^M
how are you doing good sir?^M
this is the last line^M

These files were created by an application that encoded the newline as \r\n, and the \r remained as an artifact (^M) when viewing the file with an application that defines newlines as \n. In this case, I would either process the file using dos2unix or strip the file of these carriage returns by issuing the following command:

:%s/\r//g

In a similar vein, you may sometimes run into something that looks like this:

hello world^Mhow are you doing good sir?^Mthis is the last line^M

These files were created by an application that defined the newline as a single \r, and should be handled by replacing them with newlines:

:%s/\r/\r/g

or

:%s/^M/\r/g

(you can generate the ^M control character with either <ctrl-v><ctrl-m> or <ctrl-v><enter>)

If :%s/\r/\r/g looks confusing, I don’t blame you. Although Vim fails to interpret the character sequence \r\n as a newline on read, it can successfully interpret the carriage return \r into a newline on write. Consequently, you can get rid of the ^M carriage return artifacts with the above search-and-replace command which ends up matching carriage returns and replacing them with newlines.

As for the origins of carriage returns and line feeds, it’s helpful to think about it in terms of typewriters. The carriage return moves the carousel back to the beginning of the current line, and the line feed introduces a new line by shifting the paper up. What we conceptualize as a newline today is the abstraction of the two mechanical operations that were required to accomplish the same thing on the typewriter!

References:
Newline

Sharing a screen session

Whenever you need to share a terminal with someone–whether it’s because you’re working from home and need to collaborate with a coworker, or you’re pair-programming and taking turns to edit code–the ability to share a screen session can be invaluable.

If your guest is not able to attach to the screen instance after setting up session sharing using the steps below, please make sure that the screen binary is suid root:

sudo chmod +s /usr/bin/screen

From the screen man page:

Screen must be installed as set-uid with owner root on most systems in order to be able to correctly change the owner of the tty device file for each window.

There are some security implications to this which I don’t claim to understand, so take care not to share any screen sessions with the shifty-looking fellow sitting across from you on BART.

Let’s say that ekashida wants to share a session named toranosuke with ailuvyou2:

ekashida creates the screen session:
screen -S toranosuke

ekashida activates multi-user mode from within the session:
<Ctrl-A> :multiuser on

ekashida adds ailuvyou2 to the acl (access control list):
<Ctrl-A> :acladd ailuvyou2

ailuvyou2 can then attach like so:
screen –x ekashida/toranosuke

You can list all the users attached with:
<Ctrl-A> *

That’s really all there is to it. You can modify the ACL to restrict write-access and so on, but I haven’t really ever needed to do this. More information here.

Have fun!

Follow

Get every new post delivered to your Inbox.