0.07 to 0.08

  • Added version numbers and load status printout for the encoder scripts.

  • Greatly simplified the colour parsing code in the interface scripts… all the things I didn’t know about regexp in Perl. :)

  • More error reporting… this time on invalid server or metaserver parameters.

  • Fixed a bug in command parsing which caused trailing whitespace to be treated significantly.

  • Changed /filter to /results, to reflect is more generalized functionality of re-displaying search results with various filters, etc.

  • Added a -sort flag to /filter and /search, as per a suggestion from Myers Carpenter. -sort takes one or more fields, which are used to sort search results.

  • Added -sort and -regex flags to the /browse command.

  • Changed the way the GTK GUI handles getting search results, so that the aforementioned sorting changes are reflected in the GUI.

  • Fixed the COUNT option bug that so many people reported. :)

  • Tweaked text parsing so if there are mismatched quotes in input, the code doesn’t die() a horrible death. :) Funny thing is, I don’t remember why I did it like that in the first place…

  • Modified the command_hash so that strings can be inserted as callbacks, which are evaluated as commands. What this means is you can do stuff like:

    push @{ $code_hash{&MSG_JOIN_ACK} }, “/send I have arrived!”


    push @{ $code_hash{&MSG_DISCONNECT} }, “/reconnect”

  • SOCKSv4 and v5 support added through the use of Net::SOCKS. Unfortunately, SOCKS-based file transfers currently use blocking connects, which sucks… but, at least it works (I think :).

0.06 to 0.07

  • Split the cache update code off into a seperate function which is called during program initialization (MSG_INIT hook). Should’ve done this a while ago. :)

  • Cleaned up the cache management code a little bit. I should probably do this in the rest of the code, too, but I’m lazy. :)

  • Added filename encoding framework and an example pig latin encoder.

  • Added auto-encoding to the /search command. Add -encode flag to use it.

0.05 to 0.06

  • Fixed a bug in the help code which caused CODE references to not be properly executed. Thanks to Glendon Johnson for the heads up.

  • Modified the file index code to sort the file entries before submitting to the server. Again, thanks to Glendon Johnson for the suggestion.

  • Changed the Snap version in the code. Whoops! Thanks to Iain Lea. :)

0.04 to 0.05

This release is mostly about stability:

  • Updated interface scripts so they recover nicely if required modules are missing.

  • Similarly, cleaned up the toolkit import scripts to recover cleanly.

  • Cleaned up perl eval code so errors are recovered from gracefully. This, Snap no longer crashes when you try to call an undefined function from /eval.

0.03 to 0.04

This version is yet another architectural evolution. The change to use of %handles hash for event loop hooking, further separation of GUI from core code, and many other changes, make this a hefty new version as well. :)

  • More stability! :) Uploads in the last version were rather broken. Hopefully those issues are fixed in this version. Testing is gooood…

  • Changed keyboard handling to add additional backspace mapping for UK keyboards.

  • Changed /eval to use eval_file() for evaluating script files, and added appropriate error output to eval_file(). This means Snap outputs nice errors when the RC file isn’t found, amongst other things.

  • Added -f command-line option, which specifies a script to load on startup before the rcfile is loaded. This allows, for example:

    snap -f Gtk.pl

  • Moved SnapGtk into the scripts directory, and now treat it like a true script. As well, SnapGtk is now known as just plain Gtk.

  • Created the Curses interface script, similar in spirit to the Gtk script. This means that you can choose to load the Curses module or not.

  • Created the Plain interface script, which provides a plain text interface with colour codes stripped out.

  • Updated the default snaprc file with the new interface loading commands.
    Also simplified and cleaned up the script.

  • Created the new Sock module, for controlling Snap through a TCP/IP socket.

  • Created the new %handles variable, which contains a hash which maps sockets and handlers, in the following structure:

    “$sock” => { Handle => $sock, Callback => \&sub }

    This structure is used to add user handles to the event loop of Snap. See the sock.pl script for an example use. This idea was inspired by a similar mechanism in Net::IRC.

    See the Gtk.pl script for how wrapper scripts can use tie() to intercept additions to the %handles variable to incorporate them into their event loops.

  • Due to the existence of the new %handles variable, I’ve completely removed the input code from the main snap script, and placed it in the interface scripts. As well, I’ve taken out any remaining window dependancies (clear, pageup/down) so the interface code is now totally segregated from the main snap script.

  • Added MSG_SHUTDOWN message type, to allow hooking into the shutdown procedure. Now used in the Curses module to call endwin() at the appropriate time.

  • Added MSG_INIT. Changed interface code to use MSG_INIT to initialize themselves, and then overwrite main_loop() if necessary. snaprc script changed to use MSG_INIT for loading scripts. Modified snap to use MSG_INIT to set up server and Napster connection.

  • Changed cache behaviour so entries are allowed only if the file exists and it is in the correct upload directory.

  • Changed hotlist and cache behaviour to not create data files if there are no entries.

  • /clear works again in the Curses interface. :)

  • Changed all downloads, uploads, server, etc, to use the new %handles hash for hooking into the event loop. This is much more interface independant, and a much more pleasant way to implement things.

  • Changed Gtk script so it properly uses %handles for event handling.

  • Fixed hotlist and cache saving so, if the file can’t be created, an appropriate error is displayed.

  • Added support for file type in OpenNap searches.

  • Improved documentation in example snaprc file, including some undocumented variables, like the max upload speed and queue limit variables.

  • Fixed upload speed throttling code.

  • Fixed “sent” field updating in Uploads list.

  • Changed Remote so it doesn’t advertise itself in your client ID, as a security precaution.

  • Fixed bug in filter labeling all returned results as number 1.

  • Added ability to specify messages to trace for debugging purposes.

  • Added ability to specify which debug messages to log to file for debugging.

  • Split the Gtk module into a library import module and the actual GUI module. This allows you to use Gtk with other interface modules like Curses or Plain, if you want to do that. Or you could implement a different GUI entirely while reusing the Gtk import module.

  • Split off the %handles wrapper object into a seperate object in the SnapLib directory, to make it easier to wrap Snap in another event model.

  • Due to the previous change, we now have the TkImport module, for wrapping Snap in Perl/Tk.

  • Wrote rudimentary Perl/Tk interface script. Provides an input line and a fully-functional text window.

  • Cleaned up file transfer callbacks (the INIT and START callbacks) for ULs and DLs so the called functions receive the same hash, and the START callback no longer hash an old_hash and new_hash argument.

  • Fixed the Time::HiRes dependency for uploads. You should be able to operate quite happily without it now. :)

  • Added proper error handling for all sysread() and syswrite() calls. This should help to clear up file transfer bugs… we’ll see, though.

  • Extended the ul_kill and dl_kill functions to take upload/download structure references. This was exploited to greatly clean up the process reaper.

