d9898ee8 |
1 | #! @PERL@ |
2 | #$Id: userdb.pl.in,v 1.11 2000/05/07 17:36:31 mrsam Exp $ |
3 | # |
4 | # Copyright 1998 - 1999 Double Precision, Inc. See COPYING for |
5 | # distribution information. |
6 | |
7 | use Fcntl ':flock'; |
8 | |
9 | $prefix="@prefix@"; |
10 | $exec_prefix="@exec_prefix@"; |
11 | $userdb="@userdb@"; |
12 | |
13 | eval { |
14 | die "SYMLINK\n" if -l $userdb; |
15 | }; |
16 | |
17 | die "ERROR: Wrong userdb command.\n ($userdb is a symbolic link)\n" |
18 | if $@ eq "SYMLINK\n"; |
19 | |
20 | sub usage { |
21 | print "Usage: $0 [path/.../ | -f file ]name set field=value field=value...\n"; |
22 | print " $0 [path/.../ | -f file ]name unset field field...\n"; |
23 | print " $0 [path/.../ | -f file ]name del\n"; |
24 | print " $0 -show [path/... | -f file ] [name]\n"; |
25 | exit 1; |
26 | } |
27 | |
28 | $name=shift @ARGV; |
29 | $doshow=0; |
30 | |
31 | if ($name eq "-show") |
32 | { |
33 | $doshow=1; |
34 | $name=shift @ARGV; |
35 | } |
36 | |
37 | if ($name eq "-f") |
38 | { |
39 | $userdb=shift @ARGV; |
40 | $name=shift @ARGV; |
41 | } |
42 | elsif ( $name =~ /^(.*)\/([^\/]*)$/ ) |
43 | { |
44 | $userdb="$userdb/$1"; |
45 | $name=$2; |
46 | } |
47 | |
48 | |
49 | if ($doshow) |
50 | { |
51 | &usage unless $userdb =~ /./; |
52 | } |
53 | else |
54 | { |
55 | $verb=shift @ARGV; |
56 | |
57 | &usage unless $verb =~ /./ && $name =~ /./ && $userdb =~ /./; |
58 | } |
59 | |
60 | while (defined ($link= &safe_readlink($userdb))) |
61 | { |
62 | $userdb .= "/"; |
63 | $userdb = "" if $link =~ /^\//; |
64 | $userdb .= $link; |
65 | } |
66 | |
67 | $tmpuserdb= $userdb =~ /^(.*)\/([^\/]*)$/ ? "$1/.tmp.$2":".tmp.$userdb"; |
68 | $lockuserdb= $userdb =~ /^(.*)\/([^\/]*)$/ ? "$1/.lock.$2":".lock.$userdb"; |
69 | |
70 | if ( $doshow && ! defined $name) |
71 | { |
72 | } |
73 | else |
74 | { |
75 | die "Invalid name: $name\n" |
d2b6c28d |
76 | unless $name =~ /^[\@a-zA-Z0-9+:_\.\-]+$/; |
d9898ee8 |
77 | } |
78 | |
79 | grep( (/[\|\n]/ && die "Invalid field or value.\n"), @ARGV); |
80 | |
81 | umask(066); |
82 | |
83 | open(LOCK, ">$lockuserdb") or die "Can't open $lockuserdb: $!"; |
84 | flock(LOCK,LOCK_EX) || die "Can't lock $lockuserdb: $!"; |
85 | |
86 | if ( $doshow ) |
87 | { |
88 | if (open (OLDFILE, $userdb)) |
89 | { |
90 | stat(OLDFILE); |
91 | die "$userdb: not a file.\n" unless -f _; |
92 | |
93 | while ( defined($_=<OLDFILE>) ) |
94 | { |
95 | chop if /\n$/; |
96 | next if /^#/; |
97 | next unless /^([^\t]+)(\t(.*))?$/; |
98 | ($addr,$vals)=($1,$3); |
99 | if (defined $name) |
100 | { |
101 | if ($name eq $addr) |
102 | { |
103 | $vals =~ s/\|/\n/g; |
104 | print "$vals\n"; |
105 | last; |
106 | } |
107 | } |
108 | else |
109 | { |
110 | print "$addr\n"; |
111 | } |
112 | } |
113 | } |
114 | close (OLDFILE); |
115 | } |
116 | elsif ( $verb eq "set" ) |
117 | { |
118 | $isatty=1; |
119 | |
120 | eval { |
121 | $isatty=0 unless -t STDIN; |
122 | } ; |
123 | |
124 | &doadd; |
125 | $mode= (stat $userdb)[2]; |
126 | chmod ($mode & 0777,$tmpuserdb ) if defined $mode; |
127 | rename $tmpuserdb,$userdb; |
128 | } |
129 | elsif ( $verb eq "unset" ) |
130 | { |
131 | if ($#ARGV >= 0 && &dodel) |
132 | { |
133 | $mode= (stat $userdb)[2]; |
134 | chmod ($mode & 0777 ,$tmpuserdb) if defined $mode; |
135 | rename ($tmpuserdb,$userdb) |
136 | } |
137 | } |
138 | elsif ( $verb eq "del" ) |
139 | { |
140 | &usage unless $#ARGV < 0; |
141 | if (&dodel) |
142 | { |
143 | $mode= (stat $userdb)[2]; |
144 | chmod ($mode & 0777 ,$tmpuserdb) if defined $mode; |
145 | rename ($tmpuserdb,$userdb) |
146 | } |
147 | } |
148 | else |
149 | { |
150 | &usage; |
151 | } |
152 | exit 0; |
153 | |
154 | sub doadd { |
155 | my (%FIELDS); |
156 | my ($key, $in); |
157 | |
158 | foreach $key (@ARGV) |
159 | { |
160 | next if $key =~ /=/; |
161 | print "$name.$key: " if $isatty; |
162 | exit 1 unless defined ($in=<STDIN>); |
163 | chop $in if $in =~ /\n$/; |
164 | die "Invalid value.\n" if $in =~ /[\|\n]/; |
165 | $key = "$key=$in"; |
166 | } |
167 | |
168 | open (NEWFILE, ">$tmpuserdb") || die "$!\n"; |
169 | if (open (OLDFILE, $userdb)) |
170 | { |
171 | stat(OLDFILE); |
172 | die "$userdb: not a file.\n" unless -f _; |
173 | while ( defined($_=<OLDFILE>) ) |
174 | { |
175 | chop if /\n$/; |
176 | if ( /^([^\t]+)(\t(.*))?$/ && ($1 eq $name)) |
177 | { |
178 | grep( (/^([^=]*)(=.*)?$/, |
179 | $FIELDS{$1}="$2"), split(/\|/, $3)); |
180 | while ( defined ($key=shift @ARGV)) |
181 | { |
182 | $key =~ /^([^=]*)(=.*)?$/; |
183 | $FIELDS{$1}="$2"; |
184 | } |
185 | $name="$name\t"; |
186 | grep ( $name="$name$_$FIELDS{$_}|", |
187 | keys %FIELDS); |
188 | chop $name; |
189 | print NEWFILE "$name\n" || die "$!\n"; |
190 | while (<OLDFILE>) |
191 | { |
192 | print NEWFILE || die "$!\n"; |
193 | } |
194 | close (OLDFILE); |
195 | close (NEWFILE) || die "$!\n"; |
196 | return; |
197 | } |
198 | print NEWFILE "$_\n" || die "$!\n"; |
199 | } |
200 | close (OLDFILE); |
201 | } |
202 | |
203 | $name="$name\t"; |
204 | grep ( $name="$name$_|", @ARGV ); |
205 | chop $name; |
206 | print NEWFILE "$name\n" || die "$!\n"; |
207 | close (NEWFILE) || die "$!\n"; |
208 | } |
209 | |
210 | sub dodel { |
211 | my (%FIELDS); |
212 | |
213 | open (NEWFILE, ">$tmpuserdb") || die "$!\n"; |
214 | if (open (OLDFILE, $userdb)) |
215 | { |
216 | stat(OLDFILE); |
217 | die "$userdb: not a file.\n" unless -f _; |
218 | while ( defined($_=<OLDFILE>) ) |
219 | { |
220 | chop if /\n$/; |
221 | if ( /^([^\t]+)(\t(.*))?$/ && ($1 eq $name)) |
222 | { |
223 | if ($#ARGV >= 0) |
224 | { |
225 | grep( (/^([^=]*)(=.*)?$/, |
226 | $FIELDS{$1}=$2), |
227 | split(/\|/, $3)); |
228 | grep( delete $FIELDS{$_}, @ARGV); |
229 | |
230 | $name="$name\t"; |
231 | grep ( $name="$name$_$FIELDS{$_}|", |
232 | keys %FIELDS); |
233 | chop $name; |
234 | $name="$name\n"; |
235 | print NEWFILE "$name" || die "$!\n"; |
236 | } |
237 | while (<OLDFILE>) |
238 | { |
239 | print NEWFILE || die "$!\n"; |
240 | } |
241 | close (OLDFILE); |
242 | close (NEWFILE) || die "$!\n"; |
243 | return (1); |
244 | } |
245 | print NEWFILE "$_\n" || die "$!\n"; |
246 | } |
247 | close (OLDFILE); |
248 | } |
249 | unlink "$tmpuserdb"; |
250 | return (0); |
251 | } |
252 | |
253 | sub safe_readlink { |
254 | my ($l)=@_; |
255 | my ($err,$link); |
256 | |
257 | eval { |
258 | |
259 | $link=readlink($l); |
260 | } ; |
261 | |
262 | $link=undef if $@; |
263 | return $link; |
264 | } |