2009-01-02

TightVNC Port Number Gotcha

TightVNC is great if you want to remote-control someone else's PC without resorting to MS' Remote Desktop solution.

Something that cost me about an hour's worth of frustration, though, is their way of specifying an alternative to the standard port (5900):

You either

  1. specify an alternate screen number (a small integer, e.g. 5 means screen 5 means port 5905); or

  2. explicitly specify an alternate port, e.g. 5905 .


Alternative 1 is selected with a colon between the host address and the screen number, e.g.

66.66.66.66:5

To specify an alternate port, you need to insert two colons:

66.66.66.66::5905

Because colons are just tiny freckles on the screen, especially in proportional fonts, this is easy to overlook in the documentation. Many other utilities (and URLs) use single colons before a port number, so habit has us do the wrong thing by default.

2008-12-20

Autocompletion in the Windows command processor

Registry key:

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor (for all users)
or
HKEY_CURRENT_USER\Software\Microsoft\Command Processor (for the current user)

Set
CompletionChar to 9 to have TAB complete file names,
PathCompletionChar to 9 to have TAB complete folder names.

Nuff said.

2008-12-14

HTML Help Gotcha on toc.hhc

If you're trying to create MS HTML Help files (.CHM) programmatically, you may need to generate your own TOC.

The documentation available from Microsoft does its best to keep you in the dark: They tell you how to generate it in Help Workshop using their point-and-click GUI. It's serviceable but not much fun to use. No wonder there's such a huge cottage industry of MS Help front ends!

Paul Wise bravely documents what he could re-engineer about the innards of the .CHM file but only devotes a rather short section to the Sitemap format of the TOC, which I quote here:

These formats are based on HTML and use the following doctype:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">

The <HEAD> tag contains a <meta> tag providing information on the program that generated the files and a comment indicating the version of the file. e.g.:

<meta name="GENERATOR"content="Microsoft® HTML Help Workshop 4.1">
<!-- Sitemap 1.0 -->

The <BODY> tag contains an <OBJECT> tag that stores properties of the file in <param> tags, followed by a <UL> tag, whose <LI> tags have <OBJECT> tags that store the properties of the Contents/Index items in <param> tags. e.g.:

<BODY>
<OBJECT type="text/site properties">
<param name="Property Name" value="Property Value">

</OBJECT>
<UL>
<LI> <OBJECT type="text/sitemap">
<param name="Property Name" value="Property Value">

</OBJECT>

</UL>
</BODY>

Note that the Property Names and Property Values and tags are not case-sensitive, but HHW will always write all three in the default capitilization, when appropriate.

Note that the tags are mostly in uppercase and the <LI> tag is not closed; this is in compliance with the doctype.

I spent some days generating the TOC from a different structure. To help with eyeball debugging, my HTML was nicely indented. I started a new line for each tag - not entirely unreasonable. Without the indentation, here's an example of what I created:
<HTML>
<BODY>
<UL>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="Heading 1">
<param name="Local" value="h1.htm">
</OBJECT>
</LI>
</UL>
</BODY>
</HTML>

Try as I might, HHW (the Workshop) would not display such a TOC, and HHC (the Compiler) would not produce a working .CHM from it. I spent a long time figuring out what's needed to make it work, as in the following:
<HTML>
<BODY>
<UL>
<LI><OBJECT type="text/sitemap">
<param name="Name" value="Heading 1">
<param name="Local" value="h1.htm">
</OBJECT>
</LI>
</UL>
</BODY>
</HTML>

This appears to be one of the best kept secrets of the HTML Help generating industry:

If you don't put <LI> on the same line as <OBJECT>, the TOC parser will fail!

So the accepted format is essentially an HTML Unordered List of Objects with details in Params, give or take a horrible bug in the scanner/parser.

On the bright side, in my experience the following bits are not essential:

  • As Paul states, tags and even attribute names are accepted in upper or lower case.

  • The stuff in the <HEAD> isn't needed and can be dispensed with.

  • The text/site properties OBJECT is only needed if you want to fiddle with the options

  • Tags may be consistently closed (XML fashion), including those that HTML is inconsistent about, such as <meta> and <param. Similarly, it's OK to have closing </LI>'s.

2008-12-12

Running HTML Help Workshop under Wine

Help Workshop is a Microsoft product that creates somewhat compressed help files (.CHM) for use in/with MS programs. The Workshop "main" is a GUI application but there's also a standalone compiler.

Installed and run under Wine in a modern Linux (Ubuntu 8.04), hhw.exe and hhc.exe kept telling me:
HHC5010: Error: Cannot open "C:\windows\temp\TFS483e.tmp". Compilation stopped.

I found a simple fix at The MRPT Project:

You are advised to open "Wine Configuration," set up new configs for hhw.exe and/or hhc.exe . For either or both, in the Libraries tab, add a new override for "itss," then edit it to select "native."

My Wine installation already had an itss.dll in .wine/drive_c/windows/system32, but it was a tiny thing a little over 4 KB in size. I found a "real" itss.dll on the 'net of about 134 KB and plunked that over the installed one.

