Sync 4.next from master
[exim.git] / src / util / mkcdb.pl
1 #!/usr/bin/perl -wT
2 #
3 # Create cdb file from flat alias file. DPC: 15/10/98.
4 # Args:      source  (may be relative or absolute)
5 #            target  (may be relative or absolute. Default = source)
6 # Generates: target.cdb
7 #            target.tmp
8 #
9 # Little Perl script to convert flat file into CDB file. Two advantages over
10 # cdbmake-12 awk script that is distributed with CDB:
11 #  1) Handles 'dpc22:dpc22@hermes' as well as 'dpc22 dpc22@hermes'
12 #  2) Perl works with arbitrary length strings: awk chokes at 1,024 chars
13 #
14 # Cambridge: hermes/src/admin/mkcdb,v 1.9 2005/02/15 18:14:12 fanf2 Exp
15
16 use strict;
17
18 BEGIN { pop @INC if $INC[-1] eq '.' };
19 $ENV{'PATH'} = "";
20 umask(022);
21
22 my $CDB = '/opt/cdb/bin/cdbmake';
23
24 my $prog = $0;
25 $prog =~ s|(.*/)?([^/]+)|$2|;
26
27 my $source;
28 my $target;
29 if (@ARGV == 1) {
30     $source = shift(@ARGV);
31     $target = $source;
32 } elsif (@ARGV == 2) {
33     $source = shift(@ARGV);
34     $target = shift(@ARGV);
35 } else {
36     die("$prog: usage: <source> [<target>]\n");
37 }
38 # trust the invoker ?!
39 $source =~ /(.*)/;
40 $source = $1;
41 $target =~ /(.*)/;
42 $target = $1;
43
44 open(SOURCE, "< ${source}")
45     or die("$prog: open < $source: $!\n");
46
47 open(PIPE, "| $CDB $target.cdb $target.tmp")
48     or die("$prog: open | $CDB $target: $!\n");
49
50 sub add_item ($$) {
51     my $key = shift;
52     my $val = shift;
53     printf PIPE ("+%d,%d:%s->%s\n", length($key), length($val), $key, $val);
54 }
55
56 sub add_line ($) {
57     my $line = shift;
58     if ($line =~ /^([^\s:]+)\s*:\s*(.*)$/s) {   # key : values
59         add_item($1,$2);
60         return;
61     }
62     if ($line =~ /^(\S+)\s+(.*)$/s) {       # key: values
63         add_item($1,$2);
64         return;
65     }
66     if ($line =~ /^(\S+)$/s) {              # key (empty value)
67         add_item($1,'');
68         return;
69     }
70     warn "$prog: unrecognized item: $line";
71 }
72
73 my $data;
74 while(<SOURCE>) {
75     next if /^#/ or /^\s*$/;
76     m/^(\s*)(\S.*)\s+$/s;
77     if (length($1) == 0) {
78             add_line($data) if defined $data;
79             $data = $2;
80     } else {
81             $data .= " $2";
82     }
83 }
84 add_line($data) if defined $data;
85 print PIPE "\n";
86
87 close(SOURCE)
88     or die("$prog: close < $source: $!\n");
89 close(PIPE)
90     or die($! ? "$prog: close | $CDB $target: $!\n"
91            : "$prog: close | $CDB $target: exited $?\n");
92
93 exit 0;