Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mscdex committed Dec 10, 2010
0 parents commit 446de28
Show file tree
Hide file tree
Showing 5 changed files with 3,268 additions and 0 deletions.
Empty file added README.md
Empty file.
38 changes: 38 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
- File xfer

- ICQ testing and debugging (don't even bother trying it yet)

- Improve error messages -- check for subcodes, etc.

- Offline message support

- Secure connection support

- Replace HTTP-based method of fetching contact icons with the OSCAR method -- connecting to a secondary server that
supports BART (service 0x10). Note: The reason I switched to the HTTP method is because ECONNRESET was occurring on
the first (main) connection if any packets were sent on that connection after the auth cookie was sent on the second
connection. However, incoming packets are received just fine in this situation on the main connection and do not cause ECONNRESET.

- If requesting a new service and our main connection is SSL, add empty TLV 0x8C to the service request.
Similarly, if the requested service redirect response (0x05) contains TLV 0x8E, use SSL if val > 0, else no SSL

- Handle server-initiated BOS migrations

- Queue any requests for paused services and replay them after migration is complete or a resume response is sent by the server

- Use setTimeout to send a keepalive packet on FLAP channel 0x05 -- time == 1 min? Digsby & Pidgin use a 30 sec timeout)
Note: Pidgin only seems to send keepalive on the main connection, unlike Digsby which sends keepalive on every connection
Also: the timer should be (re)started after each write to the socket and thus should not be sent if the connection isn't idle

- Actually reply every x hours (given by the server-initiated USAGE_STATS SNAC) with service 0x0B subtype 0x03

- Pay attention to rate warnings and limits -- automatically do this at the _send() level and queue up commands before we hit
the limit and SNACs start dropping?

- Set up an interval to periodically clean out any answered requests or requests that have gone unanswered for some
fixed length of time (will require tagging each request with a (unix) timestamp). Although, calling delete can send
V8 into a slow case, maybe we should instead just set anything not already undefined to undefined?

- Automatically use a secure connection (to slogin.oscar.aol.com for AOL or slogin.icq.com for ICQ) if options.connection.host
is one of the defaults (login.oscar.aol.com for AOL or login.icq.com for ICQ).
Port 5190 or 443 can be used for secure connections. Also, there is an alternate non-secure address for AOL: login.messaging.aol.com
261 changes: 261 additions & 0 deletions hexy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
//= hexy.js -- utility to create hex dumps
//
// `hexy` is a javascript (node) library that's easy to use to create hex
// dumps from within node. It contains a number of options to configure
// how the hex dumb will end up looking.
//
// It should create a pleasant looking hex dumb by default:
//
// var hexy = require('hexy.js'),
// b = new Buffer("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789")
//
// console.log(hexy.hexy(b))
//
// results in this dump:
//
// 0000000: 00 01 03 05 1f 0a 09 62 63 64 65 66 67 68 69 6a .......b cdefghij
// 0000010: 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a klmnopqr stuvwxyz
// 0000020: 30 31 32 33 34 35 36 37 38 39 01234567 89
//
// but it's also possible to configure:
//
// * Line numbering
// * Line width
// * Format
// * Case of hex decimals
// * Presence of the ASCII annotation in the right column.
//
// This mean you can do exciting dumps like:
//
// 0000000: 0001 0305 1f0a 0962 .... ...b
// 0000008: 6364 6566 6768 696a cdef ghij
// 0000010: 6b6c 6d6e 6f70 7172 klmn opqr
// 0000018: 7374 7576 7778 797a stuv wxyz
// 0000020: 3031 3233 3435 3637 0123 4567
// 0000028: 3839 89
//
// or even:
//
// 0000000: 00 01 03 05 1f 0a 09 62 63 64 65 66 67 68 69 6a
// 0000010: 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a
// 0000020: 30 31 32 33 34 35 36 37 38 39
//
// with hexy!
//
// Formatting options are configured by passing a `format` object to the `hexy` function:
//
// var format = {}
// format.width = width // how many bytes per line, default 16
// format.numbering = n // ["hex_bytes" | "none"], default "none"
// format.format = f // ["fours"|"twos"|"none"], how many nibbles per group
// // default "fours"
// format.caps = c // ["lower"|"upper"], default lower
// format.annotate=a // ["ascii"|"none"], ascii annotation at end of line?
// // default "ascii"
// format.prefix=p // <string> something pretty to put in front of each line
// // default ""
// format.indent=i // <num> number of spaces to indent
// // default 0
//
// console.log(hexy.hexy(buffer, format))
//
// In case you're really nerdy, you'll have noticed that the defaults correspond
// to how `xxd` formats it's output.
//
//
//== Installing
//
// Either use `npm`:
//
// npm install hexy
//
// This will install the lib which you'll be able to use like so:
//
// var hexy = require("hexy.js"),
// buf = // get Buffer from somewhere,
// str = hexy.hexy(buf)
//
// It will also install `hexy.js` into your path in case you're totally fed up
// with using `xxd`.
//
//
// If you don't like `npm`, grab the source from github:
//
// http://github.com/a2800276/hexy.js
//
//== TODOS
//
// The current version only pretty prints Buffers. Which probably means it
// can only be used from within node. What's more important what it
// doesn't support: Strings (which would be nice for the sake of
// completeness) and Streams/series of Buffers which would be nice so you
// don't have to collect the whole things you want to pretty print in
// memory. `hexy` is probably most useful for debugging and getting binary
// protocol stuff working, so that's probably not an too much of an issue.
//
//== History
//
// This is a fairly straightforward port of `hexy.rb` which does more or less the
// same thing. You can find it here:
//
// http://github.com/a2800276/hexy
//
// in case these sorts of things interest you.
//
//== Mail
//
// In case you discover bugs, spelling errors, offer suggestions for
// improvements or would like to help out with the project, you can contact
// me directly (tim@kuriositaet.de).

