#!/usr/bin/env ruby
#-*-ruby-*-
require "dpklib/command"
require "dpklib/file"
require "dpklib/parsearg"
require "dpklib/replacefile"
require "dpklib/shadow"

class PasswdProgram < Dpklib::CommandLineProgram
  def start
    opts = Dpklib.parse_args(argv, "d", "f:") || usage

    is_delete = opts[:d]
    file = opts[:f] || usage
    user = opts.shift || usage

    File.exist?(file) || File.open(file, "wb").close()
    Dpklib.replace_file(file) { |input, output|
      manager = Dpklib::ShadowPasswordManager.new
      manager.add_text(input.read)
      if is_delete
        manager.delete(user)
      else
        entry = Dpklib::ShadowPasswordEntry.new
        entry.username = user
        entry.password = read_passwd("Type password for #{user}: ")
        retyped = read_passwd("Re-type password: ")
        entry.verify(entry.username, retyped) ||
          die("Password mismatched.")

        manager << entry
      end
      output.write(manager.to_text)
    }
  end

  def read_passwd(prompt)
    stdout.print(prompt)
    stdout.flush
    passwd = `bash -c 'read -s && echo -n "$REPLY"'`
    ($? == 0) || die("Cannot read password.")
    stdout.puts
    passwd
  end

  def usage
    die(<<-EOF)
usage: #{progname} [-d] -f PASSWDFILE USERNAME
  -d: Delete entry.
  -f PASSWDFILE:
    Edit file PASSWDFILE. (If none, creates.)
    EOF
  end
end #/PasswdProgram
PasswdProgram.exec
