Saturday, October 27. 2007Cross-compiling pwsafe for ARM
I've spent a good part of this weekend playing around with my shiny new Sharp Zaurus SL-C3200. I'm not going to give it any more of an introduction, because it would be impossible to top what this guy has written.
Instead, what I'm going to focus on is cross-compiling one of the apps I consider quite useful -- pwsafe. Pwsafe is a password manager (originally for Windows) which has clones for Linux, which is great for me, since I use Windows at work, and Linux at home. It stores passwords in an encrypted database which you can take with you wherever you go. So, to put this thing onto a Zaurus, you need a couple of things to start with:
Now, you will need to build and install OpenSSL. I used these instructions to guide me. I couldn't really follow them to the letter, though -- something seems fishy with their patch file. Anyway, configure the library for ARM, specifying the preferred install directory. Use the ARM cross-compiler: CODE: export PATH=/opt/Embedix/tools/arm-linux/bin:$PATH ./Configure linux-elf-arm --prefix=/home/misha/zaurus/arm You'll need to hand edit the Makefile (or, if you're feeling lucky, try and patch it). All I had to change was add -ldl to the list of libraries to use. CODE: EX_LIBS= -ldl All should be good to make and install the OpenSLL library now. Now, it's time for pwsafe.
CODE: CXXFLAGS=-fpermissive ./configure --host=arm \ --with-openssl-dir=/home/misha/src/zaurus/openssl-0.9.7d/dist --with-readline=no --with-x=no
At this point, all you have left to do is make and deploy to the Zaurus. Libs (libssl and libcrypto) go in /opt/QtPalmtop/lib and the binary (pwsafe) goes into /opt/QtPalmtop/bin. I'll wrap this up in an ipk a bit later to make deployment easier. Thursday, September 13. 2007Programming can ruin your life
A colleague at work sent this this link around. I must admit, I felt a slight shock while reading it. "Wow, this is kind what is happening to me," I thought. At the same time, I entertained brief thoughts of relief... "Whew, at least I'm not a complete geek". At times like this I generally seek salvation in sports, or hobbies that have as little to do with programming as possible.
I remember second year uni, where in a desperate attempt to not burn out in computing I took Japanese as an elective. It helped, and I made it through second year and managed to eventually graduate, but I can't help thinking that learning a foreign language isn't completely unrelated to programming... Now that I think about it, the majority of the things I do are in someway programming related. And even if they are not, I find myself taking a programmer's approach to them. While it works, and I tend to achieve most of the goals that I set, it's kind of concerning to acknowledge that my choice of profession has resulted in a mind-altering experience. Then again, if I think back to my days as a gamer back in high school, I distinctly recall a brief period of time where I was obsessed with completing a stage of a game in the most perfect way I could find. If I screwed up, then I re-loaded from a "perfect" save-point and tried again. I do remember acknowledging to myself that in a way it was ridiculous, it didn't really matter that much, cause I was having fun. I find some consolation in that those those days were years before I even thought about programming -- so, in a way, it could be that my behavioral pattern matched my career choice, as opposed to my career choice altering my behavioural patterns... If that is so, then the title of the above-mentioned article doesn't really apply to me, because in essence my life was "ruined" well before programming managed to get it's claws on it As I'm writing about this, I'm chatting with my father, who has also been blessed with the experience of treating programming as a profession. "That's like saying that life leads you to death," was his opinion of the article. While I agree, it was an interesting and thought provoking read. Tuesday, September 4. 2007Bug in System.Uri constructor?
I'm using the System.Uri class to clean up some the URLs we're passing around, e.g. compacting http://hostname//somefolder//somefile to http://hostname/somefolder/somefile.
The documentation clearly states that the Uri constructor takes care of this: MSDN. This works fine on my machine. However, when I try this on our server box (Win 2003), I just get back the string I passed to the constructor. I've checked the .NET versions and the assembly versions on both the target machine and my workstation. They match. Here's the code: CODE: using System; namespace sandpit { class Program { public static void Main(string[] args) { Type type = typeof(Uri); Console.WriteLine(type.ToString()); Console.WriteLine(type.Assembly); Console.WriteLine(type.AssemblyQualifiedName); Console.WriteLine(type.UnderlyingSystemType); Uri uri = new Uri(args.Length == 0 ? "http://hostname/// somefile.txt" : args[0]); Console.WriteLine(uri.ToString()); } } } I've posted this on Google Groups but so far, to no avail. Thursday, August 16. 2007The operation is not valid due to the current state of the object
I've recently become re-united with an old friend -- that's right, I'm back to working with SharePoint. Since this time I'm armed with a little bit more time and resources, I'm hoping it will be less painful than it was last time.
The first major snag I've hit so far is the issue of how to deploy custom web services on the SharePoint server. The docs from the SDK recommend the approach of adding the web service to SharePoint so that it can be accessed from _vti_bin/servicename.asmx. From my relatively inexperienced point of view, this is good for a number of reasons, the main one being that the custom web service runs as part of SharePoint, and things like permissions, privileges and access control seem to be handled for you. Great. There's a catch though. The main one is that you need to dump the WS assembly into the server's GAC. There are other pains in getting the disco and wsdl files set up for your custom WS, but the SDK walks you through those. An alternative to the recommended approach is to deploy your custom web service to an IIS web site separate from SharePoint (obviously, this is still on the SharePoint server). This seems to opens up a whole new can of worms with privileges. The fun begins. The problem I ran into was an "The operation is not valid due to the current state of the object" exception being thrown when adding files or updating items. Google saved the day rather quickly -- http://howtocode.blogspot.com/2007_06_01_archive.html. QUOTE: You must not call the SPListItem.Update inside the RunWithElevatedPrivileges block. Instead you should only instantiate the SPSite or SPWeb there and call Update afterwards... The strange thing is that this seemed to work last year, when I was bashing my head against the WSS Beta TR2. I guess things change... Wednesday, July 18. 2007Motobook
I've finally uploaded a small app I've been writing in my spare time -- get it here.
QUOTE:
This is a command-line utility that can be used to backup and restore the phonebook on a Motorola phone. I was motivated to write it as I couldn't find a way to backup my phonebook without booting into Windows. I use it with my RAZR V3, and haven't tested it with any other model, so your mileage may vary. Wednesday, December 6. 2006Wait, this was MY bug?
Recently, a colleague has pointed out that a part of my code could be the source of a potential memory leak.
The issue is described in detail here. QUOTE: If you create a thread and never call its start() method, then later null your reference to that thread, it will never be garbage collected. In my case, the culprit class was extending Thread. After creation, there would be some checking performed, and it will get started only if certain conditions were met. A quick and easy solution was to make it implement Runnable instead, and hold off creating the Thread until it is actually required. Nasty. Friday, October 20. 2006Back to the Drawing Board
It seems I spoke too soon about finding out a way to work around ExtendedProperties not being propagated. I noticed that this approach was not working 100% of the time. There would be times when the OnTaskCreated activity would never commence, leaving the workflow in an `In Progress' state permanently. At first I thought it may have been something I've changed, but after hours of searching I've found the root of the problem.
This MSDN article ruined my afternoon... QUOTE: This activity currently does not work in the Beta 2 version of Microsoft Windows SharePoint Services 3.0. Brilliant. At least they are honest about it. So I'm still out looking for a way to get around the property propagation issue. If I continue to pursue the manual propagation idea, I'll need an alternative to the OnTaskCreated activity that will force the workflow to commit its' data and create the actual task. This MSDN document describes why this is necessary. Invoking an External Process from a .NET web service
Recently, I've had to work on a .NET web service that needed to invoke an external process as part of its' normal operation. This is usually fairly trivial using the System.Diagnostics.Process class. In my case, however, there was a catch (yeah, there always is) -- the external process was a .NET windows application.
Using the Process class, I could get it to start, but it would never complete. Command-line applications worked fine. I soon noticed that in Task Manager, the new process belonged to the ASPNET user (or NETWORK SERVICES on a Windows 2003 box). My initial hunch that ASPNET didn't have the right privileges to start Windows apps made me start ASP.NET as a different user (a local user account). That worked. Thus my crusade to work out how to start the external process under a different user name began. I tried a variety of approaches, from changing the process owner programmatically to changing the owner of the application pool the web service ran in (not good). The last approach was the only one that worked consistently on WinXP and Win2003, but it broke other stuff, so I was still out looking for an alternative. A colleague saved my day, pointing me to this MS Support Article. The first paragraph exposed the futility of my previous attempts: QUOTE: To spawn a process that runs under the context of the impersonated user, you cannot use the System.Diagnostics.Process.Start method. This is because in ASP.NET, impersonation is performed at the thread level and not at the process level. Therefore, any process that you spawn from ASP.NET will run under the context of the ASP.NET worker process and not under the impersonated context. The article provides code to spawn a process in the context of the impersonated user. In the end, I could settle for this -- I configured the web service for anonymous access, with the anonymous account having sufficient rights to launch a Windows app. Friday, October 13. 2006Bug in SharePoint? ExtendedProperties Propagation
While working on my WSS workflow, I've noticed that the SPWorkflowTaskProperties.ExtendedProperties hashtable isn't propagated to the SPListItem.Properties hashtable of the corresponding task. This MSDN document says that it should:
QUOTE: If a value's key-name does not match any of the field for that task, the value is written to the SPListItem.Properties object of that task. The SPListItem.Properties property returns a System.Collections.Hashtable object. Writing data to this object makes it available through the Microsoft Windows SharePoint Services 3.0 object model. In other words, if you happen to do something like: CODE: createScanTask1_TaskProperties1.ExtendedProperties["hello"] = "world"; Then in theory you should be able to retrieve the same property like this: CODE: SPListItem task = ... // retrieve the task item string result = task.Properties["hello"]; In practice, however, that doesn't happen. The SPListItem.Properties hashtable does not contain any of the properties specified in SPWorkflowTaskProperties.ExtendedProperties. Of all the `issues' I've come across with SharePoint so far, this one takes the cake. Is it a bug? I'm not the one who can answer that. I've posted yet again to microsoft.public.sharepoint.development_and_programming, but to no avail. If it's a feature, then I'd be tempted to ask why it has been made so obscure (if you read what the documentation says, you can go as far as to say it's plain contradictory). In any case, I hope there's a better workaround than what I've had to write up in the meantime. At first, I thought I could take care of the property propagation manually. So, at the end of the workflow, I added a code activity which does roughly the following: CODE: int maxTaskID = 0 SPListItem taskItem = null; SPList taskList = workflowProperties.Web.Lists["Tasks"]; foreach (SPListItem item in taskList.Items) { if (item.ID > maxTaskID) { maxTaskID = item.ID; taskItem = item; } } // Manual propagation SPWorkflowTask.AlterTask(taskItem, createScanTask1_TaskProperties1, true); The whole thing rests on the assumption that the task you created has the highest ID in the task list. Not exactly safe, but I couldn't find a better way to find the ID of the task you have just created. Unfortunately, it doesn't seem like the task actually appears in the Tasks list until the workflow completes. I'm looking into why this is so, but have yet to come up with an answer. Until I do, it means I won't be able to propagate the properties manually, either. So, what to do, what to do?... I managed to get around it, but I've had to write some of the hackiest code I've written since the earlier years of uni, and I'm not exactly proud of it. It involves a web service. Need I say more? I'd be keen to ditch that approach for something more elegant. At this point, I'm just going to include a link to the SharePoint Team Blog. I'm hoping they can provide the answers I've been looking for. Tuesday, October 10. 2006Missing in Action: SPWorkflow.TemplateId Property
The SharePoint saga continues. Recently, I installed the Beta 2 technical refresh on the server, hoping it would solve some of the problems I was having. It didn't -- but I still felt somewhat more at ease knowing I was running a more up-to-date version.
Contrary to my naive expectations that the update wouldn't break any of my existing stuff, at least one thing did get broken -- the SPWorkflow class no longer has the property TemplateId. It's still present here in MSDN, but if you've downloaded the WSS V3 TR2 SDK (what a mouthful), you'll see it's no longer there. Now, the CollectFeedback sample (it's part of the Workflow Developer Starter Kit, if I'm not mistaken) that I have learned to love and hate over the last few weeks references that property in one of it's content type ASPX pages -- and the page goes boom!. Luckily, the error message is informative enough to point me in the right direction. It looks like I'm going to have to go and figure out what the hell that template ID thing was, cause neither Google nor Google Groups come up with anything too informative. Either that, or just hose the code using the templateId completely. The last option is the more tempting, and also the more appealing to the more time-constrained individuals like myself. Wouldn't mind knowing what happened to it, though. Monday, October 9. 2006More SharePoint
I know it hasn't been long since the last whinge about SharePoint, but I've run into another `issue'.
CODE: SPSite collection = new SPSite("http://tito"); The code fragment above works fine on a general task. However, if the task has been created as part of a workflow, and the workflow is still running -- then you have problems. In my particular instance, I have a OnTaskChange activity waiting for modifications to the task. The code above causes an Microsoft.SharePoint.SPException to be thrown -- `This task is currently locked by a running workflow and cannot be edited'.SPWebCollection webs = collection.AllWebs; SPWeb expenseWeb = webs[0]; SPListItemCollection listItems = expenseWeb.Lists["Tasks"].Items; foreach (SPListItem item in listItems) { if (item.ID == id) { Hashtable ht = new Hashtable(); ht["TaskStatus"] = "Completed"; SPWorkflowTask.AlterTask(item, ht, true); item.Update(); Console.WriteLine("Task updated"); break; } } Great. Nice informative error message (pleasant surprise from Microsoft). It's somewhat false, though -- I can edit the task just fine through SharePoint, changing any of it's regular properties like title, description, comments, etc. So it's not that it can't be edited -- it just can't be edited by anything except SharePoint. Fantastic. I'm hoping a post to microsoft.public.sharepoint.development_and_programming will help me work around it. SharePoint Woes
Recently, I've been blessed with the task of writing a workflow for Windows SharePoint Services (WSS) 3. It sounded like a pretty good idea at the start -- workflows make our lives easier by leaving the mundane administration-like tasks to the computer. So, off I went on an amazing journey on discovery. This post is purely for my own convenience -- I'm going to use it to keep track of relevant links as I move along. Read on at your own risk
First, I had a look at the Windows Workflow Foundation stuff that is at the guts of the workflow stuff in WSS. Then, some papers and webcasts on how the workflow stuff it all fits into WSS. Here's a list of links that I consider to be quite useful in my quest:
The great thing about debugging WSS 3.0 workflows is the generous amount of information you get when things go wrong. You receive the proverbial `An error has occured in HandyDandyWorkflow'. That's it. It could be an attempt to dereference null, I/O problems, changing phases of the moon -- you name it. So in search for more info, I decided to ask the people behind SharePoint. Link: SharePoint Team Blog. Another hurdle I had to take was debugging Web applications remotely. Once again, symbols for the web application DLL weren't being loaded, and I wasn't able to make much use of the debugger. A few hours of Googling finally came up with a result -- it's slightly ironic, but the original question was asked at pretty much the same time I was hopelessly bashing my head against it. Link: microsoft.public.vsnet.debugging (Google Groups). Moving right along. The next somewhat mysterious issue I've encountered is this -- I have a few lines of code that execute without a problem when running inside a console app on the server. Put the same code in a web service, and you've got yourself a problem. I whinged about it on a Microsoft newsgroup -- microsoft.public.sharepoint.development_and_programming. As you would guess, some of it is really frustrating stuff. The part that's worst about it is that's it's time-consuming and low-productivity work. Running into errors generally means that you have to recompile, redeploy, cancel an existing workflow instance, restart the process, continue until it hits another error. Rinse, dry, repeat. It's kind of fun, cause it's new... And it's challenging. Perhaps not the foreign-language-learning type of challening -- it's say it's more like learning to touch-type with your nose. But I'm sure I'll get there eventually. Monday, September 4. 2006Russian input table for SCIM
Over the weekend, I started feeling a bit nostalgic about uni and decided to install Fluxbox on my home machine. One of the first problems I ran into was switching keyboard layouts -- I needed to enter text in Russian and Japanese as well as English. Previously, I used Gnome, which had an app to change the X keyboard layout, and SCIM, which I could use as an input method for Japanese.
I had long wondered whether I need both the X keyboard switcher and SCIM, since SCIM seems sophisticated enough to handle it alone. But, alas, the only Russian input table I could find was the somewhat weird Yawerty. The more popular Jcuken was nowhere to be found. But I didn't really have a reason to do anything about it... until now. There didn't seem to be any good keyboard layout switchers for Fluxbox, so I decided to have a go at writing my very own SCIM table. It actually wasn't so hard... Armed with instructions from the SCIM page, Fluxbox FAQ, the Yawerty input table, and a copy of Vim's russian-jcuken.vim tables, I set out on my heroic quest. The result -- behold... Russian Jcuken keyboard layout for SCIM. Done deal. Edit: I thought I might clarify why exactly you'd need this sort of thing. After all, keyboard layouts are handled perfectly fine by X (setxkbmap). You don't really need SCIM here. It gets a bit more complicated when you want to input in languages that require a little more than a keyboard layout change -- in my case, I sometimes need to input Japanese. So to save myself using two separate input language switchers, I decided to use SCIM for both of them. Thursday, July 6. 2006WinCVS 2.0.2.4 whinge
I've recently had to do some work on a laptop -- the environment was mostly the same as my work machine (Windows XP, Eclipse, WinCVS was all set up for me) so I didn't expect there to be any transition problems. However, when I fired up WinCVS and tried to consumate it with my near and dear gVim I was caught in a state of shock and horror as I wasn't able to get it to diff using gVim. You get gVim to diff two files by passing it `-id' as a command line argument.
So here the fun begins. WinCVS isn't smart enough to realise that '-d' is an argument and not part of the executable name. No biggie. Previous versions of WinCVS (like the ancient 1.3.13.2 Build 13 -- yeah, it's the lucky build) were happy enough to use a Windows shortcut to fire up gVim in diff mode. WinCVS 2.0.2.4, in its' wisdom, dereferences the shortcut to locate the executable, and ignores the command line argument... great. So what do you do? I didn't have to hold on to that laptop for too long, and as it already had WinMerge installed I just grit my teeth and used that. Not that WinMerge isn't good, it's just that I've grown so attached to Vim that it takes a lot to get me to use anything else resembling a text editor. However, when I got back to my work machine, curiosity set in. I'd probably have to upgrade to a newer WinCVS version at some point, anyway. And, as reluctant as I am to even look in the direction of MS-DOS, it seems to do the trick here. CODE: start /D"C:\Program Files\Vim\vim70" gvim.exe -d %1 %2 Stick that into a batch file somewhere convenient, and specify the batch file as your diff program. I'm no DOS wizard, so I needed a little bit of help. This place provided the info I needed. The start command kicks off Vim as a different process so that ugly DOS window doesn't hang around. The /D option specifies the working directory. The -d flag tells gvim to start in diff mode. The %1 and %2 pass the command-line arguments to the executable. Done deal. Wednesday, June 21. 2006Feeling Pragmatic Enough Yet?
A few months ago, my workplace bookshelf received a fresh addition -- The Pragmatic Programmer. I started reading it straight away, and while I can't say that I was unable to put it down (it's kind of been a couple of weeks, I've been busy, etc), I'm finally through it now. Personally, my thoughts are `Wow, what an interesting and useful book'. The way the book is written helps a great deal -- it is divided into relatively small sections, some of which share logical connections but are mostly independent. For me it meant I could read it on and off while time-consuming stuff was happening in the background. I'm not going to bother reviewing it, as I'm sure many other places already have, but I reckon it's a great book that's well worth a read.
I'm hoping that this marks an end to the more or less recent `reading drought' that I have been experiencing. We shall see soon enough...
(Page 1 of 2, totaling 19 entries)
» next page
|
Calendar
QuicksearchArchivesCategoriesSyndicate This BlogBlog Administration |
|||||||||||||||||||||||||||||||||||||||||||||||||
