command page 2 - Dave's Blog

Search
My timeline on Mastodon

Think you've mastered Linux? Prove it, with Suicide Linux

2010 Feb 23, 9:38Think you're a bad ass having installed some obscure and difficult to use Linux distro, then prove how hardcore of a Linux nerd you are with '...Suicide Linux, where any unrecognized command is parsed as "rm -rf /"...'PermalinkCommentshumor geek linux bash technical

Researchers identify command servers behind Google attack

2010 Jan 14, 2:54Wow: "If the report's findings are correct, it suggests that the government of China has been engaged for months in a massive campaign of industrial espionage against US companies."PermalinkCommentsinternet google china security politics privacy

WPAD Server Fiddler Extension

2010 Jan 5, 7:42

I've made a WPAD server Fiddler extension and in a fit of creativity I've named it: WPAD Server Fiddler Extension.

Of course you know about Fiddler, Eric's awesome HTTP debugger tool, the HTTP proxy that lets you inspect, visualize and modify the HTTP traffic that flows through it. And on the subject you've probably definitely heard of WPAD, the Web Proxy Auto Discovery protocol that allows web browsers like IE to use DHCP or DNS to automatically discover HTTP proxies on their network. While working on a particularly nasty WPAD bug towards the end of IE8 I really wished I had a way to see the WPAD requests and responses and modify PAC responses in Fiddler. Well the wishes of me of the past are now fulfilled by present day me as this Fiddler extension will respond to WPAD DHCP requests telling those clients (by default) that Fiddler is their proxy.

When I started working on this project I didn't really understand how DHCP worked especially with respect to WPAD. I won't bore you with my misconceptions: it works by having your one DHCP server on your network respond to regular DHCP requests as well as WPAD DHCP requests. And Windows I've found runs a DHCP client service (you can start/stop it via Start|Run|'services.msc', scroll to DHCP Client or via the command line with "net start/stop 'DHCP Client'") that caches DHCP server responses making it just slightly more difficult to test and debug my extension. If a Windows app uses the DHCP client APIs to ask for the WPAD option, this service will send out a DHCP request and take the first DHCP server response it gets. That means that if you're on a network with a DHCP server, my extension will be racing to respond to the client. If the DHCP server wins then the client ignores the WPAD response from my extension.

Various documents and tools I found useful while working on this:

PermalinkCommentsproxy fiddler http technical debug wpad pac tool dhcp

Time/Date Conversion Tool

2009 Aug 28, 3:39

I built timestamp.exe, a Windows command line tool to convert between computer and human readable date/time formats mostly for working on the first run wizard for IE8. We commonly write out our dates in binary form to the registry and in order to test and debug my work it became useful to be able to determine to what date the binary value of a FILETIME or SYSTEMTIME corresponded or to produce my own binary value of a FILETIME and insert it into the registry.

For instance, to convert to a binary value:

[PS C:\] timestamp -inString 2009/08/28:10:18 -outHexValue -convert filetime
2009/08/28:10:18 as FILETIME: 00 7c c8 d1 c8 27 ca 01

Converting in the other direction, if you don't know what format the bytes are in, just feed them in and timestamp will try all conversions and list only the valid ones:

[PS C:\] timestamp -inHexValue  "40 52 1c 3b"
40 52 1c 3b as FILETIME: 1601-01-01:00:01:39.171
40 52 1c 3b as Unix Time: 2001-06-05:03:30:08.000
40 52 1c 3b as DOS Time: 2009-08-28:10:18:00.000
(it also supports OLE Dates, and SYSTEMTIME which aren't listed there because the hex value isn't valid for those types). Or use the guess option to get timestamp's best guess:
[PS C:\] timestamp -inHexValue  "40 52 1c 3b" -convert guess
40 52 1c 3b as DOS Time: 2009-08-28:10:18:00.000

When I first wrote this I had a bug in my function that parses the date-time value string in which I could parse 2009-07-02:10:18 just fine, but I wouldn't be able to parse 2009-09-02:10:18 correctly. This was my code:

