Windows has a “find” command, but it’s nothing like the Unix command “find” and is pretty useless.  DIR can do recursive searches (using /s/b options), and is pretty useful, but there’s no way to get it to search based on dates – just file names.

But what if you want to know, for example, which log files have been modified today?  Turns out, XCOPY can do this.  It can copy files based on modification date, and the /L option tells it to just print the names of the files it would copy, but not actually copy them.  Here’s the command to find all .log files on the C: drive that were modified on or after October 26, 2009:

xcopy /s /d:10-26-2009 /i /l /y c:\*.log \temp

Update:

Of course, you don’t want to manually specify the date every time.  You could use the %DATE% cmd variable, but the output is wrong:

C:\temp>echo %DATE%
Wed 10/28/2009

The solution is to pick apart the string returns by %DATE% and munge it back together in the desired format:

C:\temp>echo %DATE:~4,2%-%DATE:~7,2%-%DATE:~10,4%
10-28-2009

So, the command to find all tomcat logs that have changed today becomes:

xcopy /s /d:%DATE:~4,2%-%DATE:~7,2%-%DATE:~10,4% /i /l /y c:\tomcat5.5\*.log \temp

One of the great things about Java tool chain is that it accepts the Unix principle of “small sharp tools”. So, instead of some crazy proprietary binary format, java libraries are either .class files in a directory tree that mirrors their package hierarchy or they’re a .zip file, again with the paths of the .class files it contains mirroring their package hierarchy (that’s all a .jar file is).

This means that you don’t need to use specialized tools to do some simple browsing. For example, I’ve recently needed to construct an SDK to work with a third party web-based application that we’re using at my day job. The vendor doesn’t have a productized SDK that I can use, but I do have a working server, so in theory I have all the .jar files that I need *somewhere*. All I needed to do is figure out where.

Since a .jar file is just a Zipped archive of class files, if I can get the list of each .class file in all the .jars on the system, I should be able to figure out which one holds the class I needed, and just copy that to my development machine.

The command to get the list of .class files in a .jar file is this:

jar.exe -tvf jar file name

To only list those files that match the name of your class, do this.  Note that you can use the entire path, like com.mycompanyname.MyClassName.  Jar outputs ‘/’s instead ‘.’s to separate package segments, since as far as jar is concerned, these are file paths, not java package names, but since the ‘.’ is a findstr pattern that means ‘match any character’, it works just fine):

jar.exe -tvf jar file name | findstr class name

To recursively perform a command on all jar files in a directory tree, you use the FOR command, like this:

for /r tree root %f in (*.jar) do my command to %f

Combined, they look like this:

for /r tree root %f in (*.jar) do jar.exe -tvf %f | findstr class name

Unfortunately, this just outputs the names of the class files that match the class name argument. What we really want is the names of the .jar files. It’s in %f, so all we need to do is ECHO %f. But, we only want to do that if FINDSTR found a match. For that, we need the && operator – cmd1 && cmd2 executes cmd1, and if cmd1 sets ERRORLEVEL to 0, executes cmd2. Since FINDSTR sets ERRORLEVEL to 0 on match and 1 on no match, this will work perfectly.

Here’s the final result:

for /r tree root %f in (*.jar) do jar.exe -tvf %f | findstr class name && echo %f

Or, if we just want to see the .jar names, and not the names of the .class files in that .jar that matched:

for /r tree root %f in (*.jar) do jar.exe -tvf %f | findstr class name > NUL && echo %f

The Pomodoro Technique is a great way to cut down on procrastination.  Unless you start writing your own Pomodoro Timer apps instead of actually doing anything…  For those of you about to head down that path, here’s mine.  Find another way to procrastinate.  You’ll need python and wxpython:

Read the rest of this entry »

Today’s Microsoft Hate

October 8, 2009

If you have an environment variable defined called “outdir” Visual Studio 2005’s command line build will put your the output of your builds there.  I can’t find anywhere where this is documented, and it isn’t how the GUI build works.  For the life of me, I couldn’t figure out why my DLLs were going to this bizarre location.

Total time wasted: 1 hour.

Memcached’s Protocol

October 7, 2009

Amen to this:

