#!/usr/bin/env perl
use strict;
use warnings;
use YAML::XS;

local $/ = undef;

my %param = %{ YAML::XS::Load( <> ) };

my ( $user, $pass ) = @param{qw( argv __PASSWD )};

my $idie = sub{ print shift;exit 1; };

&$idie( "argv no ARRAY" ) unless $user && ref $user eq 'ARRAY';
&$idie( "PASSWD format err" ) if $pass && $pass !~ /^[a-zA-Z0-9]+$/;

my $passwd = sub
{
    my ( $length, $chars ) = ( 16, [ "A" .. "Z", "a" .. "z", 0 .. 9 ] );
    join("", @$chars[ map { rand @$chars } ( 1 .. $length ) ]);
};

for my $usr ( @$user )
{
    my $password = $pass || &$passwd();

    my @p = getpwnam $usr;
    next unless @p;

    my $cmd = "echo '$usr:$password'|chpasswd >/dev/null 2>&1";
  
    if( system( "chpasswd --help >/dev/null 2>&1" ) )
    {
        $cmd = "echo '$password' |passwd --stdin '$usr' >/dev/null 2>&1";
        my $help = `passwd --help`;
        &$idie( "nonsupport" ) unless $help && $help =~ /--stdin/;
    }

    system $cmd;

    if( $? == -1 )
    {
        print "failed to execute: $!\n";
        exit 1;
    }
    elsif ( $? & 127 )
    {
        printf "child died with signal %d, %s coredump\n",
            ( $? & 127 ), ( $? & 128 ) ? 'with' : 'without';
        exit 1;
    }
    my $exit = $? >> 8;
    exit $exit if $exit && print "child exited with value $exit\n";

    print "$usr:$password\n";
}

exit 0;
