9 use File::Path 'make_path';
11 our ($opt_g, $opt_d, $opt_r);
14 # usage: print usage information to stderr and exit with error.
16 my $cmd = basename $0;
18 "usage: $cmd [-g command] [-d dir] add [-m] name\n" .
19 " $cmd [-d dir] rm name ...\n" .
20 " $cmd [-g command] [-d dir] show name\n" .
21 " $cmd [-d dir] mv from to\n" .
22 " $cmd [-d dir] ls\n";
25 # getrecipient: return string to be used with gpg's -r option.
27 # Past versions of gpm (written in shell) required explicit recipient, set by
28 # option -r, or the GPM_RECIPIENT environment variable. This is completely
29 # unnecessary now, due to GPM_GPG and -g, but legacy syntax is still maintained.
32 defined $r or $r = $ENV{GPM_RECIPIENT};
38 # Return 1 if $path doesn't start with /, or contain .. files, and 0 otherwise.
41 return $p !~ m,^/, && $p ne ".." && $p !~ m,^\.\./, && $p !~ m,/\.\./,
47 # Returns the correct path for $f (with or without the .gpg suffix), or dies
48 # if no such file exists.
53 -f $f2 or die "neither $f, nor $f2 exist as regular files\n";
59 # prunetree $d: remove empty directories, starting from $d, and going up.
61 for (my ($d) = @_; $d ne "."; $d = dirname $d) {
68 # Encrypt the secret from stdin, and store the ciphertext in file specified
69 # on the command line.
76 $cmd .= " -r $r" if defined $r;
78 getopts('m') or usage;
81 my $outfile = $ARGV[0];
82 ckpath $outfile or die "bad path: $outfile\n";
84 -e $outfile and die "$outfile already exists\n";
86 if (-t STDIN && !$opt_m) {
95 die "Sorry\n" if $sec ne $sec2;
98 } else { while (<STDIN>) { $sec .= $_; } }
100 my $pid = open2(my $reader, my $writer, $cmd);
104 while (<$reader>) { $out .= $_; }
108 my $d = dirname $outfile;
109 make_path($d, {mode => 0700});
111 unless (open FH, ">$outfile") {
113 die "couldn't open $outfile for writing: $!\n";
115 unless (print FH $out) {
117 die "couldn't write to $outfile: $!\n";
123 # Produce a listing of files in the gpm directory, using the GPM_LSCMD
124 # environment variable if defined.
126 my $cmd = $ENV{GPM_LSCMD};
127 unless (defined $cmd) {
128 opendir my $dh, "." or die "couldn't open directory .: $!\n";
129 while (readdir $dh) {
130 if ($_ ne "." && $_ ne ".." && -d $_) {
131 $cmd = "find . -type f | sed 's,^\./,,'";
135 $cmd = "ls" unless defined $cmd;
141 # mv: safely rename $ARGV[0] to $ARGV[1].
143 $#ARGV >= 1 || usage;
144 my ($from, $to) = @ARGV;
145 ckpath $from or die "bad path $from\n";
146 ckpath $to or die "bad path $to\n";
147 -e $to and die "$to already existst\n";
148 $from = cklegacy $from;
150 make_path(dirname $to, {mode => 0700});
152 prunetree(dirname $from);
155 # rm: unlink arguments, asking each time.
157 $#ARGV >= 0 || usage;
161 print STDERR "bad path $f\n";
165 print "Really remove $f? ";
166 <STDIN> =~ m/^[Yy]/ and unlink $f;
167 prunetree(dirname $f);
171 # show: decrypt file, and print plaintext to stdout.
173 $#ARGV >= 0 or usage;
175 ckpath $file or die "bad path $file\n";
176 $file = cklegacy $file;
178 system("$gpg -d $file");
182 getopts('g:d:r') or usage;
184 $#ARGV >= 0 or usage;
189 $gpg = $ENV{GPM_GPG} unless defined $gpg;
190 $gpg = "gpg" unless defined $gpg;
193 defined $gpmd or $gpmd = $ENV{GPM_DIR};
194 unless (defined $gpmd) {
195 if (defined $ENV{XDG_DATA_HOME}) {
196 $gpmd = $ENV{XDG_DATA_HOME} . "/gpm";
197 } elsif (defined $ENV{HOME}) {
198 $gpmd = $ENV{HOME} . "/.gpm";
200 die "couldn't determine the gpm directory\n";
204 make_path($gpmd, {mode => 0700});
205 chdir $gpmd or die "couldn't change directory to $gpmd: $!\n";
208 if (/^a/) { add; last; }
209 if (/^l/) { ls; last; }
210 if (/^m/) { mv; last; }
211 if (/^r/) { rm; last; }
212 if (/^s/) { show; last; }