The old simple textual protocols, e.g., HTTP, FTP, SMTP and POP3 are still in use on the modern Internet. Not only because textual protocols can be easily parsed and extended, but also they are convenient for human being to read and debug. This is where the UNIX philosophy shines.

Try explaining this to programmers with an embedded background, though.  If I can convince them not to put a CRC in their protocols (TCP already does that for you, for pete’s sake), I feel like a success.

I prefer URLs that end in in a trailing slash, but there’s no automatic way to do that in Twisted (that I can find). Nevow has an addSlash attribute for rend.Page, and django has the APPEND_SLASH setting, but I couldn’t find anything equivalent for twisted.

Twisted’s resources receive a parsed list of URL segments in the request object, so /here/is/my/path becomes ['here', 'is', 'my', 'path']. A URL with a trailing slash is parsed to a empty segment, so /here/is/my/path/ becomes ['here', 'is', 'my', 'path', '']. What this means is that the way to check if your resource is being called with a trailing slash is to check that request.prepath[-1] == ''. And to redirect from a resource without a trailing slash to one with, you need to redirect to the ” child, like this: request.redirect(request.childLink("")).

Easy enough, except that you need to modify two methods to do this, render (to check if we should actually render or if we should redirect) and getChild (since the resource is at /url, and /url/ is its child).

Doing this for every Resource-derived class that you want to have a trailing slash is going to be tedious and error prone. Luckily, this is python and meta-programming is easy. Here’s my solution:

def append_slashes(rsc_class):
    original_getChild = rsc_class.getChild
    original_render = rsc_class.render

    def slash_appending_getChild(self, path, request):
        if path == '':
            return self
        else:
            return original_getChild(self, path, request)

    def slash_appending_render(self, request):
        if request.prepath[-1] != '':
            request.redirect(request.childLink(""))
            return ""
        else:
            return original_render(self, request)

    class slash_appending_rsc_class(rsc_class):
        pass

    slash_appending_rsc_class.getChild = slash_appending_getChild
    slash_appending_rsc_class.render = slash_appending_render
    slash_appending_rsc_class.isLeaf = False
    return slash_appending_rsc_class

# test code
# entering http://localhost:8080/hello should redirect to http://localhost:8080/hello/ 

from twisted.internet import reactor
from twisted.python import log
from twisted.web import server, resource, static
import sys

class MyPage(resource.Resource):
    def render_GET(self, request):
        return "<html><body><p>Hello World</p></body></html>"
MyPage = append_slashes(MyPage)

log.startLogging(sys.stdout)
root = resource.Resource()
root.putChild("", append_slashes(static.Data)("hello people", "text/plain"))
root.putChild("hello", MyPage())
root.putChild("hello2", append_slashes(static.Data)("hello 2", "text/plain"))
site = server.Site(root)
reactor.listenTCP(8080, site)
reactor.run()
def append_slashes(rsc_class):
original_getChild = rsc_class.getChild
original_render = rsc_class.render

def slash_appending_getChild(self, path, request):
if path == ”:
return self
else:
return original_getChild(self, path, request)

def slash_appending_render(self, request):
if request.prepath[-1] != ”:
request.redirect(request.childLink(“”))
return “”
else:
return original_render(self, request)

class slash_appending_rsc_class(rsc_class):
pass

slash_appending_rsc_class.getChild = slash_appending_getChild
slash_appending_rsc_class.render = slash_appending_render
slash_appending_rsc_class.isLeaf = False
return slash_appending_rsc_class

# test code
# entering http://localhost:8080/hello should redirect to http://localhost:8080/hello/

from twisted.internet import reactor
from twisted.python import log
from twisted.web import server, resource, static
import sys

class MyPage(resource.Resource):
def render_GET(self, request):
return “<html><body><p>Hello World</p></body></html>”
MyPage = append_slashes(MyPage)

log.startLogging(sys.stdout)
root = resource.Resource()
root.putChild(“”, append_slashes(static.Data)(“hello people”, “text/plain”))
root.putChild(“hello”, MyPage())
root.putChild(“hello2”, append_slashes(static.Data)(“hello 2”, “text/plain”))
site = server.Site(root)
reactor.listenTCP(8080, site)
reactor.run()