new stuff added, this is a patch and a script
[netbsd-linux-nis-yp.git] / master-passwd.pl
1 #!/usr/bin/perl -w
2 #
3 # convert from linux passwd/shadow to master.passwd
4 #
5 use strict;
6 use Class::Date qw(:errors date now);
7 use Data::Dumper;
8
9
10 sub read_file {
11     my ($f, $data, $fields) = @_;
12
13     open(FH, '<', $f) || die "can't open $f";
14     while (<FH>) {
15         chomp;
16         my @list = split(':');
17
18         for (my $i = 0; $i < scalar(@$fields); $i++) {
19             $data->{$list[0]}->{$fields->[$i]} = $list[$i];
20         }
21     }
22     close(FH);
23 }
24
25 sub write_file {
26     my ($fh, $data, $fields) = @_;
27
28     foreach my $key (keys(%$data)) {
29         print $fh join(':', map { my $x = $data->{$key}->{$_}; die $_ unless(defined($x)); $x } @$fields), "\n";
30     }
31 }
32
33 sub read_passwd {
34     my ($f, $users) = @_;
35     &read_file($f, $users, 
36             ['login', 'pw', 'uid', 'gid', 'gecos', 'home', 'shell']);
37 }
38
39 sub read_shadow {
40     my ($f, $users) = @_;
41     &read_file($f, $users, 
42             ['login', 'pw', 'last_changed', 'may_change', 'must_change', 'expire_warn', 'disable', 'disabled_since', 'reserved']);
43 }
44
45 sub write_bsd {
46     my ($users) = @_;
47     &write_file(\*STDOUT, $users, 
48         [ 'login', 'pw', 'uid', 'gid', 'class', 'change', 'expire', 'gecos', 'home', 'shell' ]);
49 }
50
51 sub days_to_epoch_seconds {
52     my ($days) = @_;
53     my $from = now;
54     my $rel = new Class::Date::Rel { day => $days };
55     my $r = $from+$rel;
56     return $r->epoch;
57 }
58
59 sub conv_class {
60     my ($u, $d) = @_;
61     $d->{'class'} = '';
62 }
63
64 sub conv_change {
65     my ($u, $d) = @_;
66     my $f = $d->{'must_change'};
67
68     if (defined($f) && $f > 0) {
69         $d->{'change'} = &days_to_epoch_seconds($f);
70     } elsif ($f == '-1') {
71         $d->{'change'} = -1;
72     } else {
73         $d->{'change'} = '';
74     }
75 }
76
77 sub conv_expire {
78     my ($u, $d) = @_;
79     $d->{'expire'} = '';
80 }
81
82 sub conv_fields {
83     my ($data) = @_;
84
85     while (my ($user, $data) = each(%$data)) {
86         &conv_class($user, $data);
87         &conv_change($user, $data);
88         &conv_expire($user, $data);
89     }
90 }
91
92 sub usage {
93         print STDERR "Usage: $0 <passwd> <shadow>\n";
94         exit 1;
95 }
96
97 sub main {
98     &usage() if (scalar(@ARGV) != 2);
99     my %users;
100
101     &read_passwd($ARGV[0], \%users);
102     &read_shadow($ARGV[1], \%users);
103     &conv_fields(\%users);
104     &write_bsd(\%users);
105 }
106
107 &main;
108
109 # all done!