rhc 0.92.11 → 0.93.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. data/README.md +1 -9
  2. data/Rakefile +1 -55
  3. data/bin/rhc +31 -1
  4. data/bin/rhc-app +62 -127
  5. data/bin/rhc-chk +6 -7
  6. data/bin/rhc-create-app +8 -8
  7. data/bin/rhc-create-domain +6 -86
  8. data/bin/rhc-ctl-app +3 -3
  9. data/bin/rhc-ctl-domain +4 -4
  10. data/bin/rhc-domain +16 -18
  11. data/bin/rhc-domain-info +3 -3
  12. data/bin/rhc-port-forward +127 -24
  13. data/bin/rhc-snapshot +7 -46
  14. data/bin/rhc-sshkey +13 -79
  15. data/bin/rhc-tail-files +16 -8
  16. data/lib/rhc-common.rb +406 -230
  17. data/lib/rhc-rest.rb +3 -3
  18. data/lib/rhc-rest/client.rb +1 -1
  19. data/lib/rhc-rest/domain.rb +1 -1
  20. data/lib/rhc.rb +20 -0
  21. data/lib/rhc/cli.rb +38 -0
  22. data/lib/rhc/client.rb +15 -0
  23. data/lib/rhc/commands.rb +32 -0
  24. data/lib/rhc/commands/base.rb +67 -0
  25. data/lib/rhc/commands/server.rb +24 -0
  26. data/lib/rhc/config.rb +141 -0
  27. data/lib/rhc/core_ext.rb +15 -0
  28. data/lib/rhc/helpers.rb +142 -0
  29. data/lib/rhc/json.rb +52 -0
  30. data/lib/rhc/targz.rb +46 -0
  31. data/lib/rhc/vendor/okjson.rb +600 -0
  32. data/lib/rhc/vendor/zliby.rb +628 -0
  33. data/lib/rhc/wizard.rb +579 -0
  34. data/spec/rhc/assets/foo.txt +1 -0
  35. data/spec/rhc/assets/targz_corrupted.tar.gz +1 -0
  36. data/spec/rhc/assets/targz_sample.tar.gz +0 -0
  37. data/spec/rhc/cli_spec.rb +24 -0
  38. data/spec/rhc/command_spec.rb +88 -0
  39. data/spec/rhc/commands/server_spec.rb +39 -0
  40. data/spec/rhc/helpers_spec.rb +171 -0
  41. data/spec/rhc/json_spec.rb +30 -0
  42. data/spec/rhc/targz_spec.rb +42 -0
  43. data/spec/rhc/wizard_spec.rb +426 -0
  44. data/spec/spec_helper.rb +192 -0
  45. data/test/functional/application_test.rb +71 -0
  46. data/test/functional/domain_test.rb +123 -0
  47. data/test/functional/test_credentials.rb +5 -0
  48. data/test/sample-usage.rb +122 -0
  49. data/test/support/server.rb +14 -0
  50. data/test/support/testcase.rb +3 -0
  51. data/test/test_helper.rb +4 -0
  52. data/test/unit/command_test.rb +19 -0
  53. metadata +181 -29
  54. data/ext/mkrf_conf.rb +0 -58
  55. data/lib/rhc +0 -115