success = swscanf_s(timeString, L"%hi%*[\\/- ,]%hi%*[\\/- ,]%hi%*[\\/- ,Tt:.]%hi%*[:.]%hi%*[:.]%hi%*[:.]%hi", 
&systemTime->wYear,
&systemTime->wMonth,
&systemTime->wDay,
&systemTime->wHour,
&systemTime->wMinute,
&systemTime->wSecond,
&systemTime->wMilliseconds) > 1;
See the problem?

To convert between these various forms yourself read The Old New Thing date conversion article or Josh Poley's date time article. I previously wrote about date formats I like and dislike.

PermalinkCommentsdate date-time technical time windows tool

Apollo 11 lunar and command module software open-sourced

2009 Jul 23, 2:59"hand-typed from original scans by the Virtual AGS project; in the comments, numero mysterioso and hope hope hope"PermalinkCommentshumor code space programming via:waxy technical

Pizzas - Commander - Speed Rabbit Pizza

2009 Apr 1, 12:32Spped Rabbit Pizza's "IE8 Explorer" pizza: 8 slices, 8 ingredients, 8 Euros.PermalinkCommentshumor pizza ie8 ie france

Command-line Fu - The best UNIX commands on the web

2009 Mar 23, 9:35Ohhh some nice ones in here. "Command-Line-Fu is the place to record those command-line gems that you return to again and again."PermalinkCommentsshell unix linux cli howto tips via:swannman

Subst Allows Non-Letter Drive Letters

2009 Mar 4, 2:39

I knew that the command line tool subst would create virtual drives that map to existing directories but I didn't know that subst lets you name the virtual drives with characters that aren't US-ASCII letters. For instance you can run 'subst 4: C:\windows' and then 'more 4:\win.ini' to dump C:\windows\win.ini. This also works for non-US-ASCII characters like, "C" (aka U+FF23, Fullwidth Latin Capital Letter C), which when displayed by cmd.exe via some best fit style character conversions looks just like the regular US-ASCII 'C'. None of Explorer, IE, or the common file dialogs allow the use of these odd virtual drives -- just cmd.exe, so I'm not sure how this would ever be useful but I thought it was odd and I wanted to share.

PermalinkCommentscli technical boring subst windows

Post to Twitter using the command line - Download Squad

2009 Jan 15, 10:28Thanks to Matt, for the first time I can see myself using Twitter. Twitter app on my phone notifies me when something's posted so my build process can let me know when its done, or when sync finally finishes, etc. I'd been meaning to setup a mini-notification system with a command line tool to my phone (w/o paying per text msg) but I didn't think of Twitter.PermalinkCommentsvia:swannman api internet curl cli twitter

Tab Expansion in PowerShell

2008 Nov 18, 6:38

PowerShell gives us a real CLI for Windows based around .Net stuff. I don't like the creation of a new shell language but I suppose it makes sense given that they want something C# like but not C# exactly since that's much to verbose and strict for a CLI. One of the functions you can override is the TabExpansion function which is used when you tab complete commands. I really like this and so I've added on to the standard implementation to support replacing a variable name with its value, tab completion of available commands, previous command history, and drive names (there not restricted to just one letter in PS).

Learning the new language was a bit of a chore but MSDN helped. A couple of things to note, a statement that has a return value that you don't do anything with is implicitly the return value for the current function. That's why there's no explicit return's in my TabExpansion function. Also, if you're TabExpansion function fails or returns nothing then the builtin TabExpansion function runs which does just filenames. This is why you can see that the standard TabExpansion function doesn't handle normal filenames: it does extra stuff (like method and property completion on variables that represent .Net objects) but if there's no fancy extra stuff to be done it lets the builtin one take a crack.

Here's my TabExpansion function. Probably has bugs, so watch out!


function EscapePath([string] $path, [string] $original)
{
    if ($path.Contains(' ') -and !$original.Contains(' '))
    {
        '"'   $path   '"';
    }
    else
    {
        $path;
    }
}

function PathRelativeTo($pathDest, $pathCurrent)
{
    if ($pathDest.PSParentPath.ToString().EndsWith($pathCurrent.Path))
    {
        '.\'   $pathDest.name;
    }
    else
    {
        $pathDest.FullName;
    }
}

