<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1985725707144494069</id><updated>2012-01-23T03:48:44.254-08:00</updated><category term='SQL'/><category term='dom0'/><category term='Scaleability'/><category term='2.6.27'/><category term='Vcard'/><category term='paravirt_ops'/><category term='Form'/><category term='Paper'/><category term='cisco'/><category term='RTSP'/><category term='vlan'/><category term='Streaming'/><category term='N810'/><category term='wpa_supplicant'/><category term='rdp'/><category term='scp'/><category term='paravirt'/><category term='xrdp'/><category term='Darwin Streaming Server'/><category term='Video'/><category term='protection'/><category term='xen'/><category term='64 bit'/><category term='generator'/><category term='serial port'/><category term='FDF'/><category term='wpa_supplicant.conf'/><category term='Charger'/><category term='domu'/><category term='PDF'/><category term='WPA'/><category term='Nokia'/><category term='bridge'/><category term='ffmpeg'/><category term='live555'/><category term='Videolan'/><category term='intrepid'/><category term='Enterprise'/><category term='anonymous'/><category term='iPhone'/><category term='G1'/><category term='remote desktop'/><category term='network'/><category term='jailbreak'/><category term='Printing'/><category term='virtualization'/><category term='pty'/><category term='Attachment'/><category term='GWT'/><category term='Email'/><category term='Patch'/><category term='VirtualBox'/><category term='64bit'/><category term='psuedo terminal'/><category term='hacking'/><category term='Encryption'/><category term='crack'/><category term='Security'/><category term='MAC'/><category term='5V'/><category term='ADOBE'/><category term='n00b'/><category term='HTC Dream'/><category term='iBatis'/><category term='x86_64'/><category term='jailbroken'/><category term='1064'/><category term='Android'/><category term='anon'/><category term='ifconfig'/><category term='zenity'/><category term='hack'/><category term='MIME'/><category term='newb'/><category term='E71'/><category term='Google Web Toolkit'/><category term='howto'/><category term='mount'/><category term='random'/><category term='noob'/><category term='COM'/><category term='PwnageTool'/><category term='Java'/><category term='vnc'/><category term='VLC'/><category term='X'/><category term='PHP'/><category term='sfdisk'/><category term='iphone-dev'/><category term='wireless'/><category term='802.11'/><category term='Linux'/><category term='unlock'/><category term='virus'/><category term='LPT'/><category term='Ubuntu'/><category term='DSS'/><category term='progress'/><category term='fdisk'/><category term='password'/><category term='visitor'/><category term='Compile'/><category term='DOS'/><title type='text'>Clayton Shepard</title><subtitle type='html'>Random Tech Tidbits and Howtos</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>23</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-4716925838381396595</id><published>2010-02-16T05:05:00.001-08:00</published><updated>2010-02-16T05:17:17.121-08:00</updated><title type='text'>Compiling vnStat on iPhone</title><content type='html'>&lt;a href="http://humdi.net/vnstat/"&gt;vnStat&lt;/a&gt; is a neat little bandwidth monitoring cli utility for Linux and FreeBSD.&lt;br /&gt;&lt;br /&gt;Actually the hardest part about this is just getting the toolchain running, after that it is a couple modifications to the Makefiles.&lt;br /&gt;&lt;br /&gt;So there is quite a bit of documentation out there on how to get the toolchain running.  The easiest way I found was on the device itself, using &lt;a href="http://iphonesdkdev.blogspot.com/2009/10/how-to-compile-mobilesubstrate.html"&gt;these instructions&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;After you do that then you need to just change the top of the Makefile to:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;CC=arm-apple-darwin9-g++&lt;br /&gt;Sysroot=/var/toolchain/sys30&lt;br /&gt;&lt;br /&gt;LDFLAGS=        -multiply_defined suppress \&lt;br /&gt;                -L$(Sysroot)/usr/lib \&lt;br /&gt;                -Wall \&lt;br /&gt;                -Werror \&lt;br /&gt;                -march=armv6 \&lt;br /&gt;                -mcpu=arm1176jzf-s \&lt;br /&gt;                &lt;br /&gt;CFLAGS= -I$(Sysroot)/usr/include&lt;br /&gt;&lt;br /&gt;# bin and man dirs for Linux&lt;br /&gt;BIN = $(DESTDIR)/usr/bin&lt;br /&gt;SBIN = $(DESTDIR)/usr/sbin&lt;br /&gt;MAN = $(DESTDIR)/usr/share/man&lt;br /&gt;&lt;br /&gt;# bin and man dirs for *BSD&lt;br /&gt;BIN_BSD = $(DESTDIR)/usr/local/bin&lt;br /&gt;SBIN_BSD = $(DESTDIR)/usr/local/sbin&lt;br /&gt;MAN_BSD = $(DESTDIR)/usr/local/man&lt;br /&gt;&lt;br /&gt;default: vnstat&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This worked for vnStat 1.10 on an iPhone 3GS 3.0.1.&lt;br /&gt;&lt;br /&gt;You also need to sign the files using ldid:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ldid -S src/vnstat&lt;br /&gt;ldid -S src/vnstatd&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Or you can just put them in the src/Makefile so it does it automatically for you:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;...&lt;br /&gt;all: vnstat vnstatd vnstati&lt;br /&gt;&lt;br /&gt;vnstat: $(OBJS)&lt;br /&gt; $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o vnstat&lt;br /&gt; ldid -S vnstat&lt;br /&gt;vnstatd: $(DOBJS)&lt;br /&gt; $(CC) $(LDFLAGS) $(DOBJS) $(LDLIBS) -o vnstatd&lt;br /&gt; ldid -S vnstatd&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The make install didn't work well for me so I just run it from my /var/root/vnstat directory.  You also want to make your db directory and copy the rc file over:&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;mkdir ~/.vnstat&lt;br /&gt;cp cfg/vnstat.config ~/.vnstatrc&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Then modify the ~/.vnstatrc to set the DatabaseDirectory correctly:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# location of the database directory&lt;br /&gt;DatabaseDir "/var/root/.vnstat"&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-4716925838381396595?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/4716925838381396595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=4716925838381396595' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4716925838381396595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4716925838381396595'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2010/02/compiling-vnstat-on-iphone.html' title='Compiling vnStat on iPhone'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-6792643331756164721</id><published>2010-02-14T01:47:00.000-08:00</published><updated>2010-02-19T15:06:29.961-08:00</updated><title type='text'>Apple Late Model iPhone 3GS Clarifications</title><content type='html'>A couple things I've learned over the past couple days:&lt;br /&gt;&lt;br /&gt;iRecovery reports the iBoot version wrong on all the 3GSs I have tried.  It always reports 636.66, when in fact the versions were 359.3.2 and 359.3.&lt;br /&gt;&lt;br /&gt;The 4th and 5th digits of the serial number are the manufacture week.  According to &lt;a href="http://theiphonewiki.com/wiki/index.php?title=S5L8920_(Bootrom)"&gt;theiphonewiki&lt;/a&gt; iPhones made after week 40 are not vulnerable to the 24kpwn (untethered) exploit.  This isn't quite true, as I have at least one week 41 that was vulnerable to 24kpwn.&lt;br /&gt;&lt;br /&gt;I have yet to find a good way to put 3GSs in DFU mode, or more importantly, get them out of DFU mode, which is the only way I have seen to reliably tell which iBoot version they have.  I have tried holding the power and home button for 30 seconds, even a minute, or just the power, or just the home button for that long.  iRecovery won't even detect it.&lt;br /&gt;&lt;br /&gt;To build &lt;a href="http://github.com/westbaer/irecovery"&gt;iRecovery&lt;/a&gt; you need a couple packages, namely readline and libusb.  On the Mac this apparently requires &lt;a href="http://darwinports.com/download/"&gt;darwin ports&lt;/a&gt; then &lt;a href="http://libusb.darwinports.com/"&gt;libusb&lt;/a&gt;, but I never actually got it to build on OSX.  For ubuntu you just need to apt-get libusb-dev and libreadline5-dev (although I also installed libusb-1.0-0-dev before I saw libusb-dev, just in case you need both).  Also, while building on Ubuntu, I had to add "include &amp;lt;signal.h&amp;gt;" to irecovery.c, or else it couldn't find SIGINT.&lt;br /&gt;&lt;br /&gt;Also, from what I can tell, even if you have your SHSH saved, you can never downgrade your baseband, so if you accidentally upgrade to 3.1.3 you lose your ability to unlock.&lt;br /&gt;&lt;br /&gt;Finally, switching back and forth from blackra1n and redsn0w has worked fine so far.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt;  Switching from redsn0w to blackra1n caused iTunes not to be able to sync, giving error message "iTunes cannot read the contents of the iPhone  xxxx. Go to the Summary tab in iPhone preferences and click Restore to restore this iPhone to factory settings."  The fix is to delete /private/var/mobile/Media/iTunes_Control/iTunes/iTunesDB and any files under /private/var/mobile/Media/iTunes_Control/Music.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-6792643331756164721?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/6792643331756164721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=6792643331756164721' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/6792643331756164721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/6792643331756164721'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2010/02/apple-late-model-iphone-3gs.html' title='Apple Late Model iPhone 3GS Clarifications'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-2874653264925463981</id><published>2009-11-09T20:34:00.000-08:00</published><updated>2009-11-09T21:56:26.188-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jailbroken'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='1064'/><category scheme='http://www.blogger.com/atom/ns#' term='PwnageTool'/><category scheme='http://www.blogger.com/atom/ns#' term='jailbreak'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone-dev'/><category scheme='http://www.blogger.com/atom/ns#' term='unlock'/><title type='text'>A Couple Issues Jailbreaking iPhone OS 3.1.2</title><content type='html'>I ran in to three issues jailbreaking iPhone 3GS OS 3.1.2 with PwnageTool 3.1.4:&lt;br /&gt;&lt;br /&gt;1)  Error 1064 when iTunes tried to deploy a custom image&lt;br /&gt;2)  No cellular signal after jailbreak&lt;br /&gt;3)  Cydia immediately crashing when you try to open it&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;--------------------------1--------------------------&lt;br /&gt;&lt;br /&gt;The 1064 error was solved simply by pwning the phone again.  The hardest part was getting the phone out of DFU mode.  A couple of the published "hold home and power for 8 seconds, then hold home and power for 8 seconds, then again, but keep holding the home button for 20 seconds" methods didn't work.  &lt;a href="http://download572.mediafire.com/n0tzkd0ynjtg/ywhxqzdoimg/iHackintosh+iRecovery+Package+for+Windows+%26+Mac.rar"&gt;iRecovery&lt;/a&gt; worked perfectly first try.  After downloading and extracting it run:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;./iRecovery -s&lt;br /&gt;#after the prompt appears enter:&lt;br /&gt;&lt;br /&gt;setenv auto-boot true&lt;br /&gt;saveenv&lt;br /&gt;/exit&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Note: In Windows XP this needs to be run in compatibility mode and as administrator...&lt;br /&gt;&lt;br /&gt;Then just run the PwnageTool again and tell it the phone hasn't been pwned.  This only happened to one of the phones I was messing with, so it could have been a user error.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;--------------------------2--------------------------&lt;br /&gt;&lt;br /&gt;This is just because I told PwnageTool to activate the phone even though I had a legite cell plan...  Disabling the activation feature made everything work fine again.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;--------------------------3--------------------------&lt;br /&gt;&lt;br /&gt;I traced this issue back to using expert mode of PwnageTool and telling it to install all of the outdated pre-downloaded packages that come with PwnageTool.  The fix is to either just not preinstall any packages, or to update the packages before they are installed.&lt;br /&gt;&lt;br /&gt;The reason that simply hitting the refresh button under Cydia Settings-&gt;Download Packages doesn't work is because it is using a different repository than Cydia ends up using on the iPhone.  So you have to go to "Manage sources" and remove the existing "http://apt.saurik.com/dists/tangelo/main/binary-iphoneos-arm/Packages" repository (click it and hit delete), then add "http://apt.saurik.com/dists/tangelo-3.7/main/binary-iphoneos-arm/Packages".  Now go back to "Download packages", select the 3.7 repository, sort by Status, highlight all of the packages that have a new version available (shift+click), and click add to queue and wait for them to download.  Now you can add all the packages you want via "Select packages" and create an image that won't cause Cydia to immediately crash.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------&lt;br /&gt;&lt;br /&gt;Another tidbit:  iTunes asked me if I wanted to update my carrier settings.  I was a bit skeptical after having just jailbroken the phone, but all it does is update some APN information and such, not the baseband or firmware or anything.  So it is fine to say yes to AFAIK.&lt;br /&gt;&lt;br /&gt;Also, I did notice the lowered WiFi signal after installing blackra1n, but a network settings reset seemed to fix it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-2874653264925463981?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/2874653264925463981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=2874653264925463981' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/2874653264925463981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/2874653264925463981'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2009/11/couple-issues-jailbreaking-iphone-os.html' title='A Couple Issues Jailbreaking iPhone OS 3.1.2'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-7355878404066628612</id><published>2009-08-21T09:39:00.000-07:00</published><updated>2010-02-07T22:41:55.428-08:00</updated><title type='text'>Drawable Image View in Android</title><content type='html'>I recently needed an image view that scaled a bitmap to its size and could be drawn on using a touchscreen.&lt;br /&gt;&lt;br /&gt;&lt;span style="text-decoration: line-through;"&gt;Its not very polished or extensible (the line size and color is hardcoded), but it works well for a prototype:&lt;/span&gt;  &lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt; I went ahead and made the color and line width configurable:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import android.content.Context;&lt;br /&gt;import android.graphics.Bitmap;&lt;br /&gt;import android.graphics.Canvas;&lt;br /&gt;import android.graphics.Matrix;&lt;br /&gt;import android.graphics.Paint;&lt;br /&gt;import android.view.MotionEvent;&lt;br /&gt;import android.view.View;&lt;br /&gt;&lt;br /&gt;public class DrawableImageView extends View {&lt;br /&gt;    private Bitmap mBitmap;&lt;br /&gt;    private Bitmap pic;&lt;br /&gt;    private Canvas mCanvas;&lt;br /&gt;    private final Paint mPaint;&lt;br /&gt;    private int a = 255;&lt;br /&gt;    private int r = 255;&lt;br /&gt;    private int g = 255;&lt;br /&gt;    private int b = 255;&lt;br /&gt;    private float width = 4;&lt;br /&gt;    &lt;br /&gt;    public DrawableImageView(Context c, Bitmap img) {&lt;br /&gt;        super(c);&lt;br /&gt;        pic = img;&lt;br /&gt;        mPaint = new Paint();&lt;br /&gt;        mPaint.setAntiAlias(true);&lt;br /&gt;        mPaint.setARGB(a,r,g,b);&lt;br /&gt;&lt;br /&gt;        &lt;br /&gt;        Bitmap newBitmap = Bitmap.createBitmap(img.getWidth(), img.getHeight(), Bitmap.Config.RGB_565);&lt;br /&gt;  Canvas newCanvas = new Canvas();&lt;br /&gt;  newCanvas.setBitmap(newBitmap);&lt;br /&gt;  if (img != null) {&lt;br /&gt;   newCanvas.drawBitmap(img, 0, 0, null);&lt;br /&gt;  }&lt;br /&gt;  mBitmap = newBitmap;&lt;br /&gt;  mCanvas = newCanvas;&lt;br /&gt;        &lt;br /&gt;        mCanvas.setBitmap(mBitmap);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public DrawableImageView(Context c, Bitmap img, int alpha, int red, int green, int blue) {&lt;br /&gt;     this(c, img);&lt;br /&gt;     setColor(alpha, red, green, blue);&lt;br /&gt;    }    &lt;br /&gt;    public DrawableImageView(Context c, Bitmap img, int alpha, int red, int green, int blue, float w) {&lt;br /&gt;     this(c, img, alpha, red, green, blue);&lt;br /&gt;     width = w;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public Bitmap getBitmap() {return mBitmap;}&lt;br /&gt;    public void setWidth(float w) {width = w;}&lt;br /&gt;    public void setColor(int alpha, int red, int green, int blue) {&lt;br /&gt;     a = alpha;&lt;br /&gt;     r = red;&lt;br /&gt;     g = green;&lt;br /&gt;     b = blue;&lt;br /&gt;        mPaint.setARGB(a,r,g,b);&lt;br /&gt;    }&lt;br /&gt;    public void Undo() {&lt;br /&gt;  mCanvas.drawBitmap(pic, 0, 0, null);&lt;br /&gt;  invalidate();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;    float scaleX;&lt;br /&gt;    float scaleY;&lt;br /&gt;    float scale;&lt;br /&gt;    @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {        &lt;br /&gt;     scaleX = (float) w/mBitmap.getWidth();&lt;br /&gt;     scaleY = (float) h/mBitmap.getHeight();&lt;br /&gt;     scale = scaleX &gt; scaleY ? scaleY : scaleX;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override protected void onDraw(Canvas canvas) {&lt;br /&gt;        if (mBitmap != null) {&lt;br /&gt;            Matrix matrix = new Matrix();&lt;br /&gt;         matrix.postScale(scale, scale);&lt;br /&gt;         canvas.drawBitmap(mBitmap, matrix, null);&lt;br /&gt;            //canvas.drawBitmap(mBitmap, 0,0, null);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    float lastX;&lt;br /&gt;    float lastY;&lt;br /&gt;    @Override public boolean onTouchEvent(MotionEvent event) {&lt;br /&gt;        mPaint.setStrokeWidth(width/scale);&lt;br /&gt;        &lt;br /&gt;        float curX =  event.getX()/scale;&lt;br /&gt;        float curY =  event.getY()/scale;&lt;br /&gt;  switch (event.getAction()){ &lt;br /&gt;   case MotionEvent.ACTION_DOWN:{&lt;br /&gt;             mCanvas.drawCircle(curX, curY,width/2/scale, mPaint);&lt;br /&gt;             break;&lt;br /&gt;   }&lt;br /&gt;   case MotionEvent.ACTION_MOVE:{&lt;br /&gt;    mCanvas.drawLine(lastX, lastY, curX, curY, mPaint);&lt;br /&gt;             mCanvas.drawCircle(curX, curY,width/2/scale, mPaint);  //fix for weird jaggies occur between line start and line stop&lt;br /&gt;             break;&lt;br /&gt;   } &lt;br /&gt;   case MotionEvent.ACTION_CANCEL:&lt;br /&gt;   case MotionEvent.ACTION_UP:{&lt;br /&gt;    mCanvas.drawLine(lastX, lastY, curX, curY, mPaint);&lt;br /&gt;             mCanvas.drawCircle(curX, curY,width/2/scale, mPaint);&lt;br /&gt;             break;&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;  lastX = curX;&lt;br /&gt;  lastY = curY;&lt;br /&gt;        invalidate();  //invalidate only modified rect...&lt;br /&gt;     &lt;br /&gt;     return true;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.html"&gt;TouchPaint&lt;/a&gt; was used extensively to figure out how to do this, along with the &lt;a href="http://developer.android.com/guide/topics/graphics/2d-graphics.html"&gt;standard 2d drawing doc&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;For me the most non-obvious part of the whole 2d drawing thing was how canvases work.  I originally didn't quite understand how a given canvas was linked to what was actually drawn on the screen.  In short you have your own canvas, in this case mCanvas, that operates on your own bitmap, mBitmap, then when the onDraw(Canvas) method is called, you copy your bitmap over to the canvas that method provides.  The canvas provided by onDraw is backed by the bitmap rendered to the screen, which is how your modifications actually make it to the screen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-7355878404066628612?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/7355878404066628612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=7355878404066628612' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/7355878404066628612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/7355878404066628612'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2009/08/drawable-image-view-in-android.html' title='Drawable Image View in Android'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-7096082174414488153</id><published>2009-07-15T20:22:00.000-07:00</published><updated>2009-07-17T20:09:22.465-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cisco'/><category scheme='http://www.blogger.com/atom/ns#' term='vlan'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='anonymous'/><category scheme='http://www.blogger.com/atom/ns#' term='random'/><category scheme='http://www.blogger.com/atom/ns#' term='MAC'/><category scheme='http://www.blogger.com/atom/ns#' term='802.11'/><category scheme='http://www.blogger.com/atom/ns#' term='wireless'/><category scheme='http://www.blogger.com/atom/ns#' term='anon'/><category scheme='http://www.blogger.com/atom/ns#' term='visitor'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><category scheme='http://www.blogger.com/atom/ns#' term='generator'/><title type='text'>Simple Hacking on Cisco WCS for Seamless Anonymous Browsing</title><content type='html'>My university has a Cisco network, which has all sorts of nice management features such as a wireless control system (WCS), vlans, CleanAccess, and I'm sure many more goodies.  The wireless network broadcasts two SSIDs: one is for people associated with the university, requires credentials, and puts you in the appropriate vlan, the other is for visitors and provides completely anonymous access.  The visitor network requires you to click a button to accept some University policy before you gain access, and this annoying redirect is reset every 6 hours or so.  This is particularly cumbersome because if I open Firefox before accepting the policy then it redirects every saved tab to the policy page, and then to the university homepage.&lt;br /&gt;&lt;br /&gt;I use the visitor network for various reasons, one is that because of some ridiculous network policies from the student vlan I can't get to some ports (svn, rdp, etc) on the DMZ vlan where I have a couple servers, despite the fact that 99% of the internet can access those ports.  I think this is being fixed, but until then I need to use the visitor network.  Also, I believe anonymous access to the internet is critical, but I am going to refrain from philosophical/political rants on a technical blog.&lt;br /&gt;&lt;br /&gt;Just to procrastinate real work I decided to attempt to automate the policy accept process, and thus save my Firefox tabs.&lt;br /&gt;&lt;br /&gt;I started by taking look at the policy page html and javascript, but it was a bit obtruse, so I went ahead and installed &lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt; and took a look at its "Net" tab.  Unfortunately since the policy page uses 20 gazillion different redirects, it kept changing pages before I could see what it was sending.  (If anyone knows a workaround for this please let me know; I tried enabling redirect warnings in the Firefox preferences, but it didn't help.)  &lt;br /&gt;&lt;br /&gt;So I changed my hosts file to point wirelessauth.university.edu to 127.0.0.1, and fired up netcat.  Turns out the policy page was accessing wirelessauth over ssl, so netcat was kind of useless.  This also meant packet sniffers would be useless...  So I just installed apache w/ ssl.  This worked like a charm and I was able to use Firebug to see that it was POSTing some stuff to https://wirelesssauth.university.edu/login.html:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;POST /login.html HTTP/1.1&lt;br /&gt;Host: wirelessauth.university.edu&lt;br /&gt;User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.8) Gecko/20090331&lt;br /&gt;00 Ubuntu/9.04 (jaunty) Firefox/3.0.8&lt;br /&gt;Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&lt;br /&gt;Accept-Language: en-us,en;q=0.5&lt;br /&gt;Accept-Encoding: gzip,deflate&lt;br /&gt;Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7&lt;br /&gt;Keep-Alive: 300&lt;br /&gt;Connection: keep-alive&lt;br /&gt;Referer: http://www.university.edu/it/network/visitor_wireless/?switch_url=https://wirelessauth.university.edu/login.html&amp;ap_mac=00:0b:85:7f:26:40&amp;wlan=Visitor&amp;redirect=woot.com/&lt;br /&gt;Cookie: __utma=64401068.180182089960766140.1247531434.1247531434.1247531434.1; __utmz=64401068.1247531434.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=64401068&lt;br /&gt;&lt;br /&gt;buttonClicked=4&amp;err_flag=0&amp;err_msg=&amp;info_flag=0&amp;info_msg=&amp;redirect_url=&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Notably it is sending all sorts of crap: cookies, host, referrer, url encoded values, etc.  I replicated everything except for the cookies and used wget to send a login request.  This worked just fine:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;wget --post-data="buttonClicked=4&amp;err_flag=0&amp;err_msg=&amp;info_flag=0&amp;info_msg=&amp;redirect_url=" --user-agent="Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.8) Gecko/2009033100 Ubuntu/9.04 (jaunty) Firefox/3.0.8" --referer="http://www.university.edu/it/network/visitor_wireless/?switch_url=https://wirelessauth.university.edu/login.html&amp;ap_mac=00:0b:85:7f:26:40&amp;wlan=Visitor&amp;redirect=woot.com/" http://wirelessauth.university.edu/login.html&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Turns out all you really need is:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;wget --post-data="buttonClicked=4" https://wirelessauth.university.edu/login.html&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Which is easy enough to remember :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I did leave out one little detail... that is how I was able to play with the policy/login page without having to wait 6 hours for it to timeout.  This is obvious for network guys, just disassociate from the wifi network and change your MAC address:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sudo ifconfig wlan0 down&lt;br /&gt;sudo ifconfig wlan0 hw ether ##:##:##:##:##:##&lt;br /&gt;sudo ifconfig wlan0 up&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;While disconnecting and forgetting a network in NetworkManager is relatively easy:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;gconftool-2 --recursive-unset /system/networking/connections/1&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I haven't figured out an easy way to add a connection from the cli.  It is pretty simple to associate to a wifi network with other command line tools, but I would like to go through gconf/NetworkManager.  This code snippet just removes the first remembered connection, there is probably a relatively easy way to do it by name too.&lt;br /&gt;&lt;br /&gt;Since I'm on an anonymous wireless network (and booting from a livecd for that matter) it would be nice to have a random MAC address too.  Putting it all together:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;gconftool-2 --recursive-unset /system/networking/connections/1&lt;br /&gt;&lt;br /&gt;sudo ifconfig wlan0 down&lt;br /&gt;&lt;br /&gt;#randomize...  Almost all legite MACs start with 00&lt;br /&gt;eth=00&lt;br /&gt;for i in `seq 1 5`; do&lt;br /&gt; eth=$eth:`head -c1 /dev/random |hexdump -e '1 "%x"'`&lt;br /&gt;done&lt;br /&gt;sudo ifconfig wlan0 hw ether $eth&lt;br /&gt;sudo ifconfig wlan0 up&lt;br /&gt;&lt;br /&gt;#need code to join network... for now just click, then do the wget manually&lt;br /&gt;#wget --post-data="buttonClicked=4" https://wirelessauth.university.edu/login.html&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;After concocting my random MAC address generator I realized somebody else probably already did it.  Sure enough &lt;a href="http://www.commandlinefu.com/commands/view/745/generat-a-random-mac-address"&gt;here&lt;/a&gt; is one of the first hits.  I like my method better because it actually uses the appropriate random number generator, not /proc/interrupts.  That example leaves off the first byte, which should be 0. Both because &lt;a href="http://standards.ieee.org/regauth/oui/oui.txt"&gt;most legitimate MAC addresses start with 00&lt;/a&gt;, and the 7th and 8th bits signify multi/unicast and global/local uniqueness.  Granted you could probably just do:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;MAC=00:`head /dev/urandom|md5sum| sed -r 's/^(.{10}).*$/\1/; s/([0-9a-f]{2})/\1:/g; s/:$//;'`&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;or:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;MAC=00:`head -c5 /dev/urandom|hexdump -e '"%x"'| sed -r 's/(..)/\1:/g; s/:$//;'`&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I'm using urandom rather than random because random can block, especially without mouse or keyboard movements.  I don't know how random md5sum is (probably more than enough for this application), but the second example doesn't use it.  Apparently bash also has a $RANDOM variable, but it is in decimal, not hex.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-7096082174414488153?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/7096082174414488153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=7096082174414488153' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/7096082174414488153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/7096082174414488153'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2009/07/simple-hacking-on-cisco-wcs-for.html' title='Simple Hacking on Cisco WCS for Seamless Anonymous Browsing'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-3964713866324999986</id><published>2009-06-20T22:19:00.000-07:00</published><updated>2009-06-29T22:25:04.812-07:00</updated><title type='text'>QualNet (Scalable Networks Technologies) Website and Issues</title><content type='html'>I had a number of issues with the &lt;a href="http://www.scalable-networks.com/"&gt;QualNet website&lt;/a&gt;, which ended up resulting in this email dated June 3rd to license@scalable-networks.com and&lt;br /&gt;evals@scalable-networks.com:&lt;br /&gt;&lt;br /&gt;&lt;quote&gt;Dear Scalable Networks,&lt;br /&gt;&lt;br /&gt;I recently signed up for a 30 day evaluation of QualNet.  When I log in I get a welcome message that states the following:&lt;br /&gt;&lt;br /&gt;"Thank you for evaluating QualNet. Your 30-day Evaluation License File has been generated and posted to your download page."&lt;br /&gt;&lt;br /&gt;However, when I go to the download page and click the link to the license file (http://www.scalable-networks.com/distributions/download/license/evals/qualnet-4.5.1-eval-2009.07.03.lic) I am immediately redirected to the sitemap (http://www.scalable-networks.com/sitemap.php).  Since I am on Linux/Firefox and was having other issues with your site (such as broken CSS suckerfish dropdown menus), I decided to try logging in on a Windows PC.&lt;br /&gt;&lt;br /&gt;This attempt was even more broken/disturbing, [since] as soon as I logged in I received a non-html page that stated:&lt;br /&gt;&lt;br /&gt;INSERT INTO ErrorLog (UID, address, SID, error, login, password) VALUES ('', '#.#.#.#', 'nodnhkck0rlkh0qc2442skijh5', 'Password is not correct', 'my@email.com', 'MyPassword'')&lt;br /&gt;&lt;br /&gt;Subsequent attempts to log in on the Windows machine do not even take me to the login page, they simply show this SQL query.  I initial[ly] thought my password was correct, however if you look closely there is an extra single quote at the end of it, which I must have hit while submitting the form with the enter key.  I had to clear my cookies in order to be able to log in correctly.  Unfortunately the license file link was still broken (as were the dropdown menus).&lt;br /&gt;&lt;br /&gt;In summary:&lt;br /&gt;&lt;br /&gt;1.  Your CSS suckerfish dropdown menus have extra pixels [between] them and the popup which causes them to break in Linux and Windows Firefox.&lt;br /&gt;2.  You are likely not sanitizing your user input before inserting it in to your SQL database, which is a huge security hole.&lt;br /&gt;3.  You are storing your passwords in plain-text which is a very, very, bad practice.  A simple SQL injection could potentially reveal every stored password.&lt;br /&gt;4.  You are sending passwords in plain-text over email which is not necessarily encrypted; this is also a very bad security practice.&lt;br /&gt;5.  And most importantly, I still cannot download my evaluation license file.  Please let me know what I need to do to get this.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thank You,&lt;br /&gt;&lt;br /&gt;Clayton Shepard&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;P.S.  &lt;a href="http://xkcd.com/327/"&gt;http://xkcd.com/327/&lt;/a&gt;&lt;br /&gt;&lt;/quote&gt;&lt;br /&gt;(I apologize for the typos, noted in brackets.  Clearly I removed my plaintext password, IP, and email.)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I guess I just find it ironic, and somewhat amusing, that a technology oriented company has such glaring flaws with their website and security.  In their defense they very promptly replied with the license file.  Also, the SQL table was just the "ErrorLog", which means they could still be using a hash for the actual passwords somewhere else; arguably this is still a security threat though, since mistyped passwords are likely very close to the original.  For &lt;a href="http://www.eff.org/issues/coders/grey-hat-guide"&gt;obvious reasons&lt;/a&gt; I did not try a SQL injection attack, so I can not verify whether or not that is actually a security hole (although my guess is that it is).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On entirely different note, I was unable to get QualNet 4.5 running on Ubuntu 9.04 AMD64 because of library issues.  In short they require gcc 4.0 and glibc2.3 or earlier to compile/install.  Getting glibc2.3 to run on 9.04 is a huge pain.  When asked, their official tech support reply is to &lt;a href="http://www.scalable-networks.com/forums/viewtopic.php?p=11191"&gt;use Ubuntu 6.06&lt;/a&gt; :(.  Unfortunate.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This reminds of the MSDNAA (MSDN Academic Alliance) website which also sends plaintext passwords in emails.  Sigh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-3964713866324999986?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/3964713866324999986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=3964713866324999986' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/3964713866324999986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/3964713866324999986'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2009/06/qualnet-scalable-networks-technologies.html' title='QualNet (Scalable Networks Technologies) Website and Issues'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-4295963232897995715</id><published>2009-06-17T23:21:00.000-07:00</published><updated>2009-08-21T09:39:03.148-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='psuedo terminal'/><category scheme='http://www.blogger.com/atom/ns#' term='progress'/><category scheme='http://www.blogger.com/atom/ns#' term='pty'/><category scheme='http://www.blogger.com/atom/ns#' term='zenity'/><category scheme='http://www.blogger.com/atom/ns#' term='scp'/><title type='text'>Showing scp's Progress Using zenity (pseudo terminal example)</title><content type='html'>I recently discovered zenity for making quick, straightforward, graphical interfaces for shell scripts.  One such script I wrote uses scp for backups.  Since scp prints its percentage progress to stdout I figured it would be pretty easy to simply use a regex to parse the output and pipe it to zenity.  I guessed this venture would take about ten minutes (I am not very experienced with regex), since zenity --progress just expects a number printed to its stdin in order to update the progress bar.  I couldn't have been more mistaken; after four hours of hacking and wtfs I gave up.  Finally, after a discussion with my old operating systems professor and a little bit of coding I finally have a solution.&lt;br /&gt;&lt;br /&gt;After piping scp's output to various c and perl programs I determined that the problem was probably a terminal mode problem.  A standard (canonical) terminal sends input to the program as lines, thus if there are never any new lines (such as in scp's output) the program would never receive the data. After figuring out how to put c (and perl) in to raw mode, as well as playing with stty, I managed to get a couple programs working that could read input before a newline was sent.  I tested these with stdin and pipes and they seemed to work fine, but they still wouldn't work with scp.  After a bit of debugging I figured out that when the data was piped to my c program I couldn't put the terminal in to raw mode.  Go figure, when you pipe data to a program it doesn't use a terminal... it uses a pipe (duh!).  This is the point where I gave up, as I didn't really feel like digging through the scp source code, and I certainly didn't want to run a modified copy of scp (that would kind of defeat the whole purpose).&lt;br /&gt;&lt;br /&gt;After discussing the problem with an old professor he hypothesized that scp was checking if it was being run on a terminal, and if it wasn't then it was disabling output.  Sure enough, &lt;a href="ftp://filedump.se.rit.edu/pub/OpenBSD/OpenSSH/portable/openssh-5.2p1.tar.gz"&gt;on line 396 of scp.c&lt;/a&gt;:&lt;br /&gt;&lt;code&gt;&lt;br /&gt; if (!isatty(STDOUT_FILENO))&lt;br /&gt;  showprogress = 0;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;As a possible solution he mentioned pseudo terminals.  Apparently back in the old days psuedo terminals were quite a pain since you had to find a free one manually before you could use it.  Luckily linux provides a convenient function, forkpty(), that finds a free pseudo terminal, forks a new process, and attaches the new process to the terminal.  Sweet.  Now with some simple fileio it works fine:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;main(int argc, char **argv) {&lt;br /&gt; int fd;&lt;br /&gt; pid_t pid;&lt;br /&gt; char c,c1,c2;&lt;br /&gt;&lt;br /&gt; if (argc != 3) {&lt;br /&gt;  printf("usage: [[user@]host1:]file1 [[user@]host2:]file2\n\nThis is a program that wraps scp and prints out the numeric progress on separate lines.\n");&lt;br /&gt;  fflush(stdout);&lt;br /&gt;  _exit(1);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; pid = forkpty (&amp;fd, NULL, NULL, NULL);&lt;br /&gt; if (pid == 0) {&lt;br /&gt;  execlp ("scp", "scp", argv[1], argv[2], (char *) NULL);&lt;br /&gt;  _exit (1);&lt;br /&gt; } else if (pid == -1) {&lt;br /&gt;  return 1;&lt;br /&gt; } else {&lt;br /&gt;  FILE *F;&lt;br /&gt;&lt;br /&gt;  F = fdopen (fd, "r");&lt;br /&gt;&lt;br /&gt;  //reading character by character isn't horribly efficient...&lt;br /&gt;  while((c = fgetc(F)) != -1) {&lt;br /&gt;   if (c == '%') {&lt;br /&gt;    if (c1 == ' ')&lt;br /&gt;     printf("%c\n", c2);  //one digit progess&lt;br /&gt;    else if (c1 == '0' &amp;&amp; c2 == '0')&lt;br /&gt;     printf("100\n"); //done&lt;br /&gt;    else&lt;br /&gt;     printf("%c%c\n", c1,c2); //two digit progress&lt;br /&gt;   }&lt;br /&gt;   fflush(stdout);&lt;br /&gt;   c1 = c2;&lt;br /&gt;   c2 = c;                   &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; fflush (F);&lt;br /&gt; wait (0);&lt;br /&gt; }&lt;br /&gt; return 0;&lt;br /&gt;} &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Notably, I went ahead and parsed the scp output in c.  It seemed to be a cleaner solution than piping this output to a perl script and then to zenity.  I initially missed the fflush() in the while loop, which took me a while to figure out :/.&lt;br /&gt;&lt;br /&gt;To compile it you need to use the -lutil switch.  So first copy and paste this c program in to scpwrap.c.  Then run "gcc -lutil scpwrap.c -oscpwrap".  Before you can use it you have to get rid of scp's authentication prompt by setting up some authentication keys:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ssh-keygen -t rsa&lt;br /&gt;cat .ssh/id_rsa.pub | ssh user@example.com 'cat &gt;&gt; .ssh/authorized_keys'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now to use the wrapper you can do something like:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;./scpwrap /home/ubuntu/somefile user@example.com:~ | zenity --progress&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Of course you can add whatever zenity switches you want.  You cannot, however, add any scp switches without modifying the c program... Sorry.&lt;br /&gt;&lt;br /&gt;---------------------Notes and Sources---------------------------&lt;br /&gt;&lt;br /&gt;Terminal raw mode "stty raw".&lt;br /&gt;&lt;br /&gt;Perl expression to parse the scp output:  &lt;br /&gt;&lt;code&gt;perl -015 -l -ne 'print /(\d+)%/'&lt;/code&gt;&lt;br /&gt;Notice the "-015" that tells it to use carriage returns as the line delimiter.  Pretty cool, it probably would have worked if scp wasn't checking if it was running on a terminal.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://search.cpan.org/dist/TermReadKey/ReadKey.pm"&gt;Perl code to put terminal in to raw mode:&lt;/a&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;use Term::ReadKey;&lt;br /&gt;&lt;br /&gt;ReadMode 5; # Turn off controls keys&lt;br /&gt;while (($key=getc) ) {&lt;br /&gt;  print "$key\n";&lt;br /&gt;  last if $key eq "q";&lt;br /&gt;}; &lt;br /&gt;print "Get key $key\n";&lt;br /&gt;ReadMode 0; # Reset tty mode before exiting&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://docs.linux.cz/programming/c/unix_examples/raw.html"&gt;C code to put terminal in to raw mode.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Zenity Progress Example 1:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(for a in `seq 1 100` ;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;do&lt;br /&gt;echo $a;&lt;br /&gt;sleep 0.03;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;done) | zenity --auto-close --progress \&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;--text="Slow counting from 1 to 100" \&lt;br /&gt;--title="Example Progress"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forums.fedoraforum.org/archive/index.php/t-79124.html"&gt;Zenity Progress Example 2:&lt;/a&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;(&lt;br /&gt;echo "10" ; sleep 1&lt;br /&gt;echo "# Updating mail logs" ; sleep 1&lt;br /&gt;echo "20" ; sleep 1&lt;br /&gt;echo "# Resetting cron jobs" ; sleep 1&lt;br /&gt;echo "50" ; sleep 1&lt;br /&gt;echo "This line will just be ignored" ; sleep 1&lt;br /&gt;echo "75" ; sleep 1&lt;br /&gt;echo "# Rebooting system" ; sleep 1&lt;br /&gt;echo "100" ; sleep 1&lt;br /&gt;) |&lt;br /&gt;zenity --progress \&lt;br /&gt;--title="Update System Logs" \&lt;br /&gt;--text="Scanning mail logs..." \&lt;br /&gt;--percentage=0&lt;br /&gt;&lt;br /&gt;if [ "$?" = -1 ] ; then&lt;br /&gt;zenity --error \&lt;br /&gt;--text="Update canceled."&lt;br /&gt;fi&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt; I modified the scp source (openssh5.2p1) to include a '-n' switch to print out the progress meter on new lines, regardless of whether stdout is a tty.  I proposed this new feature to the openssh-unix-dev listserv, but I doubt they will adopt it.  The email thread and patch can be found in their &lt;a href="http://lists.mindrot.org/pipermail/openssh-unix-dev/2009-June/027712.html"&gt;archives&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update 2:&lt;/span&gt;  Hrm, the pseudo terminal hack doesn't work if you run it from a launcher (kind of the whole point).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-4295963232897995715?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/4295963232897995715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=4295963232897995715' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4295963232897995715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4295963232897995715'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2009/06/showing-scp-progress-using-zenity.html' title='Showing scp&apos;s Progress Using zenity (pseudo terminal example)'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-6775279601555554350</id><published>2009-04-29T16:17:00.000-07:00</published><updated>2009-05-02T17:33:06.149-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LPT'/><category scheme='http://www.blogger.com/atom/ns#' term='DOS'/><category scheme='http://www.blogger.com/atom/ns#' term='serial port'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><category scheme='http://www.blogger.com/atom/ns#' term='VirtualBox'/><category scheme='http://www.blogger.com/atom/ns#' term='Printing'/><title type='text'>Printing from DOS in VirtualBox</title><content type='html'>&lt;a href="http://forums.virtualbox.org/viewtopic.php?t=320"&gt;VirtualBox doesn't support LPT ports.&lt;/a&gt;  DOS has limited ability to print to USB printers, and the program I am using definitely doesn't support it.  Thus I need to find an automatic, or at least semi-automatic, user friendly way to print from DOS.&lt;br /&gt;&lt;br /&gt;----------------------------------- The Mount Method -------------------------------------&lt;br /&gt;&lt;br /&gt;My first approach was to print to a file in DOS, then simply mount the .vdi and read/print the file.&lt;br /&gt;&lt;br /&gt;This has three drawbacks:&lt;br /&gt;&lt;br /&gt;1. You need sudo to mount the .vdi.&lt;br /&gt;2. You can't use it with snapshots or non fixed sized disks.&lt;br /&gt;3. I don't like mounting a disk that is already in use.&lt;br /&gt;&lt;br /&gt;The first problem can be solved by adding an entry in the fstab or using &lt;a href="http://fuse.sourceforge.net/"&gt;FUSE&lt;/a&gt;.  The second and third problems can be solved by printing to a floppy image and then mounting that instead.&lt;br /&gt;&lt;br /&gt;So the basic process is go to Devices and mount a floppy image, print to the floppy using filename "print", unmount the floppy, then run this script in Linux:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;#we need recode (sudo apt-get install recode)&lt;br /&gt;#add the floppy image to fstab to avoid sudo.&lt;br /&gt;#mount writable and erase the print file so DOS doesn't prompt to overwrite?&lt;br /&gt;&lt;br /&gt;mkdir -p ~/dosprint/printtemp&lt;br /&gt;sudo mount -o loop,ro ~/dosprint/flopppy.img ~/dosprint/printtemp/&lt;br /&gt;cp ~/printtemp/print ~/dosprint/printing&lt;br /&gt;recode IBM437/CR-LF ~/dosprint/printing&lt;br /&gt;lpr ~/dosprint/printing&lt;br /&gt;umount ~/dosprint/printtemp&lt;br /&gt;rmdir ~/dosprint/printtemp&lt;br /&gt;rm ~/dosprint/printing&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Notice that I am calling recode to convert the old DOS formatting. Obviously you will have to change floppy.img to match the floppy image you printed to.&lt;br /&gt;&lt;br /&gt;This isn't a terrible option, but it does make the user have to remember the exact filename to print to, or else the script won't work.  The whole mount/unmount process is a bit tedious too.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;----------------------------------- The Serial Port Method -------------------------------------&lt;br /&gt;&lt;br /&gt;To fix this I started looking at VirtualBox's COM emulation.  It can connect the VM's COM port to a socket on the filesystem (it calls it a pipe, but it is really a socket... I probably would have preferred a real pipe).  Anyway, after fiddling with it a bit I came up with a, hopefully, better solution.&lt;br /&gt;&lt;br /&gt;After enabling COM1 on the VM to output to a "pipe" start up the VM.  Then run &lt;code&gt;socat -u UNIX-CONNECT:$HOME/dosprint/printpipe GOPEN:$HOME/dosprint/printfile&lt;/code&gt; in a terminal.  You may have to do a 'sudo apt-get install socat' if it isn't already installed.  The DOS VM now can print to COM1.  After printing in DOS simply run this script:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;printfile="$HOME/dosprint/printfile"&lt;br /&gt;&lt;br /&gt;#check to make sure the file exists and is not empty.&lt;br /&gt;if [ ! -f $printfile ] || [ "`stat -c %s $printfile`" -le "1" ]; then&lt;br /&gt; zenity --error --text "The Print File is Empty or Does Not Exist\!"&lt;br /&gt; echo "" &gt; $printfile&lt;br /&gt; exit 1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;lpr $printfile&lt;br /&gt;&lt;br /&gt;#check to make sure it printed&lt;br /&gt;if [ "$?" -ne "0" ]; then&lt;br /&gt; zenity --error --text "Error Printing!"&lt;br /&gt; echo "" &gt; $printfile&lt;br /&gt; exit 1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;echo "" &gt; $printfile&lt;br /&gt;zenity --info --text "Printing\!"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;There are probably some better ways to use socat here, but this worked the best so far.  I would prefer to use a pipe, but it didn't work as expected.  Also notice I didn't have to use recode, which was nice; this however is dependent on the printer driver DOS is using.  In one incarnation I had to use dos2unix; unix2dos; then recode to get it to print properly.  (In Ubuntu dos2unix is in the package 'tofrodos'.)&lt;br /&gt;&lt;br /&gt;The biggest drawback here is that socat has to be run every time the VM is started, and you can't even run it as a startup script because it returns immediately unless the VM is running.  At least it gets rid of the mounting and naming issues.&lt;br /&gt;&lt;br /&gt;Here is a simple script to start the VM and run socat automatically:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;VirtualBox --startvm DOS&amp;amp;&lt;br /&gt;echo "" &gt; ~/dosprint/printfile&lt;br /&gt;sleep 5&lt;br /&gt;socat -u UNIX-CONNECT:$HOME/dosprint/printpipe GOPEN:$HOME/dosprint/printfile&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You can create a launcher (right click desktop or nautilus window) if you want to be able to open this script without being prompted to run in terminal or display.&lt;br /&gt;&lt;br /&gt;P.S.  &lt;a href="http://live.gnome.org/Zenity"&gt;Zenity&lt;/a&gt; &lt;a href="http://www.freesoftwaremagazine.com/columns/saving_my_sanity_zenity_shell_script_interaction_gui"&gt;is very nice :)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a href="http://automatthias.wordpress.com/"&gt;Maciej Bliziński&lt;/a&gt; for &lt;a href="http://automatthias.wordpress.com/2008/09/13/serial-port-in-virtualbox/"&gt;some nice info on VirtualBox's serial port pipes&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Update:  I ended up using iconv rather than recode, since recode had some problems with some special characters.  Careful with iconv, it changed between the version on Ubuntu 8.04 and 8.10 (mainly the overwrite in place functionality).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-6775279601555554350?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/6775279601555554350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=6775279601555554350' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/6775279601555554350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/6775279601555554350'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2009/04/printing-from-dos-in-virtualbox.html' title='Printing from DOS in VirtualBox'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-4267190136443105436</id><published>2009-04-27T13:12:00.000-07:00</published><updated>2009-04-30T16:59:20.171-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sfdisk'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><category scheme='http://www.blogger.com/atom/ns#' term='fdisk'/><category scheme='http://www.blogger.com/atom/ns#' term='VirtualBox'/><category scheme='http://www.blogger.com/atom/ns#' term='mount'/><category scheme='http://www.blogger.com/atom/ns#' term='xen'/><title type='text'>Mount Xen and VirtualBox Images in Linux</title><content type='html'>If you use Xen disk images then you can mount them fairly easily to directly modify them on dom0 or another system:&lt;br /&gt;&lt;br /&gt;Use "fdisk -luC 530 WinXP.disk" to print the partition table of the disk (where WinXP.disk is your disk image...).&lt;br /&gt;Then multiply sector size by the sector start of the partition you want, then simply mount using that offset:&lt;br /&gt;"sudo mount -o loop,offset=32256 WinXP.disk /media/mountpoint"&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;code&gt;fdisk -luC 530 WinXP.disk &lt;br /&gt;&lt;br /&gt;Disk WinXP.disk: 0 MB, 0 bytes&lt;br /&gt;255 heads, 63 sectors/track, 530 cylinders, total 0 sectors&lt;br /&gt;Units = sectors of 1 * 512 = 512 bytes&lt;br /&gt;Disk identifier: 0x6c896c89&lt;br /&gt;&lt;br /&gt;     Device Boot      Start         End      Blocks   Id  System&lt;br /&gt;WinXP.disk1   *          63    41913584    20956761    7  HPFS/NTFS&lt;br /&gt;Partition 1 has different physical/logical endings:&lt;br /&gt;     phys=(1023, 254, 63) logical=(2608, 254, 63)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Then 63 sectors * 512 bytes per sector =32256, so:&lt;br /&gt;&lt;code&gt;sudo mount -o loop,offset=32256 WinXP.disk /media/mountpoint&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This info was found &lt;a href="http://www.novell.com/communities/node/2638/how-mount-specific-partition-xen-file-backed-virtual-disk"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In VirtualBox the operation is similar, but since the .vdi format is different you have to jump through another hoop.  Note this only works with fixed size images.  First you have to find the start of the disk, then use that to find the start of the partition:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;od -j344 -N4 -td4 image.vdi | awk 'NR==1{print $2;}'&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now use the number it returns as #offset# in:&lt;br /&gt;&lt;code&gt;dd if=image.vdi of=vdstart bs=1 skip=#offset# count=1b&lt;br /&gt;/sbin/sfdisk -luS vdstart&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This takes the partition table of the virtual disk, dumps it to a file, then reads the partition table to tell you where the partition starts.  Now the process is similar to Xen, multiply the sector size by the sector offset of the partition to find the start of the partition, but you also have to add the vdi offset you found before.  You can then use that offset to mount the partition:&lt;br /&gt;&lt;code&gt;mount -o loop,offset=39424,ro image.vdi /media/image/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;For Example:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ od -j344 -N4 -td4 DOS.vdi | awk 'NR==1{print $2;}'&lt;br /&gt;7168&lt;br /&gt;$ dd if=DOS.vdi of=vdstart bs=1 skip=7168 count=1b&lt;br /&gt;512+0 records in&lt;br /&gt;512+0 records out&lt;br /&gt;512 bytes (512 B) copied, 0.00523881 s, 97.7 kB/s&lt;br /&gt;$sfdisk -luS vdstart &lt;br /&gt;Disk vdstart: cannot get geometry&lt;br /&gt;&lt;br /&gt;Disk vdstart: 0 cylinders, 255 heads, 63 sectors/track&lt;br /&gt;Warning: The partition table looks like it was made&lt;br /&gt;  for C/H/S=*/64/63 (instead of 0/255/63).&lt;br /&gt;For this listing I'll assume that geometry.&lt;br /&gt;Units = sectors of 512 bytes, counting from 0&lt;br /&gt;&lt;br /&gt;   Device Boot    Start       End   #sectors  Id  System&lt;br /&gt; vdstart1   *        63   3253823    3253761   6  FAT16&lt;br /&gt; vdstart2             0         -          0   0  Empty&lt;br /&gt; vdstart3             0         -          0   0  Empty&lt;br /&gt; vdstart4             0         -          0   0  Empty&lt;br /&gt;$sudo mount -o loop,offset=39424,ro DOS.vdi /media/dos/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The mount offset was calculated by: 7168 (vdi header) + 63 (sectors) * 512 (bytes per sector) = 39424&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Works like a charm :)  Thanks &lt;a href="http://przemoc.net"&gt;Przemoc&lt;/a&gt;.  More info can be found &lt;a href="http://wiki.przemoc.net/tips/linux#mounting_partition_from_vdi_fixed-size_image"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I am still looking for a way to do it with Snapshots though :/.  On a different note, &lt;a href="http://www.linux.com/feature/151029"&gt;this&lt;/a&gt; looks like it could be useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-4267190136443105436?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/4267190136443105436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=4267190136443105436' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4267190136443105436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4267190136443105436'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2009/04/mount-xen-and-virtualbox-images-in.html' title='Mount Xen and VirtualBox Images in Linux'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-5279454833268700155</id><published>2009-04-12T15:02:00.000-07:00</published><updated>2009-11-02T23:17:32.030-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpa_supplicant.conf'/><category scheme='http://www.blogger.com/atom/ns#' term='HTC Dream'/><category scheme='http://www.blogger.com/atom/ns#' term='wpa_supplicant'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='Enterprise'/><category scheme='http://www.blogger.com/atom/ns#' term='WPA'/><category scheme='http://www.blogger.com/atom/ns#' term='G1'/><title type='text'>WPA Enterprise on Android HTC G1 Dream</title><content type='html'>Unfortunately Android still does not have a GUI interface for connecting to corporate/enterprise networks; however, it does support it.  While this isn't a solution for most users, it is fairly easy for those who have already rooted their phone or aren't scared of the command line.&lt;br /&gt;&lt;br /&gt;First, you need to root your phone or else you can't get to the files you need to configure.  Newer firmwares aren't as easy to root as older ones; either way &lt;a href="http://forum.xda-developers.com/showthread.php?t=442480"&gt;this&lt;/a&gt; tutorial should walk you through what you need to do.  It is very user friendly, and if you have any problems then it is probably addressed later in the forum comments.  I had two problems when I did it:&lt;br /&gt;&lt;br /&gt;1) I skipped the reformatting of the SD card since mine was already FAT.  For some reason the phone needs FAT32 in order to recognize boot files... So don't skip this step.&lt;br /&gt;&lt;br /&gt;2) The first link, and corresponding MD5 sum, to the modified OS images are to the BuildEnvironments rather than the actual OS image.  Just go to the second link and download the actual image (it will be a zip file and 40.5MB rather than a .tar.gz that is 7.5MB).  Hopefully Koush will update the post and fix this.&lt;br /&gt;&lt;br /&gt;Anyway, after your device is rooted pull up a command prompt on the phone somehow.  If you already know how to do this then skip ahead.  You have a couple options:&lt;br /&gt;&lt;br /&gt;1)  &lt;span style="font-weight:bold;"&gt;All on the phone:&lt;/span&gt; I am pretty sure the terminal emulator comes pre-installed on that image.  If not then you can just download it from the Market.  You can just use this, but I wouldn't recommend it unless you really like typing on your phone.&lt;br /&gt;&lt;br /&gt;2)  &lt;span style="font-weight:bold;"&gt;Through telnetd:&lt;/span&gt;  Use the terminal emulator then type "su" then enter.  This will pull up the super user whitelist prompt.  Tell it "Yes" that is okay for the Terminal to run as super user.  Meanwhile the terminal may timeout, in which case you need to type it again.  You can that you are root by running "whoami" which will tell you that you are uid 0 if you are root.  Make sure the phone is connected to wifi.  You can get the IP from the Wireless gui or running "ip a". Now run "telnetd".  From another computer on the network run "telnet #android_IP#" where #android_IP# is the IP of the phone.&lt;br /&gt;&lt;br /&gt;3)  &lt;span style="font-weight:bold;"&gt;Using the debugger:&lt;/span&gt; This involves doing &lt;a href="http://developer.android.com/guide/developing/device.html"&gt;this&lt;/a&gt; then looking at &lt;a href="http://developer.android.com/guide/developing/debug-tasks.html"&gt;this&lt;/a&gt;.  If your device is all set up and plugged in to a computer this entails basically running "adb shell".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now all you have to do is edit the /data/misc/wifi/wpa_supplicant.conf file.  You can do this by copying it to your sdcard, editing it on a computer, then copying it back.  I prefer just to edit in place.  &lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt;  Sorry I forgot to mention you need to run "su" first, or else you will get permission denied errors.&lt;br /&gt;&lt;br /&gt;Regardless, you probably first want to backup the existing wpa_supplicant.conf file:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cd /data/misc/wifi/&lt;br /&gt;cp wpa_supplicant.conf wpa_supplicant.conf.orig&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To copy to sdcard (make sure you have one in there):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cd /data/mis/wifi/&lt;br /&gt;cp wpa_supplicant.conf /sdcard&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To edit in place:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cd /data/mis/wifi/&lt;br /&gt;vi wpa_supplicant.conf&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The wpa_supplicant file will contain all of your remembered wifi networks.  Something like:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ctrl_interface=tiwlan0&lt;br /&gt;update_config=1&lt;br /&gt;&lt;br /&gt;network={&lt;br /&gt;    ssid="linksys"&lt;br /&gt;    key_mgmt=NONE&lt;br /&gt;   priority=11&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now add the parameters for your network.  Many schools/business will provide this config for you, so you can just copy it over.  Mine looks like:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ctrl_interface=tiwlan0&lt;br /&gt;update_config=1&lt;br /&gt;&lt;br /&gt;eapol_version=1&lt;br /&gt;fast_reauth=1&lt;br /&gt;network={&lt;br /&gt;    ssid="Some SSID"&lt;br /&gt;    scan_ssid=1&lt;br /&gt;    key_mgmt=WPA-EAP&lt;br /&gt;    eap=TTLS&lt;br /&gt;    identity="USERID"&lt;br /&gt;    password="PASSWORD"&lt;br /&gt;    phase2="auth=PAP"&lt;br /&gt;    priority=1&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;network={&lt;br /&gt;    ssid="linksys"&lt;br /&gt;    key_mgmt=NONE&lt;br /&gt;   priority=11&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This will now make "Some SSID" show up as remembered on the WiFi config GUI screen, and when in range, if everything is configured right, it will connect automatically.  Note that in this case my password is stored in plain text on a file in my phone.  This is bad, but I'm not sure there is a way around it at this point.&lt;br /&gt;&lt;br /&gt;More information on how to configure this can be found &lt;a href="http://hostap.epitest.fi/gitweb/gitweb.cgi?p=hostap.git;a=blob_plain;f=wpa_supplicant/README"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Notably Android automatically deleted the eapol_version=1 and fast_reauth=1 lines, however it still works fine.&lt;br /&gt;&lt;br /&gt;There is a relate Google code issue &lt;a href="http://code.google.com/p/android/issues/detail?id=1386"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt;  I am having problems with the phone rapidly associating and disassociating from every AP in range.  I filed a bug report &lt;a href="http://code.google.com/p/android/issues/detail?id=2434"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt;  This is fixed in Haykuro's latest &lt;a href="http://code.google.com/p/sapphire-port-dream/"&gt;build&lt;/a&gt;.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Update:&lt;/span&gt;  Allegedly there is a program in the market that can do all of this from a GUI (although you still need a rooted phone).  It is called Wifi Helper by Fan Zhang; I haven't tested it personally yet.  I kind of doubt it fixes the AP hopping issue on older versions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-5279454833268700155?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/5279454833268700155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=5279454833268700155' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/5279454833268700155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/5279454833268700155'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2009/04/wpa-enterprise-on-android-htc-g1-dream.html' title='WPA Enterprise on Android HTC G1 Dream'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-4796773378919371031</id><published>2009-02-09T05:36:00.000-08:00</published><updated>2009-02-09T06:36:40.616-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='5V'/><category scheme='http://www.blogger.com/atom/ns#' term='Nokia'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='E71'/><category scheme='http://www.blogger.com/atom/ns#' term='Charger'/><category scheme='http://www.blogger.com/atom/ns#' term='N810'/><title type='text'>WTF Nokia?  N810 and E71 Won't Charge from USB?</title><content type='html'>This is completely retarded.  It almost makes them unusable.  Even worse, the frakin charger is is 5v... I'm half tempted to tear the devices open and put a trace wire from the usb connector to the charger connector so it will automatically charge.  I like being able to use my laptop as a backup battery for my other devices.  I like being able to use one cord to charge any device.  I like being able to carry a small generic cord that I can plug in to the front of any computer rather than a large charger that I have to dig under the desk to plug in...&lt;br /&gt;&lt;br /&gt;It doesn't matter how awesome your device is, but you can really piss people off if you do something stupid like this.  On that note, why the hell doesn't the iPhone support A2DP (or HID, or USB Mass Storage, or SD...)?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ugh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-4796773378919371031?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/4796773378919371031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=4796773378919371031' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4796773378919371031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4796773378919371031'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2009/02/wtf-nokia-n810-and-e71-wont-charge-from.html' title='WTF Nokia?  N810 and E71 Won&apos;t Charge from USB?'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-2795330229509603660</id><published>2009-02-09T04:49:00.000-08:00</published><updated>2011-07-07T17:03:57.966-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PDF'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Form'/><category scheme='http://www.blogger.com/atom/ns#' term='Vcard'/><category scheme='http://www.blogger.com/atom/ns#' term='Attachment'/><category scheme='http://www.blogger.com/atom/ns#' term='Email'/><category scheme='http://www.blogger.com/atom/ns#' term='Paper'/><category scheme='http://www.blogger.com/atom/ns#' term='FDF'/><category scheme='http://www.blogger.com/atom/ns#' term='ADOBE'/><category scheme='http://www.blogger.com/atom/ns#' term='MIME'/><title type='text'>Forms:  FDF, PDF, and PHP</title><content type='html'>I have always been somewhat opposed to PDF documents.  While they are great for cross-platform viewing and printing, the inability to edit them without buying special software was philosophically unacceptable.  Also, not being able to save forms you fill out is really stupid.  While there are some free alternatives now, they are really a kind of pain in the ass compared to Adobe Professional.   So, unfortunately, that is what I used to get this to work quickly and easily.  Thanks to &lt;a href="http://koivi.com/"&gt;Justin Koivisto&lt;/a&gt;, who's &lt;a href="http://koivi.com/fill-pdf-form-fields/tutorial.php"&gt;tutorial&lt;/a&gt; really helped.&lt;br /&gt;&lt;br /&gt;For those of you that don't know (as I didn't before starting this project), FDF files are used to save filled out PDF forms, however they don't store the original PDF document.  Instead the FDF file just has a pointer to the PDF document which can either be on the local computer or on the web.&lt;br /&gt;&lt;br /&gt;So here is the scenario:&lt;br /&gt;&lt;br /&gt;1)  User fills out an online form.&lt;br /&gt;2)  PHP parses the form, and creates a VCard as well as an FDF.&lt;br /&gt;3)  PHP emails the files as attachments, and displays the filled out PDF for the user to print.&lt;br /&gt;&lt;br /&gt;This is very useful for populating PDF forms that already exist, and may be in use in paper form.  This makes it easy to transition to an electronic system.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The first step is a standard HTML form that will submit the data to a PHP script (application.html):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;              &amp;lt;html&amp;gt;&lt;br /&gt; &amp;lt;body&amp;gt;&lt;br /&gt;  &amp;lt;form method="post" action="./submit.php"&amp;gt;&lt;br /&gt;    &amp;lt;table&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;First Name&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="firstName" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Last Name&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="lastName" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mobile Phone Number&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="mobilePhone" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Home Phone Number&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="homePhone" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;E-Mail&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="email" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Date of Birth (MM-DD-YYYY)&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="dobMonth" maxlength="2" size="2"/&amp;gt;-&amp;lt;input type="text" name="dobDay" maxlength="2" size="2"/&amp;gt;-&amp;lt;input type="text" name="dobYear" maxlength="4" size="4"/&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Address&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="address" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;City&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="city" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;State&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="state" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Zip Code&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="zip" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;     &amp;lt;!--&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;--&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Age&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type="text" name="age" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;    &amp;lt;/table&amp;gt;&lt;br /&gt;    &amp;lt;input type="submit" value="Submit" /&amp;gt;&lt;br /&gt;  &amp;lt;/form&amp;gt;&lt;br /&gt; &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next is the PHP script to create the VCard and FDF, emails them, and displays the FDF (submit.php):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt; include("./vcard.php");&lt;br /&gt; include("./fdf.php");&lt;br /&gt; include ("./mail_attachment.php");&lt;br /&gt; &lt;br /&gt; $emailto = "someone@example.com";&lt;br /&gt; &lt;br /&gt; //The pdf file that the fdf file points to:&lt;br /&gt; $pdf_doc='http://example.com/application.pdf';&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; //We need to check POST variables to make sure the form was submitted correctly, we should also make sure they don't enter more than one email address, and that they enter an email address&lt;br /&gt;/*&lt;br /&gt; if(isset($_POST["firstName"])) {&lt;br /&gt; echo $_POST["firstName"];&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt;  echo "BAD!!!!";&lt;br /&gt;*/&lt;br /&gt; $v = new vCard();&lt;br /&gt;&lt;br /&gt; $v-&amp;gt;setPhoneNumber($_POST["mobilePhone"], "PREF;CELL;VOICE");&lt;br /&gt; $v-&amp;gt;setPhoneNumber($_POST["homePhone"], "PREF;HOME;VOICE");&lt;br /&gt; $v-&amp;gt;setName($_POST["lastName"], $_POST["firstName"], "", "");&lt;br /&gt; $v-&amp;gt;setBirthday($_POST["dobYear"]."-".$_POST["dobMonth"]."-".$_POST["dobDat"]);&lt;br /&gt; $v-&amp;gt;setAddress("", "", $_POST["address"], $_POST["city"], $_POST["state"], $_POST["zip"], "US");&lt;br /&gt; $v-&amp;gt;setEmail($_POST["email"]);&lt;br /&gt; //$v-&amp;gt;setNote("You can take some notes here.\r\nMultiple lines are supported via \\r\\n.");&lt;br /&gt; //$v-&amp;gt;setURL("http://www.thomas-mustermann.de", "WORK");&lt;br /&gt;/*&lt;br /&gt; $output = $v-&amp;gt;getVCard();&lt;br /&gt; $filename = $v-&amp;gt;getFileName();&lt;br /&gt;&lt;br /&gt; Header("Content-Disposition: attachment; filename=$filename");&lt;br /&gt; Header("Content-Length: ".strlen($output));&lt;br /&gt; Header("Connection: close");&lt;br /&gt; Header("Content-Type: text/x-vCard; name=$filename");&lt;br /&gt;&lt;br /&gt; echo $output;*/&lt;br /&gt; &lt;br /&gt; /*$outfdf = fdf_create();&lt;br /&gt; fdf_set_value($outfdf, "volume", $volume, 0);&lt;br /&gt;&lt;br /&gt; fdf_set_file($outfdf, "http:/testfdf/resultlabel.pdf");&lt;br /&gt; fdf_save($outfdf, "outtest.fdf");&lt;br /&gt; fdf_close($outfdf);&lt;br /&gt; Header("Content-type: application/vnd.fdf");&lt;br /&gt; $fp = fopen("outtest.fdf", "r");&lt;br /&gt; fpassthru($fp);&lt;br /&gt; unlink("outtest.fdf");*/&lt;br /&gt; &lt;br /&gt; foreach($_POST as $name =&amp;gt; $val) {&lt;br /&gt;  $data[$name] = $val;&lt;br /&gt;  //echo $name."&amp;lt;br/&amp;gt;";&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; // generate the file content&lt;br /&gt; $fdf_data=createFDF($pdf_doc,$data);&lt;br /&gt; $attachments[0]['data']=$v-&amp;gt;getVCard();&lt;br /&gt; $attachments[0]['filename']=$_POST['firstName'].$_POST['lastName'].".vcf";&lt;br /&gt; $attachments[0]['mime']="text/x-vcard";&lt;br /&gt; &lt;br /&gt; $attachments[1]['data']=$fdf_data;&lt;br /&gt; $attachments[1]['filename']=$_POST['firstName'].$_POST['lastName'].".fdf";&lt;br /&gt; $attachments[1]['mime']="application/vnd.fdf";&lt;br /&gt; &lt;br /&gt; $from=$_POST['firstName']." ".$_POST['lastName']." &amp;lt;".$_POST['email']."&amp;gt;";&lt;br /&gt; &lt;br /&gt; mail_attachment($from,$emailto,"Rental Application", "Lease: from ".$_POST['leaseStart']." to ".$_POST['leaseEnd'], $attachments);&lt;br /&gt; Header("Content-type: application/vnd.fdf");&lt;br /&gt; echo $fdf_data;&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This shows an example of how to use the multi-attachment email script shown below. We should be checking the POST inputs to make sure someone isn't trying to do something nasty, there could be a security problem there.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Notably, there included files that you need.  The first is the VCard creator (vcard.php):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?&lt;br /&gt;&lt;br /&gt;/***************************************************************************&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PHP vCard class v2.0&lt;br /&gt;&lt;br /&gt;(c) Kai Blankenhorn&lt;br /&gt;&lt;br /&gt;www.bitfolge.de/en&lt;br /&gt;&lt;br /&gt;kaib@bitfolge.de&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This program is free software; you can redistribute it and/or&lt;br /&gt;&lt;br /&gt;modify it under the terms of the GNU General Public License&lt;br /&gt;&lt;br /&gt;as published by the Free Software Foundation; either version 2&lt;br /&gt;&lt;br /&gt;of the License, or (at your option) any later version.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This program is distributed in the hope that it will be useful,&lt;br /&gt;&lt;br /&gt;but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;&lt;br /&gt;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;&lt;br /&gt;GNU General Public License for more details.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You should have received a copy of the GNU General Public License&lt;br /&gt;&lt;br /&gt;along with this program; if not, write to the Free Software&lt;br /&gt;&lt;br /&gt;Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;***************************************************************************/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function encode($string) {&lt;br /&gt;&lt;br /&gt; return escape(quoted_printable_encode($string));&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function escape($string) {&lt;br /&gt;&lt;br /&gt; return str_replace(";","\;",$string);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// taken from PHP documentation comments&lt;br /&gt;&lt;br /&gt;function quoted_printable_encode($input, $line_max = 76) {&lt;br /&gt;&lt;br /&gt; $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');&lt;br /&gt;&lt;br /&gt; $lines = preg_split("/(?:\r\n|\r|\n)/", $input);&lt;br /&gt;&lt;br /&gt; $eol = "\r\n";&lt;br /&gt;&lt;br /&gt; $linebreak = "=0D=0A";&lt;br /&gt;&lt;br /&gt; $escape = "=";&lt;br /&gt;&lt;br /&gt; $output = "";&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; for ($j=0;$j&amp;lt;count($lines);$j++) {&lt;br /&gt;&lt;br /&gt;  $line = $lines[$j];&lt;br /&gt;&lt;br /&gt;  $linlen = strlen($line);&lt;br /&gt;&lt;br /&gt;  $newline = "";&lt;br /&gt;&lt;br /&gt;  for($i = 0; $i &amp;lt; $linlen; $i++) {&lt;br /&gt;&lt;br /&gt;   $c = substr($line, $i, 1);&lt;br /&gt;&lt;br /&gt;   $dec = ord($c);&lt;br /&gt;&lt;br /&gt;   if ( ($dec == 32) &amp;&amp; ($i == ($linlen - 1)) ) { // convert space at eol only&lt;br /&gt;&lt;br /&gt;    $c = "=20"; &lt;br /&gt;&lt;br /&gt;   } elseif ( ($dec == 61) || ($dec &amp;lt; 32 ) || ($dec &amp;gt; 126) ) { // always encode "\t", which is *not* required&lt;br /&gt;&lt;br /&gt;    $h2 = floor($dec/16); $h1 = floor($dec%16); &lt;br /&gt;&lt;br /&gt;    $c = $escape.$hex["$h2"].$hex["$h1"]; &lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   if ( (strlen($newline) + strlen($c)) &amp;gt;= $line_max ) { // CRLF is not counted&lt;br /&gt;&lt;br /&gt;    $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay&lt;br /&gt;&lt;br /&gt;    $newline = "    ";&lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   $newline .= $c;&lt;br /&gt;&lt;br /&gt;  } // end of for&lt;br /&gt;&lt;br /&gt;  $output .= $newline;&lt;br /&gt;&lt;br /&gt;  if ($j&amp;lt;count($lines)-1) $output .= $linebreak;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return trim($output);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class vCard {&lt;br /&gt;&lt;br /&gt; var $properties;&lt;br /&gt;&lt;br /&gt; var $filename;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; function setPhoneNumber($number, $type="") {&lt;br /&gt;&lt;br /&gt; // type may be PREF | WORK | HOME | VOICE | FAX | MSG | CELL | PAGER | BBS | CAR | MODEM | ISDN | VIDEO or any senseful combination, e.g. "PREF;WORK;VOICE"&lt;br /&gt;&lt;br /&gt;  $key = "TEL";&lt;br /&gt;&lt;br /&gt;  if ($type!="") $key .= ";".$type;&lt;br /&gt;&lt;br /&gt;  $key.= ";ENCODING=QUOTED-PRINTABLE";&lt;br /&gt;&lt;br /&gt;  $this-&amp;gt;properties[$key] = quoted_printable_encode($number);&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; // UNTESTED !!!&lt;br /&gt;&lt;br /&gt; function setPhoto($type, $photo) { // $type = "GIF" | "JPEG"&lt;br /&gt;&lt;br /&gt;  $this-&amp;gt;properties["PHOTO;TYPE=$type;ENCODING=BASE64"] = base64_encode($photo);&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; function setFormattedName($name) {&lt;br /&gt;&lt;br /&gt;  $this-&amp;gt;properties["FN"] = quoted_printable_encode($name);&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; function setName($family="", $first="", $additional="", $prefix="", $suffix="") {&lt;br /&gt;&lt;br /&gt;  $this-&amp;gt;properties["N"] = "$family;$first;$additional;$prefix;$suffix";&lt;br /&gt;&lt;br /&gt;  $this-&amp;gt;filename = "$first%20$family.vcf";&lt;br /&gt;&lt;br /&gt;  if ($this-&amp;gt;properties["FN"]=="") $this-&amp;gt;setFormattedName(trim("$prefix $first $additional $family $suffix"));&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; function setBirthday($date) { // $date format is YYYY-MM-DD&lt;br /&gt;&lt;br /&gt;  $this-&amp;gt;properties["BDAY"] = $date;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; function setAddress($postoffice="", $extended="", $street="", $city="", $region="", $zip="", $country="", $type="HOME;POSTAL") {&lt;br /&gt;&lt;br /&gt; // $type may be DOM | INTL | POSTAL | PARCEL | HOME | WORK or any combination of these: e.g. "WORK;PARCEL;POSTAL"&lt;br /&gt;&lt;br /&gt;  $key = "ADR";&lt;br /&gt;&lt;br /&gt;  if ($type!="") $key.= ";$type";&lt;br /&gt;&lt;br /&gt;  $key.= ";ENCODING=QUOTED-PRINTABLE";&lt;br /&gt;&lt;br /&gt;  $this-&amp;gt;properties[$key] = encode($name).";".encode($extended).";".encode($street).";".encode($city).";".encode($region).";".encode($zip).";".encode($country);&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;  if ($this-&amp;gt;properties["LABEL;$type;ENCODING=QUOTED-PRINTABLE"] == "") {&lt;br /&gt;&lt;br /&gt;   //$this-&amp;gt;setLabel($postoffice, $extended, $street, $city, $region, $zip, $country, $type);&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; function setLabel($postoffice="", $extended="", $street="", $city="", $region="", $zip="", $country="", $type="HOME;POSTAL") {&lt;br /&gt;&lt;br /&gt;  $label = "";&lt;br /&gt;&lt;br /&gt;  if ($postoffice!="") $label.= "$postoffice\r\n";&lt;br /&gt;&lt;br /&gt;  if ($extended!="") $label.= "$extended\r\n";&lt;br /&gt;&lt;br /&gt;  if ($street!="") $label.= "$street\r\n";&lt;br /&gt;&lt;br /&gt;  if ($zip!="") $label.= "$zip ";&lt;br /&gt;&lt;br /&gt;  if ($city!="") $label.= "$city\r\n";&lt;br /&gt;&lt;br /&gt;  if ($region!="") $label.= "$region\r\n";&lt;br /&gt;&lt;br /&gt;  if ($country!="") $country.= "$country\r\n";&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;  $this-&amp;gt;properties["LABEL;$type;ENCODING=QUOTED-PRINTABLE"] = quoted_printable_encode($label);&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; function setEmail($address) {&lt;br /&gt;&lt;br /&gt;  $this-&amp;gt;properties["EMAIL;INTERNET"] = $address;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; function setNote($note) {&lt;br /&gt;&lt;br /&gt;  $this-&amp;gt;properties["NOTE;ENCODING=QUOTED-PRINTABLE"] = quoted_printable_encode($note);&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; function setURL($url, $type="") {&lt;br /&gt;&lt;br /&gt; // $type may be WORK | HOME&lt;br /&gt;&lt;br /&gt;  $key = "URL";&lt;br /&gt;&lt;br /&gt;  if ($type!="") $key.= ";$type";&lt;br /&gt;&lt;br /&gt;  $this-&amp;gt;properties[$key] = $url;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; function getVCard() {&lt;br /&gt;&lt;br /&gt;  $text = "BEGIN:VCARD\r\n";&lt;br /&gt;&lt;br /&gt;  $text.= "VERSION:2.1\r\n";&lt;br /&gt;&lt;br /&gt;  foreach($this-&amp;gt;properties as $key =&amp;gt; $value) {&lt;br /&gt;&lt;br /&gt;   $text.= "$key:$value\r\n";&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  $text.= "REV:".date("Y-m-d")."T".date("H:i:s")."Z\r\n";&lt;br /&gt;&lt;br /&gt;  //$text.= "MAILER:PHP vCard class\r\n";&lt;br /&gt;&lt;br /&gt;  $text.= "END:VCARD\r\n";&lt;br /&gt;&lt;br /&gt;  return $text;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; function getFileName() {&lt;br /&gt;&lt;br /&gt;  return $this-&amp;gt;filename;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//  USAGE EXAMPLE&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;&lt;br /&gt;$v = new vCard();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$v-&amp;gt;setPhoneNumber("+49 23 456789", "PREF;HOME;VOICE");&lt;br /&gt;&lt;br /&gt;$v-&amp;gt;setName("Mustermann", "Thomas", "", "Herr");&lt;br /&gt;&lt;br /&gt;$v-&amp;gt;setBirthday("1960-07-31");&lt;br /&gt;&lt;br /&gt;$v-&amp;gt;setAddress("", "", "Musterstrasse 20", "Musterstadt", "", "98765", "Deutschland");&lt;br /&gt;&lt;br /&gt;$v-&amp;gt;setEmail("thomas.mustermann@thomas-mustermann.de");&lt;br /&gt;&lt;br /&gt;$v-&amp;gt;setNote("You can take some notes here.\r\nMultiple lines are supported via \\r\\n.");&lt;br /&gt;&lt;br /&gt;$v-&amp;gt;setURL("http://www.thomas-mustermann.de", "WORK");&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$output = $v-&amp;gt;getVCard();&lt;br /&gt;&lt;br /&gt;$filename = $v-&amp;gt;getFileName();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Header("Content-Disposition: attachment; filename=$filename");&lt;br /&gt;&lt;br /&gt;Header("Content-Length: ".strlen($output));&lt;br /&gt;&lt;br /&gt;Header("Connection: close");&lt;br /&gt;&lt;br /&gt;Header("Content-Type: text/x-vCard; name=$filename");&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;echo $output;*/&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Next is the FDF creator (fdf.php):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;&lt;br /&gt;KOIVI HTML Form to FDF Parser for PHP (C) 2004 Justin Koivisto&lt;br /&gt;&lt;br /&gt;Version 2.1.2&lt;br /&gt;&lt;br /&gt;Last Modified: 9/12/2005&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    This library is free software; you can redistribute it and/or modify it&lt;br /&gt;&lt;br /&gt;    under the terms of the GNU Lesser General Public License as published by&lt;br /&gt;&lt;br /&gt;    the Free Software Foundation; either version 2.1 of the License, or (at&lt;br /&gt;&lt;br /&gt;    your option) any later version.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    This library is distributed in the hope that it will be useful, but&lt;br /&gt;&lt;br /&gt;    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY&lt;br /&gt;&lt;br /&gt;    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public&lt;br /&gt;&lt;br /&gt;    License for more details.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    You should have received a copy of the GNU Lesser General Public License&lt;br /&gt;&lt;br /&gt;    along with this library; if not, write to the Free Software Foundation,&lt;br /&gt;&lt;br /&gt;    Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Full license agreement notice can be found in the LICENSE file contained&lt;br /&gt;&lt;br /&gt;    within this distribution package.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Justin Koivisto&lt;br /&gt;&lt;br /&gt;    justin.koivisto@gmail.com&lt;br /&gt;&lt;br /&gt;    http://koivi.com&lt;br /&gt;&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;&lt;br /&gt;*   createFDF&lt;br /&gt;&lt;br /&gt;*&lt;br /&gt;&lt;br /&gt;*   Takes values submitted via an HTML form and fills in the corresponding&lt;br /&gt;&lt;br /&gt;*   fields into an FDF file for use with a PDF file with form fields.&lt;br /&gt;&lt;br /&gt;*&lt;br /&gt;&lt;br /&gt;*   @param  $file   The pdf file that this form is meant for. Can be either&lt;br /&gt;&lt;br /&gt;*                   a url or a file path.&lt;br /&gt;&lt;br /&gt;*   @param  $info   The submitted values in key/value pairs. (eg. $_POST)&lt;br /&gt;&lt;br /&gt;*   @result Returns the FDF file contents for further processing.&lt;br /&gt;&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;function createFDF($file,$info){&lt;br /&gt;&lt;br /&gt;    $data="%FDF-1.2\n%????\n1 0 obj\n&amp;lt;&amp;lt; \n/FDF &amp;lt;&amp;lt; /Fields [ ";&lt;br /&gt;&lt;br /&gt;    foreach($info as $field =&amp;gt; $val){&lt;br /&gt;&lt;br /&gt;        if(is_array($val)){&lt;br /&gt;&lt;br /&gt;            $data.='&amp;lt;&amp;lt;/T('.$field.')/V[';&lt;br /&gt;&lt;br /&gt;            foreach($val as $opt)&lt;br /&gt;&lt;br /&gt;                $data.='('.trim($opt).')';&lt;br /&gt;&lt;br /&gt;            $data.=']&amp;gt;&amp;gt;';&lt;br /&gt;&lt;br /&gt;        }else{&lt;br /&gt;&lt;br /&gt;            $data.='&amp;lt;&amp;lt;/T('.$field.')/V('.trim($val).')&amp;gt;&amp;gt;';&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    $data.="] \n/F (".$file.") /ID [ &amp;lt;".md5(time())."&amp;gt;\n] &amp;gt;&amp;gt;".&lt;br /&gt;&lt;br /&gt;        " \n&amp;gt;&amp;gt; \nendobj\ntrailer\n".&lt;br /&gt;&lt;br /&gt;        "&amp;lt;&amp;lt;\n/Root 1 0 R \n\n&amp;gt;&amp;gt;\n%%EOF\n";&lt;br /&gt;&lt;br /&gt;    return $data;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;There is an &lt;a href="http://us2.php.net/fdf"&gt;official PHP FDF creator&lt;/a&gt;, but it uses some ridiculous dll file that you need to install.  PHP is great at string manipulation, why the heck do we need a dll? Anyway, thanks a lot Justin Koivisto.&lt;br /&gt;&lt;br /&gt;Finally a custom email script I wrote to email multiple attachments (mail_attachment.php):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;function mail_attachment ($from , $to, $subject, $message, $attachments){&lt;br /&gt;&lt;br /&gt; $email_from = $from; // Who the email is from &lt;br /&gt;&lt;br /&gt; $email_subject =  $subject; // The Subject of the email &lt;br /&gt;&lt;br /&gt; $email_txt = $message; // Message that the email has in it &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; $email_to = $to; // Who the email is to&lt;br /&gt;&lt;br /&gt; $headers = "From: ".$email_from;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; $semi_rand = md5(time()); &lt;br /&gt;&lt;br /&gt; $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; &lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt; $headers .= "\nMIME-Version: 1.0\n" . &lt;br /&gt;&lt;br /&gt;            "Content-Type: multipart/mixed;\n" . &lt;br /&gt;&lt;br /&gt;            " boundary=\"{$mime_boundary}\""; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; $email_message .= "This is a multi-part message in MIME format.\n\n" . &lt;br /&gt;&lt;br /&gt;                "--{$mime_boundary}\n" . &lt;br /&gt;&lt;br /&gt;                "Content-Type:text/html; charset=\"iso-8859-1\"\n" . &lt;br /&gt;&lt;br /&gt;               "Content-Transfer-Encoding: 7bit\n\n" . $email_txt . "\n\n"; &lt;br /&gt;&lt;br /&gt;      &lt;br /&gt;&lt;br /&gt; foreach ($attachments as $a) {&lt;br /&gt;&lt;br /&gt;  $data = chunk_split(base64_encode($a['data'])); &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  $email_message .= "--{$mime_boundary}\n" . &lt;br /&gt;&lt;br /&gt;                   "Content-Type: {$a['mime']};\n" . &lt;br /&gt;&lt;br /&gt;                   " name=\"{$a['filename']}\"\n" . &lt;br /&gt;&lt;br /&gt;                   "Content-Transfer-Encoding: base64\n\n" . &lt;br /&gt;&lt;br /&gt;                  $data . "\n\n";&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; $email_message .= "--{$mime_boundary}--\n";&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; $ok = @mail($email_to, $email_subject, $email_message, $headers); &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; if($ok) { &lt;br /&gt;&lt;br /&gt; } else { &lt;br /&gt;&lt;br /&gt;  die("There was a problem sending the email. Please check your inputs."); &lt;br /&gt;&lt;br /&gt; } &lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thank you about.com for the &lt;a href="http://javascript.about.com/library/blscr01.htm"&gt;HTML Converter&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-2795330229509603660?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/2795330229509603660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=2795330229509603660' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/2795330229509603660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/2795330229509603660'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2009/02/forms-fdf-pdf-and-php.html' title='Forms:  FDF, PDF, and PHP'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-765048029913084718</id><published>2009-01-28T20:59:00.000-08:00</published><updated>2009-02-09T05:45:17.110-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bridge'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='ifconfig'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><category scheme='http://www.blogger.com/atom/ns#' term='xen'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Howto: Xen Bridging with Static and DHCP NICs</title><content type='html'>I have been meaning to figure out how to put Xen virtual machines on different networks for over a year.  Every once in a while I would start poking at it, but never could get it to work.  Now a project I'm doing requires VMs on different networks, and to easily be able to switch them, so I finally took the time to learn.  Notably it is more linux networking 101 than anything.&lt;br /&gt;&lt;br /&gt;This would have been relatively easy if both NICs used static IPs, &lt;a href="http://toic.org/2008/10/06/multiple-network-interfaces-in-xen/"&gt;this&lt;/a&gt; tutorial would have worked more or less out of the box.  It turns out that throwing dhcp in the mix really screws with routing and dns.  Even worse the dhcp daemon running in the background keeps screwing it up unless you disable it.&lt;br /&gt;&lt;br /&gt;-------------------------------------------------&lt;br /&gt;&lt;br /&gt;Howto:&lt;br /&gt;&lt;br /&gt;Note:  This is on Ubuntu 8.04 and Xen 3.2.  I want dom0 to access the internet via a static ip on eth0.&lt;br /&gt;&lt;br /&gt;First create /etc/xen/scripts/multi-network-bridge then put the following in it:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;/etc/xen/scripts/network-bridge $@ vifnum=1 netdev=eth1 bridge=xenbr1&lt;br /&gt;/etc/xen/scripts/network-bridge $@ vifnum=0 netdev=eth0 bridge=xenbr0&lt;br /&gt;&lt;br /&gt;ifconfig xenbr1 up&lt;br /&gt;ifconfig xenbr0 up&lt;br /&gt;ip route flush table main&lt;br /&gt;ip route add X.X.X.X/X dev xenbr0&lt;br /&gt;ip route add default via X.X.X.X&lt;br /&gt;cp /etc/resolv.conf.bak /etc/resolv.conf&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Where X.X.X.X/X is your static network such as 192.168.1.0/24 and X.X.X.X is your static gateway (192.168.1.1).  /etc/resolv.conf.bak is a copy of your static dns servers.&lt;br /&gt;&lt;br /&gt;Now make the script executable and disable the dhcp daemon:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo chmod +x /etc/xen/scripts/multi-network-bridge&lt;br /&gt;sudo update-rc.d -f dhcdbd remove&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Finally, find the line in /etc/xen/xend-config.spx that has "(network-script network-bridge)" and change it to "(network-script multi-network-bridge)".&lt;br /&gt;&lt;br /&gt;Now check to make sure that /etc/network/interfaces is configured properly, mine looks like:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;auto lo&lt;br /&gt;iface lo inet loopback&lt;br /&gt;&lt;br /&gt;auto eth1&lt;br /&gt;iface eth1 inet dhcp&lt;br /&gt;&lt;br /&gt;auto eth0&lt;br /&gt;iface eth0 inet static&lt;br /&gt; address x.x.x.x&lt;br /&gt; gateway x.x.x.x&lt;br /&gt; netmask x.x.x.x&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For DomUs to use the bridge you need to change the cfg file to look like:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;vif         = [ 'mac=xx:xx:xx:xx:xx:xx,ip=x.x.x.x,bridge=xenbr0' ]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;For the static network, or:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;dhcp        = 'dhcp'&lt;br /&gt;vif         = [ 'mac=xx:xx:xx:xx:xx:xx,bridge=xenbr1' ]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;For the dhcp network.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Reboot Dom0 to make sure that networking comes back right.&lt;br /&gt;&lt;br /&gt;------------------------------------------------&lt;br /&gt;&lt;br /&gt;If you don't specifically name the bridges, then they will automatically be named eth0 and eth1 (and you probably won't have to do the ifconfig xxxx up either).  This makes the output of ifconfig look slightly more normal.  &lt;br /&gt;&lt;br /&gt;A couple other things I found out along the way:&lt;br /&gt;&lt;br /&gt;1.  The interfaces should already be up and configured properly (with ips) before the bridge script is run.  This should happen automatically if /etc/network/interfaces is set up properly.&lt;br /&gt;&lt;br /&gt;2.  Dom0 connects to the bridge directly, which is why it has an ip assigned.&lt;br /&gt;&lt;br /&gt;3.  "ip route" and "brctl show" are your friends.&lt;br /&gt;&lt;br /&gt;4.  The tapX devices are from hardware virtual machines.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note:  Doing this can confuse firefox in to thinking it is offline.  If you have issues with firefox make sure File-&gt;Work Offline is unchecked (sometimes checking it then unchecking it helps).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Update:&lt;br /&gt;&lt;br /&gt;Here is my new multi-network-bridge script:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;/etc/xen/scripts/network-bridge $@ vifnum=1 netdev=eth1&lt;br /&gt;/etc/xen/scripts/network-bridge $@ vifnum=0 netdev=eth0&lt;br /&gt;&lt;br /&gt;ip route flush table main&lt;br /&gt;ip route add X/X dev eth0&lt;br /&gt;ip route add default via X&lt;br /&gt;cp /etc/resolv.conf.bak /etc/resolv.conf&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If you don't specify a bridge then it defaults to eth0.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-765048029913084718?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/765048029913084718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=765048029913084718' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/765048029913084718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/765048029913084718'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2009/01/howto-xen-bridging-with-static-and-dhcp.html' title='Howto: Xen Bridging with Static and DHCP NICs'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-8570801318016250562</id><published>2008-12-20T11:00:00.000-08:00</published><updated>2008-12-20T11:04:18.172-08:00</updated><title type='text'>GWT-WishList</title><content type='html'>As a sort of test project for a bunch of other things I was learning/doing such as AuthSub, iBatis, SQL joins, gwt authentication, etc.  I created a little pet project to manage wishlists:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/gwt-wishlist/"&gt;http://code.google.com/p/gwt-wishlist/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It is a good, relatively small, project for looking at how to integrate iBatis and GWT or AuthSub and GWT.  The code is in a pretty ugly/uncommented state right now.  If I get a chance I will make a blog entry about how it actually works... and comment my code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-8570801318016250562?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/8570801318016250562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=8570801318016250562' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/8570801318016250562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/8570801318016250562'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2008/12/gwt-wishlist.html' title='GWT-WishList'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-4459721778343507094</id><published>2008-12-17T07:17:00.000-08:00</published><updated>2009-01-29T00:24:22.746-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dom0'/><category scheme='http://www.blogger.com/atom/ns#' term='2.6.27'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><category scheme='http://www.blogger.com/atom/ns#' term='domu'/><category scheme='http://www.blogger.com/atom/ns#' term='xen'/><category scheme='http://www.blogger.com/atom/ns#' term='intrepid'/><category scheme='http://www.blogger.com/atom/ns#' term='paravirt'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='paravirt_ops'/><title type='text'>Howto Ubuntu Intrepid Ibex 8.10 Xen Dom0</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Intro&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So... much to my dismay &lt;a href="http://news.cnet.com/8301-13580_3-9867657-39.html"&gt;Ubuntu quit&lt;/a&gt; &lt;a href="http://allaboutubuntu.wordpress.com/2008/02/27/ubuntu-and-kvm-virtualization-understanding-the-long-term-direction/"&gt;supporting Xen&lt;/a&gt; as a Dom0.  The default kernel intrepid ships with is supposed to support being a domU, but that is just because of the addition of paravirt_ops into the standard linux kernel.&lt;br /&gt;&lt;br /&gt;Anyway, they aren't supporting xen anymore because they are going with KVM as their server virtualization technology, and virtualbox as their destkop virt tech.  Not that I am opposed to KVM, it just seems like &lt;a href="https://help.ubuntu.com/community/KVM"&gt;this&lt;/a&gt; is a bit more complicated than xen-create-image... especially since I am not familiar with it.&lt;br /&gt;&lt;br /&gt;As it so happens there are a &lt;a href="http://code.google.com/p/gentoo-xen-kernel/"&gt;couple&lt;/a&gt; branches of 2.6.27 linux xen kernels, and while they are not official, they seem to be working well.  I think that the &lt;a href="http://www.redhat.com/archives/fedora-xen/2008-March/msg00013.html"&gt;plan is to integrate&lt;/a&gt; &lt;a href="http://fedoraproject.org/wiki/Features/XenPvops"&gt;dom0 functionality into the paravirt_ops&lt;/a&gt;, which basically means creating the backend drivers, but since that is not completed yet, we will need to use one of these unstable branches to get a functioning dom0 with a recent kernel (although they seem very stable to me -- the one I'm using is from Novell Suse).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Howto:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Install a fresh Ubuntu Server 8.10 AMD64.  I opted for lvm, but that is certainly not necessary.  Luckily Xen 3.3.0 is in the intrepid repos, unfortunately it doesn't have a compatible linux kernel, so we have to download, compile, and install one.&lt;br /&gt;&lt;br /&gt;Note: MAKE SURE ITS AMD64, apparently there are build problems with 32bit.  Besides there really is no point to have a 32bit dom0 -- it can't see more than like 3gb of ram, and you can always make 32bit domUs.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt; sudo apt-get install ubuntu-xen-server build-essential libncurses5-dev gawk mercurial&lt;br /&gt; mkdir -p /home/#user#/build/linux-2.6.27-xen&lt;br /&gt; cd /usr/src/&lt;br /&gt; sudo hg clone http://xenbits.xensource.com/ext/linux-2.6.27-xen.hg&lt;br /&gt; cd linux-2.6.27-xen.hg&lt;br /&gt; make O=/home/#user#/build/linux-2.6.27-xen/ menuconfig&lt;br /&gt; make O=/home/#user#/build/linux-2.6.27-xen/ -j12 #put number of cores X1.5 here#&lt;br /&gt; sudo make O=/home/#user#/build/linux-2.6.27-xen/ modules_install install&lt;br /&gt; sudo depmod 2.6.27.5&lt;br /&gt; sudo mkinitramfs -o /boot/initrd-2.6.27.5.img 2.6.27.5&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The most important part here is the menuconfig, by default none of the xen stuff is enabled.  I had to disable 10000 Mbps ethernet (ixgbe), the slub allocator, and perfmon (or maybe I selected that and shouldn't have) because they wouldn't compile.  You can either build two kernels, one with backend drivers (dom0), and the other with frontend drivers (domUs), or you can put both of them in one build and use the kernel for both dom0 and domUs.  See &lt;a href="http://en.gentoo-wiki.com/wiki/Xen"&gt;this&lt;/a&gt; and &lt;a href="http://www.gentoo.org/doc/en/xen-guide.xml"&gt;this&lt;/a&gt; for various xen options.  Pushing h in the menuconfig helps a lot&lt;br /&gt;&lt;br /&gt;Now you have to edit your /boot/grub/menu.lst to boot to the new kernel under xen.  It should look something like:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;title         Xen 3.3 / Ubuntu 8.10, kernel 2.6.27-xen&lt;br /&gt;uuid          538bd858-c116-45e8-bbb5-93c073464889&lt;br /&gt;kernel        /xen-3.3.gz&lt;br /&gt;module        /vmlinuz-2.6.27.5 root=/dev/mapper/LVMVG-LV ro console=tty0&lt;br /&gt;module        /initrd-2.6.27.5.img&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You should now be able to boot in to xen by simply rebooting.  If your dom0 doesn't come up then simply reboot and change the grub selection to the non-xen and fix whatever it is you broke ;p.&lt;br /&gt;&lt;br /&gt;Oddly the ubuntu-xen-server doesn't include hardy or intrepid configs for it's xen tools configs.  This will fix that though:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo ln -s /usr/lib/xen-tools/edgy.d /usr/lib/xen-tools/hardy.d&lt;br /&gt;sudo ln -s /usr/lib/xen-tools/edgy.d /usr/lib/xen-tools/intrepid.d&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now you can create an intrepid image using:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo xen-create-image --hostname=somehost.example.com --size=10Gb --swap=2Gb --ide --mac=00:00:00:00:00:00 --memory=2Gb --arch=amd64 --lvm=VolumeGroup --kernel=/boot/vmlinuz-2.6.27.5 --initrd=/boot/initrd-2.6.27.5.img --install-method=debootstrap --dist=intrepid --mirror=http://archive.ubuntu.com/ubuntu/ --passwd --accounts --dhcp&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;---------------------Cut---------------------------&lt;br /&gt;You might be able to fix this somewhere in the default config, but you need to change the console both in the generated .cfg file and in the actual disk image it created:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo echo "console='xvc0'" &gt;&gt; /etc/xen/somehost.example.com.cfg&lt;br /&gt;sudo mkdir /media/domudisk&lt;br /&gt;sudo mount /dev/mapper/LVMVGroup--somehost.example.com--disk /media/domudisk&lt;br /&gt;cd /media/domudisk/etc/event.d/&lt;br /&gt;sudo nano tty1&lt;br /&gt;cd ~&lt;br /&gt;sudo umount /media/domudisk&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;On the last line change 'tty1' to 'xvc0'.&lt;br /&gt;---------------------------------------------------&lt;br /&gt;Update:  You can fix this with a config:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo su &lt;br /&gt;echo "console='xvc0'" &gt;&gt; /etc/xen-tools/xm.tmpl&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;(sudo echo doesn't work for me...)&lt;br /&gt;Then add the line "sed -i "s/tty1/${serial_device}/" ${prefix}/etc/event.d/tty1" to /usr/lib/xen-tools/edgy.d/30-disable-gettys, so that last if section reads:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#&lt;br /&gt;#  Are we using an alternative serial device?&lt;br /&gt;#&lt;br /&gt;if [ ! -z "${serial_device}" ]; then&lt;br /&gt;&lt;br /&gt;    serial_device=`basename ${serial_device}`&lt;br /&gt;    echo "Setting DomU Serial Device to $serial_device"&lt;br /&gt;    # Let the user know.&lt;br /&gt;    logMessage "Replacing default serial device (tty1) with ${serial_device}"&lt;br /&gt;&lt;br /&gt;    # replace existing device.&lt;br /&gt;    &lt;span style="font-weight:bold;"&gt;sed -i "s/tty1/${serial_device}/" ${prefix}/etc/event.d/tty1&lt;/span&gt;&lt;br /&gt;    mv ${prefix}/etc/event.d/tty1  ${prefix}/etc/event.d/${serial_device}&lt;br /&gt;    sed -i -e s/tty1/${serial_device}/ ${prefix}/etc/inittab&lt;br /&gt;&lt;br /&gt;    # make sure that it is allowed to login.&lt;br /&gt;    echo $serial_device &gt;&gt; ${prefix}/etc/securetty&lt;br /&gt;    echo "Serial device set"&lt;br /&gt;    echo $serial_device&lt;br /&gt;fi&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;and, finally, uncomment "serial_device = xvc0" and "disk_device = xvda" in /etc/xen-tools/xen-tools.conf&lt;br /&gt;&lt;br /&gt;There are other goodies in /etc/xen-tools/xen-tools.conf (such as defaults for image creation) too.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The vanilla kernel that ships with Ubuntu as well as building a new kernel from kernel.org (if you enable the paravirt_ops and frontend drivers), will both run as domUs, you simply have to change the hda/sda references in the cfg file to xvda manually, or you can uncomment the "disk_device = xvda" in /etc/xen-tools/xen-tools.conf.  MAKE SURE YOU COPY YOUR /lib/modules/2.6.27.whatever over to the domU drive!!! xen-tools will not do this for you (without more script mods at least -- a simple hack would be to replace what /usr/lib/xen-tools/edgy.d/80-install-modules does with cp -r /usr/lib/modules/* ${prefix}/usr/lib/modules).&lt;br /&gt;&lt;br /&gt;To build the latest linux kernel:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;mkdir -p /home/user/build/linux-2.6.27/&lt;br /&gt;git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.27.y.git&lt;br /&gt;cd linux-2.6.27.y&lt;br /&gt;make O=/home/#user#/build/linux-2.6.27-xen/ menuconfig&lt;br /&gt;make O=/home/#user#/build/linux-2.6.27-xen/ -j12 #put number of cores X1.5 here#&lt;br /&gt;sudo make O=/home/xepra/build/linux-2.6.27.y/ modules_install install&lt;br /&gt;depmod 2.6.27.9&lt;br /&gt;mkinitramfs -o /boot/initrd.img-2.6.27-9 2.6.27.9&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Notes:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I will update with some more details... hopefully&lt;br /&gt;&lt;br /&gt;On another note -- I actually did this with a gentoo install cd initially and booted directly to a xen kernel.  It worked surprisingly well, especially since I am a gentoo neophyte, but there weren't any image creation tools.  After manually creating a domU and getting it running I had all sorts of networking problems that I never had with Ubuntu... so I went back to Ubuntu.&lt;br /&gt;&lt;br /&gt;I also went through this process on Debian lenny, but also had some problems; I think xen 3.3 wasn't in the repos so I had to compile it from scratch...  I also was using grub2, which was a bit different, but not hard to figure out and get working.&lt;br /&gt;&lt;br /&gt;Update:  It looks like Boris Derzhavets used this entry and did a &lt;a href="http://bderzhavets.wordpress.com/2009/01/03/setup-xen-330-ubuntu-intrepid-server-dom0-via-build-xen-kernel-based-on-httpxenbitsxensourcecomextlinux-2627-xenhg/"&gt;follow up&lt;/a&gt; with a lot more detail, screen shots, and output.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-4459721778343507094?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/4459721778343507094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=4459721778343507094' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4459721778343507094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4459721778343507094'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2008/12/howto-ubuntu-intrepid-ibex-810-xen-dom0.html' title='Howto Ubuntu Intrepid Ibex 8.10 Xen Dom0'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-944154046379918501</id><published>2008-11-20T20:28:00.000-08:00</published><updated>2009-01-30T11:02:35.376-08:00</updated><title type='text'>Passwords</title><content type='html'>In &lt;a href="/2008/08/security.html"&gt;this post&lt;/a&gt;  I mentioned that you should not use the same password for everything due to a number of security reasons.  I also mentioned that you shouldn't store your passwords unencrypted anywhere.&lt;br /&gt;&lt;br /&gt;Most people aren't going to remember a different password for every website/computer/email address they use.  So what should you do?&lt;br /&gt;&lt;br /&gt;Well the first option is to store them in an encrypted file (which requires a password to access...).  Also, if you ever lose that file (stolen, deleted, hard drive crash, etc)  then you are SOL.&lt;br /&gt;&lt;br /&gt;The way I solve this problem is to use a predefined pattern to modify a base password.  For a simple example say your base password is "VerySecret7" then you could make your password for Gmail "GerySecret7" and your password for Facebook "FerySecret7".  Granted this is not a very secure example (yet still much more secure than the same password!), but you can extend this to make more complicated patterns.  For example:&lt;br /&gt;&lt;br /&gt;1.  Use the next letter of the alphabet so the connection isn't as apparent. (thus "HerySecret7" for Gmail and "EerySecret7" for Digg)&lt;br /&gt;&lt;br /&gt;2.  Convert letters to numbers.  ("7erySecret7" Gmail and "25erySecret7" for Yahoo).&lt;br /&gt;&lt;br /&gt;3.  Take multiple letters from the service name.  (IE take the first and third letter and put them at the end -- "VerySecret7Ga" for Gmail or "VerySecret7Fc" for Facebook)&lt;br /&gt;&lt;br /&gt;4.  Use classes of passwords.  (For banks use "SuperSecret39" for your base password, then apply your normal pattern to it.)  This is probably overkill if you have a half decent pattern/base password.&lt;br /&gt;&lt;br /&gt;5.  If the first letter of the service starts with a letter after M spell your base password backwards.  (Also probably overkill)&lt;br /&gt;&lt;br /&gt;6.  You get the idea, basically whatever you can think of.  Combinations of patterns will be more secure, and symbols, caps, and numbers always improve password security.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Get creative, but not so creative that you won't remember it...  Just be consistent.  A relatively simple pattern such as take the letter after the first letter of the service name and add it to the front, then convert the last letter to a number gives you a pretty secure password and fairly unrecognizable pattern ("Hery11ecret7" for gmail).&lt;br /&gt;&lt;br /&gt;It would be very hard for someone who has one of your passwords to both know you are using a pattern and discover your pattern (if it is half decent, not VerySecret7Gmail...).  On the other hand it *should* remain easy for you to remember all of your passwords without writing them down.&lt;br /&gt;&lt;br /&gt;The big drawback of this is that you can't change just one password without breaking the pattern, so to change one password you need to change all of them...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This technique is essentially a simple hash function.  If you have a better solution (IE it solves the above problem), please let me know :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-944154046379918501?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/944154046379918501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=944154046379918501' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/944154046379918501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/944154046379918501'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2008/11/passwords.html' title='Passwords'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-4249843319475752463</id><published>2008-11-17T04:45:00.000-08:00</published><updated>2008-11-20T20:27:50.720-08:00</updated><title type='text'>iPhone Goodness</title><content type='html'>Some useful iPhone tidbits:&lt;br /&gt;&lt;br /&gt;1.  All of the below is contigent on &lt;a href="http://iphone-dev.org"&gt;jailbreaking&lt;/a&gt;.  Really this is the only way I could ever justify buying an iPhone...  Thanks a lot to the iphone-dev team.  You guys rock.&lt;br /&gt;&lt;br /&gt;2.  If you want to develop an iPhone application, and don't want to pay apple, wait for their certificate, or go through their application review process then you should try: http://www.saurik.com/id/8 and &lt;a href="http://www.saurik.com/id/1"&gt;Cydia&lt;/a&gt; for development, deployment, and distribution.  In general everything by saurik is badass and worth reading.&lt;br /&gt;&lt;br /&gt;3.  If you want to be able run official applications in the back ground (for example listen to pandora while looking up something on maps) checkout "&lt;a href="http://gizmodo.com/5058234/iphone+backgrounder-hack-brings-true-background-multitasking-to-iphone-apps"&gt;backgrounder&lt;/a&gt;" on cydia.&lt;br /&gt;&lt;br /&gt;4.  If you write your own app, and don't care about releasing it in the app store, you can run it in the background using:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;@interface Thing : UIApplication {&lt;br /&gt;}&lt;br /&gt;@implementation Thing&lt;br /&gt;- (void)applicationSuspend:(UIApplication *)application {&lt;br /&gt;    [super applicationSuspend: application];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Thanks AlJaMa in iphone-dev irc for that.  (I haven't tried it yet)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5.  If you want to be able to use Fring (or other wifi limited applications) over the cellular network, then there is a patch on cydia for that too: Voipover3g.  You can apparently specify which applications to spoof wifi access for by editing /Library/MobileSubstrate/DynamicLibraries/VoIPover3G.plist&lt;br /&gt;&lt;br /&gt;The default config looks something like: "Filter = {Bundles = ("com.Fringland.Fring", "com.apple.AppStore", "com.audiofile.Interstate", "com.apple.MobileStore");};"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;6.  I haven't tried Erling's accelerometer hack on 2.x firmware yet, but hopefully it still works (allows you to adjust sample rate): http://blog.medallia.com/2007/08/iphone_accelerometer_source_co.html&lt;br /&gt;&lt;br /&gt;UPDATE: It appears that there is a way to use the SDK to set the sample rate through &lt;a href="http://iphonesdkdev.blogspot.com/2008/06/uiaccelerometer-sample-code.html"&gt;UIAccelerometer&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;7.  http://www.cocoamachine.com/blog/ has also been a good resource.  And of course there is always #iphone-dev on irc.osx86.hu&lt;br /&gt;&lt;br /&gt;8.  There are some headers missing from the official framework.  You should be able to do a &lt;a href="http://iphone.freecoder.org/classdump_en.html"&gt;class dump&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;class-dump -H /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Library/Frameworks/UIKit.framework/UIKit -o output-directory&lt;br /&gt;&lt;br /&gt;The file it spits out is mach-o.&lt;br /&gt;&lt;br /&gt;9.  PDANet also from cydia, allows you to share the iphones 3g connection via wifi.&lt;br /&gt;&lt;br /&gt;10.  Netatalk appletalk / general storage.&lt;br /&gt;&lt;br /&gt;11.  &lt;a href="http://www.digidna.net/diskaid/"&gt;DiskAid&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Other: terminal, hp calc, stumbler plus, and on the app store Rooms (irc) and motionX dice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-4249843319475752463?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/4249843319475752463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=4249843319475752463' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4249843319475752463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4249843319475752463'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2008/11/iphone-goodness.html' title='iPhone Goodness'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-4938026095265689583</id><published>2008-11-17T03:49:00.000-08:00</published><updated>2008-11-17T04:09:41.051-08:00</updated><title type='text'>GWT RPC Exceptions</title><content type='html'>So...  Most of GWT's documentation is pretty good, but the part about RPC exceptions is kind of lacking.&lt;br /&gt;&lt;br /&gt;I found some posts such as:&lt;br /&gt;&lt;br /&gt;http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/c048700dcaee7b2a&lt;br /&gt;http://astithas.blogspot.com/2007/08/case-of-disappeared-exception-message.html&lt;br /&gt;http://blog.platinumsolutions.com/node/198&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;But all of them mentioned the now deprecated SerializableException.  According to the API this was deprecated because Exception implements Serializable, and thus a normal exception should work fine... (http://google-web-toolkit.googlecode.com/svn/javadoc/1.5/com/google/gwt/user/client/rpc/SerializableException.html)&lt;br /&gt;&lt;br /&gt;Unfortunately I was still getting the "the call failed on the server see server log for details" message from exceptions that reached the client.&lt;br /&gt;&lt;br /&gt;Anyway, the solution I reached was very, very, simple.  My ServiceImpl class throws a standard RuntimeException ("throw new RuntimeException("Epic Fail");").  But this is what I was already doing that didn't work.  I had to add "throws Exception" to the method, and thus the client side service interface as well.  Worked like a charm after that.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public interface SomeService extends RemoteService {&lt;br /&gt;    void doSomething(Object someObject) throws exception;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface SomeServiceAsync {&lt;br /&gt;    void doSomething(Object someObject, AsyncCallback callback);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class SomeServiceImpl extends RemoteServiceServlet implements SomService {&lt;br /&gt;    public void doSomething(Object someObject) throws Exception {&lt;br /&gt;        if(epic.fail())&lt;br /&gt;            throw new RuntimeException("Epic Fail");&lt;br /&gt;        else &lt;br /&gt;            doSomethingCool();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-4938026095265689583?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/4938026095265689583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=4938026095265689583' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4938026095265689583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4938026095265689583'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2008/11/gwt-rpc-exceptions.html' title='GWT RPC Exceptions'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-3711800024918939815</id><published>2008-10-08T01:18:00.000-07:00</published><updated>2008-10-08T07:22:38.681-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iBatis'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='GWT'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Web Toolkit'/><category scheme='http://www.blogger.com/atom/ns#' term='Enterprise'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Scaleability'/><title type='text'>Too many choices for RIAs...</title><content type='html'>Notably this, like most of my ramblings, is mainly for thought aggregation and self-reference later, in this case mainly keywords to look up, but if it helps you out then good :).&lt;br /&gt;&lt;br /&gt;The number of options for web development is overwhelming!  The more complex the application is, the more options you have.  For a simple web page its easy -- HTML, and if you want to get fancy you use javascript and CSS.  More than that is when it starts to get complicated, you have Javascript libraries like jQuery and Dojo or embedded stuff like Flash, Java Applets, and, now, Silverlight.  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now what if you want to do something on the back-end?  There's SSI, PHP, ColdFusion, Python, Java Servlets, JSP, Java Restlets, Ruby...  and the list goes on.  Hell, if you wanted to you could write the whole thing, web server and all, in C or C++ -- at least it would be fast as hell :).&lt;br /&gt;&lt;br /&gt;Now what about databases?  MySQL is kind of the open source standard that seems to scale well, but enterprises tend to lean towards PostgreSQL or commercial options like MSSQL and Oracle.  I also took a look at FirebirdDB, which looks very interesting.  In all honesty I am surprised that more people don't use FirebirdDB and PostgresSQL over MySQL.  Then there is also &lt;a href="http://hadoop.com"&gt;Hadoop&lt;/a&gt;...  but thats not even SQL.&lt;br /&gt;&lt;br /&gt;Then there are database abstraction layers (DALs), and the selection depends on your language.  With PHP the most promising ones (for me) are PEAR DB and adoDB (which actually can run some native C code to speed things up, very cool).  adoDB works with Python too.  In Java there are Spring, Hibernate, and iBatis.  I don't even know all the options for the other languages.  While there are &lt;a href="http://jeremy.zawodny.com/blog/archives/002194.html"&gt;arguments against database abstraction&lt;/a&gt;, some of the solutions make coding much simpler and faster.  ORMs in particular look very useful.&lt;br /&gt;&lt;br /&gt;Once you start getting more complex interfaces you have to worry about cross browser compatibility which is just nasty.  Coding for IE6 as well as standards compliant browsers was awful, just awful.  Not to mention debugging and writing maintainable code is non-trivial (thank god for firebug).  In short it is a layer that a system architect for a complex RIA just does not want to deal with.  There are various options for circumventing this, even some CMSs such as Drupal and Wordpress do this indirectly, but there are a couple packages that do this very elegantly and quickly such as OpenLaszlo, Adobe Flex, and Google Web Toolkit, and one other one I can't think of right off. &lt;a href="http://www.sys-con.com/node/489336"&gt;Here&lt;/a&gt; is an interesting article comparing those three.&lt;br /&gt;&lt;br /&gt;Next you need to consider reliability, performance, scalability, and code maintenance.  In enterprises performance is irrelevant if it is scalable -- you can always just throw more servers at it.  This is one reason Java has been so well adopted on an enterprise level; even though it is very slow when compared with C or C++, it is scalable, more flexible, and produces more maintainable code.  "Programmer performance is worth far more than system performance ;-)." [1].&lt;br /&gt;&lt;br /&gt;For scalability you can look at products like Squid which will do reverse caching and load balancing for web pages as well as sqlrelay which will do connection pooling and load balancing for sql servers.  &lt;a href="http://danga.com"&gt;http://danga.com&lt;/a&gt; has some cool stuff too.&lt;br /&gt;&lt;br /&gt;Since most of these technologies are interchangeable, you can mix and match almost any combination of them; this creates a huge number of deployment options.  Hmm, maybe I will do GWT -&gt; PHP -&gt; adoDB -&gt; SQLRelay -&gt; MySQL.  Or you could even do PHP -&gt; Python -&gt; PostgresSQL, if you decided you like Python for some of your server interactions and PHP just for templating, and, in this case, you opted not to have a DAL.  These are important decisions to make before a project begins, as backtracking can be prohibitively expensive and choosing the wrong architecture can cause problems with stability and development; even worse is its hard to predict how it will scale until the application is completely written.  Luckily for small, homebrew, applications almost all of these technologies will be able to handle any load you throw at it, so the common recommendation is do it however you are comfortable with, but when you get in to large enterprise applications then things like persistent database connections, clustering, stability, and collaborative code development need to be carefully considered.&lt;br /&gt;&lt;br /&gt;This brings me to a minor point - in my experience it is much easier to write bad PHP code than good PHP code, where as it is much easier to write good Java code than bad Java code.  Granted there are exceptions, but the loose typing and script like nature of PHP can very easily lead to unreadable code.  Java, on the other hand, is strictly object oriented and tends to lead to better design patterns.  Sure a bad coder can screw up either royally, but it is something to consider while choosing a collaborative language.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So far, after looking at all of these packages, GWT -&gt; JBoss -&gt; iBatis -&gt; WhateverSQL [2] looks very, very, promising for quickly producing scalable and maintainable RIAs.  GWT makes communication between a browser and a Java Servlet seamless and lets you stay away from the HTML/Javascript pit of death.  JBoss has all sorts of neato scalability.  iBatis looks like a great ORM that doesn't abstract the SQL too much; it also does connection pooling and balancing.  Lets assume WhateverSQL has seamless clustering and replication ;).  This looks much easier (and cleaner!) than HTML -&gt; JavaScript -&gt; PHP -&gt; adoDB -&gt; SQLRelay -&gt; WhateverSQL.  We'll see how it goes. &lt;a href="http://www.pleso.net/en/publications/2007/10/16/gwt-ibatis/"&gt;Here is a nice little tutorial for GWT + iBatis.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[1] &lt;a href="http://forums.devshed.com/firebird-sql-development-61/mysql--vs--firebird-sql-62269.html?s=&amp;perpage=80"&gt;rycamor&lt;/a&gt;&lt;br /&gt;[2] I actually just don't want to put that I am using Oracle for this particular project...  Who the hell pays $40,000+ for one license when there are so many free options?  It may have some cool features, which I have yet to see, but unless it writes the damn webapp for you then just use Postgres.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Alphabet Soup:&lt;br /&gt;&lt;br /&gt;PHP  -&gt;  PHP: HypeText Preprocessor&lt;br /&gt;RIA  -&gt;  Rich Internet Application&lt;br /&gt;SQL  -&gt;  Structured Query Language&lt;br /&gt;HTML -&gt;  HyperText Markup Language&lt;br /&gt;GWT  -&gt;  Google Web Toolkit&lt;br /&gt;MSSQL-&gt;  Microsoft SQL&lt;br /&gt;CSS  -&gt;  Cascading Style Sheet&lt;br /&gt;adoDB-&gt;  Active Data Objects DataBase&lt;br /&gt;ORM  -&gt;  Object Relational Mapping&lt;br /&gt;SSI  -&gt;  Server Side Includes&lt;br /&gt;JSP  -&gt;  Java Server Pages&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-3711800024918939815?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/3711800024918939815/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=3711800024918939815' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/3711800024918939815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/3711800024918939815'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2008/10/too-many-choices-for-rias.html' title='Too many choices for RIAs...'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-1564397266563143552</id><published>2008-10-04T21:09:00.000-07:00</published><updated>2008-10-08T07:33:59.088-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rdp'/><category scheme='http://www.blogger.com/atom/ns#' term='remote desktop'/><category scheme='http://www.blogger.com/atom/ns#' term='xrdp'/><category scheme='http://www.blogger.com/atom/ns#' term='vnc'/><category scheme='http://www.blogger.com/atom/ns#' term='X'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Multiple Desktops in Linux (even Remote ones...)</title><content type='html'>Although I love the ability to control Linux PCs and servers remotely with ssh and X tunneling, I was never satisfied with VNC as a complete Remote Desktop solution.  For starters it is insecure and to secure it you have to jump through a couple hoops.  The biggest problem, however, is that you already have to have a session running on the remote computer in order to use VNC.&lt;br /&gt;&lt;br /&gt;I wanted an easy to use, built-in, secure way to get a complete remote desktop on a Linux machine at any time, from anywhere.&lt;br /&gt;&lt;br /&gt;Luckily I found one:&lt;br /&gt;&lt;br /&gt;1) go to a new terminal via ctrl-alt-f2 and login.&lt;br /&gt;2) type "xinit -- :1".  This should pop up a new instance of x with a terminal running.  I had to mouse over the terminal to type.&lt;br /&gt;3) type "ssh -CX user@host" and login to the remote server  (C is compression...)&lt;br /&gt;4) now type "gnome-session" or "startkde" or whatever desktop you want to start.&lt;br /&gt;&lt;br /&gt;Thats it.  No special programs and it is already encrypted through an ssh tunnel =).&lt;br /&gt;&lt;br /&gt;To close this desktop type "ctrl-alt-backspace".  &lt;br /&gt;To get back to your primary desktop type "ctrl-alt-f7".  &lt;br /&gt;To switch back to the remote desktop type "ctrl-alt-f9".&lt;br /&gt;&lt;br /&gt;You can open another desktop if you would like even with these two open, just use "xinit -- :2"  which will be on the f10 terminal...  You can do as many as 5 or 6.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you want another local, rather than remote, desktop you can just ignore the ssh step (3) and just start the new desktop locally.  This will allow you to run kde, gnome, and xcfe side by side and switch between them with a single key combo.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Also, you may find it useful to know that many programs have a --desktop option that allows you to open programs on any desktop from any terminal.  ie "firefox --desktop :1".  If you have multiple monitors you can even do "firefox --desktop :1.1" to specify the second monitor.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you want to do this from windows just use a program like Xming :).  Although the beta xrdp project is kind of interesting, it still seems a bit rough around the edges.  The only thing that this doesn't really allow you to do is resume already running sessions :/&lt;br /&gt;&lt;br /&gt;Update:  What I was looking for was Xephyr.  Works like a charm:  http://ubuntuforums.org/showthread.php?p=3816948#post3816948  (The whole terminal thing is still cool tho =p)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-1564397266563143552?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/1564397266563143552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=1564397266563143552' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/1564397266563143552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/1564397266563143552'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2008/10/multiple-desktops-in-linux-even-remote.html' title='Multiple Desktops in Linux (even Remote ones...)'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-4747581396288183027</id><published>2008-08-29T16:06:00.000-07:00</published><updated>2008-08-29T16:57:42.270-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Compile'/><category scheme='http://www.blogger.com/atom/ns#' term='ffmpeg'/><category scheme='http://www.blogger.com/atom/ns#' term='VLC'/><category scheme='http://www.blogger.com/atom/ns#' term='RTSP'/><category scheme='http://www.blogger.com/atom/ns#' term='64bit'/><category scheme='http://www.blogger.com/atom/ns#' term='Videolan'/><category scheme='http://www.blogger.com/atom/ns#' term='64 bit'/><category scheme='http://www.blogger.com/atom/ns#' term='live555'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='x86_64'/><title type='text'>Compiling VLC in 64 Bit Ubuntu 8.04.1</title><content type='html'>If you haven't compiled VLC recently then you may be caught off guard by a couple changes made.  The --with-ffmpeg-tree is now deprecated because ffmpeg started using the pkg-config system.  Also the version of live555 in the Ubuntu repositories is currently too old - you will have to compile that yourself as well.&lt;br /&gt;&lt;br /&gt;Hopefully, since you are trying to compile something, you are tech savvy enough to understand a shell script just about as well as my ramblings, so I'll just paste that:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;#get dependencies&lt;br /&gt;sudo apt-get install cvs build-essential subversion git git-core automake1.9 libtool libgcrypt-dev libfaad-dev libtwolame-dev libqt4-dev libjack-dev libfaac-dev liblame-dev libxpm-dev libcddb2-dev liblua5.1-0-dev libzvbi-dev libshout-dev wget&lt;br /&gt;&lt;br /&gt;#get the latest live555&lt;br /&gt;wget http://www.live555.com/liveMedia/public/live555-latest.tar.gz&lt;br /&gt;tar -xzvf live555-latest.tar.gz live&lt;br /&gt;cd live&lt;br /&gt;#modify config.linux to add -fPIC to the first line (for 64bit only)&lt;br /&gt;mv config.linux config.linux.orig&lt;br /&gt;echo `head -1 config.linux.orig` -fPIC &gt; config.linux&lt;br /&gt;tail -16 config.linux.orig &gt;&gt; config.linux&lt;br /&gt;./genMakefiles linux&lt;br /&gt;make -j 8&lt;br /&gt;&lt;br /&gt;#get vlc&lt;br /&gt;cd ~&lt;br /&gt;git clone git://git.videolan.org/vlc.git&lt;br /&gt;cd vlc/&lt;br /&gt;./bootstrap&lt;br /&gt;&lt;br /&gt;#git x264&lt;br /&gt;cd ~/vlc/extras/&lt;br /&gt;git clone git://git.videolan.org/x264.git&lt;br /&gt;cd x264&lt;br /&gt;./configure --enable-pic --disable-asm&lt;br /&gt;make -j 8&lt;br /&gt;sudo make install&lt;br /&gt;&lt;br /&gt;#ffmpeg  (need amr?)&lt;br /&gt;cd ~/vlc/extras/&lt;br /&gt;svn co svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg&lt;br /&gt;cd ffmpeg&lt;br /&gt;./configure --enable-gpl --enable-postproc --enable-pthreads --enable-libmp3lame --enable-libfaac --enable-swscale --disable-static --enable-shared&lt;br /&gt;make -j 8&lt;br /&gt;sudo make install&lt;br /&gt;&lt;br /&gt;# this is for that pkg-config system ffmpeg now uses&lt;br /&gt;export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig/"&lt;br /&gt;&lt;br /&gt;#build&lt;br /&gt;cd ~/vlc&lt;br /&gt;mkdir build&lt;br /&gt;cd build&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#originally I had this configured for no gui - you may need to play with it.&lt;br /&gt;#watch for warnings - it will still compile with missing functionality if you are missing needed libraries&lt;br /&gt;../configure --prefix=/usr \&lt;br /&gt;        --enable-snapshot --enable-debug \&lt;br /&gt;        --enable-dbus --enable-dbus-control --disable-musicbrainz \&lt;br /&gt;        --enable-shared-libvlc --disable-mozilla \&lt;br /&gt;        --enable-lirc \ &lt;br /&gt;        --enable-x264 --with-x264-tree=../extras/x264 \&lt;br /&gt;        --enable-shout --disable-taglib \&lt;br /&gt;        --enable-v4l  \&lt;br /&gt;        --enable-dvb  \&lt;br /&gt;        --enable-realrtsp --enable-real --disable-xvmc \&lt;br /&gt;        --enable-svg   --enable-dvdread \&lt;br /&gt;        --enable-dc1394 --enable-dv \&lt;br /&gt;        --enable-theora --enable-faad \&lt;br /&gt;        --enable-twolame --enable-real \&lt;br /&gt;        --enable-flac --enable-tremor \&lt;br /&gt;        --enable-skins2 --enable-qt4 --enable-x11 --enable-xvideo\&lt;br /&gt;        --enable-ncurses \&lt;br /&gt;        --enable-aa --enable-caca \&lt;br /&gt;        --enable-esd --disable-portaudio \&lt;br /&gt;        --enable-jack --disable-xosd \&lt;br /&gt;        --enable-galaktos --enable-goom \&lt;br /&gt;        --enable-ggi \&lt;br /&gt;        --disable-cddax --disable-vcdx \&lt;br /&gt;        --disable-qte --disable-quicktime --disable-lua \&lt;br /&gt;        --with-live555-tree=~/live \&lt;br /&gt;        --enable-libmpeg2 --enable-mkv \&lt;br /&gt;        --enable-ogg --enable-vorbis --enable-release  --disable-hd1000v &gt; config.out&lt;br /&gt;&lt;br /&gt;make -j 8&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note that I use make -j 8 rather than just make because I am compiling with multiple cores (in this case it was 6 - it is usually good to start a couple more threads than the number of cores you have).  &lt;br /&gt;&lt;br /&gt;I had to add "--disable-static --enable-shared" to the ffmpeg or else it wouldn't compile - I think it had to do with some 64 bit PIC problems.&lt;br /&gt;&lt;br /&gt;Notice the --disable-asm in the x264 config.  This is BAD.  The latest version of yasm in the Ubuntu repositories is not new enough for x264.  This will be fixed in the next release of Ubuntu, but if I get around to it I will post an update before then.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-4747581396288183027?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/4747581396288183027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=4747581396288183027' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4747581396288183027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/4747581396288183027'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2008/08/compiling-vlc-in-64-bit-ubuntu-8041.html' title='Compiling VLC in 64 Bit Ubuntu 8.04.1'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-277376914280488728</id><published>2008-08-29T15:29:00.000-07:00</published><updated>2009-02-18T07:37:17.461-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='noob'/><category scheme='http://www.blogger.com/atom/ns#' term='virus'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Encryption'/><category scheme='http://www.blogger.com/atom/ns#' term='crack'/><category scheme='http://www.blogger.com/atom/ns#' term='password'/><category scheme='http://www.blogger.com/atom/ns#' term='protection'/><category scheme='http://www.blogger.com/atom/ns#' term='n00b'/><category scheme='http://www.blogger.com/atom/ns#' term='newb'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Security</title><content type='html'>Most people, tech and non-tech alike, have some very basic, easily correctable, user created security holes.  Here are the most common I run in to:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1.  If you use Firefox to store your passwords and don't set a master password then anyone who uses your computer can view your password in clear text with about 5 clicks - or about three seconds.  &lt;span style="font-weight:bold;"&gt;Either don't use Firefox to store your passwords or set a master password&lt;/span&gt;.  Be aware that other browsers have similar security issues when storing passwords.&lt;br /&gt;&lt;br /&gt;2.  &lt;span style="font-weight:bold;"&gt;Do not use the same password for everything.&lt;/span&gt;  If someone manages to hack, crack, steal, or find out your password any way then they will have access to all of your accounts that use that password.  Anyone who runs a website has access to the password you use at their website; do you trust them?  Also many sites do not use encryption while authenticating you, thus your password is sent in clear text over the internet for anyone to see.&lt;br /&gt;&lt;br /&gt;3.  &lt;span style="font-weight:bold;"&gt;Check to see if a website is using encryption, especially for authentication.&lt;/span&gt;  (You can check by looking at the url, which should start with http&lt;span style="font-weight:bold;"&gt;s&lt;/span&gt;://, and there is usually a padlock in the bottom right corner of your browser.)  Gmail by default only uses encryption to authenticate you; all of your email is sent unencrypted - this includes any passwords that are emailed to you by other websites.  Last month they (finally) added a setting to always use encryption, but it isn't enabled by default...  If a website does not use encryption for authentication then be very, very, sure to use a different password for that website.&lt;br /&gt;&lt;br /&gt;4.  &lt;span style="font-weight:bold;"&gt;Your email is a security hole for all the accounts tied to it.&lt;/span&gt;  Be careful to not leave your email logged on anywhere other people have access to it.  If you use email on a mobile phone/device then be sure to that it is protected with a pin or password. (*cough* iPhone *cough*)&lt;br /&gt;&lt;br /&gt;5.  &lt;span style="font-weight:bold;"&gt;Anyone with physical access to your computer can access all of your files&lt;/span&gt; in the time it takes to reboot the PC, regardless of whether you have it password protected.  It is ill-advised to store passwords in a text file on your computer.  There are plenty of programs that allow you to store passwords in an encrypted format (including Firefox, if you set a master password).  If you have a lot of sensitive data then you may want to look in to full disk encryption, such as LUKS (Linux only...).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-277376914280488728?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/277376914280488728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=277376914280488728' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/277376914280488728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/277376914280488728'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2008/08/security.html' title='Security'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1985725707144494069.post-5800689972823787572</id><published>2008-08-29T12:00:00.000-07:00</published><updated>2009-02-02T16:36:52.854-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DSS'/><category scheme='http://www.blogger.com/atom/ns#' term='Video'/><category scheme='http://www.blogger.com/atom/ns#' term='RTSP'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='64bit'/><category scheme='http://www.blogger.com/atom/ns#' term='Streaming'/><category scheme='http://www.blogger.com/atom/ns#' term='Darwin Streaming Server'/><category scheme='http://www.blogger.com/atom/ns#' term='64 bit'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='x86_64'/><category scheme='http://www.blogger.com/atom/ns#' term='Patch'/><title type='text'>Darwin Streaming Server 6.0.3 on Linux</title><content type='html'>Quick tutorial for installing DSS on Ubuntu 8.04.1 64bit (x86_64).&lt;br /&gt;&lt;br /&gt;Most of these details can be found here:  &lt;a href ="http://dss.macosforge.org/trac/ticket/6"&gt;http://dss.macosforge.org/trac/ticket/6&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hopefully they will integrate these patches in to the next release, but until then here are the build instructions for Ubuntu:&lt;br /&gt;&lt;br /&gt;Download DSS 6.0.3: &lt;a href="http://static.macosforge.org/dss/downloads/DarwinStreamingSrvr6.0.3-Source.tar"&gt;http://static.macosforge.org/dss/downloads/DarwinStreamingSrvr6.0.3-Source.tar&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Download this patch: &lt;a href="http://dss.macosforge.org/trac/raw-attachment/ticket/6/dss-6.0.3.patch"&gt;http://dss.macosforge.org/trac/raw-attachment/ticket/6/dss-6.0.3.patch&lt;/a&gt; (Thank you Sverker Abrahamsson!)&lt;br /&gt;&lt;br /&gt;And this patch: &lt;a href="http://dss.macosforge.org/trac/raw-attachment/ticket/6/dss-hh-20080728-1.patch"&gt;http://dss.macosforge.org/trac/raw-attachment/ticket/6/dss-hh-20080728-1.patch&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Finally get the modified Install script:  &lt;a href="http://dss.macosforge.org/trac/raw-attachment/ticket/6/Install"&gt;http://dss.macosforge.org/trac/raw-attachment/ticket/6/Install&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The basic process is:&lt;br /&gt;&lt;br /&gt;1.  Get the build dependencies from the repositories.&lt;br /&gt;2.  Set up the qtss user (this is because the Install script does it in a way that is incompatible with Ubuntu)&lt;br /&gt;3.  Extract the source code.&lt;br /&gt;4.  Apply both patches.&lt;br /&gt;5.  Replace the Install script and chmod +x it.&lt;br /&gt;6.  Compile.&lt;br /&gt;7.  Install.&lt;br /&gt;&lt;br /&gt;Notably for ssl admin you need the openssl and libnet-ssleay-perl packages, unfortunately even with these packages I was unable to get ssl admin to work.&lt;br /&gt;&lt;br /&gt;I created the modified Install script; you can do a diff with the original if you want to see what I changed.  Mostly just the paths were broken, but I am guessing that some other modules and such will probably not work.&lt;br /&gt;&lt;br /&gt;Here is the bash script I used to do everything (including automatically download everything):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;sudo apt-get install build-essential wget&lt;br /&gt;sudo addgroup --system qtss&lt;br /&gt;sudo adduser --system --no-create-home --ingroup qtss qtss&lt;br /&gt;&lt;br /&gt;wget http://static.macosforge.org/dss/downloads/DarwinStreamingSrvr6.0.3-Source.tar&lt;br /&gt;tar -xvf DarwinStreamingSrvr6.0.3-Source.tar&lt;br /&gt;mv DarwinStreamingSrvr6.0.3-Source DarwinStreamingSrvr6.0.3-Source.orig&lt;br /&gt;wget http://dss.macosforge.org/trac/raw-attachment/ticket/6/dss-6.0.3.patch&lt;br /&gt;patch -p0 &lt; dss-6.0.3.patch&lt;br /&gt;mv DarwinStreamingSrvr6.0.3-Source.orig DarwinStreamingSrvr6.0.3-Source&lt;br /&gt;wget http://dss.macosforge.org/trac/raw-attachment/ticket/6/dss-hh-20080728-1.patch&lt;br /&gt;patch -p0 &lt; dss-hh-20080728-1.patch&lt;br /&gt;#need to answer n then y&lt;br /&gt;cd DarwinStreamingSrvr6.0.3-Source&lt;br /&gt;mv Install Install.orig&lt;br /&gt;wget http://dss.macosforge.org/trac/raw-attachment/ticket/6/Install&lt;br /&gt;chmod +x Install&lt;br /&gt;./Buildit&lt;br /&gt;sudo ./Install&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update 2/2/2009:&lt;/span&gt;  I changed the links to all point to dss.macosforge.org, which is a much more reliable host.  Everyone should also take a look at that &lt;a href="http://dss.macosforge.org/trac/ticket/6"&gt;thread&lt;/a&gt;, as there are a lot of updates, including a newer patch from Horace Hsieh.  I haven't played with this in a while, but if I get a chance I will try to update this with the newer patch.  Please let me know if there are any problems (I just turned comment notifications on :/).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1985725707144494069-5800689972823787572?l=cwshep.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cwshep.blogspot.com/feeds/5800689972823787572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1985725707144494069&amp;postID=5800689972823787572' title='37 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/5800689972823787572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1985725707144494069/posts/default/5800689972823787572'/><link rel='alternate' type='text/html' href='http://cwshep.blogspot.com/2008/08/darwin-streaming-server-603-on-linux.html' title='Darwin Streaming Server 6.0.3 on Linux'/><author><name>Clayton Shepard</name><uri>http://www.blogger.com/profile/11139128931368750934</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>37</thr:total></entry></feed>
