summaryrefslogtreecommitdiff
path: root/bin/envstore
blob: 59d9a678e2f09a2d3196d64cd2cce9f8161b3fc0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/env perl
## envstore - save and load environment variables
## Copyright © 2009 by Daniel Friesel <derf@derf.homelinux.org>
## License: WTFPL <http://sam.zoy.org/wtfpl>
use strict;
use warnings;
use 5.010;
use Pod::Usage;
use Storable 'nstore', 'retrieve';

my $store_file = $ENV{ENVSTORE_FILE} || "/tmp/envstore-$>";
my %store;
my $action = shift;
my $arg = shift;
my $arg2 = shift;

sub usage {
	pod2usage(
		-message  => 'Syntax error',
		-exitval  => 1,
		-verbose  => 99,
		-sections => 'SYNOPSIS|DESCRIPTION',
		-output   => \*STDERR,
	);
	return;
}

sub check_store {
	my ($mode, $uid);

	if (-e $store_file) {
		($mode, $uid) = (stat($store_file))[2,4];
	}
	else {
		return 0;
	}

	if ($uid != $<) {
		print STDERR "envstore: store file is insecure (not owned by us)\n";
		exit 1;
	}
	if (($mode & 0x00077) > 0) {
		print STDERR "envstore: store file is insecure (writable by group/others)\n";
		exit 1;
	}
	return 1;
}

sub load_store {
	if (check_store) {
		%store = %{retrieve($store_file) || {}};
	}
	return;
}

sub save_store {
	umask(0077);
	nstore(\%store, $store_file);
	return;
}

sub get_keyvalue {
	my ($key, $value) = @_;
	if (not defined($value)) {
		if (exists($ENV{$key})) {
			$value = $ENV{$key};
		}
		else {
			print STDERR "No such parameter: $key (perhaps you forgot to export it?)\n";
			exit(1);
		}
	}
	return($key, $value);
}

if (
	not defined $action
	or ($action ~~ ['save', 'rm'] and not defined $arg)
) {
	usage;
}
load_store;

given ($action) {
	when ('save') {
		my ($key, $value) = get_keyvalue($arg, $arg2);
		$store{$key} = $value;
		save_store;
	}
	when ('eval') {
		while (my ($key, $value) = each(%store)) {
			$value =~ s/'/'"'"'/g;
			print "export $key='$value'\n";
		}
	}
	when (['show', 'list']) {
		while (my ($key, $value) = each(%store)) {
			printf("%-15s = %s\n", $key, $value);
		}
	}
	when ('rm') {
		delete($store{$arg});
		save_store;
	}
	when ('clear') {
		unlink($store_file);
	}
	default {
		usage;
	}
}
__END__

=head1 NAME

envstore - save and restore environment variables

=head1 SYNOPSIS

B<envstore> I<command> [ I<arguments> ]

=head1 DESCRIPTION

envstore can save and restore environment variables, thus transferring them
between different shells.

I<command> must be one of

=over

=item B<clear>

Forget all stored variables

=item B<eval>

Produce shell code for evaluation, restoring all saved variables

=item B<save> I<variable> [I<value>]

Save I<variable> either with its current shell value or with I<value>

=item B<show>

List saved variables in better readable format

=item B<rm> I<variable>

Remove I<variable> from store

=back

=head1 ENVIRONMENT

=over

=item B<ENVSTORE_FILE>

The file in which the environment parameters are stored. By default
F</tmp/envstore-$UID>

=back

=head1 LIMITATIONS

You should not store null bytes or similar extremely weird binary data. They
might work fine, but there's a high chance that somewhere, something goes wrong
and you start to lose bytes or get undefined behaviour.

Also, since shells 'flatten' the input when using eval, newlines in variable
values will be stored correctly, but silently dropped when loading the
environment with eval.  You can work around that by doing
C<< envstore eval E<gt> $tmpfile; source $tmpfile >> or (in zsh)
C<< source E<lt>(envstore eval) >>.

=head1 AUTHOR

B<envstore> was written by Daniel Friesel E<lt>derf@derf.homelinux.orgE<gt>

Original idea and script by Maximilian Gass E<lt>mxey@ghosthacking.netE<gt>