369: def call(args, opts = {}, ioe = {})
370: argv = []
371:
372: while (arg = args.shift)
373: case arg
374: when '--compress', '-z'
375: opts[:compress] = true
376: else
377: argv << arg
378: end
379: end
380:
381: if argv.size < 2
382: ioe[:output] << "Not enough arguments.\n\n"
383: CommandPattern["help"][["create"]]
384: return 255
385: end
386:
387: output = argv.shift
388: if '-' == output
389: opts[:name] = "STDOUT"
390: output = ioe[:output]
391: opts[:output] = ioe[:error]
392: else
393: opts[:name] = output
394: output = File.open(output, "wb")
395: opts[:output] = ioe[:output]
396: end
397:
398: if opts[:name] =~ /\.tar\.gz$|\.tgz$/ or opts[:compress]
399: output = Zlib::GzipWriter.new(output)
400: end
401:
402: files = []
403: if argv.include?("--")
404:
405: files = ""
406: files << ioe[:input].read while not ioe[:input].eof?
407: files = files.split(/\r\n|\n|\r/)
408: args.delete("--")
409: end
410:
411: files << argv.to_a
412: files.flatten!
413:
414: if opts[:verbose]
415: watcher = lambda do |action, name, stats|
416: opts[:output] << "#{name}\n" if action == :dir or action == :file_done
417: end
418: finisher = lambda { opts[:output] << "\n" }
419: elsif opts[:progress]
420: progress = ProgressBar.new(opts[:name], 1)
421: watcher = lambda do |action, name, stats|
422: case action
423: when :file_start, :dir
424: progress.title = File.basename(name)
425: if action == :dir
426: progress.total += 1
427: progress.inc
428: else
429: progress.total += stats[:size]
430: end
431: when :file_progress
432: progress.inc(stats[:currinc])
433: end
434: end
435: finisher = lambda do
436: progress.title = opts[:name]
437: progress.finish
438: end
439: else
440: watcher = nil
441: finisher = lambda { }
442: end
443:
444: Archive::Tar::Minitar.pack(files, output, &watcher)
445: finisher.call
446: 0
447: ensure
448: output.close if output and not output.closed?
449: end