#  This is the default function to use for tab expansion. It handles simple
# member expansion on variables, variable name expansion and parameter completion
# on commands. It doesn't understand strings so strings containing ; | ( or { may
# cause expansion to fail.

function TabExpansion($line, $lastWord)
{
    switch -regex ($lastWord)
    {
         # Handle property and method expansion...
         '(^.*)(\$(\w|\.) )\.(\w*)$' {
             $method = [Management.Automation.PSMemberTypes] `
                 'Method,CodeMethod,ScriptMethod,ParameterizedProperty'
             $base = $matches[1]
             $expression = $matches[2]
             Invoke-Expression ('$val='   $expression)
             $pat = $matches[4]   '*'
             Get-Member -inputobject $val $pat | sort membertype,name |
                 where { $_.name -notmatch '^[gs]et_'} |
                 foreach {
                     if ($_.MemberType -band $method)
                     {
                         # Return a method...
                         $base   $expression   '.'   $_.name   '('
                     }
                     else {
                         # Return a property...
                         $base   $expression   '.'   $_.name
                     }
                 }
             break;
          }

         # Handle variable name expansion...
         '(^.*\$)([\w\:]*)$' {
             $prefix = $matches[1]
             $varName = $matches[2]
             foreach ($v in Get-Childitem ('variable:'   $varName   '*'))
             {
                 if ($v.name -eq $varName)
                 {
                     $v.value
                 }
                 else
                 {
                    $prefix   $v.name
                 }
             }
             break;
         }

         # Do completion on parameters...
         '^-([\w0-9]*)' {
             $pat = $matches[1]   '*'

             # extract the command name from the string
             # first split the string into statements and pipeline elements
             # This doesn't handle strings however.
             $cmdlet = [regex]::Split($line, '[|;]')[-1]

             #  Extract the trailing unclosed block e.g. ls | foreach { cp
             if ($cmdlet -match '\{([^\{\}]*)$')
             {
                 $cmdlet = $matches[1]
             }

             # Extract the longest unclosed parenthetical expression...
             if ($cmdlet -match '\(([^()]*)$')
             {
                 $cmdlet = $matches[1]
             }

             # take the first space separated token of the remaining string
             # as the command to look up. Trim any leading or trailing spaces
             # so you don't get leading empty elements.
             $cmdlet = $cmdlet.Trim().Split()[0]

             # now get the info object for it...
             $cmdlet = @(Get-Command -type 'cmdlet,alias' $cmdlet)[0]

             # loop resolving aliases...
             while ($cmdlet.CommandType -eq 'alias') {
                 $cmdlet = @(Get-Command -type 'cmdlet,alias' $cmdlet.Definition)[0]
             }

             # expand the parameter sets and emit the matching elements
             foreach ($n in $cmdlet.ParameterSets | Select-Object -expand parameters)
             {
                 $n = $n.name
                 if ($n -like $pat) { '-'   $n }
             }
             break;
         }

         default {
             $varNameStar = $lastWord   '*';

             foreach ($n in @(Get-Childitem $varNameStar))
             {
                 $name = PathRelativeTo ($n) ($PWD);

                 if ($n.PSIsContainer)
                 {
                     EscapePath ($name   '\') ($lastWord);
                 }
                 else
                 {
                     EscapePath ($name) ($lastWord);
                 }
             }

             if (!$varNameStar.Contains('\'))
             {
                foreach ($n in @(Get-Command $varNameStar))
                {
                    if ($n.CommandType.ToString().Equals('Application'))
                    {
                       foreach ($ext in @((cat Env:PathExt).Split(';')))
                       {
                          if ($n.Path.ToString().ToLower().EndsWith(($ext).ToString().ToLower()))
                          {
                              EscapePath($n.Path) ($lastWord);
                          }
                       }
                    }
                    else
                    {
                        EscapePath($n.Name) ($lastWord);
                    }
                }

                foreach ($n in @(Get-psdrive $varNameStar))
                {
                    EscapePath($n.name   ":") ($lastWord);
                }
             }

             foreach ($n in @(Get-History))
             {
                 if ($n.CommandLine.StartsWith($line) -and $n.CommandLine -ne $line)
                 {
                     $lastWord   $n.CommandLine.Substring($line.Length);
                 }
             }

             # Add the original string to the end of the expansion list.
             $lastWord;

             break;
         }
    }
}

PermalinkCommentscli technical tabexpansion powershell

Investigation of a Few Application Protocols (Updated)

2008 Oct 25, 6:51

Windows allows for application protocols in which, through the registry, you specify a URL scheme and a command line to have that URL passed to your application. Its an easy way to hook a webbrowser up to your application. Anyone can read the doc above and then walk through the registry and pick out the application protocols but just from that info you can't tell what the application expects these URLs to look like. I did a bit of research on some of the application protocols I've seen which is listed below. Good places to look for information on URI schemes: Wikipedia URI scheme, and ESW Wiki UriSchemes.

Some Application Protocols and associated documentation.
Scheme Name Notes
search-ms Windows Search Protocol The search-ms application protocol is a convention for querying the Windows Search index. The protocol enables applications, like Microsoft Windows Explorer, to query the index with parameter-value arguments, including property arguments, previously saved searches, Advanced Query Syntax, Natural Query Syntax, and language code identifiers (LCIDs) for both the Indexer and the query itself. See the MSDN docs for search-ms for more info.
Example: search-ms:query=food
Explorer.AssocProtocol.search-ms
OneNote OneNote Protocol From the OneNote help: /hyperlink "pagetarget" - Starts OneNote and opens the page specified by the pagetarget parameter. To obtain the hyperlink for any page in a OneNote notebook, right-click its page tab and then click Copy Hyperlink to this Page.
Example: onenote:///\\GUMMO\Users\davris\Documents\OneNote%20Notebooks\OneNote%202007%20Guide\Getting%20Started%20with%20OneNote.one#section-id={692F45F5-A42A-415B-8C0D-39A10E88A30F}&end
callto Callto Protocol ESW Wiki Info on callto
Skype callto info
NetMeeting callto info
Example: callto://+12125551234
itpc iTunes Podcast Tells iTunes to subscribe to an indicated podcast. iTunes documentation.
C:\Program Files\iTunes\iTunes.exe /url "%1"
Example: itpc:http://www.npr.org/rss/podcast.php?id=35
iTunes.AssocProtocol.itpc
pcast
iTunes.AssocProtocol.pcast
Magnet Magnet URI Magnet URL scheme described by Wikipedia. Magnet URLs identify a resource by a hash of that resource so that when used in P2P scenarios no central authority is necessary to create URIs for a resource.
mailto Mail Protocol RFC 2368 - Mailto URL Scheme.
Mailto Syntax
Opens mail programs with new message with some parameters filled in, such as the to, from, subject, and body.
Example: mailto:?to=david.risney@gmail.com&subject=test&body=Test of mailto syntax
WindowsMail.Url.Mailto
MMS mms Protocol MSDN describes associated protocols.
Wikipedia describes MMS.
"C:\Program Files\Windows Media Player\wmplayer.exe" "%L"
Also appears to be related to MMS cellphone messages: MMS IETF Draft.
WMP11.AssocProtocol.MMS
secondlife [SecondLife] Opens SecondLife to the specified location, user, etc.
SecondLife Wiki description of the URL scheme.
"C:\Program Files\SecondLife\SecondLife.exe" -set SystemLanguage en-us -url "%1"
Example: secondlife://ahern/128/128/128
skype Skype Protocol Open Skype to call a user or phone number.
Skype's documentation
Wikipedia summary of skype URL scheme
"C:\Program Files\Skype\Phone\Skype.exe" "/uri:%l"
Example: skype:+14035551111?call
skype-plugin Skype Plugin Protocol Handler Something to do with adding plugins to skype? Maybe.
"C:\Program Files\Skype\Plugin Manager\skypePM.exe" "/uri:%1"
svn SVN Protocol Opens TortoiseSVN to browse the repository URL specified in the URL.
C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe /command:repobrowser /path:"%1"
svn+ssh
tsvn
webcal Webcal Protocol Wikipedia describes webcal URL scheme.
Webcal URL scheme description.
A URL that starts with webcal:// points to an Internet location that contains a calendar in iCalendar format.
"C:\Program Files\Windows Calendar\wincal.exe" /webcal "%1"
Example: webcal://www.lightstalkers.org/LS.ics
WindowsCalendar.UrlWebcal.1
zune Zune Protocol Provides access to some Zune operations such as podcast subscription (via Zune Insider).
"c:\Program Files\Zune\Zune.exe" -link:"%1"
Example: zune://subscribe/?name=http://feeds.feedburner.com/wallstrip.
feed Outlook Add RSS Feed Identify a resource that is a feed such as Atom or RSS. Implemented by Outlook to add the indicated feed to Outlook.
Feed URI scheme pre-draft document
"C:\PROGRA~2\MICROS~1\Office12\OUTLOOK.EXE" /share "%1"
im IM Protocol RFC 3860 IM URI scheme description
Like mailto but for instant messaging clients.
Registered by Office Communicator but I was unable to get it to work as described in RFC 3860.
"C:\Program Files (x86)\Microsoft Office Communicator\Communicator.exe" "%1"
tel Tel Protocol RFC 5341 - tel URI scheme IANA assignment
RFC 3966 - tel URI scheme description
Call phone numbers via the tel URI scheme. Implemented by Office Communicator.
"C:\Program Files (x86)\Microsoft Office Communicator\Communicator.exe" "%1"
(Updated 2008-10-27: Added feed, im, and tel from Office Communicator)PermalinkCommentstechnical application protocol shell url windows

Why Verbs? - Not The User's Fault

2008 Aug 28, 11:15I can't say why this is funny: "First, the really big picture of what Ubiquity is supposed to be all about: It's a step towards a Web where verbs (i.e. functionality, i.e. commands, i.e. services) are first-class citizens. And that's why I'm thinking it should be renamed from Ubiquity to something like "Mozilla Verbs", maybe."PermalinkCommentsmozilla firefox ubiquity ui via:ethan_t_hein

URI Addressable Text Adventure Games

2008 Mar 2, 9:18

This post is about creating a server side z-code interpreter that represents game progress in the URI. Try it with the game Lost Pig.

I enjoy working on URIs and have the mug to prove it. Along those lines I've combined thoughts on URIs with interactive fiction. I have a limited amount of experience with Inform which generates Z-Code so I'll focus on pieces written in that. Of course we can already have URIs identifying the Z-Code files themselves, but I want URIs to identify my place in a piece of interactive fiction. The proper way to do this would be to give Z-Code its own mimetype and associate with that mimetype the format of a fragment that would contain the save state of user's interactive fiction session. A user would install a browser plugin that would generate URIs containing the appropriate fragment while you play the IF piece and be able to load URIs identifying Z-Code files and load the save state that appears in the fragment.

But all of that would be a lot of work, so I made a server side version that approximates this. On the Web Frotz Interpreter page, enter the URI of a Z-Code file to start a game. Enter your commands into the input text box at the bottom and you get a new URI after every command. For example, here's the beginning of Zork. I'm running a slightly modified version of the Unix version of Frotz. Baf's Guide to the IF Archive has lists of IF games to try out.

There are two issues with this thought, the first being the security issues with running arbitrary z-code and the second is the practical URI length limit of about 2K in IE. From the Z-Code standard and the Frotz source it looks like 'save' and 'restore' are the only commands that could do anything interesting outside of the Z-Code virtual machine. As for the length-limit on URIs I'm not sure that much can be done about that. I'm using a base64 encoded copy of the compressed input stream in the URI now. Switching to the actual save state might be smaller after enough user input.

PermalinkCommentszork frotz interactive-fiction zcode if technical uri fragment

Registration Info Editor (REGEDIT) Command-Line Switches

2008 Jan 21, 2:13FTA: "This article describes the command-line switches for REGEDIT.EXE."PermalinkCommentsmicrosoft reference regedit registry editor windows command

Some Handy Commands - comm & seq

2008 Jan 13, 11:57Brief intro to comm & seq, two handy commands of which I was previously unaware.PermalinkCommentsvia:kris.kowal tool tools unix seq comm

IPv6 Roundup: Address Syntax on Windows

2008 Jan 9, 11:34

IPv6 address syntax consists of 8 groupings of colon delimited 16-bit hex values making up the 128-bit address. An optional double colon can replace any consecutive sequence of 0 valued hex values. For example the following is a valid IPv6 address: fe80::2c02:db79

Some IPv6 addresses aren't global and in those cases need a scope ID to describe their context. These get a '%' followed by the scope ID. For example the previous example with a scope ID of '8' would be: fe80::2c02:db79%8

IPv6 addresses in URIs may appear in the host section of a URI as long as they're enclosed by square brackets. For example: http://[fe80::2c02:db79]/. The RFC explicitly notes that there isn't a way to add a scope ID to the IPv6 address in a URI. However a draft document describes adding scope IDs to IPv6 addresses in URIs. The draft document uses the IPvFuture production from the URI RFC with a 'v1' to add a new hostname syntax and a '+' instead of a '%' for delimiting the scope id. For example: http://[v1.fe80::2c02:db79+8]/. However, this is still a draft document, not a final standard, and I don't know of any system that works this way.

In Windows XPSP2 the IPv6 stack is available but disabled by default. To enable the IPv6 stack, at a command prompt run 'netsh interface ipv6 install'. In Vista IPv6 is the on by default and cannot be turned off, while the IPv4 stack is optional and may be turned off by a command similar to the previous.

Once you have IPv6 on in your OS you can turn on IPv6 for IIS6 or just use IIS7. The address ::1 refers to the local machine.

In some places in Windows like UNC paths, IPv6 addresses aren't allowed. In those cases you can use a Vista DNS IPv6 hack that lives in the OS name resolution stack that transforms particularly crafted names into IPv6 addresses. Take your IPv6 address, replace the ':'s with '-'s and the '%' with an 's' and then append '.ipv6-literal.net' to the end. For example: fe80--2c02-db79s8.ipv6-literal.net. That name will resolve to the same example I've been using in Vista. This transformation occurs inside the system's local name resolution stack so no DNS servers are involved, although Microsoft does own the ipv6-literal.net domain name.

MSDN describes IPv6 addresses in URIs in Windows and I've described IPv6 addresses in URIs in IE7. File URIs in IE7 don't support IPv6 addresses. If you want to put a scope ID in a URI in IE7 you use a '%25' to delimit the scope ID and due to a bug you must have at least two digits in your scope ID. So, to take the previous example: http://[fe80::2c02:db79%2508]/. Note that its 08 rather than just 8.

PermalinkCommentsroundup ip windows ipv6 technical microsoft boring syntax

Windows Media Center and Zune Integration Hack

2007 Nov 28, 1:23One of the new Zune features that had me the most excited was the claimed improved Windows Media Center integration which unfortunately turned out to simply mean support for the Win MCE video format (with an exception for HD). I wanted to be able to pick shows recorded by my Win MCE and have the Zune automatically sync up the latest episodes. However, with the improved podcast support in the Zune software one can easily create a ridiculous hack to accomplish this.

The new Zune software has podcast support which does everything I'd want to do with a Win MCE recorded TV series so the goal is to shoehorn a TV series into a Zune podcast. An overview of the steps: Create an XSLT that converts Win MCE data to a podcast, run the XSLT as a scheduled task every few hours per TV series, setup a Web server pointed at the resulting podcasts and the Win MCE Recorded TV directory, and subscribe to the resulting podcasts in the Zune software.
  1. Reading through the Win MCE data stored as an XML file in "C:\ProgramData\Microsoft\eHome\Recording\Recordings.xml" and the spec for podcasts I created an XSLT to convert a series from Win MCE data to a podcast.
  2. I added a new task to the Scheduled Tasks to run my XSLT using my xsltproc.js script. The task runs a handful of commands that look something like the following:

    C:\windows\system32\wscript.exe C:\users\dave\bin\xsltproc.js C:\Users\Dave\Documents\trunk\development\mce-zune\mce-to-podcast.xslt C:\ProgramData\Microsoft\eHome\Recording\Recordings.xml --param title "The Daily Show With Jon Stewart" --param max 4 --param baseURI "http://groucho/" --param thisRelURI "tds.xml" -o "D:\recorded tv\tds.xml"

    For each TV series I run a command like the above and that outputs a podcast for that series into my "D:\Recorded TV\" directory.
  3. Zune only allows http URIs for its podcasts so I installed a web server on my Win MCE server. I'm running Vista Ultimate so it was quick and easy for me to install IIS7 but any Web server will do. Then I pointed it at "D:\Recorded TV\".
  4. Once all the above was done I just subscribed to the resulting podcasts via my Web server and viola! Since I'm forced to use a Web server I can even run the Zune software on a machine other than my Win MCE server. You can see a screen-shot above of my Zune software showing my Colbert Report podcast.
PermalinkCommentstechnical xml mce hack windows media center zune windows xslt podcast

URL Schemes Supported in Lynx

2007 Oct 11, 12:55The list of URI schemes supported by the command line based web browser Lynx.PermalinkCommentslynx uri scheme internet web browser reference

XSL Transforms in JavaScript

2007 Oct 7, 4:12In a previous post I mentioned an xsltproc like js file I made. As noted in that post, on Windows you can write console script files in JavaScript, name them foo.js, and execute them from the command prompt. I later found that MSDN has an XSLT javascript sample which looks similar to mine, but I like mine better for the XSLT parameter support and having a non-ridiculous way of interpreting filenames. The code for my xsltproc.js follows. The script is very simple and demonstrates the ease with which you can manipulate these system objects and all it takes is opening up notepad.
var createNewXMLObj = function() {
   var result = new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
   result.validateOnParse = false;
   result.async = false;
   return result;
}

var args = WScript.arguments;
var ofs = WScript.CreateObject("Scripting.FileSystemObject");

var xslParams = [];
var xmlStyle = null;
var xmlInput = null;
var inputFile = null;
var outputFile = null;
var error = false;

for (var idx = 0; idx < args.length && !error; ++idx)
   if (args.item(idx) == "-o") {
      if (idx + 1 < args.length) {
         outputFile = ofs.GetAbsolutePathName(args.item(idx + 1));
         ++idx;
      }
      else
         error = true;
   }
   else if (args.item(idx) == "--param" || args.item(idx) == "-param") {
      if (idx + 2 < args.length) {
         xslParams[args.item(idx + 1)] = args.item(idx + 2);
         idx += 2;
      }
      else
         error = true;
   }
   else if (xmlStyle == null) {
      xmlStyle = createNewXMLObj();
      xmlStyle.load(ofs.GetAbsolutePathName(args.item(idx)));
   }
   else if (xmlInput == null) {
      inputFile = ofs.GetAbsolutePathName(args.item(idx));
      xmlInput = createNewXMLObj();
      xmlInput.load(inputFile);
   }

if (xmlStyle == null || xmlInput == null || error) {
   WScript.Echo('Usage:\n\t"xsltproc" xsl-stylesheet input-file\n\t\t["-o" output-file] *["--param" name value]');
}
else {
   var xslt = new ActiveXObject("MSXML2.XSLTemplate.3.0");
   xslt.stylesheet = xmlStyle;
   var xslProc = xslt.createProcessor();
   xslProc.input = xmlInput;

   for (var keyVar in xslParams)
      xslProc.addParameter(keyVar, xslParams[keyVar]);

   xslProc.transform();

   if (outputFile == null)
      WScript.Echo(xslProc.output);
   else {
      var xmlOutput = createNewXMLObj();
      xmlOutput.loadXML(xslProc.output);
      xmlOutput.save(outputFile);
   }
}
PermalinkCommentsjs xml jscript windows xslt technical xsltproc wscript xsl javascript

Native Win32 ports of some GNU utilities

2007 Aug 9, 1:33Win32 versions of many common Unix commands.PermalinkCommentsunix linux tool tools download windows sourceforge shell software free
Older EntriesNewer Entries Creative Commons License Some rights reserved.