[#2617] irb for 1.5.x — Andrew Hunt <Andy@...>
5 messages
2000/05/03
[#2639] OT: Japanese names — Dave Thomas <Dave@...>
4 messages
2000/05/09
[#2643] Ruby Toplevel — Dave Thomas <Dave@...>
7 messages
2000/05/09
[#2656] Re: Append alias for Array.append? — Aleksi Niemel<aleksi.niemela@...>
Hideto ISHIBASHI:
5 messages
2000/05/09
[#2660] win OLE / eRuby — Andrew Hunt <Andy@...>
8 messages
2000/05/09
[#2663] Re: win OLE / eRuby — Aleksi Niemel<aleksi.niemela@...>
>At Tue, 9 May 2000 09:14:51 -0400,
4 messages
2000/05/09
[#2667] The reference manual is now online — Dave Thomas <Dave@...>
6 messages
2000/05/09
[#2668] Re: The reference manual is now online — schneik@...
4 messages
2000/05/09
[#2702] Re: Append alias for Array.append? — Andrew Hunt <andy@...>
>From: Aleksi Niemel<aleksi.niemela@cinnober.com>
7 messages
2000/05/10
[#2752] RE: Array.pop and documentation [was: Append al ias for Array.append?] — Aleksi Niemel<aleksi.niemela@...>
6 messages
2000/05/11
[#2758] Re: irb install — Andrew Hunt <andy@...>
>|Excellent! Will you consider adding mod_ruby to install_app as
7 messages
2000/05/11
[#2777] Re: irb install
— "NAKAMURA, Hiroshi" <nakahiro@...>
2000/05/12
Hi,
[#2764] More code browsing questions — Albert Wagner <alwagner@...>
I see some class definitions contain "include" and "extend" statements.
6 messages
2000/05/12
[#2843] Re: editors for ruby — "Conrad Schneiker" <schneiker@...>
(Posted on comp.lang.ruby and ruby-talk ML.)
6 messages
2000/05/17
[#2874] RE: simple httpd for local use — Aleksi Niemel<aleksi.niemela@...>
> I personally use it for access to full-text indexed linux
6 messages
2000/05/18
[#2875] Re: simple httpd for local use
— hipster <hipster@...4all.nl>
2000/05/18
On Thu, 18 May 2000 09:10:28 +0200, Aleksi Niemelwrote:
[#2920] SWIG: virtual variable? — Yasushi Shoji <yashi@...>
hello,
4 messages
2000/05/22
[#2928] FYI: What our Python friends are up to. — "Conrad Schneiker" <schneiker@...>
Hi,
8 messages
2000/05/22
[#2964] Thank you — h.fulton@...
Thanks, Matz (and others) for your replies to
4 messages
2000/05/24
[#2973] Re: Socket.getnameinfo — ts <decoux@...>
>>>>> "D" == Dave Thomas <Dave@thomases.com> writes:
10 messages
2000/05/25
[#3016] rbconfig.rb — Dave Thomas <Dave@...>
5 messages
2000/05/28
[#3039] Re: Final for World Series: Python vs Ruby — "Dat Nguyen" <thucdat@...>
1 message
2000/05/30
[#3058] FailureClass? — Aleksi Niemel<aleksi.niemela@...>
Question arising from the FAQ:
7 messages
2000/05/31
[ruby-talk:03000] Another ruby core dump
From:
"David Douthitt" <DDouthitt@...>
Date:
2000-05-26 21:05:27 UTC
List:
ruby-talk #3000
# ./ppp-time.rb | less
./ppp-time.rb:335: [BUG] gc_sweep(): unknown data type 121
#--------------------------
# ppp-time.rb
#--------------------------
Report generated at May 26 15:54
Abort (core dumped)
# uname -a
Linux shoo.to.you 2.2.5-15 #13 Thu Jan 6 10:59:30 CST 2000 i586 unknown
# ruby -v
ruby 1.4.3 (1999-12-08) [i586-linux-gnu]
#
The code is longish, but here it is....
#!/usr/bin/ruby
# ppp-time.rb
#
# PURPOSE: Scan through ppp.auth and
# produce statistics and billing
# reports
#
# DATE: Sat Apr 15 09:17:23 CDT 2000
# PROGRAMMER: David Douthitt
# ppp.auth format:
#
# 948840929:peer1:tty1:in
# 948840933:peer1:tty1:out
# 948852042:ddouthitt:/dev/ttyG0_19:in
# 948852203:ddouthitt:/dev/ttyG0_19:out
# 948853385:ddouthitt:/dev/ttyG0_20:in
# 948859439:jforsmo:/dev/ttyG0_22:in
# 948860584:jforsmo:/dev/ttyG0_22:out
#---------------------------------------------
# GENERIC CLASSES
#---------------------------------------------
class Array
def each_line
self.each { |line|
yield line.chomp
}
end
end
class TextFile < File
def each_line
super { |line|
yield line.chomp
}
end
alias each each_line
end
class String
def fields
split(":")
end
end
class Numeric
def to_mins
self / 60
end
def to_mins_rounded
# (self + 30) / 60 # round to nearest minute
(self / 60) + 1 # round to next minute up
end
def to_hrs
self / 60 / 60
end
def format_time
raise ("bad time format!") if self <= 0;
if (self > 3600)
sprintf("%d:%02d:%02d", self / 3600, (self / 60) % 60, self % 60);
else
sprintf("%d:%02d", self / 60, self % 60);
end
end
end
#---------------------------------------------
# SPECIFIC CLASSES
#---------------------------------------------
class PPPAuth < TextFile
def PPPAuth.open
super("/var/log/ppp.auth")
end
end
class Report
def Report.header
print "#--------------------------\n";
print "# ppp-time.rb\n";
print "#--------------------------\n";
print "\nReport generated at ",
Time.now.strftime("%b %d %H:%M"), "\n\n";
end
end
class System
attr_accessor :online, :uptime;
def initialize
@online = 0;
@uptime = 0;
end
def upsince (time)
@uptime = (Time.now - Time.at(time)).to_i;
end
def summary
printf(" Total online time: %10s\n", @online.to_mins.format_time);
printf(" Total uptime: %10s * since first recorded login\n\n", @uptime.to_mins.format_time);
printf(" Total online usage: %10.2f%%\n\n", @online * 100.0 / @uptime);
end
end
class Passwd
# /etc/passwd file format:
#
# Go look for yourself :-)
Userdata = Hash.new
def initialize
TextFile.open("/etc/passwd") { |f|
f.readlines.each_line { |line|
# user, pwd, uid, gid, info, home, shell = line.fields
user, *data = line.fields
Userdata[user] = data;
}
}
end
def Passwd.uid (str)
raise("user #{str} not in passwd file!") if Userdata[str] == nil;
(Userdata[str])[1]
end
def Passwd.gid (str)
raise("user #{str} not in passwd file!") if Userdata[str] == nil;
(Userdata[str])[2]
end
def Passwd.info (str)
raise("user #{str} not in passwd file!") if Userdata[str] == nil;
(Userdata[str])[3]
end
def Passwd.home (str)
raise("user #{str} not in passwd file!") if Userdata[str] == nil;
(Userdata[str])[4]
end
def Passwd.shell (str)
raise("user #{str} not in passwd file!") if Userdata[str] == nil;
(Userdata[str])[5]
end
def Passwd.user? (str)
(Userdata[user] != nil)
end
def Passwd.login? (str)
! (Passwd.shell(str) === "/bin/false")
end
end
class Login
attr_accessor :name, :time, :tty, :login, :logout, :action;
def initialize (str, time, tty, action)
@time = 0;
@login = 0;
@name = str;
@time = time;
@tty = tty;
@action = action;
@login = time;
@logout = 0;
end
def online?
@logout == 0
end
def login_s
Time.at(@login).strftime("%b %d %H:%M")
end
def logout_s
if (self.logout == 0)
"--"
else
Time.at(@logout).strftime("%b %d %H:%M")
end
end
def online_summary
printf(" %s %s %s\n",
@name, login_s, @tty.tty_short);
end
def summary
if (@logout == 0)
printf(" %-15s %8s %6s %s\n",
login_s, "----", "----",
@tty.tty_short);
else
printf(" %-15s %8s %6.2f%% %s\n",
login_s, @time.to_mins_rounded.format_time,
@time * 100.0 / $sys.online,
@tty.tty_short);
end
end
end
class Tty
attr_accessor :online, :name
def initialize (tty)
@online = 0
@name = tty
end
def online (time_secs)
@online += time_secs
end
def print_summary
printf(" %-8s %8s %8.2f%%\n", @name.tty_short, @online.to_mins.format_time,
@online * 100 / $sys.online)
end
end
class User
attr_accessor :name, :actual_secs, :total_mins, :lastlogin, :charge;
def initialize (str)
@name = str
@total_mins = 0
@actual_secs = 0
@lastlogin = 0
@charge = 0.02;
end
def summary
printf(" %-15s %8s %8.2f%%\n", @name, @total_mins.format_time,
@actual_secs * 100.0 / $sys.online);
end
def charges
printf("\n %-15s %8s @ $%.2f/min. = $%.2f\n\n",
"Total", @total_mins.format_time,
@charge, @total_mins * @charge);
end
def reset_lastlogin
@lastlogin = 0;
end
def charge (secs)
@actual_secs += secs;
@total_mins += secs.to_mins_rounded;
end
def user_info
print "User: ", Passwd.info(@name), "\n";
if Passwd.login? (@name)
print "Login Shell: ", Passwd.shell (@name), "\n"
end
print "\n";
end
end
class String
def tty_short
self =~ /.*(tty.*)/
$1
end
end
class Array
def usersort
sort { |a,b| a.name <=> b.name }
end
end
#---------------------------------------------
# MAIN PROGRAM
#---------------------------------------------
$sys = System.new;
$charge = .02;
ttys = Hash.new
Passwd.new;
Report.header
users = Hash.new ; logins = Hash.new
PPPAuth.open { |auth|
auth.readlines.each_line { |line|
time, user, tty, action = line.fields
time_secs = time.to_i
raise("invalid online time!") if (time_secs <= 0);
$sys.upsince(time_secs) if $sys.uptime == 0;
users[user] = User.new(user) unless users.include?(user);
ttys[tty] = Tty.new(tty) unless ttys.include?(tty);
case action
when "in"
logins[time_secs] = Login.new(user, time_secs, tty, action);
users[user].lastlogin = time_secs; # - - - this line appears to be suspect....
when "out"
lastlogin_secs = users[user].lastlogin; # temp_var for speed concessions
raise("logout time without login time!") if (lastlogin_secs == 0);
raise("login data lost!") if logins[lastlogin_secs] == nil;
logins[lastlogin_secs].logout = time_secs;
online_secs = time_secs - lastlogin_secs;
users[user].reset_lastlogin;
users[user].charge(online_secs);
logins[lastlogin_secs].time = online_secs;
ttys[tty].online(online_secs);
$sys.online += online_secs;
else
raise("bad data: action = #{action}");
end
}
}
#---------------------------------------------
# REPORTS
#---------------------------------------------
#----------------------------
# User Summary Report
print "User Summary:\n\n";
users.values.usersort.each { |userdata|
userdata.summary
}
#----------------------------
# System Summary Report
print "\nSystem Summary:\n\n";
$sys.summary
#----------------------------
# Online Summary Report
if (logins.values.find{ |login| login.online? } != nil)
print "Currently Online:\n\n";
logins.values.select{ |login| login.online? }.each { |login|
login.online_summary
}
print "\n"
end
#----------------------------
# TTY Usage Summary Report
print "TTY Summary:\n\n";
ttys.values.sort { |a,b| a.name <=> b.name }.each { |tty|
tty.print_summary
}
print "\n";
#----------------------------
# User Login Detail Report
users.values.usersort.each { |userdata|
userdata.user_info
logins.values.select { |login|
userdata.name == login.name }.each { |login|
login.summary
}
userdata.charges;
}