mpeppler has asked for the wisdom of the Perl Monks concerning the following question:

My DBD::Sybase module needs to know the version of the Sybase libraries that are available at installation to turn on/tune certain features, or work around bugs in older versions of the libs.

On Unix I simply run

strings $filename
and grep for the version string.

I need to do the same thing for systems where strings isn't available (typically Win32). I suppose I could simply open the file in my Makefile.PL and use a normal read/pattern match loop, maybe using sysread() to avoid slurping in too much at a time given the size of these binary files.

Any other suggestions?

Thanks,

Michael

Replies are listed 'Best First'.
Re: Portable way to extract string from a binary
by tachyon (Chancellor) on Jul 14, 2004 at 13:12 UTC
    C:\>perl -ne "print $1,$/ while m/([\w ]{2,})/gc" myscript.exe MZ This program cannot be run in DOS mode efx Rich PE RES text rdata data C:\>

    Add whatever you want to the character class according to your definition of a string :-)

    cheers

    tachyon

      To match strings(1) as I'm used to, you'd want something like:

      my( $min, $max ) = ( 4, 32*1024 ); local( $/ ) = \(32*1024); my $prev = ''; while( <> ) { $prev .= $_; while( $prev =~ /([\n\t -~]{$min,$max})\0/g ) { print "$1\n"; } $prev =~ s/.*\0//s; }

      Though I notice that strings(1) on FreeBSD replaces the "followed by '\0'" with "followed by an unprintable character", which my testing finds to be a disadvantage (at least it should be made optional).

      - tye        

        Hmm, while I take your point about looking for null termination the code you present does not work for me. The first issue is this:

        C:\>strings.pl myscript.exe Quantifier in {,} bigger than 32766 before HERE mark in regex m/([\n\t + -~]{ << HERE 4,32768})\0/
Re: Portable way to extract string from a binary
by jfroebe (Parson) on Jul 14, 2004 at 14:03 UTC

    Hi Michael

    Err... did you check your doc? ;-)

    syb_oc_version (string)
    Returns the identification string of the version of Client Library that this binary is currently using. This is a read-only attribute.

    For example:

    troll (7:59AM):348 > perl -MDBI -e '$dbh = DBI->connect("dbi:Sybase:", "sa"); print "$dbh->{syb_oc_version}\n";'
    Sybase Client-Library/11.1.1/P/Linux Intel/Linux 2.2.5 i586/1/OPT/Mon Jun 7 07:50:21 1999

    This is very useful information to have when reporting a problem.

    Sorry... I just had to do it... ;-) A little teasing here

    Jason L. Froebe

    No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1

    Edit by tye, remove PRE tags around long lines

      But that's after the module is built - I need this before...:-)

      Michael

        Lol.. yup, I know, I'm opening a case with Sybase on it. Will let you know what I find.

        This is what I asked in the case:

        basically I'm looking for something like so:

        $ my_app --openclient-version
        ----
        This application is using OpenClient 12.5.1 ebf 9999 for Linux 64bit. This application was BUILT using OpenClient 12.5.1 ebf 9980.
        ---

        The "built" line would be hard coded by the application during the compilation process - I would handle this...

        The "using" would be read from some method in the openclient library (ctlib or dblib) that my application is using *now*.

        I'm looking for a way to determine the "using" openclient version without performing a system call to run the ldd or strings commands.

        A little more than what we are looking for but, I think it would be a better solution

        Jason L. Froebe

        No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1

        Edit by tye, remove PRE tags around long lines

Re: Portable way to extract string from a binary
by ccn (Vicar) on Jul 14, 2004 at 13:11 UTC

    You can run sqlsrvr.exe -v and parse it's output to get the version

      Thanks - but that gives me the version of the server - it's the client software version that I need, so the closest approximation would be running isql -v.

      I think tachyon's solution looks good.

      Michael