Dec 25, 2009

Quick Tip: light switch effect

Here's a quick tip for novice programmers. Every time you want to create a "light-switch" effect for toggling a parameter on and off, or should I say true or false, 0 or 1, ... You can simply do it by typing:
p ^= 1;
This is a binary-safe Exclusive-OR assignment operator. First, it computes the value of p XOR 1 (p = p ^ 1) and then stores that value in p. If we look at the truth table of exclusive-or (XOR)

a

b

a XOR b

0

0

0

0

1

1

1

0

1

1

1

0

We see that if our b variable is 1 (true) the result of a ^ 1 (a XOR 1) is exactly the opposite of a. All in all, this operation is simply a shortcut for these assignments:
p = p ^ 1;

p = !p;

p = p ? false : true;

if(p) p = false; else p = true;

So if you want to toggle something ON and OFF, let's say when a user clicks a button, this method is extremely short and useful.

Dec 20, 2009

Facebook Connect: FB.Connect.streamPublish() does not show up

DUE TO FREQUENT FACEBOOK API CHANGES THIS ARTICLE IS OUTDATED.

Here are the reasons why FBJS functions sometimes fail:
  • xd_reciever.html is not installed correctly
  • application key is not set in FB.init()
  • Facebook Connect callback URL is not set in the application settings
  • Facebook JavaScript API is not set correctly in your HTML. This should be set immediately after the body tag <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script> This should be set before the closing body tag <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US" type="text/javascript"></script>
  • Facebook functions are called before JavaScript objects are initialized. FB.init(api_key, channel_path); FB.ensureInit(function() { // put your functions here });
  • All Facebook JavaScript functions are called BEFORE the FeatureLoader.js.php You should put your functions after this call and into FB.ensureInit() function
  • There are JavaScript errors in your code
If any of the errors mentioned above are met, the function will fail. If FBML tags are not rendered, you might also want to check, if you set the HTML header correctly. http://wiki.developers.facebook.com/index.php/XFBML Also, XFBML tags are required to render tags correctly.

Sep 17, 2009

PHP: mail() Sender domain must exist - UPDATE

Regarding my last post, it seems that you can't set the Return-Path in the header parameter of the mail() function. The workaround is in the fifth argument of mail() - the additional parameters. If you set the "-fsender@domain.com" it should set the Return-Path. Here's my mail() wrapper function:
function construct_mail($to,$subject,$content,$sender='') {
$from = ADMIN_EMAIL;
if(!empty($sender)) $from = $sender;
$header  = "From: $from\r\n";
$header .= "Content-Type: text/html; charset=utf-8\r\n";
$header .= "Date: ".date("r")."\r\n";
$header .= "Reply-To: $from\r\n";
$header .= "Return-Path: $from\r\n";
$header .= "X-Mailer: PHP\r\n";
$content = ''.$content.'';
$subject = ' =?UTF-8?B?'. base64_encode($subject) ."?=";
return mail($to,$subject,$content,$header,"-f$from");
}
Also, the -f switch might trigger a E_WARNING if you don't set the trusted users (the user that executes the script - webserver) in the /etc/mail/trusted-users

UPDATE: http://dev.kafol.net/2013/01/sendmail-x-authentication-warning-user.html

PHP: mail() Sender domain must exist

Lately I've found out that a lot of emails sent from PHP's mail() get bounced (they weren't before). Servers bounce the message with the "Sender domain must exist" error, or more precisely, the domain in question was the servers (the server that the script runs on, not the email server) hostname. Well of course that domain doesn't exist (localhost.localdomain), so after some googling, I figured that some additional headers might help, like Return-Path and Reply-To.
$from = "your@email.com";
$header  = "From: $from\r\n";
$header .= "Content-Type: text/html; charset=utf-8\r\n";
$header .= "Date: ".date("r")."\r\n";
$header .= "Reply-To: $from\r\n";
$header .= "Return-Path: $from\r\n";
$header .= "X-Mailer: PHP\r\n";
I'll test it now, when this post reaches my newsletter subscribers.

UPDATE: http://dev.kafol.net/2009/09/php-mail-sender-domain-must-exist.html

UPDATE #2: http://dev.kafol.net/2013/01/sendmail-x-authentication-warning-user.html

Aug 3, 2009

PHP: calculating age with no bugs

As it turns out, calculating a person's age is not a very simple thing to do.

I've been very lazy lately so I googled for a PHP or MySQL function to calculate age in years. The more I searched, the more I found out that people were doing it wrong.

For example: floor(time_difference_in_days) / 356, let's say 7000/356 = 19,66.

What the hell? That won't work. We have leap years and such.

And even worse: some calculated the difference in days with strtotime() or mktime() that uses unix timestamps, which is very unfortunate for people born before 1970-01-01. (if you don't know why, read the wiki)

I decided to do this the way that we humans do it. It's commented and streched out for a reason. Stop doing it wrong.
function age($dob) {
//year, month, day of birth
 list($y, $m, $d) = explode('-', $dob);
//this year,month, day
 list($yn, $mn, $dn) = explode('-', date('Y-m-d'));

//AGE is (THIS_YEAR - YEAR_OF_BIRTH) if the person already had or is having his birthday THIS_YEAR
 $age = $yn - $y;

//If the person didn't have his birthday yet, then AGE is (THIS_YEAR - YEAR_OF_BIRTH - 1)
 if ($mn < $m) {
//THIS_MONTH is less than MONTH_OF_BIRTH so no birtday yet this year!    
  $age--;
 } else {
//if it's the same MONTH_OF_YEAR then the birthday did not occur only if THIS_DAY_OF_MONTH is less than DAY_OF_BIRTH    
  if ($mn == $m) {
   if ($dn < $d) {
    $age--;
   }
  }
 }
 return $age;
}

Jul 31, 2009

ActionScript: fade in/out

function fadeAnimation(target,show,speed) {
 target.showing = show;
 target.speed = speed;
 if(show) target._visible = true;
 
 target.onEnterFrame = function() {
  this._alpha += (this.showing) ? +this.speed : -this.speed;  
  if(this._alpha<=0 && !this.showing) {
   this._visible = false;
   delete this.onEnterFrame;
  }
  if(this._alpha>=100 && this.showing) {
   delete this.onEnterFrame;
  }
 }
}

Jul 11, 2009

Windows Tips: How Be Safe From Viruses / Kako ostati varen pred virusi

English version | Slovene version

Here's a non-developing blog entry... So, how to be safe from viruses?

I get asked this question a lot lately (wish I knew why, is there a new dark age coming or something?), especially which Anti-Virus software should one use, to be 100% safe from viruses.

Well, I'm not a big fan of Anti-Virus programs (I do use one, for "just in case"), nor do I want to advertise such software and above all, I don't think that any program can ensure full security.

Here's why (sorry for the lecture):
Viruses exist for any Operating System (Windows, Linux, ...). They're not called the same on different operating systems, but they act the same. They have simmilar methods of reproduction, and so on. Making a virus is very easy, even if you are a beginner at programming, making a good virus is a bit harder, but not much. A virus is a program, like any other, but it does stuff it's not supposed to, and that's why it's flagged as being a virus (malicious). And because it's a program, detecting it may be difficult sometimes, because it's functions don't look as fishy as they actually are - the program does things any normal program would do, let's say connects to a server and communicates with it. A lot of programs do that. Your browser does that. Your browser could be a "virus" if it would let someone else have access to things they're not supposed to.

Okay, enough of that, let's get to the good part.

Here's a short list of 4 simple tips you should follow, and if you'll follow all of them, you'll quickly find out that you don't have any use of your Anti-Virus program anymore.
They mostly apply on Windows Operating systems, but the idea is general.
  1. Disable Auto-Run
    Disable it. Disable it for everything. For CDs, USB keys, everything. It's useless and it's a major security problem. It's also a VERY popular way of virus reproduction.
    If you don't know what Auto-Run is, read about it on the wiki, but in a nutshell, AutoRun is a Windows service that enables a computer to run a program automatically when you plug in your USB key or a CD/DVD. Running a program whitout knowing what it is is like jumping from a bridge. It's dangerous and it's very likely that you'll get hurt.

    I'll be short on How-Tos, but here are some links:
    Basically, you navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Cdrom in your Registry, and set the AutoRun DWORD value to 0. You might also disable autoplay in your gpedit.msc - Local computer Policy\Computer configuration\Administrative Templates\System, select the item "Turn off Autoplay" and click the "Enabled" radio button.

    Also, if you don't know how to disable AutoRun, there is an alternative:
    If you hold the
    Shift key when you plug in a USB key/CD, you temporarily disable AutoRun.

  2. Use a firewall
    Firewalls come in many forms - there are physical firewalls, such as routers (but firewalling is not the router's primary function), and there are software firewalls.
    Firewalls block certain types of internet communication. They filter open ports which is also a very common way for virus reproduction:
    An infected machine connects through the internet to another vulnerable machine which has a vulnerable service running. But note that:
    • A computer is only vulnerable if it has a vulnerable service running
    • If the computer has no open ports (no services running) it cannot be infected/hacked via the internet.

    Which brings us to...
  3. Updates!
    A lot of people disable automatic updating (Control panel\System Properties\Automatic updates), because either they're afraid they might get that annoying little Windows Genuine Advantage tool or that they'll get viruses from it. Viruses from Microsoft updates?!?! Come on...
    Updates are in most cases a very good thing to do - if you don't care about security, you should at least care about the cool new features you get with the new version of any program. Programmers don't always get it right in the first try, that's why updates come in handy.

  4. Use your brain
    You heard me. Don't be stupid. Don't click on everything shiny, don't click on anything before reading what it is and understanding what it does. Don't open every email attachment. When you're browsing on the web, don't click on every link. Look at where it's pointing (in the status bar). If it's an .EXE file (a program) be extra careful, don't run it if you don't know what it is. KeyGens are NEVER what they say they are on the internet. Don't click on every "OK" or "I Agree" button. Some people think that when they suddenly have an unknown toolbar in their favourite browser, they have a virus. That's not true. They got that toolbar when they clicked on "I Agree" sometime in the near past without reading what it does.


Well that's all folks, I hope this article widens your horizon on computer security. Because I'm in an extra helping mood today, I'll translate the article for all of my Slovene friends.
Top
___________________________________________________________________________________

Zdaj pa en ne-programerski članek. Kako ostati varen pred virusi?

Zadnje čase dobivam to vprašanje zelo pogosto (ko bi le vedel zakaj, prihaja kakšna temna doba ali kaj podobnega?), še posebej: kateri Anti-Virus program naj bi uporabili, da bi bili 100% varni pred virusi.

Nisem ravno navdušen nad AntiVirus programi (sicer uporabljam enega "za vsak primer"), nimam niti želje oglaševati teh programov in povrh vsega, ne verjamem, da lahko program zagotovi popolno varnost.

Še razlog zakaj (oprostite za pridigo):

Virusi obstajajo za vsak Operacijski Sistem (Windows, Linux, ...). Ne kličejo se povsod enako, vendar obnašajo se isto. Imajo podobne načine razmnoževajna in tako naprej. Narediti virus je zelo lahko, tudi za začetnika programiranja. Narediti dober virus je malo težje, vendar ne veliko.
Virus je program, kot vsak drugi, le da počne stvari, ki jih nebi smel in zato je označen kot "virus". In ker je program kot vsak program je včasih zelo težko ga odkriti. Včasih so funkcije virusa zelo podobne običajnim programom, recimo, program se poveže na strežnik in z njim komunicira. Veliko programov to počne. Vaš brskalnik to počne. Vaš brskalnik bi lahko bil virus, če bi dovolil nekomu dostop do reči, do katerih nebi smel.

No, dovolj tega, preidimo do bistva.

Tukaj je kratek seznam štirih preprostih namigov, katerim lahko sledite, če pa upoštevate vse, lahko hitro ugotovite, da nimate več potrebe po uporabi antivirusnega programa.
Namigi so večinoma za Windows operacijske sisteme, vendar velja za vse.
  1. Izklopite Auto-Run
    Izklopite ga. Izklopite ga za vse. Za CD-je, USB ključke, vse. Neuporaben je in jezelo velik problem kar se tiče varnosti. Poleg tega je to zelo popularen način za samodejno razmnoževanje virusov.
    Če ne veste kaj je AutoRun, preberite o tem na Wikiju, v bistvu je pa to orodje operacijskega sistema Windows, ki omogoča samodejno zaganjanje programov, ko priklopite USB ključ ali CD/DVD v računalnik. Zaganjanje programov, brez vedeti kaj počno je kot skakanje čez most. Je nevarno in zelo verjetno je, da se boste poškodovali.

    Bom kratek pri navodilih kako to izklopiti, tukaj je pa nekaj povezav o tem: V registru pridete do mape HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Cdrom in nastavite AutoRun DWORD vrednost na 0. Dobro je tudi izklopiti autoplay v gpedit.msc - Local computer Policy\Computer configuration\Administrative Templates\System, izberite "Turn off Autoplay" in kliknite na "Enabled".

    Če ne znate izklopiti AutoRun, obstaja alternativa:
    Če držite tipko
    Shift, ko priklopite USB ključ ali CD s tem začasno izklopite AutoRun.

  2. Uporabljajte požarni zid
    Požarni zidovi obstajajo v različnih oblikah - obstajajo fizični požarni zidovi kot so usmerjevalniki (vendar požarni zid ni glavna funkcija usmerjevalnika), obstajajo pa tudi programski požarni zidovi. Požarni zid blokira določene vrste komunikacije prek iterneta. Filtrirajo odprta vrata kar je tudi zelo razširjen način razmnoževanja virusov:
    Okužen računalnik se poveže na ranljivega prek interneta, na katerem teče ranljiv program. Vendar pomnite:
    • Računalnik je ranljiv samo, če na njim teče ranljiv program
    • Če na računalniku ni odprtih vrat, potem ta računalnik ne more biti okužen preko interneta / vanj se ne da vdreti preko interneta.

    Kar nas privede do...
  3. Posodabljanje!
    Veliko ljudi izklopi avtomatično posodabljanje (Nadzorna plošča\Sistem\Avtomatične posodobitve). Ali se bojijo, da bodo s tem dobili tisto nadležno Windows Genuine Advantage orodje, ali pa da bodo s tem dobili viruse. Virusi pri posodabljanju Microsoft?!?! Dajte no...
    Posodabljanje je v zelo veliki večini primerov zelo dobra stvar - če vas ne zanima varnost na računalniku, vas bi lahko vsaj zanimale vse nove in kul funkcije, ki jih dobite z novo verzijo programa. Programerji ne zadenejo vse v prvo, zato pridejo posodobitve zelo prav.

  4. Uporabljajte možgane
    Prav ste me slišali. Ne bodite neumni. Ne klikajte na vse kar se sveti, ne klikajte na karkoli, predno preberete kaj piše in razumete kaj bo stvar storila. Ne odpirajte vsake priponke v spletni pošti. Če brskate po spletu, ne klikajte na vsako povezavo, poglejte kam kaže (na dnu programa piše). Če je povezava .EXE datoteka (program) bodite še posebej previdni, ne zaganjajte ga, če ne veste kaj bo storil. KeyGeni niso NIKOLI kar pravijo da so na internetu. Ne klikajte na vsak "V redu" ali "Strinjam se" gumb. Nekateri mislijo, da ko se na njihovem priljubljenem brskalniku nenadoma pokaže nova orodna vrstica, da je to virus. To ni res. To orodno vrstico so dobili, ker so v nedavni preteklosti kliknili na gumb "Strinjam se", brez da bi prebrali kaj piše.

No, to je to, upam da vam ta članek razširi obzorje računalniške varnosti.
Vrh

Jul 8, 2009

Quick Tip: ActionScript: Instance Name

Here's a quick tip: Getting an instance name of a movie clip is not mc.instanceName, but mc._name. Odd, but it works.

Jun 22, 2009

Kill a zombie process

Well, yes, everybody knows that zombie processes can't be killed, as they're already dead. That's all very well documented and repeated so many times, and the solution to this would be to: "kill the parent process".


Since killing the parent process makes init the parent of the zombie process which can kill zombies, if the real parent can't.

My problem was - how to get the parent process? That's not written anywhere! Why not? Is it so hard?

After some research it turns out it isn't.

You can get the parent process id (PPID) with the -o parameter in 'ps' command:

# ps auxo ppid | grep Z

You know what 'grep Z' does, don't you? It prints only the processes in the Zombie state.

Well when you get the ppid, the solution to zombie killing or reaping is simple.

Just kill -9 the ppid.

I hope this article saves someone from the midnight frustration on why the machine just won't start any new processes, even if CPU load and memory usage are near zero.

May 5, 2009

ActionScript: Printing

function print_mc(mc) {
 
 var myPrintJob:PrintJob = new PrintJob();

 myPrintJob.start();
 myPrintJob.addPage(mc);
 myPrintJob.send();

}

PHP: generate a photographic mosaic

I have written a command-line, procedural PHP script to generate a photographic mosaic.

Some samples:




The script works in two stages. The first one scans all of the images to work out an average color, and saves that information to a txt file on the disk.

This is then used in the second stage of the process, where a template of the mosaic is made - this is an image, shrinked down in size to as many pixels as is the number of images on the horizontal and vertical axis. This way each image represents one pixel of the template. The second stage begins composing the mosaic from images, that have the closest average color to the current pixel in the template.

The process is optimized by caching average colors to disk (this optimization is mandatory) and an caching smaller images to disk (there's a BIG difference in speed if you try to open a 5MB file or 100K file).

Here's the code that does all the work: http://pastebin.com/f70e3ccf7

May 1, 2009

PHP: average functions: Mean (Arithmetic, Geometric, Harmonic) · Median · Mode

See Wiki for detail on mean, median or mode. Please write your own optimizations / implementations in the comments.
function arithmetic_mean($a) {
 return array_sum($a)/count($a);
}

function geometric_mean($a) {
 foreach($a as $i=>$n) $mul = $i == 0 ? $n : $mul*$n;
 return pow($mul,1/count($a));
}

function harmonic_mean($a) {
 $sum = 0;
 foreach($a as $n) $sum += 1 / $n;
 return (1/$sum)*count($a);
}

function median($a) {
 sort($a,SORT_NUMERIC); 
 return (count($a) % 2) ? 
  $a[floor(count($a)/2)] : 
  ($a[floor(count($a)/2)] + $a[floor(count($a)/2) - 1]) / 2;
}

function modal_score($a) {
 $quant = array();
 foreach($a as $n) $quant["$n"]++;
 $max = 0;
 $mode = 0;
 foreach($quant as $key=>$n) {
  if($n>$max) {
   $max = $n;
   $mode = $key;
  }
 }
 return $mode;
}

Apr 25, 2009

How to download full resolution satellite images from Google Earth/Maps

Google Maps uses the following technique to serve images: It displays 256x256px blocks of images from their server. The server displays the image from the given parameters, for example:
http://khm3.google.com/kh/v=38&hl=en&x=35415&s=&y=23296&z=16
So, with a script, you can fetch all the images from the starting X and Y, to the ending and then stitch them together piece by piece. Below is an example how to get the parameters for the image (v,x,y,z) And here's a script that does all the work:
<?php
error_reporting(E_ALL ^ E_NOTICE);
set_time_limit(0);
ini_set("memory_limit","1024M");

// Bottom Left
//http://khm0.google.com/kh/v=38&hl=en&x=141234&s=&y=93147&z=18&s=G
//Top Right
//http://khm3.google.com/kh/v=38&hl=en&x=141273&s=&y=93105&z=18&s=Gali

//How big is the block (in pixels)
$block_width = 256;
$block_height = 256;

//I don't know what that is, but look at the URL
$v = 38;
//Zoom level
$z = 18;

//Get these parameters from the url
$start_x = 141234;
$start_y = 93105;

$end_x = 141273;
$end_y = 93147;

//Do some simple math... Dimensions of the panorama
$dim_x = $end_x - $start_x;
$dim_y = $end_y - $start_y;

$dim_x *= $block_width;
$dim_y *= $block_height;

print("$dim_x x $dim_y px\n");

//Allocate memory space for the panorama
$img = imagecreatetruecolor($dim_x,$dim_y);

for($x = $start_x ; $x <= $end_x ; $x++) {
 for($y = $start_y ; $y <= $end_y ; $y++) {
  $f = "$x-$y-$z.jpg";
  $url = "http://www.najdi.si/servlet/ServletRedirectTileImage?x=$x&y=$y&zl=$z";
  $url = "http://khm3.google.com/kh/v=$v&x=$x&y=$y&z=$z";
  
  //Download the block
  $cache = "wget \"$url\" -O $f";
  print("$cache\n");
  passthru($cache);
  
  //Put it on the panorama
  $block = imagecreatefromjpeg($f);
  imagecopy($img, $block, ($x-$start_x)*$block_width, ($y-$start_y)*$block_height, 0, 0, $block_width, $block_height);
  imagedestroy($block);
 }
}

imagejpeg($img,"$start_x-$end_x-_-$start_y-$end_y.jpg",100);
?>
I also noticed that many mapping sites are using the same technique. End result:


full.jpg

Apr 14, 2009

Java:: Coin Change Problem - dynamic programming - memoization - recursion

Problem: We have a series of coins, eg. 1, 3, 5 and we're trying to find the least possible number coins to sum up to a value, eg. 11 The smallest possible solution is 3 coins (5+5+1, 5+3+3).

Solution: The Greedy algorithm only works in special cases, but we're trying to find the ultimate, smallest and fast solution.

The goal is to check all possibilities, which can take a lot of time, if we don't use memoization. The solution below is a recursive function with two arguments:
  • int[] k - table of coins (1, 3, 5) ordered ascending
  • int val - the value we wish to solve
Read the comments for more information
 public static Hashtable<Integer, Integer> solved = new Hashtable<Integer, Integer>();
 
 public static int kovanci(int[] k, int val) {
  // we've reached the end of recursion - a leaf
  // if the value is less than zero it means that the current combination is not solvable
  // if the value is zero, it means it is solvable
  if (val <= 0) return val;

  // for as many coins try to decrease the value for the coin value 
  // and try to solve the smaller problem
  int min = -1; //default: if it's not solvable
  for (int i = k.length - 1; i >= 0; i--) {
   
   // if the coin k[i] exists in the solution, it means the solution is
   // solutions(value - coin_value) + 1
   // eg. we have coins: 1, 3, 5 and the value is 11
   // if the coin 5 exists in the solution, try to solve the problem for value 11-5 = 6
   // the solution is smaller_solution + 1
   int newVal = val - k[i];
   int r;

   // dynamic programming - memoization
   // if we already have the minimum for the new value, fetch it (with time complexity O(1)), 
   // so that we don't recursively re-solve the problem and waste time
   if (solved.get(newVal) != null) {
    //solution = smaller_sollution + 1
    r = solved.get(newVal) + 1;
   } else {
    //try to solve the smaller problem
    r = kovanci(k, newVal);
    //if the solution is valid, the new solution is smaller_solution + 1
    if (r >= 0) r++;
    //else, keep the negative value - it means that it's not valid
    //eg: coins 3, 5, value 11 is not solvable, the solution is -1
   }
   // from all of the solutions, get the minimum value
   // and skip invalid solutions ( less than zero )
   if ((r > 0) && (min == -1 || r < min)) {
    min = r;
   }
  }
  // dynamic programming - memoization
  // once we do get the smallest possible solution, save it for later use
  // it saves A LOT of time and useless work, that's already been done
  solved.put(val, min);
  return min;
 }

Feb 12, 2009

PHP: array delete

//deletes a number on index $idx in array and returns the new array
function array_delete($idx,$array) {
 unset($array[$idx]);
 return (is_array($array)) ? array_values($array) : null;
}

Feb 9, 2009

PHP: substring between two substrings in a string

Useful if you want to, for example get the text between HTML tags
 function between($s,$l,$r) {
  $il = strpos($s,$l,0)+strlen($l);
  $ir = strpos($s,$r,$il);
  return substr($s,$il,($ir-$il));
 }

//example
$html = file_get_contents('http://www.example.com');
$title = between($html,'<title>','</title>');

For more complex searches, you would need to use regular expressions.

Jan 4, 2009

Tunnel all traffic through SSH

I'd like to show you how to easily set up a Socks 5 proxy server and use it on a large number of applications.

I used only two applications - PuTTY and FreeCap on client side and OpenSSH on serverside.

So OpenSSH is a SSH server, most commonly used to log in to a remote computer, but you can also benefit from it by SSH tunneling.

PuTTY has an option to set up a proxy server on a local machine, and tunneling traffic from proxy to a SSH server. You can do that by executing putty with additional parameters:

putty.exe -D 8080 -P 22 -ssh sshhost.com

so:
-D option is for binding a proxy server port
-P is the port of the SSH server
-ssh is the hostname of the SSH server

when PuTTY starts you log in as you normally would, and when the connection is established, you have a proxy server running on your machine.

By changing the proxy settings in your favourite browser to 127.0.0.1:8080, you can check your IP and you will see, that you're using the SSH server's IP address.

Now, some applications don't have proxy settings, so that's where FreeCap comes in handy. It routes traffic from the application you want to use to the proxy server on your machine.

I haven't got ALL aplications to run through FreeCap, but it's a good start, since now I can use more applications to access the internet than before, on my extra-hard-firewalled internet conection in the student dormitory.

You should give these sites a read:
- http://www.buzzsurf.com/surfatwork/
- http://www.freecap.ru/eng/?p=whatis