var hexy = function (buffer, config) {
config = config || {}
var h = new Hexy(buffer, config)
return h.toString()
}

var Hexy = function (buffer, config) {
var self = this

self.buffer = buffer // magic string conversion here?
self.width = config.width || 16
self.numbering = config.numbering == "none" ? "none" : "hex_bytes"
self.groupSpacing = config.groupSpacing || 0

switch (config.format) {
case "none":
case "twos":
self.format = config.format
break
default:
self.format = "fours"
}

self.caps = config.caps == "upper" ? "upper" : "lower"
self.annotate = config.annotate == "none" ? "none" : "ascii"
self.prefix = config.prefix || ""
self.indent = config.indent || 0

for (var i = 0; i!=self.indent; ++i) {
self.prefix = " "+prefix
}

var pos = 0

this.toString = function () {
var str = ""

//split up into line of max `self.width`
var line_arr = lines()

//lines().forEach(function(hex_raw, i){
for (var i = 0; i!= line_arr.length; ++i) {
var hex_raw = line_arr[i],
hex = hex_raw[0],
raw = hex_raw[1]
//insert spaces every `self.format.twos` or fours
var howMany = hex.length
if (self.format === "fours") {
howMany = 4
} else if (self.format === "twos") {
howMany = 2
}

var hex_formatted = ""
var middle = Math.floor(self.width / 2)-1
var groupSpaces = (new Array(self.groupSpacing+1)).join(' ');
for (var j=0; j<hex.length; j+=howMany) {
var s = hex.substr(j, howMany)
hex_formatted += s + (j/2 === middle && self.groupSpacing > 0 ? groupSpaces : " ")
}
str += self.prefix

if (self.numbering === "hex_bytes") {
str += pad(i*self.width, 8) // padding...
str += ": "
}

var padlen = 0
switch(self.format) {
case "fours":
padlen = self.width*2 + self.width/2
break
case "twos":
padlen = self.width*3 + 2
break
default:
padlen = self * 2
}

str += rpad(hex_formatted, padlen)
if (self.annotate === "ascii") {
str+=" "
str+=raw.replace(/[\000-\040\177-\377]/g, ".")
}
str += "\n"
}
return str
}

var lines = function() {
var hex_raw = []


for (var i = 0; i<self.buffer.length ; i+=self.width) {
var begin = i,
end = i+self.width >= buffer.length ? buffer.length : i+self.width,
slice = buffer.slice(begin, end),
hex = self.caps === "upper" ? hexu(slice) : hexl(slice),
raw = slice.toString('ascii')

hex_raw.push([hex,raw])
}
return hex_raw

}

var hexl = function (buffer) {
var str = ""
for (var i=0; i!=buffer.length; ++i) {
str += pad(buffer[i], 2)
}
return str
}
var hexu = function (buffer) {
return hexl(buffer).toUpperCase()
}

var pad = function(b, len) {
var s = b.toString(16)

while (s.length < len) {
s = "0" + s
}
return s
}
var rpad = function(s, len) {
while(s.length < len) {
s += " "
}
return s
}

}
/*
var fs = require('fs'),
file = process.argv[2]
var data = fs.readFileSync(file)
//console.log(hexy(data))
var format = {}
//format.format = "fours"
format.caps = "upper"
format.annotate = "none"
//format.numbering = "none"
format.width = 8
console.log(hexy(data, format))
console.log("doen")
*/

exports.hexy = hexy
Loading

0 comments on commit 446de28

Please sign in to comment.