Both hhw and hhc work for me now.

2008-11-16

Tomcat permissions

As packaged with Ubuntu 8.04, Tomcat is set up pretty tight on security. The configured permissions are quite minimal, so many things you'd want to do in your servlets or JSPs needs to be explicitly permitted.

This isn't necessarily surprising; but it can be a pain.

First, some helpful links: The Security Manager HOW-TO in Apache's Tomcat documentation explains the basics. For specifics on the format of permission entries, see Sun's documentation on Default Policy Implementation and Policy File Syntax.

Notes:


  • Tomcat's policy settings are (on my Ubuntu box) in /usr/share/tomcat5.5/conf/catalina.policy. But heed the warning in the file's header: If your system is Debian-esque (and that includes Ubuntu) then that file is auto-generated from a set of files in conf/policy.d, and those are the ones you want to be editing. Permissions you want to add for your web apps will likely best fit in 50user.policy.


  • The policy files are concatenated and the settings initialized when Tomcat starts. Hence, you need to restart Tomcat in order for permission changes to have an effect.


  • The codeBase string is a URL, so it always takes forward slashes. File names for FilePermission may be operating system dependent, so you should use ${file.separator} instead there.


  • As explained in the Sun doc, an asterisk (*) in a path for FilePermission (roughly) means "everything in this directory", while a dash (-) means "everything in this directory and recursively in all subdirectories". Likewise, the beginning of a host address for SocketPermission may be wildcarded with an asterisk. In the extreme case, the entire host address may be an asterisk and so will apply to "any host".


  • If you're having trouble getting permissions to take effect, you can try narrowing down the problem by making either the codeBase universal (surprisingly, the "codeBase" descriptor is optional, so it's quite legal to have a stanza that starts with "permit {" or the permission all-encompassing: that would be "java.security.AllPermission". Once you get stuff working with this gaping security hole, you will want to go back and try to tighten it up again.

2008-11-15

Document is null

I tried to read an XML configuration file into a DOM, like so:

InputStream configInputStream = this.getClass().getClassLoader().getResourceAsStream(CONF_FILE_NAME);
log("configInputStream = " + configInputStream);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(configInputStream);
log("Found and read configuration: " + doc);
configInputStream.close();

...and the log said:
INFO: ToonGrator: Found and read configuration: [#document: null]

I guess the square brackets and the extra text should have tipped me off, but I sure thought
I had read in a null document!

It isn't really. It turns out that the root (or document) node always contains no text, so
whatever its toString() returns will say "null". Oh well, back to work!

2008-11-12

Writing files from JavaScript

In Internet Explorer, you can use the ActiveXObject "microsoft.xmldom" to load an XML file into a DOM that can be inspected and manipulated from JavaScript. So far so good. But what if you want to write an XML file to the local file system? XmlDom has a save() method and the argument lets you specify a local file path. But in IE6 and later, the attempt will always fail.

The 'net is full of forum posts with frantic pleas for help with titles like "XML DOM save - File Permission denied". In almost all cases, the answers fell into the following categories:

"Tough luck, that's the way it is" / "the cookie crumbles."

True enough, but not helpful.

"You need to have write permission on the folder you're writing to!"

True enough, but I'll bet everyone with half a brain checked that before posting. Even if that was the problem, you'd run up against the previous one.

"I have the same problem. Please email me the answer!"

Me too!

"You can't do that from HTML, you need a HTA

True enough, but if the requester could get a user to download and execute an application he wouldn't have this problem in the first place.

"In ASP on the server you do this..."

That doesn't help with saving files on the client's file system.



It was a long time before I came across a post that mentioned FileSystemObject. It turns out that while xmldom.save() is never allowed to write to the local file system (apparently no amount of tweaking any permissions will change that), FileSystemObject can create, read, write and even delete files, subject to permissions given in IE's Internet Options.

It's no big deal to pull the XML from the DOM as a String and to save it using a TextStream object created by FileSystemObject.CreateTextFile(). Here's a code sample of mine that does it:


function save2()
{
var xmlDoc = new ActiveXObject("microsoft.xmldom");
xmlDoc.load(path + "stuff.xml");
alert("stuff.xml loaded");
fso = new ActiveXObject("Scripting.FileSystemObject");
f2 = fso.CreateTextFile(path + "stuff2.xml", true);
f2.write(xmlDoc.xml);
f2.Close();
alert("stuff2.xml saved");
}


I surmise that more readers of those forums knew the "right" answer but chose not to tell because they suspected malicious intent on part of the requesters. When you can write to the user's file system you can do many evil things.

My take on this is: Any user surfing the Web with IE and permissions set to "trusting" is asking for trouble anyway; and the more professional malware authors already know how to exploit this. Microsoft's choice to never allow XmlDom to save looks silly in view of the fact that there's a perfectly workable back door.

My own use of this feature is legitimate, of course: I'm working with a JavaScript application that wants to store some user settings on the user's machine. More information than will fit into a cookie, and there's no server to persist the information on. Also, it's a closed environment, even to the user, with no Internet connection, so it can safely run with full permissions.