@@ -0,0 +1,628 @@
1
+ require 'stringio'
2
+
3
+ module RHC
4
+ module Vendor
5
+ module Zlib
6
+
7
+ ZLIBY_VERSION = "0.0.5"
8
+ ZLIB_VERSION = "1.2.3"
9
+ VERSION = "0.6.0" #For compatibility with Ruby-core Zlib
10
+ MAXBITS = 15
11
+ MAXLCODES = 286
12
+ MAXDCODES = 30
13
+ MAXCODES = (MAXLCODES+MAXDCODES)
14
+ FIXLCODES = 288
15
+ MAX_WBITS = 15
16
+ Z_DEFLATED = 8
17
+
18
+ def self.adler32 string="", adler=1
19
+ if adler > (2**128) - 1 then raise RangeError.new end
20
+ accum1 = adler & 0xffff
21
+ accum2 = (adler >> 16) & 0xffff
22
+
23
+ len = string.length
24
+ x = -1
25
+ while len > 0
26
+ tlen = len > 5552 ? 5552 : len
27
+ len -= tlen
28
+ while tlen >0
29
+ x += 1
30
+ accum1 += string[x]
31
+ accum2 += accum1
32
+ tlen -= 1
33
+ end
34
+ accum1 %= 65521
35
+ accum2 %= 65521
36
+ end
37
+ accum2 << 16 | accum1
38
+ end
39
+
40
+ def self.crc_table
41
+ [0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035, 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049, 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639, 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317, 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443, 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665, 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303, 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565, 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059, 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297, 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223, 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405, 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995, 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649, 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015, 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989, 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523, 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377, 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879, 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637, 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859, 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161, 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815, 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221, 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371, 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881, 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567, 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701, 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035, 2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897, 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431, 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117]
42
+ end
43
+
44
+ def self.crc32 string="", crc=0
45
+ if crc > 2**128 - 1 then raise RangeError.new end
46
+ crc = crc ^ 0xffffffff
47
+ string.each_byte do |byte|
48
+ index = (crc ^ byte) & 0xff
49
+ crc = (crc >> 8) ^ crc_table[index]
50
+ end
51
+ crc ^ 0xffffffff
52
+ end
53
+
54
+
55
+ class ZStream
56
+
57
+ def initialize
58
+ @input_buffer = []
59
+ @output_buffer = []
60
+ @out_pos = -1
61
+ @in_pos = -1
62
+ @bit_bucket = 0
63
+ @bit_count = 0
64
+
65
+ end
66
+ #Returns the adler-32 checksum of the input data.
67
+ def adler
68
+ end
69
+
70
+ #Returns the number of bytes read. Normally 0 since all bytes are read at once.
71
+ def avail_in
72
+ @input_buffer.length - @in_pos
73
+ end
74
+
75
+ #Returns number of free bytes in the output buffer. As the output buffer is self expanding this normally returns 0.
76
+ def avail_out
77
+ @output_buffer.length - @out_pos
78
+ end
79
+
80
+ #Allocates size bytes in output buffer. If size < avail_out it truncates the buffer.
81
+ def avail_out= size
82
+ size.times do
83
+ if size > avail_out
84
+ @output_buffer.push nil
85
+ else
86
+ @output_buffer.pop
87
+ end
88
+ end
89
+ end
90
+
91
+ #Closes stream. Further operations will raise Zlib::StreamError
92
+ def close
93
+ @closed = true
94
+ end
95
+
96
+ #True if stream closed, otherwise False.
97
+ def closed?
98
+ @closed
99
+ end
100
+
101
+ #Best guess of input data, one of Zlib::BINARY, Zlib::ASCII, or Zlib::UNKNOWN
102
+ def data_type
103
+ end
104
+
105
+ #See close
106
+ def end
107
+ close
108
+ end
109
+
110
+ #See closed?
111
+ def ended?
112
+ closed?
113
+ end
114
+
115
+ #Finishes the stream, flushes output buffer, implemented by child classes
116
+ def finish
117
+ close
118
+ end
119
+
120
+ #True if stream is finished, otherwise False
121
+ def finished?
122
+ if @finished.nil? then
123
+ false
124
+ else
125
+ @finished
126
+ end
127
+ end
128
+
129
+ #Flushes input buffer and returns the data therein.
130
+ def flush_next_in
131
+ @in_pos = @input_buffer.length
132
+ @finished = true
133
+ ret = @input_buffer.pack("c*")
134
+ @input_buffer = []
135
+ ret
136
+ end
137
+
138
+ #Flushes the output buffer and returns all the data
139
+ def flush_next_out
140
+ @out_pos = @output_buffer.length
141
+ @finished = true
142
+ ret = @output_buffer.pack("c*")
143
+ @output_buffer = []
144
+ ret
145
+ end
146
+
147
+ #Reset stream. Input and Output buffers are reset.
148
+ def reset
149
+ @out_pos = -1
150
+ @in_pos = -1
151
+ @input_buffer = []
152
+ @output_buffer = []
153
+ end
154
+
155
+ #See finished.
156
+ def stream_end?
157
+ finished?
158
+ end
159
+
160
+ #Size of input buffer.
161
+ def total_in
162
+ @input_buffer.length
163
+ end
164
+
165
+ #Size of output buffer.
166
+ def total_out
167
+ @output_buffer.length
168
+ end
169
+
170
+ private
171
+ #returns need bits from the input buffer
172
+ # == Format Notes
173
+ # bits are stored LSB to MSB
174
+ def get_bits need
175
+ val = @bit_bucket
176
+ while @bit_count < need
177
+ val |= (@input_buffer[@in_pos+=1] << @bit_count)
178
+ @bit_count += 8
179
+ end
180
+
181
+ @bit_bucket = val >> need
182
+ @bit_count -= need
183
+ val & ((1 << need) - 1)
184
+ end
185
+ public
186
+ end
187
+
188
+ #== DEFLATE Decompression
189
+ #Implements decompression of a RFC-1951[ftp://ftp.rfc-editor.org/in-notes/rfc1951.txt] compatible stream.
190
+ class Inflate < ZStream
191
+
192
+ def initialize window_bits=MAX_WBITS
193
+ @w_bits = window_bits
194
+ if @w_bits < 0 then
195
+ @rawdeflate = true
196
+ @w_bits *= -1
197
+ end
198
+ super()
199
+ @zstring = ""
200
+ end
201
+
202
+ #Appends data to the input stream
203
+ def <<(string)
204
+ @zstring << string
205
+ inflate
206
+ end
207
+
208
+ #Sets the inflate dictionary
209
+ def set_dictionary string
210
+ @dict = string
211
+ reset
212
+ end
213
+
214
+ #==Example
215
+ # f = File.open "example.z"
216
+ # i = Inflate.new
217
+ # i.inflate f.read
218
+ def inflate zstring=nil
219
+ @zstring = zstring unless zstring.nil?
220
+ #We can't use unpack, IronRuby doesn't have it yet.
221
+ @zstring.each_byte {|b| @input_buffer << b}
222
+
223
+ unless @rawdeflate then
224
+
225
+ compression_method_and_flags = @input_buffer[@in_pos+=1]
226
+ flags = @input_buffer[@in_pos+=1]
227
+
228
+ #CMF and FLG, when viewed as a 16-bit unsigned integer stored inMSB order (CMF*256 + FLG), is a multiple of 31
229
+ if ((compression_method_and_flags << 0x08) + flags) % 31 != 0 then raise Zlib::DataError.new("incorrect header check") end
230
+
231
+ #CM = 8 denotes the �deflate� compression method with a window size up to 32K. (RFC's only specify CM 8)
232
+ compression_method = compression_method_and_flags & 0x0F
233
+
234
+ if compression_method != Z_DEFLATED then raise Zlib::DataError.new("unknown compression method") end
235
+
236
+ #For CM = 8, CINFO is the base-2 logarithm of the LZ77 window size,minus eight (CINFO=7 indicates a 32K window size)
237
+ compression_info = compression_method_and_flags >> 0x04
238
+
239
+ if (compression_info + 8) > @w_bits then raise Zlib::DataError.new("invalid window size") end
240
+
241
+ preset_dictionary_flag = ((flags & 0x20) >> 0x05) == 1
242
+ compression_level = (flags & 0xC0) >> 0x06
243
+
244
+ if preset_dictionary_flag and @dict.nil? then raise Zlib::NeedDict.new "Preset dictionary needed!" end
245
+
246
+ #TODO: Add Preset dictionary support
247
+ if preset_dictionary_flag then
248
+ @dict_crc = @input_buffer[@in_pos+=1] << 24 | @input_buffer[@in_pos+=1] << 16 | @input_buffer[@in_pos+=1] << 8 | @input_buffer[@in_pos+=1]
249
+ end
250
+
251
+ end
252
+ last_block = false
253
+ #Begin processing DEFLATE stream
254
+ until last_block
255
+ last_block = (get_bits(1) == 1)
256
+ block_type = get_bits(2)
257
+ case block_type
258
+ when 0 then no_compression
259
+ when 1 then fixed_codes
260
+ when 2 then dynamic_codes
261
+ when 3 then raise Zlib::DataError.new("invalid block type")
262
+ end
263
+ end
264
+ finish
265
+ end
266
+
267
+ #Finishes inflating and flushes the buffer
268
+ def finish
269
+ output = ""
270
+ inflate unless @output_buffer.length > 0
271
+ @output_buffer.each {|c| output << c }
272
+ super
273
+ output
274
+ end
275
+
276
+ private
277
+
278
+ def no_compression
279
+ @bit_bucket = 0
280
+ @bit_count = 0
281
+ if @in_pos + 4 > @input_buffer.length then raise Zlib::DataError.new("not enough input to read length code") end
282
+ length = @input_buffer[@in_pos+=1] | (@input_buffer[@in_pos+=1] << 8)
283
+
284
+ if (~length & 0xff != @input_buffer[@in_pos+=1]) || (((~length >> 8) & 0xff) != @input_buffer[@in_pos+=1]) then raise Zlib::DataError.new("invalid stored block lengths") end
285
+
286
+ if @in_pos + length > @input_buffer.length then raise Zlib::DataError.new("ran out of input") end
287
+
288
+
289
+ length.times do
290
+ @output_buffer[@out_pos += 1] = @input_buffer[@in_pos += 1]
291
+ end
292
+
293
+
294
+ end
295
+
296
+ def fixed_codes
297
+ if @fixed_length_codes.nil? && @fixed_distance_codes.nil? then generate_huffmans end
298
+ codes @fixed_length_codes, @fixed_distance_codes
299
+ end
300
+
301
+ def dynamic_codes
302
+
303
+ order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]
304
+ nlen = get_bits(5) + 257
305
+ ndist = get_bits(5) + 1
306
+ ncode = get_bits(4) + 4
307
+
308
+
309
+ lengths=[]
310
+ dynamic_length_codes = Zlib::Inflate::HuffmanTree.new
311
+ dynamic_distance_codes = Zlib::Inflate::HuffmanTree.new
312
+
313
+ if (nlen > MAXLCODES || ndist > MAXDCODES) then raise Zlib::DataError.new("too many length or distance codes") end
314
+ idx = 0
315
+
316
+ while idx < ncode
317
+ lengths[order[idx]] = get_bits(3)
318
+ idx += 1
319
+ end
320
+ while idx < 19
321
+ lengths[order[idx]] = 0
322
+ idx += 1
323
+ end
324
+ err = construct_tree dynamic_length_codes, lengths, 18
325
+ if err != 0 then raise Zlib::DataError.new("code lengths codes incomplete") end
326
+
327
+ idx = 0
328
+ while idx < (nlen + ndist)
329
+ symbol = decode(dynamic_length_codes)
330
+ if symbol < 16 then
331
+ lengths[idx] = symbol
332
+ idx += 1;
333
+ else
334
+ len = 0
335
+ if symbol == 16 then
336
+ if idx == 0 then raise Zlib::DataError.new("repeat lengths with no first length") end
337
+ len = lengths[idx - 1]
338
+ symbol = 3 + get_bits(2)
339
+ elsif symbol == 17 then
340
+ symbol = 3 + get_bits(3)
341
+ elsif symbol == 18 then
342
+ symbol = 11 + get_bits(7)
343
+ else
344
+ raise Zlib::DataError.new("invalid repeat length code")
345
+ end
346
+ if (idx + symbol) > (nlen + ndist) then raise Zlib::DataError.new("repeat more than specified lengths") end
347
+ until symbol == 0
348
+ lengths[idx] = len
349
+ idx+=1
350
+ symbol -= 1
351
+ end
352
+ end
353
+ end
354
+
355
+ err = construct_tree dynamic_length_codes, lengths, nlen-1
356
+
357
+ if err < 0 || (err > 0 && (nlen - dynamic_length_codes.count[0] != 1)) then raise Zlib::DataError.new("invalid literal/length code lengths") end
358
+
359
+ nlen.times { lengths.delete_at 0 } #We do this since we don't have pointer arithmetic in ruby
360
+
361
+ err = construct_tree dynamic_distance_codes, lengths, ndist-1
362
+ if err < 0 || (err > 0 && (ndist - dynamic_distance_codes.count[0] != 1)) then raise Zlib::DataError.new("invalid distance code lengths") end
363
+
364
+ codes dynamic_length_codes, dynamic_distance_codes
365
+ end
366
+
367
+ def generate_huffmans
368
+
369
+ lengths = []
370
+
371
+ #literal/length table
372
+ for idx in (000..143)
373
+ lengths[idx] = 8
374
+ end
375
+ for idx in (144..255)
376
+ lengths[idx] = 9
377
+ end
378
+ for idx in (256..279)
379
+ lengths[idx] = 7
380
+ end
381
+ for idx in (280..287)
382
+ lengths[idx] = 8
383
+ end
384
+ @fixed_length_codes = Zlib::Inflate::HuffmanTree.new
385
+ construct_tree @fixed_length_codes, lengths, 287
386
+
387
+ for idx in (00..29)
388
+ lengths[idx] = 5
389
+ end
390
+ @fixed_distance_codes = Zlib::Inflate::HuffmanTree.new
391
+ construct_tree @fixed_distance_codes, lengths, 29
392
+
393
+ end
394
+
395
+ def codes length_codes, distance_codes
396
+ lens = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258]
397
+ lext = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0]
398
+ dists = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577]
399
+ dext = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]
400
+
401
+ symbol = 0
402
+
403
+ until symbol == 256
404
+ symbol = decode(length_codes)
405
+ if symbol < 0 then return symbol end
406
+ if symbol < 256 then @output_buffer[@out_pos+=1] = symbol end
407
+ if symbol > 256 then
408
+ symbol -= 257
409
+ if symbol >= 29 then raise Zlib::DataError.new("invalid literal/length or distance code in fixed or dynamic block") end
410
+ len = lens[symbol] + get_bits(lext[symbol])
411
+ symbol = decode(distance_codes)
412
+ if symbol < 0 then return symbol end
413
+ dist = dists[symbol] + get_bits(dext[symbol])
414
+ if dist > @output_buffer.length then raise Zlib::DataError.new("distance is too far back in fixed or dynamic block") end
415
+ while len > 0
416
+ @output_buffer[@out_pos+=1] = @output_buffer[@out_pos - dist]
417
+ len -= 1
418
+ end
419
+ end
420
+ end
421
+ return 0
422
+ end
423
+
424
+ def decode huffman_tree
425
+ code = 0
426
+ first = 0
427
+ index = 0
428
+ for len in (1..15)
429
+ code |= get_bits(1)
430
+ count = huffman_tree.count[len]
431
+ if code < (first + count) then return huffman_tree.symbol[index + (code - first)] end
432
+ index += count
433
+ first += count
434
+ first <<= 1
435
+ code <<= 1
436
+ end
437
+ -9
438
+ end
439
+
440
+ def construct_tree huffman_tree, lengths, n_symbols
441
+ offs = []
442
+
443
+ for len in (000..MAXBITS)
444
+ huffman_tree.count[len] = 0
445
+ end
446
+
447
+ for symbol in (000..n_symbols)
448
+ huffman_tree.count[lengths[symbol]] += 1
449
+ end
450
+
451
+ if huffman_tree.count[0] == n_symbols then return 0 end
452
+
453
+ left = 1
454
+ for len in (1..MAXBITS)
455
+ left <<= 1
456
+ left -= huffman_tree.count[len];
457
+ if left < 0 then return left end
458
+ end
459
+
460
+ offs[1] = 0
461
+
462
+ for len in (1..(MAXBITS-1))
463
+ offs[len+1] = offs[len] + huffman_tree.count[len]
464
+ end
465
+
466
+ for symbol in (0..n_symbols)
467
+ if lengths[symbol] != 0 then
468
+ huffman_tree.symbol[offs[lengths[symbol]]] = symbol
469
+ offs[lengths[symbol]] += 1
470
+ end
471
+
472
+ end
473
+ left
474
+ end
475
+
476
+ class HuffmanTree
477
+ attr_accessor :count, :symbol
478
+ def initialize
479
+ @count = []
480
+ @symbol = []
481
+ end
482
+ end
483
+
484
+ class << self
485
+ def inflate zstring
486
+ d = self.new
487
+ d.inflate zstring
488
+ end
489
+ end
490
+
491
+ end
492
+
493
+
494
+ class GzipFile
495
+
496
+ def initialize
497
+ @input_buffer = []
498
+ @output_buffer = []
499
+ @out_pos = -1
500
+ @in_pos = -1
501
+ end
502
+
503
+ def close
504
+ end
505
+
506
+ class Error < Exception
507
+ end
508
+
509
+ end
510
+
511
+ class GzipReader < GzipFile
512
+ OSES = ['FAT filesystem',
513
+ 'Amiga',
514
+ 'VMS (or OpenVMS)',
515
+ 'Unix',
516
+ 'VM/CMS',
517
+ 'Atari TOS',
518
+ 'HPFS fileystem (OS/2, NT)',
519
+ 'Macintosh',
520
+ 'Z-System',
521
+ 'CP/M',
522
+ 'TOPS-20',
523
+ 'NTFS filesystem (NT)',
524
+ 'QDOS',
525
+ 'Acorn RISCOS',
526
+ 'unknown']
527
+
528
+ def initialize io
529
+
530
+ #Add a helper method to check bits
531
+ ::Fixnum.module_eval do
532
+ def isbitset? bit_to_check
533
+ if self & (2 ** bit_to_check) == (2 ** bit_to_check) then true else false end
534
+ end
535
+ end
536
+
537
+ super()
538
+ @io = io
539
+ io.read.each_byte {|b| @input_buffer << b}
540
+ if @input_buffer[@in_pos+=1] != 0x1f || @input_buffer[@in_pos+=1] != 0x8b then raise Zlib::GzipFile::Error.new("not in gzip format") end
541
+ if @input_buffer[@in_pos+=1] != 0x08 then raise Zlib::GzipFile::Error.new("unknown compression method") end
542
+ flg = @input_buffer[@in_pos+=1]
543
+ @ftext = flg.isbitset? 0
544
+ @fhcrc = flg.isbitset? 1
545
+ @fextra = flg.isbitset? 2
546
+ @fname = flg.isbitset? 3
547
+ @fcomment = flg.isbitset? 4
548
+ @mtime = Time.at(@input_buffer[@in_pos+=1] | (@input_buffer[@in_pos+=1] << 8) | (@input_buffer[@in_pos+=1] << 16) | (@input_buffer[@in_pos+=1] << 24))
549
+ @xfl = @input_buffer[@in_pos+=1]
550
+ @os = OSES[@input_buffer[@in_pos+=1]]
551
+ if @fextra then
552
+ @xlen = (@input_buffer[@in_pos+=1] | (@input_buffer[@in_pos+=1] << 8))
553
+ @xtra_field = []
554
+ @xlen.times {@xtra_field << @input_buffer[@in_pos+=1]}
555
+ end
556
+ if @fname then
557
+ @original_name = ""
558
+ until @original_name["\0"].nil? == false
559
+ @original_name.concat(@input_buffer[@in_pos+=1])
560
+ end
561
+ @original_name.chop!
562
+ end
563
+ if @fcomment then
564
+ @comment = ""
565
+ until @comment["\0"].nil? == false
566
+ @comment.concat(@input_buffer[@in_pos+=1])
567
+ end
568
+ @comment.chop!
569
+ end
570
+ if @fhcrc then
571
+ @header_crc = @input_buffer[@in_pos+=1] | (@input_buffer[@in_pos+=1] << 8)
572
+ end
573
+ @contents = ""
574
+ until @in_pos == @input_buffer.length-1
575
+ @contents.concat(@input_buffer[@in_pos+=1])
576
+ end
577
+
578
+ #we do raw deflate, no headers
579
+ @zstream = Zlib::Inflate.new -MAX_WBITS
580
+ @inflated = StringIO.new(@zstream.inflate @contents)
581
+
582
+ end
583
+
584
+ def read length=nil
585
+ @inflated.read length
586
+ end
587
+
588
+ def eof?
589
+ @inflated.eof?
590
+ end
591
+
592
+ def pos
593
+ @inflated.pos
594
+ end
595
+
596
+ def rewind
597
+ @inflated.rewind
598
+ @io.seek 0, IO::SEEK_SET
599
+ end
600
+
601
+ class << self
602
+
603
+ def open filename
604
+ io = File.open filename, 'rb'
605
+ gz = self.new io
606
+ if block_given? then yield gz else gz end
607
+ end
608
+
609
+ end
610
+ end
611
+
612
+
613
+ #Generic Error
614
+ class Error < Exception
615
+ end
616
+
617
+ #Dictionary Needed
618
+ class NeedDict < Error
619
+ end
620
+
621
+ #Invalid Data
622
+ class DataError < Error
623
+ end
624
+
625
+ end
626
+
627
+ end
628
+ end