1 |
eval 'exec /home/jsoc/bin/$JSOC_MACHINE/perl -S $0 "$@"' |
2 |
if 0; |
3 |
# |
4 |
#/home/jim/cvs/JSOC/base/util/scripts/dsview |
5 |
#Perl/Tk gui to view DRMS series tables. |
6 |
# |
7 |
# |
8 |
|
9 |
#use lib ("/usr/lib/perl5/site_perl/5.8.5","/home/jim/perl_tk_800.023.xim/lib/perl5/site_perl/5.8.5"); |
10 |
#use lib ("/home/jim/perl_tk_800.023.xim/lib/perl5/site_perl/5.8.5"); |
11 |
use Tk; |
12 |
use DBI; |
13 |
use FindBin qw($RealBin); |
14 |
use lib "$RealBin/../../../localization"; |
15 |
use drmsparams; |
16 |
|
17 |
#use Config; |
18 |
#$archname = $Config{'archname'}; |
19 |
#print "arch = $archname\n"; |
20 |
|
21 |
sub usage { |
22 |
exit; |
23 |
} |
24 |
|
25 |
$DEFAULTDB = drmsparams::DBNAME; #default DB |
26 |
$DBSUMS = $DEFAULTDB . "_sums"; |
27 |
$HOSTDB = drmsparams::SUMS_DB_HOST; #host where DB runs |
28 |
$PGPORT = 5434; #for connection with jsoc_sum db |
29 |
$IMGDIR = "/home/jsoc/gallery"; #dir with the .gif files |
30 |
$INLOG = 0; #use default tape_svc log |
31 |
$nsel = 200; #number of records at a time to fetch |
32 |
$pid0 = 0; |
33 |
|
34 |
$ldate = &labeldate(); |
35 |
$user = $ENV{'USER'}; |
36 |
|
37 |
while ($ARGV[0] =~ /^-/) { |
38 |
$_ = shift; |
39 |
if (/^-l(.*)/) { |
40 |
$INLOG = $1; |
41 |
} |
42 |
elsif (/^-p(.*)/) { |
43 |
$playback = 1; |
44 |
} |
45 |
elsif (/^-h(.*)/) { |
46 |
$helpflg = 1; |
47 |
} |
48 |
elsif (/^-i(.*)/) { |
49 |
$interactive = 1; |
50 |
} |
51 |
else { |
52 |
&usage; |
53 |
} |
54 |
} |
55 |
if($#ARGV == 0) { |
56 |
$DB = $ARGV[0]; |
57 |
} |
58 |
else { |
59 |
$DB = $DEFAULTDB; |
60 |
} |
61 |
if($helpflg) { &usage; } |
62 |
$hostdb = $HOSTDB; #host where Postgres runs |
63 |
$UID = $<; #get real user id |
64 |
|
65 |
#$runtag = "/tmp/t120view_$UID.tag"; |
66 |
#if(-e $runtag) { #this user already running |
67 |
# print "Already found a $runtag\n"; |
68 |
# print "Only one instance of t120view allowed for a user\n"; |
69 |
# print "If not so do: /bin/rm $runtag\n"; |
70 |
# exit(1); |
71 |
#} |
72 |
|
73 |
$ext = "$user"."_$ldate"; |
74 |
#$log = "/usr/local/logs/SUM/dsview_$ext.log"; |
75 |
$log = "/tmp/dsview_$ext.log"; |
76 |
open(LOG, ">$log") || die "Can't open $log: $!\n"; |
77 |
select(LOG); $| = 1; select(STDOUT); #make unbuffered |
78 |
print LOG "$ldate $log\n\n"; |
79 |
my(@pl) = qw/-side top -anchor nw/; |
80 |
my(@pl1) = qw/-side left/; |
81 |
my(@pl2) = qw/-side top -pady 1.0m/; |
82 |
|
83 |
#First connect to database |
84 |
$dbh = DBI->connect("dbi:Pg:dbname=$DB;host=$hostdb", "$user", "$password"); |
85 |
if ( !defined $dbh ) { |
86 |
die "Cannot do \$dbh->connect: $DBI::errstr\n"; |
87 |
} |
88 |
|
89 |
#system "touch $runtag"; #offically started running now |
90 |
$date = &get_effdate; |
91 |
#print "effdate = $date\n"; |
92 |
|
93 |
$mw = MainWindow->new; |
94 |
#$mw->geometry("780x470+1+1"); |
95 |
$mw->geometry("780x570+1+1"); |
96 |
$mw->title("dsview"); |
97 |
$tframe = $mw->Frame(-borderwidth => 1)->pack(-side => 'top'); |
98 |
$image = $tframe->Photo(-file => "$IMGDIR/SDO_Badge.gif"); |
99 |
$tframe->Label(-image => $image)->pack(-side => 'left'); |
100 |
$tframe->Label(-text => "DRMS Series Viewer (dsview)\ndatabase=$DB", |
101 |
-font => 'arial 18 bold', -padx => 100)->pack(-side => 'left'); |
102 |
$b = $tframe->Button( |
103 |
-text => 'Exit', |
104 |
-background => 'red', |
105 |
-command => \&Exit_sub, |
106 |
); |
107 |
$b->pack(-side=> 'left', -pady => 0); |
108 |
$tframe1 = $mw->Frame(-borderwidth => 1)->pack(-side => 'top'); |
109 |
$tframe1->Label(-text => 'Note: you must have a $HOME/.pgpass file', |
110 |
-font => 'arial 18 italic')->pack(-side => 'top'); |
111 |
$image = $tframe1->Photo(-file => "$IMGDIR/GRAD_BLUE_LINE.gif"); |
112 |
$tframe1->Label(-image => $image)->pack(-side => 'top'); |
113 |
$tframe1->Label(-text => 'Select DRMS Series:', |
114 |
-font => 'arial 14 bold', -pady => 10)->pack(-side => 'top'); |
115 |
|
116 |
#$sqlcmd = "select seriesname from drms_series"; |
117 |
$sqlcmd = "select seriesname from drms_series() where seriesname not like 'dsds.%' order by seriesname"; |
118 |
#print "sqlcmd is: $sqlcmd\n\n"; #!!TEMP |
119 |
$sth = $dbh->prepare($sqlcmd); |
120 |
if ( !defined $sth ) { |
121 |
print "Cannot prepare statement: $DBI::errstr\n"; |
122 |
#system "/bin/rm $runtag"; |
123 |
exit; |
124 |
} |
125 |
# Execute the statement at the database level |
126 |
$sth->execute; |
127 |
@listbox_items = (); |
128 |
while($result = $sth->fetchrow()) { #get row from the DB |
129 |
push(@listbox_items, $result); |
130 |
} |
131 |
|
132 |
$showb = $tframe1->Button(-text => "Show 'dsds.'\nnamespace", |
133 |
-command => \&Show_dsds,) ->pack(-side=> 'left'); |
134 |
|
135 |
$lb = $tframe1->Scrolled("Listbox", -scrollbars => "w", -width => 40, |
136 |
-font => 'arial 14 bold', |
137 |
-height => 400, |
138 |
-selectmode => "single")->pack(-side => 'top', -pady => 10); |
139 |
$lb->insert('end', @listbox_items); |
140 |
$lb->bind('<Button-1>', \&lb_sub); |
141 |
$sth->finish(); |
142 |
# $bsubmit = $tframe1->Button( |
143 |
# -text => 'Submit', |
144 |
# -background => 'grey', |
145 |
# -command => \&dtable_sub, |
146 |
# ); |
147 |
# $bsubmit->pack(-side=> 'top'); |
148 |
|
149 |
MainLoop; |
150 |
|
151 |
########################################################################### |
152 |
sub lb_sub { |
153 |
if(Exists($dtabf)) { |
154 |
$dtabf->destroy(); |
155 |
} |
156 |
if(Exists($queryf)) { |
157 |
$queryf->destroy(); |
158 |
} |
159 |
$ds = $lb->get($lb->curselection( )); |
160 |
@schema = `echo "\\d $ds" | psql -h $hostdb $DB`; |
161 |
$queryf = $mw->Toplevel(); |
162 |
#$queryf->geometry("500x330+5+500"); |
163 |
$queryf->geometry("500x330+5+601"); |
164 |
$queryf->title("dsview - $ds"); |
165 |
# my $yf = $queryf->Frame(-borderwidth => 0) |
166 |
# ->pack(-fill => 'both', -side => 'top'); |
167 |
$queryf->Label(-text => "Previous Next First Last") |
168 |
->pack(-side => 'top'); |
169 |
# $yf->Label(-text => " Next ")->pack(@pl1); |
170 |
# $yf->Label(-text => " First ")->pack(@pl1); |
171 |
# $yf->Label(-text => " Last")->pack(@pl1); |
172 |
|
173 |
$xyf = $queryf->Frame(-borderwidth => 0) |
174 |
->pack(-fill => 'both', -side => 'top'); |
175 |
$xyf->Label(-text => " Fetch next n:", -anchor => 'e', |
176 |
-justify => 'right')->pack(-side=> 'left', -padx => 4); |
177 |
$image = $xyf->Photo(-file => "$IMGDIR/arrow04.gif"); |
178 |
$xyf->Button(-command => \&Previous, -image => $image) |
179 |
->pack(-side=> 'left', -padx => 10); |
180 |
$image = $xyf->Photo(-file => "$IMGDIR/arrow05.gif"); |
181 |
$xyf->Button(-command => \&Next, -image => $image) |
182 |
->pack(-side=> 'left', -padx => 10); |
183 |
$image = $xyf->Photo(-file => "$IMGDIR/arrow06.gif"); |
184 |
$xyf->Button(-command => \&First, -image => $image) |
185 |
->pack(-side=> 'left', -padx => 10); |
186 |
$image = $xyf->Photo(-file => "$IMGDIR/arrow03.gif"); |
187 |
$xyf->Button(-command => \&Last, -image => $image) |
188 |
->pack(-side=> 'left', -padx => 10); |
189 |
$yyf = $queryf->Frame(-borderwidth => 0) |
190 |
->pack(-fill => 'both', -side => 'top', -pady => 20); |
191 |
$yyf->Label(-text => 'Fetch n records at a time:') |
192 |
->pack(-side => 'left'); |
193 |
$yyf->Entry(-textvariable => \$nsel, -width => 6, -font=>'arial 12 bold') |
194 |
->pack(-side=>'left'); |
195 |
$yyf->Label(-text => 'Goto recnum:') |
196 |
->pack(-side => 'left', -padx => 5); |
197 |
$yyf->Entry(-textvariable => \$gotorecnum,-width => 8,-font=>'arial 12 bold') |
198 |
->pack(-side=>'left'); |
199 |
$yyf->Button(-text => "Go", -command => \&Recnum_go,) |
200 |
->pack(-side=> 'left'); |
201 |
$zyf = $queryf->Frame(-borderwidth => 0) |
202 |
->pack(-fill => 'both', -side => 'top', -pady => 10); |
203 |
$zyf->Label(-text => 'SQL or psql cmd (\h shows sql cmds, \? shows psql)') |
204 |
->pack(-side => 'top'); |
205 |
$zyf->Label(-text => 'NOTE: a ";" will terminate the cmd and execute, or use Execute button') |
206 |
->pack(-side => 'top'); |
207 |
$zyf->Entry(-textvariable => \$sqlc, -width => 60, -font=>'arial 12 bold', |
208 |
-validate => 'key', -validatecommand => \&Sql_ck) |
209 |
->pack(-side=>'top'); |
210 |
$ayf = $queryf->Frame(-borderwidth => 0) |
211 |
->pack(-fill => 'both', -side => 'top', -pady => 5); |
212 |
$ayf->Button(-text => "Execute", -command => \&Execute,) |
213 |
->pack(-side=> 'left'); |
214 |
$byf = $queryf->Frame(-borderwidth => 0) |
215 |
->pack(-fill => 'both', -side => 'top', -pady => 5); |
216 |
$byf->Label(-text => 'Query sum_main for sunum =') |
217 |
->pack(-side => 'left'); |
218 |
$byf->Entry(-textvariable => \$summainc, -width => 10, -font=>'arial 12 bold', |
219 |
-validate => 'key', -validatecommand => \&Sum_ck) |
220 |
->pack(-side=>'left'); |
221 |
$byf->Button(-text => "Go", -command => \&Sum_go,) |
222 |
->pack(-side=> 'left'); |
223 |
|
224 |
$queryf->bind('all', '<Control-c>' => \&exit); |
225 |
|
226 |
$dtabf = $mw->Toplevel(); |
227 |
$dtabf->geometry("700x560+540+140"); |
228 |
$dtabf->title("dsview - $ds"); |
229 |
$text = $dtabf->Scrolled("Text", -scrollbars => "w", -height => 20) |
230 |
->pack(-side => 'top', -fill => 'both'); |
231 |
while(my $x = shift(@schema)) { |
232 |
$text->insert('end', $x); |
233 |
} |
234 |
$sqlcmd = "select min(recnum) from $ds"; |
235 |
$sth = $dbh->prepare($sqlcmd); |
236 |
if ( !defined $sth ) { |
237 |
print "Cannot prepare statement: $DBI::errstr\n"; |
238 |
#system "/bin/rm $runtag"; |
239 |
exit; |
240 |
} |
241 |
# Execute the statement at the database level |
242 |
$sth->execute; |
243 |
$first = $sth->fetchrow_array(); |
244 |
if(!$first) { $first = 1; } |
245 |
$sqlcmd = "select * from $ds where recnum >= $first and recnum < $first+$nsel"; |
246 |
#$sqlcmd = "select * from $ds where recnum >= 1 and recnum <= $nsel"; |
247 |
$nselnext = ($first+$nsel) - 1; |
248 |
$nselprev = $first-1; |
249 |
#print "sqlcmd is: $sqlcmd\n\n"; #!!TEMP |
250 |
$text1 = $dtabf->Scrolled("Text", -height => 20, -wrap => 'none') |
251 |
->pack(-side => 'top', -fill => 'both'); |
252 |
|
253 |
@schema = `echo "$sqlcmd" | psql -h $hostdb $DB`; |
254 |
while(my $x = shift(@schema)) { |
255 |
$text1->insert('end', $x); |
256 |
$none = 0; |
257 |
} |
258 |
$sth->finish(); |
259 |
} |
260 |
|
261 |
sub Text1_sub { |
262 |
$tline = $text1->get($lb->curselection( )); |
263 |
print "tline = $tline\n"; |
264 |
} |
265 |
|
266 |
sub Sql_ck { |
267 |
if($_[1] eq ';') { |
268 |
&Execute; |
269 |
} |
270 |
return(1); |
271 |
} |
272 |
|
273 |
sub Sum_ck { |
274 |
if($_[1] eq ';') { |
275 |
&Sum_go; |
276 |
} |
277 |
return(1); |
278 |
} |
279 |
|
280 |
sub Recnum_go { |
281 |
$nselnext = ($gotorecnum - 1); |
282 |
&Next; |
283 |
return(1); |
284 |
} |
285 |
|
286 |
sub Show_dsds { |
287 |
$sqlcmd = "select seriesname from drms_series() where seriesname like 'dsds.%' order by seriesname"; |
288 |
$sth = $dbh->prepare($sqlcmd); |
289 |
if ( !defined $sth ) { |
290 |
print "Cannot prepare statement: $DBI::errstr\n"; |
291 |
#system "/bin/rm $runtag"; |
292 |
exit; |
293 |
} |
294 |
# Execute the statement at the database level |
295 |
$sth->execute; |
296 |
@listbox_items = (); |
297 |
while($result = $sth->fetchrow()) { #get row from the DB |
298 |
push(@listbox_items, $result); |
299 |
} |
300 |
$showb->configure(-text => "Show non 'dsds.'\nnamespace", |
301 |
-command => \&Show_non_dsds,); |
302 |
$lb->delete(0, 'end'); |
303 |
$lb->insert('end', @listbox_items); |
304 |
$lb->bind('<Button-1>', \&lb_sub); |
305 |
$sth->finish(); |
306 |
return(1); |
307 |
} |
308 |
|
309 |
sub Show_non_dsds { |
310 |
$sqlcmd = "select seriesname from drms_series() where seriesname not like 'dsds.%' order by seriesname"; |
311 |
$sth = $dbh->prepare($sqlcmd); |
312 |
if ( !defined $sth ) { |
313 |
print "Cannot prepare statement: $DBI::errstr\n"; |
314 |
#system "/bin/rm $runtag"; |
315 |
exit; |
316 |
} |
317 |
# Execute the statement at the database level |
318 |
$sth->execute; |
319 |
@listbox_items = (); |
320 |
while($result = $sth->fetchrow()) { #get row from the DB |
321 |
push(@listbox_items, $result); |
322 |
} |
323 |
$showb->configure(-text => "Show 'dsds.'\nnamespace", |
324 |
-command => \&Show_dsds,); |
325 |
$lb->delete(0, 'end'); |
326 |
$lb->insert('end', @listbox_items); |
327 |
$lb->bind('<Button-1>', \&lb_sub); |
328 |
$sth->finish(); |
329 |
return(1); |
330 |
} |
331 |
|
332 |
sub Sum_go { |
333 |
if(Exists($dtabg)) { |
334 |
$dtabg->destroy(); |
335 |
} |
336 |
$sumsql = "select * from sum_main where ds_index=$summainc"; |
337 |
#print "sumsql = $sumsql\n"; |
338 |
@schema = `echo "$sumsql" | psql -h $hostdb -p $PGPORT $DBSUMS`; |
339 |
$dtabg = $mw->Toplevel(); |
340 |
$dtabg->geometry("700x100+540+726"); |
341 |
$dtabg->title("dsview - $ds"); |
342 |
$text2 = $dtabg->Scrolled("Text", -height => 10, -wrap => 'none') |
343 |
->pack(-side => 'top', -fill => 'both'); |
344 |
while(my $x = shift(@schema)) { |
345 |
$text2->insert('end', $x); |
346 |
if($x =~ /\/SUM/) { |
347 |
($dir, $y) = split(/\|/, $x); |
348 |
if(Exists($cyf)) { |
349 |
$cyf->destroy(); |
350 |
} |
351 |
$cyf = $queryf->Frame(-borderwidth => 0) |
352 |
->pack(-fill => 'both', -side => 'top', -pady => 5); |
353 |
#$cyf->Label(-text => "dir is $dir") ->pack(-side => 'left'); |
354 |
$cyf->Button(-text => "ls -lR $dir", -command => \&List_go,) |
355 |
->pack(-side=> 'left'); |
356 |
} |
357 |
} |
358 |
} |
359 |
|
360 |
sub List_go { |
361 |
$dtabh = $mw->Toplevel(); |
362 |
$dtabh->geometry("600x250+590+118"); |
363 |
$dtabh->title("dsview - $dir"); |
364 |
$text3 = $dtabh->Scrolled("Text", -height => 50, -wrap => 'none', |
365 |
-background => 'white') |
366 |
->pack(-side => 'top', -fill => 'both'); |
367 |
@list = `ls -lR $dir`; |
368 |
while($x = shift(@list)) { |
369 |
$text3->insert('end', $x); |
370 |
} |
371 |
} |
372 |
|
373 |
sub Execute { |
374 |
#print "sqlcmd = $sqlc\n"; |
375 |
@schema = `echo "$sqlc" | psql -h $hostdb $DB`; |
376 |
$text1->delete("1.0", 'end'); |
377 |
while(my $x = shift(@schema)) { |
378 |
$text1->insert('end', $x); |
379 |
} |
380 |
} |
381 |
sub Previous { |
382 |
my $next = $nselprev-$nsel; |
383 |
if($next < 1) { $next = 0; } |
384 |
$sqlcmd = "select * from $ds where recnum > $next and recnum <= $next+$nsel"; |
385 |
$nselnext = $next + $nsel; |
386 |
$nselprev = $next; |
387 |
@schema = `echo "$sqlcmd" | psql -h $hostdb $DB`; |
388 |
$text1->delete("1.0", 'end'); |
389 |
while(my $x = shift(@schema)) { |
390 |
$text1->insert('end', $x); |
391 |
} |
392 |
} |
393 |
sub Next { |
394 |
$sqlcmd = "select * from $ds where recnum > $nselnext and recnum |
395 |
<= $nselnext+$nsel"; |
396 |
$nselprev = $nselnext; |
397 |
$nselnext = $nselnext + $nsel; |
398 |
@schema = `echo "$sqlcmd" | psql -h $hostdb $DB`; |
399 |
$text1->delete("1.0", 'end'); |
400 |
while(my $x = shift(@schema)) { |
401 |
$text1->insert('end', $x); |
402 |
} |
403 |
} |
404 |
sub First { |
405 |
$sqlcmd = "select min(recnum) from $ds"; |
406 |
$sth = $dbh->prepare($sqlcmd); |
407 |
if ( !defined $sth ) { |
408 |
print "Cannot prepare statement: $DBI::errstr\n"; |
409 |
#system "/bin/rm $runtag"; |
410 |
exit; |
411 |
} |
412 |
# Execute the statement at the database level |
413 |
$sth->execute; |
414 |
$first = $sth->fetchrow_array(); |
415 |
if(!$first) { $first = 1; } |
416 |
$sqlcmd = "select * from $ds where recnum >= $first and recnum < $first+$nsel"; |
417 |
$nselnext = ($first+$nsel) - 1; |
418 |
$nselprev = $first-1; |
419 |
@schema = `echo "$sqlcmd" | psql -h $hostdb $DB`; |
420 |
$text1->delete("1.0", 'end'); |
421 |
while(my $x = shift(@schema)) { |
422 |
$text1->insert('end', $x); |
423 |
} |
424 |
$sth->finish(); |
425 |
} |
426 |
sub Last { |
427 |
$sqlcmd = "select max(recnum) from $ds"; |
428 |
$sth = $dbh->prepare($sqlcmd); |
429 |
if ( !defined $sth ) { |
430 |
print "Cannot prepare statement: $DBI::errstr\n"; |
431 |
#system "/bin/rm $runtag"; |
432 |
exit; |
433 |
} |
434 |
# Execute the statement at the database level |
435 |
$sth->execute; |
436 |
$last = $sth->fetchrow_array(); |
437 |
if(!$last) { $last = 1; } |
438 |
#print "last = $last\n"; |
439 |
$sqlcmd = "select * from $ds where recnum > $last-$nsel and recnum <= $last"; |
440 |
#print "sqlcmd = $sqlcmd\n"; |
441 |
$nselnext = $last; |
442 |
$nselprev = $last-$nsel; |
443 |
@schema = `echo "$sqlcmd" | psql -h $hostdb $DB`; |
444 |
$text1->delete("1.0", 'end'); |
445 |
while(my $x = shift(@schema)) { |
446 |
$text1->insert('end', $x); |
447 |
} |
448 |
$sth->finish(); |
449 |
} |
450 |
|
451 |
|
452 |
#Return effective date of now as yyyymmddhhmm |
453 |
sub get_effdate { |
454 |
local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst,$date,$sec2,$min2,$hour2,$mday2); |
455 |
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); |
456 |
$min2 = sprintf("%02d", $min); |
457 |
$hour2 = sprintf("%02d", $hour); |
458 |
$mday2 = sprintf("%02d", $mday); |
459 |
$mon2 = sprintf("%02d", $mon+1); |
460 |
$year4 = sprintf("%04d", $year+1900); |
461 |
$date = "$year4"."$mon2"."$mday2"."$hour2"."$min2"; |
462 |
return($date); |
463 |
} |
464 |
|
465 |
#Return date in form for a label e.g. 1998.01.07_14:42:00 |
466 |
sub labeldate { |
467 |
local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst,$date,$sec2,$min2,$hour2,$mday2); |
468 |
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); |
469 |
$sec2 = sprintf("%02d", $sec); |
470 |
$min2 = sprintf("%02d", $min); |
471 |
$hour2 = sprintf("%02d", $hour); |
472 |
$mday2 = sprintf("%02d", $mday); |
473 |
$mon2 = sprintf("%02d", $mon+1); |
474 |
$year4 = sprintf("%04d", $year+1900); |
475 |
$date = $year4.".".$mon2.".".$mday2._.$hour2.":".$min2.":".$sec2; |
476 |
return($date); |
477 |
} |
478 |
|
479 |
#Return time in form for a label e.g. 14:42:00 |
480 |
sub labeltime { |
481 |
my $d = &labeldate; |
482 |
my $pos = index($d, '_'); |
483 |
my $t = substr($d, $pos+1); |
484 |
return($t); |
485 |
} |
486 |
|
487 |
|
488 |
sub Exit_sub { |
489 |
$dbh->disconnect(); |
490 |
if($pid0) { #kill off our child |
491 |
`kill $pid0`; |
492 |
} |
493 |
#system "/bin/rm $runtag"; |
494 |
exit; |
495 |
} |
496 |
|
497 |
sub commify { |
498 |
my $text = reverse $_[0]; |
499 |
$text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g; |
500 |
return scalar reverse $text; |
501 |
} |
502 |
|
503 |
|