* Reintroduce failure on key not found.
[pgp-tools.git] / gpg-key2ps / gpg-key2ps
1 #!/usr/bin/perl -w
2 #
3 # gpg-key2ps: convert a PGP/GnuPG key into paper slips.
4 #
5 # $Id$
6
7 use strict;
8 use Getopt::Std;
9
10 my $version = '$Rev$';
11 $version =~ s/\$Rev:\s*(\d+)\s*\$/$1/;
12 my $usage = "Usage: $0 [-p papersize] [-r revoked-style] keyid-or-name\n";
13 my $keyids = "";
14 my $revokestyle="hide";
15
16 if ( $#ARGV < 0 ) {
17 print $usage;
18 exit 1;
19 }
20
21 my %opts;
22 getopt('pr', \%opts);
23 if ( $opts{r} ) { $revokestyle = $opts{'r'}; }
24 if ( $opts{p} ) { $ENV{'PAPERSIZE'} = $opts{'p'}; }
25 foreach (@ARGV) { $keyids .= $_ . " "; }
26
27 if ( $revokestyle !~ /^(grey|hide|note|show|strike)$/ ) {
28 print STDERR "Unknown style \"$revokestyle\". Please use one of\n";
29 print STDERR " grey - Print text in grey\n";
30 print STDERR " hide - Don't show revoked uids\n";
31 print STDERR " note - Add \"(revoked)\"\n";
32 print STDERR " show - List revoked uids normally\n";
33 print STDERR " strike - Strike through lines\n";
34 exit 1;
35 }
36
37 my $w; my $h;
38 if ( -x "/usr/bin/paperconf" ) {
39 $w=`paperconf -w`;
40 $h=`paperconf -h`;
41 chomp($w);
42 chomp($h);
43 } else {
44 # Default to A4.
45 $w=596;
46 $h=842;
47 }
48
49 if ( system( "gpg --fingerprint $keyids >/dev/null" ) != 0 ) {
50 print STDERR "Key not found. Try 'gpg --list-keys'\n";
51 exit 1;
52 }
53
54 open(GPG, "gpg --fingerprint --with-colons $keyids |");
55
56 print <<EOF;
57 %!PS-Adobe-3.0
58 %%BoundingBox: 0 0 $w $h
59 %%Title:
60 %%Creator: gpg-key2ps $version
61 EOF
62 print "%%CreationDate: " . scalar(localtime) . "\n";
63 print <<EOF;
64 %%Pages: 1
65 %%EndComments
66
67 %%Page: 1 1
68
69 /w $w def
70 /h $h def
71
72 /Times-Roman findfont 9 scalefont setfont
73
74 /newline {
75 /y y 10 sub def
76 } def
77
78 /hline {
79 30 y 3 add moveto
80 w 2 div 30 sub y 3 add lineto stroke
81 newline
82 } def
83
84 /needhline {
85 /condhline { hline } def
86 } def
87
88 /noneedhline {
89 /condhline { } def
90 } def
91
92 /showAlgorithm {
93 << 1 (R) 2 (r) 3 (s) 16 (g) 20 (G) 17 (D) >> exch get
94 show
95 } def
96
97 /pub {
98 condhline
99 50 y moveto (pub) show
100 70 y moveto show showAlgorithm (/) show show
101 150 y moveto show
102 200 y moveto show
103 newline
104 needhline
105 } def
106
107 /fpr {
108 70 y moveto (Key fingerprint = ) show show
109 newline
110 } def
111
112 /uid {
113 50 y moveto (uid) show
114 200 y moveto show
115 newline
116 } def
117
118 EOF
119
120 if ( $revokestyle eq "grey" ) {
121 print "/revuid {\n";
122 print " .5 setgray\n";
123 print " uid\n";
124 print " 0 setgray\n";
125 print "} def\n";
126 } elsif ( $revokestyle eq "hide" ) {
127 print "/revuid {} def\n";
128 } elsif ( $revokestyle eq "note" ) {
129 print "/revuid {\n";
130 print " 50 y moveto (uid) show\n";
131 print " 200 y moveto show ([revoked]) show\n";
132 print " newline\n";
133 print "} def\n";
134 } elsif ( $revokestyle eq "show" ) {
135 print "/revuid { uid } def\n";
136 } elsif ( $revokestyle eq "strike" ) {
137 print "/revuid {\n";
138 print " uid\n";
139 print " 45 y 9 add moveto h 2 div 45 sub y 18 add lineto stroke\n";
140 print "} def\n";
141 }
142
143 print <<EOF;
144
145 /sbk {
146 50 y moveto (sub) show
147 70 y moveto show showAlgorithm (/) show show
148 150 y moveto show
149 newline
150 } def
151
152 /key {
153 noneedhline
154 EOF
155
156 my $numlines = 0;
157 while(<GPG>) {
158 if ( /^(tru|uat):/ ) { next; }
159 if ( /^pub:/ ) { $numlines++; }
160 s/^pub:[^:]*:([^:]*):([0-9]*):.{8,8}(.{8,8}):([^:]*):[^:]*:[^:]*:[^:]*:([^:]*):[^:]*:[^:]*:.*/ ($5) ($4) ($3) $2 ($1) pub/;
161 if ( /^fpr:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):.*/ ) {
162 my $fpr = $1;
163 # v4 key
164 $fpr =~ s/(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})/$1 $2 $3 $4 $5 $6 $7 $8 $9 $10/;
165 # v3 key
166 $fpr =~ s/(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})/$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16/g;
167 $_ = " ($fpr) fpr\n";
168 }
169 s/^uid:[^:r]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):.*/ ($1) uid/;
170 s/^uid:[^:r]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):.*/ ($1) uid/;
171 s/^uid:r[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):.*/ ($1) revuid/;
172 s/^sub:[^:]*:([^:]*):([0-9]*):.{8,8}(.{8,8}):([^:]*):[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:.*/ ($4) ($3) $2 ($1) sbk/;
173 $numlines++;
174 print;
175 }
176 close(GPG);
177
178 print <<EOF;
179 } def
180
181 EOF
182 print "/numlines $numlines def\n";
183 print <<EOF;
184 /num w 16 sub 10 div numlines div def
185
186 /column {
187 /y w 20 sub def
188 1 1 num {
189 gsave
190 0 0 h 2 div w rectclip
191 /upper y 11 add def
192 key
193 newline
194 /lower y 11 add def
195 0 upper h 2 div upper h 2 div lower 0 lower 0 upper moveto lineto lineto lineto lineto stroke
196 grestore
197 } for
198 } def
199
200 w 0 translate
201 90 rotate
202 column
203 h 2 div 0 translate
204 column
205
206 showpage
207
208 %%Trailer
209 %%EOF
210 EOF
211
212 exit 0;
213