0.03 to 0.03a

  • Fixed a major bug in the upload code which caused a crash of the client.

0.02 to 0.03

Oy, too many to count. I’ll split them into two groups. Ones visible at the user level, and others visible at the developer and script writer’s levels.

User-Level Changes

  • The ability to run Snap without needing Curses or other modules. The interface defaults to a bare, text-mode interface if these modules aren’t loaded.

  • Fixed bugs in option handling. So /exec is fixed, among other things. (You can again just do this: /exec command).

  • Improved Curses input line. Supports ^D key for deleting characters, and the scrollback buffer now exhibits the same behaviour as GNU readline (I think :).

  • Improved Curses text window, supporting better scrollback buffer (less glitchy, I think) and support for colours using a custom colour-code system akin to Ksirc. Of course, along with all of this comes a slight speed degradation… doh! :)

  • GTK GUI module! Need I say more? ;) It’s rough, but the basic functions are there. And in time, more and more functionality will be incorporated.

  • The remote.pl script, which allows control of snap via private messages, has been totally revamped to take advantage of some of Snap’s new architecture changes. Thus, it is MUCH more stable and less hacky. :)

  • Stability! Always good… helps when you handle errors correctly. :)

  • Parameters to commands are case insensitive (as it should have been originally). Thanks to Guenter for noticing this. :) Along with this, the help was updated to be more consistent in terms of option case (even if this doesn’t matter :).

  • Simpler installation process which doesn’t require changes to the Snap script.

  • Creation of a SCRIPT_PATH variable to ease the loading of external scripts.

  • Implementation of a download queue. This is new code, so it’s rough. :) See /queue command or queue interface in GUI.

  • Addition of ETA information to the file transfers.

  • Transfer information (eg rate and ETA) are updated on a one second basis, ensuring constant information update without excessive update speeds (which results in poor application performance, particularly for GUIs).

  • Addition of no-color operating mode.

  • Ability to alias commands to one another by putting the string of the aliased command straight into the command hash. eg:

    $command_hash{“/k”} = “/dl -kill”;

    And added /alias command to do just this.

Developer-Level Changes

Well, this is pretty hefty… :)

  • Changed windowing and input routines to use nice objects. Now we have a SnapLib directory, with SnapLib::Window, SnapLib::InputLine, SnapLib::StdWindow, and SnapLib::StdinLine modules.

  • Changed printing code to use tie’d STDOUT instead of object or function calls. Simplifies things and reduces dependancies between the interface and low-level functions.

  • Due to the aforementioned changes, and some review of the code, I’ve decided to no longer pass the cmdwin and textwin variables around. These are rarely used in callbacks, and even less-so now, since the do_command() function was modified to take a command string. This is going to break a LOT of scripts (assuming there are a lot ;).

  • Changed the screen output code to allow for colour codes to specify… well… colours. :) Format is as follows: ~; where num is a colour number. ~c; is used to indicated the ending of a colour region.

  • Napster communication now done through a new NapSocket object. Encapsulates the Napster communication code very nicely, and could easily be stolen by other projects, if they like. :) Now all writes to Napster go through $sock->send(MSG_TYPE, DATA).

  • All Napster message types are stored in SnapLib::MessageTypes. Again, this is a nice, modular package, so you can use it in your own stuff if you want. :)

  • Objects created for doing the raw upload and download transactions. Handshaking is still done in the main app, but the objects are used to perform the actual transfers.

  • A lot of hooks have been added for server connections and UL/DLs, to facilitate the new GUI and allow more flexibility in scripting.

  • Error handling, Error handling, Error handling. I’ve finally added code to handle errors in places where I just didn’t bother out of sheer laziness, or because I was “going to get to that later”. :)

  • Modified the process reaper code, to make it more stable and handle large dl/ul deaths to be dealt with gracefully. Also, a non-blocking waitpid is now used, which helps to keep program flow smooth.

  • Help system changed so functions registered in %help_hash simply return a text string containing the help text, rather than printing themselves. This makes it possible to extend the help system more easily, since there is greater control over display.

  • I found out about “use lib …” :) So libraries are loaded using script-relative paths.

  • Command and code callbacks can now be arrays of function references, or function references themselves. This is mostly for convenience.

  • Download and Upload status update callbacks are called on a one-second basis through the transfer, regardless of it’s state (stalled, etc), improving application performance and user feedback.

  • Changed download semantics, so an entry is adding immediately when a request is sent, rather than when a response is returned. This makes more sense, and makes it easier to manage downloads (you can kill downloads waiting for a request response, etc).