The most active posts on Spiration http://www.spiration.co.uk/rss/active The most active posts on Spiration en-us Torkalot christo@uk.com christo@uk.com Submit is not a function http://www.spiration.co.uk/post/1232/Submit is not a function This means you have a function trying to call the form's submit() method, but you also have a button which is called submit(). This causes a conflict in javascript, because the submit method is already bound to that button. To solve the problem, simply change the name of the button so that name="moo" (or something). Your submit() call in your javascript function/method will now work. It took me a while of hacking javascript and html to work that one out - hopefully this post will mean it only takes you a minute.. christo follow me on twitter: [url]http://twitter.com/planet_guru[/url] ubuntu: error: stdio.h: No such file or directory http://www.spiration.co.uk/post/1291/ubuntu: error: stdio.h: No such file or directory Somehow I assumed that I would be able to compile a basic C program on any linux box - I mean unices are useful like that, right? So I was a bit surprised when I decided to compile a bit of C just now (in fact Christian Wolff's neat little mp3cut tool) and was faced with the following errors: [code] chris@snackerjack-lx:/usr/src/mp3cut-0.8$ make gcc -o mp3cut mp3cut.c mp3cut.c:25:19: error: stdio.h: No such file or directory mp3cut.c:26:20: error: stdlib.h: No such file or directory mp3cut.c:27:20: error: string.h: No such file or directory mp3cut.c:28:20: error: unistd.h: No such file or directory ..etc .. etc [/code] So what kind of unix comes with make and a compiler, but none of the required dev libraries and headers required to make any normal C program work? Well a brief google yielded the following solution.. Yup, you guessed it.. you need to install a dev package: [code] sudo apt-get install build-essential [/code] Excuse my rant, but if it's so 'essential', then why isn't it installed as part of the core system? I find that kinda weird. Anyway, problem fixed and C-sources are now compiling. christo follow me on twitter: [url]http://twitter.com/planet_guru[/url] Java md5 example with MessageDigest http://www.spiration.co.uk/post/1199/Java md5 example with MessageDigest This is a quick tip for implementing md5 encryption in java. We use the MessageDigest class in the java.security package and some string manipulation to turn the plain text into a byte array. The digest is then updated from the bytes from the byte array and a hash computation is conducted upon them. To quote from the Sun java api docs, The MessageDigest class provides applications the functionality of a message digest algorithm, such as MD5 or SHA. Message digests are secure one-way hash functions that take arbitrary-sized data and output a fixed-length hash value. Anyway the md5 example code below takes a session id (this is just a string which I wanted to encrypt - It could just as easily be a document, say a lump of xml or any old bit of text). This session id is pulled into the bytes array, defaultBytes and then the MessageDigest is instantiated as an instance of an md5 encryption. Java developers who have come over from PERL or PHP often get frustrated with such a longwinded means of running what could simply be a single line of code, however the snippet below could be wrapped into an md5sum class which conducts the encryption and simply returns a string of cipher text. [code] include java.security.*; ... etc sessionid="12345"; byte[] defaultBytes = sessionid.getBytes(); try{ MessageDigest algorithm = MessageDigest.getInstance("MD5"); algorithm.reset(); algorithm.update(defaultBytes); byte messageDigest[] = algorithm.digest(); StringBuffer hexString = new StringBuffer(); for (int i=0;i<messageDigest.length;i++) { hexString.append(Integer.toHexString(0xFF & messageDigest[i])); } String foo = messageDigest.toString(); System.out.println("sessionid "+sessionid+" md5 version is "+hexString.toString()); sessionid=hexString+""; }catch(NoSuchAlgorithmException nsae){ } [/code] Remember to import the java.security package. The original plain text and cipher text strings are echod to the java console just to demonstrate what has happened. Hope that's useful, christo follow me on twitter: [url]http://www.twitter.com/planet_guru[/url] Ubuntu Linux - Bluetooth and GPRS dialup connection http://www.spiration.co.uk/post/1307/Ubuntu Linux - Bluetooth and GPRS dialup connection This article explains how to set up a bluetooth connection between your ubuntu laptop and phone and get PPP working with BT's mobile service in the UK. It probably isn't so hard to repeat this for other network providers. I'm sure that if you do a Yahoo search for the GPRS settings of your mobile telco, you'll be up and runnin with little more than a few mintues of poking around. First you need to install the bluetooth packages on your linux machine: [code] $sudo apt-get install bluez-utils $sudo apt-get install blues-pin [/code] Now you need to make sure you have the ppp package installed $sudo apt-get install ppp At this point you already have enough software on your machine to do a scan of the local area and see what devices are available. this is done using hcitool. When I run this command, the output looks like this: [code] $chris@snackerjack-lx:~$ hcitool scan Scanning ... 00:07:3A:08:EE:74 n/a 00:18:13:50:0C:EB Christo Yahoo! chris@snackerjack-lx:~$ [/code] That means that my laptop can see my phone - it's reporting the MAC address and the device name. For more information on hcitool, you can run 'man hcitool'. Basically hcitool is a handy bluetooth utility which allows you to scan for and query local bluetooth devices. At this stage you can use hcitool to pair your bluetooth-enabled laptop with your phone. Use the following commands to achieve this: [code] $sudo hcitool cc 00:18:13:50:0C:EB [/code] Note, you should use the MAC address of your own phone in this command - as reported by the hcitool scan command earlier. This creates a baseband connection to your phone. The next step is: [code] $sudo hcitool auth 00:18:13:50:0C:EB [/code] This will request authentication with your phone - this is known as 'pairing' and will allow your computer to communicate with your bluetooth phone. Note again, you should replace the mac address with that of your phone. Don't use mine! The next stage is to use the Service Discovery Protocol to ask your device what bluetooth services it is offering. At this point, if you're feeling really curious, you could re-run your hcitool scan and then run an SDP discovery search on all the listed devices. You never know - it might be interesting. However, this article is about setting up a Dial-up connection through your phone, so let's keep focussed.. The command you need to issue looks like this: [code] $sdptool browse 00:18:13:50:0C:EB [/code] Again, use your own phone's MAC address - This will list all sorts of bluetooth services that your phone offers. This is what the output looks like when I run this command against my own phone.. I know it's a lot to paste, but it's worth seeing the kind of services which might be on offer: [code] chris@snackerjack-lx:~$ sdptool browse 00:18:13:50:0C:EB Browsing 00:18:13:50:0C:EB ... Service Description: Sony Ericsson K750 Service RecHandle: 0x10000 Service Class ID List: "PnP Information" (0x1200) Service Name: Dial-up Networking Service RecHandle: 0x10001 Service Class ID List: "Dialup Networking" (0x1103) "Generic Networking" (0x1201) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 1 Profile Descriptor List: "Dialup Networking" (0x1103) Version: 0x0100 Service Name: Serial Port Service RecHandle: 0x10002 Service Class ID List: "Serial Port" (0x1101) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 2 Service Name: HF Voice Gateway Service RecHandle: 0x10003 Service Class ID List: "Handfree Audio Gateway" (0x111f) "Generic Audio" (0x1203) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 3 Profile Descriptor List: "Handsfree" (0x111e) Version: 0x0101 Service Name: HS Voice Gateway Service RecHandle: 0x10004 Service Class ID List: "Headset Audio Gateway" (0x1112) "Generic Audio" (0x1203) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 4 Profile Descriptor List: "Headset" (0x1108) Version: 0x0100 Service Name: OBEX Object Push Service RecHandle: 0x10005 Service Class ID List: "OBEX Object Push" (0x1105) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 5 "OBEX" (0x0008) Profile Descriptor List: "OBEX Object Push" (0x1105) Version: 0x0100 Service Name: OBEX File Transfer Service RecHandle: 0x10006 Service Class ID List: "OBEX File Transfer" (0x1106) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 6 "OBEX" (0x0008) Profile Descriptor List: "OBEX File Transfer" (0x1106) Version: 0x0100 Service Name: OBEX SyncML Client Service RecHandle: 0x10007 Service Class ID List: "Error: This is UUID-128" (0x00000002-0000-1000-8000-0002ee000002) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 7 "OBEX" (0x0008) Service Name: OBEX IrMC Sync Server Service RecHandle: 0x10008 Service Class ID List: "IrMC Sync" (0x1104) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 8 "OBEX" (0x0008) Profile Descriptor List: "IrMC Sync" (0x1104) Version: 0x0100 Service Name: Mouse & Keyboard Service Description: Remote Control Service Provider: Sony Ericsson Service RecHandle: 0x10009 Service Class ID List: "Human Interface Device" (0x1124) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 17 "HIDP" (0x0011) Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "Human Interface Device" (0x1124) Version: 0x0100 chris@snackerjack-lx:~$ [/code] That's pretty cool - First you can see that I'm using a Sony Ericsson K750 phone and then on every bluetooth 'Service Name:' line, you can see the name of a service on offer. The one we are most interested in is the 'Dial-up Networking' service, however, we can also use this device as a voice gateway, and it will support OBEX transfer requests (ie the exchange of binary objects from other bluetooth devices). I can also use this phone as an input device (service 'Mouse & Keyboard') - note that this last service describes itself as 'Remote Control' and yes, it can be used in precisely that way - so the phone will suddenly become a pointer/mouse within the PAN. I will explain this in another article. Okay, so where are we now? Well the next step is simply to tell your system which channel you want to talk RFCOMM. RFCOMM is a special bluetooth serial port emulation over radio frequency (hence the name rf communication). It is quite literally an implementation of the RS232 serial protocol over radio. Bluetooth can handle several rfcomm channels consecutively. We just have to decide which one we're going to use for this exercise.. This is dead easy. Just look at the output of the sdp search which you ran just now and look at the RFCOMM channel number in the 'Dial up Networking' service section. In the case above, it's channel 1. All you do now is specify that channel in your rfcomm.conf - so on my system that looks like this: [code] rfcomm0 { bind yes; device 00:18:13:50:0C:EB; channel 1; comment "PPP connect"; } [/code] At this point, you can set up /dev/rfcomm0 by running the following command: [code] $sudo /etc/init.d/bluez-utils restart [/code] We're nearly there. Now that you have your rfcomm node fully configured and your phone and computer are paired, all you need to do is set up the PPP and chat settings on your computer. Chat sets up a ppp connection between your modem and a remote ppp service based on rules which you define in a chatscript. First create the file /etc/ppp/peers/bluetoothconn and put the following into it: [code] debug noauth connect "/usr/sbin/chat -v -f /etc/chatscripts/bluetoothconn" usepeerdns /dev/rfcomm0 115200 defaultroute crtscts lcp-echo-failure 0 [/code] Now edit the file /etc/chatscripts/bluetoothconn and make sure it contains the following: [code] TIMEOUT 35 ECHO ON ABORT 'nBUSYr' ABORT 'nERRORr' ABORT 'nNO ANSWERr' ABORT 'nNO CARRIERr' ABORT 'nNO DIALTONEr' ABORT 'nRINGINGrnrnRINGINGr' '' rAT OK 'AT+CGDCONT=2,"IP","btmobile.bt.com"' OK ATD*99***2# CONNECT "" [/code] It took me a while to get this configuration to work. I tried several settings for the data profile number, without any real idea of what it should be - and found that ***2 worked. You might have to play around with this for your own telco - try swapping the '2' for any integer between '1' and '4', or even remove the whole lot and just terminate with a '#'. To bring the connection up, just run the command: [code] $pon bluetoothconn [/code] and to turn it off again: [code] $poff Bluetoothconn [/code] It's as simple as that. If you still have questions about your bluetooth and GPRS setup with linux on your laptop and trying to talk to BT, please reply to this and let me know. Hope that helps. christo Follow me on twitter to catch all my tech updates [url]http://www.twitter.com/planet_guru[/url] Connecting to the Betfair API with php and Bflib http://www.spiration.co.uk/post/1438/Connecting to the Betfair API with php and Bflib [b]Connecting to the Betfair API with php and Bflib[/b] Updated July 18th 2011 This is the first of a series of tutorials designed to help you get started with writing bots and applications using the Betfair API. These tutorials use the php programming language and make heavy use of the [url=http://github.com/planetguru/bflib]bflib Betfair API library[/url]. Before you get started, you will need to download the bflib source code from it's home on github. The project page is [url=http://github.com/planetguru/bflib]here[/url] and the 'download source' link is in the top-right, just under the 'search' box. Extract the source code onto your local filesystem. If your bot/app will have a web front-end, you will need to put the source code into a directory which is accessible from your web docroot. Your bot can run headless - in which case, you can extract the bflib source code into any convenient location. [code] chris@osx-lx-vm:/export$ tar -zxvf planetguru-bflib-c2b3a8f.tar.gz chris@osx-lx-vm:/export$ mv planetguru-bflib-c2b3a8f bflib [/code] Now you need to make sure that you update the vendorConstants class file with your own username and password. In the example above, this would be under /export/bflib/classes/vendorConstants.class.php. If you are doing this for the first time, move the vendorConstants.class.php.sample to vendorConstants.class.php and then edit the file so that your username and password are correct and include your vendorId if you have one. If you don't have a vendorId, use the productID 82 and the vendorid 0, as shown below. [code] class vendorConstants { /** * bdp developer credentials. You should change the USERNAME and * PASSWORD to match your own username and password on betfair. * Remember that your account will need to be active, with recent transactions and * cleared funds in order for the SOAP APIs to allow you to authenticate * */ const USERNAME = 'yourusernamehere'; const PASSWORD = 'yourpasswordhere'; const PRODUCTID = 82; const VENDORID = 0; const LOCATIONID = 0; const IPADDRESS = 0; public function __construct(){} } [/code] Great - now we're all set up to try a very simple app - just to check that your account works. This application is headless, so has no web page or UI. All it does is return all of the top-level event types offered on betfair. Here is a walkthrough of how I get this app working. First I create a new directory to house my application. I'm going to call it betfair-test: [code] chris@osx-lx-vm:/export$ mkdir betfair-test chris@osx-lx-vm:/export$ cd betfair-test/ chris@osx-lx-vm:/export/betfair-test$ mkdir classes chris@osx-lx-vm:/export/betfair-test$ mkdir cli [/code] Now I am going to create two files. One will be a simple class file for my demo application class. The second will be the executable which I run to actually use the application. The class file should live in the 'classes' directory (created above) under the name testApp.class.php and the executable should live in the 'cli' directory - it doesn't matter what this one is called. First, this is what the source code for the testApp.class.php application class should look like: [code] <?php /** * Test use of the 'bflib' Betfair API connection library. This just requests a list of * top-level event types and displays their names. This is the simplest of requests which * can be made against the Betfair API and demonstrates that you have a working connection */ class testApp { private $context = ''; /** * construct testApp object * * @param none * @return none */ public function __construct(){ /* directly set the 'context' since this mini app isn't going to do anything else */ $this->context = 'getAllEventTypes'; } /** * Instantiate a betfairController object, passing through the 'context' * and then grab the soapresponse after the API call is made. * * @param none * @return none */ public function run(){ /* some methods are just page displays and don't need to talk to betfair */ $this->bflib = new betfairController(); $soapResult = array(); $soapResult = $this->scheduleRequest(); foreach($soapResult->Result->eventTypeItems->EventType as $eventType){ print("n".$eventType->name); } } /** * Tell the betfairController class which API verb/method we are going to use and ask it to set up the request object * Then run the controller and capture the soapResponse object that comes back * * @param none * @return none */ public function scheduleRequest(){ /* set the bflib context as this context */ $this->bflib->setContext($this->context); /* call the bflib->constructRequestData method to set up the soap data */ $this->bflib->constructRequestData($this->context); /* run the bflib->execute and bflib->prepareResponseData requests and capture the soapResult which comes back */ $soapResponse = $this->bflib->run(); return($soapResponse); } } ?> [/code] This file needs to be saved in your 'cli' directory with the name betfair-test. What you see here is really a helicopter view of the basic request cycle which occurs every time a message is sent to Betfair. The betfairController class handles the incoming request from this application class. Based on the context, it constructs arrays of request data, which are then passed into the low-level betfairDialogue class. The controller can also exposes an itemId member variable, which is used to pass in the ID of whatever the thing is you want to perform an action upon. Some Design considerations The next version of the bflib library will move away from the itemId principal within the controller, introducing a 'subjects' class, which can represent either an integer ID, or an array of IDs, or a collection of objects. This will allow one/many-to-many type operations to occur (eg bulk bet placement). It's always worth knowing that the itemId/subjects object at the betfairController level is a facade to and object of the same name within the betfairDialogue class. The former provides a home for any business logic around request data preparation and perhaps bubbling back into helper classes within the application framework before passing the assembled request down to the dialogue handler to be sent over the wire. Now all I need is an executable to instantiate the application class which I have created. It looks like this: [code] <?php /** * Define autoload classpath and require it in. * * @param $class The class to be loaded * @return none */ function __autoload( $class ){ $classpath = '../classes/'.$class.'.class.php'; if (file_exists( $classpath )){ require_once($classpath); return; } $classpath = '/export/bflib/classes/'.$class.'.class.php'; if (file_exists( $classpath )){ require_once($classpath); return; } } $testApp = new testApp(); $testApp->run(); ?> [/code] I included a specific autoload method to point down the two class paths which I'm using for this application. In doing so, I have enforced a convention whereby a class is always found within a file which bears it's name in the format <classname>.class.php. This arguably put a bit more structure around php's potentially shappy management of classnames. It will also feel more familier to folks with a java background. Something else which is worth knowing is the location of the betfairLogger's log destination. Currently this is set to /tmp/betfair-api-log within the vendorConstants.class.php configuration file. If you are having trouble getting this thing to work, then your log file is a good place to check for error codes returned from betfair. The logger functionality is new and does not yet have a toggle - The platform also doesn't yet watch for specific error codes within an exception handling framework. This is in-plan. Okay - so now let's run the app and see what we get: [code] chris@osx-lx-vm:/export/betfair-test/cli$ php -e betfair-test PHP Warning: Xdebug MUST be loaded as a Zend extension in Unknown on line 0 Poker Room Yahoo Racing Soccer Tennis Golf Cricket Rugby Union Boxing Horse Racing Motor Sport Soccer Euro 2000 Special Bets Cycling Rowing Rugby League Darts Athletics Greyhound Racing Financial Bets Snooker American Football Olympics - Sydney 2000 Baseball Basketball Hockey Ice Hockey Sumo Wrestling Australian Rules Gaelic Football Hurling Pool Test Only Chess 2002 Winter Olympics Trotting Commonwealth Games Poker Winter Sports Handball Volleyball Politics Bridge Exchange Poker International Rules Table Tennis Floorball Netball Yachting Swimming Gaelic Games Internal Markets Olympics 2004 Bowls Bandy Badminton GAA Sports Backgammon Soccer - Euro 2004 Exchange Roulette Exchange Blackjack Fishing Exchange Casino Tradefair Test Cross Sport Accumulators Featured Markets Ten Pin Bowling Exchange Card Racing Surfing Canoeing Equestrian Water Polo Fussball Exchange Omaha Hi Combat Sports Olympics 2008 Roller Hockey Polo Harness Racing Pelota Horse Racing - Virtual Squash Futsal Beach Volleyball Exchange Hi Lo Exchange Baccarat Tradefair Casino Mixed Martial Arts Exchange Gameschris@osx-lx-vm:/export/betfair-test/cli$ [/code] And bingo! we have a working connection to betfair's soap endpoint and our first request has worked. In future articles I will dive into some more complex examples and demonstrations, including price monitoring, bet placement and UI development. I'll come back and link those articles in when they emerge :) Meanwhile, why not check out the Second Tutorial in this series, which focusses on coding a betfair application with market navigation and a simple user interface - [url=http://www.spiration.co.uk/post/1442/Developing%20a%20Betfair%20application%20with%20bflib]Second betfair tutorial here[/url] Follow me on Twitter: [url]http://twitter.com/planet_guru[/url] christo ubuntu linux VPN connection without cisco vpn client http://www.spiration.co.uk/post/1293/ubuntu linux VPN connection without cisco vpn client Getting a reliably working VPN connection on your linux box isn't as easy as one might think. The Cisco VPN client for linux comes with a few major flaws - firstly it's a complete arse to install - particulary on heavily package-based distros such as Ubuntu - the program requires all the kernel headers to be present and it also insists that they exactly match the running kernel version. This may or may not be a total ballache to manage. In addition to that, I have run the Cisco VPN client for linux on at least two distros (including Slackware and Redhat) and it has been bad to say the least. Connections just die over SSH when any more than a few packets are sent and nothing less than a restart of the client will allow the system to reconnect - Such a program falls well beyond my 'suitable-for-use' radar. It was these issues which pushed me to find an alternative solution. The solution came in the form of Maurice Massar's vpnc - a relatively little-known and fairly unassuming application which does exactly as it says on the tin. Ubuntu users are one step ahead of the source-based distros just because a vpnc package does exist for dapper. First let's install that on the client system. Do this with the following command: [code] sudo apt-get install vpnc [/code] If you are not running ubuntu, you will probably have to compile the program yourself. I would image this to be quite simple. The sources are downloadable from this page: http://www.unix-ag.uni-kl.de/~massar/vpnc/ Now this is where things get a bit tricky - you have the application installed, but it won't work until you have a working config. This contains a bunch of IPSec settings required to talk to your VPN endpoint. When I first looked at these, I really didn't know where to start, but I pretty soon determined that the most important values would be these: [code] IPSec gateway IPSec ID IPSec secret Xauth username Xauth password [/code] So from whence should we collect this data? I knew that if I was to ask the IT department at work, they would probably tell me that the software isn't supported and to use the cisco client under windows. That doesn't suit my needs, but it does offer a clue. You see, for every connection profile, the Cisco VPN client keeps a profile description file called a .pcf. All I need to do is locate the .pcf file on my windows partition and copy it over. [code] mount /dev/hda1 /windows cp /windows/Program Files/Yahoo! Inc/VPN Client/profiles/London.pcf /home/chris/Desktop/. [/code] Now we can extract the vpn gateway hostname, the Group ID and the group 'secret' from the locally copied .pcf. The group secret is a very long string of characters - it's actually a hexadecimal representation of the key, (which itself is formed from a mixture of SHA-1 hashing and triple-DES in CBC mode - a web search will yield all the gory details if that interests you). This throws a slight hurdle in our path, because it is the original plain text version which we need to offer our vpnc config. Thankfully there are tools around to help us with this. First you will need to install the libgcrypt-dev package: [code] sudo apt-get install libgcrypt-dev [/code] You will then need to compile the cisco-decrypt.c utility which is downloadable from here: http://www.unix-ag.uni-kl.de/~massar/soft/cisco-decrypt.c . Note that when you come to compile the program you will need to use the following compile options: [code] gcc -Wall -o cisco-decrypt cisco-decrypt.c $(libgcrypt-config --libs --cflags) [/code] This will result in a working binary in ./cisco-decrypt. Okay, we're nearly there.. all we need to do now is decrypt that cipher string from the .pcf file and then we can paste that into our vpnc.conf. The first thing cisco-decrypt does is convert the string from hexadecimal to binary. Here's how I did that: [code] root@snackerjack-lx:~/Desktop# grep enc_GroupPwd London.pcf | awk -F= '{print $2 }' | xargs ./cisco-decrypt atat@atet8s8cu*7777uv8paiaiecrac$ root@snackerjack-lx:~/Desktop# [/code] Of course I have modified it for obvious reasons, but you get the idea. And now to the final stage - creating the config file: [code] vim /etc/vpnc/vpnc.conf [/code] Just enter the follwing lines (of course using your own settings), write out the file and exit: [code] IPSec gateway <your gateway address from the pcf> IPSec ID General IPSec secret atat@atet8s8cu*7777uv8paiaiecrac$ Xauth username clacy Xauth password nottellingyou [/code] It's worth mentioning here that if you omit the username and/or password, the vpnc program will prompt you for them at run time. I highly recommend you do this. It will save you from having to enter them in plain text into a config file. Additionally, if you use RSA-SecureID fobs for your passwords it will make using the application far easier. Nobody wants to hack a config every time they run a program! Now all you need to do is fire up the connection like this: [code] sudo vpnc /etc/vpnc/vpnc.conf [/code] If this is useful to you and you would like some of this packaged up in some way, please let me know. I think it's pretty simple as it is, but if there is any interest out there and I can make this simpler for the next person, then I will :) christo Unix / Linux change a user's home directory - usermod http://www.spiration.co.uk/post/1294/Unix / Linux change a user's home directory - usermod I watched somebody change a user's home directory today by deleting the user using 'userdel' and then re-creating the user with 'adduser' and entering a different path for their home directory. This is not the simplest way to do it.. To change the user's home directory, just use the 'usermod' command, which exists on all unices. It works like this: usermod -d /path/to/new/homedir/ username easy christo follow me on twitter: [url]http://www.twitter.com/planet_guru[/url]