Subversion Repositories camp_sysinfo_client_3

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
74 rodolico 1
#! perl -w
2
# use strict; # eval doesn't work with use strict !?
3
# see POD documentation at end
152 rodolico 4
# Alternate versions at
5
# https://www.windowscentral.com/how-check-your-computer-uptime-windows-10
74 rodolico 6
 
96 rodolico 7
 
8
 
74 rodolico 9
=head1 NAME
10
 
11
uptime.pl - Uptime for Windows. Version 0.27.
12
 
13
=cut
14
 
96 rodolico 15
$^O eq "MSWin32" || exit;
74 rodolico 16
 
101 rodolico 17
our $VERSION = '0.1';
18
 
74 rodolico 19
my $max_results = 5; # if we have to use tick counts
20
 
21
my $VERSION = 0.27;
22
 
23
my $debug = $ENV{'QUERY_STRING'} || $ARGV[0];
24
print "$0 version $VERSION\n" if $debug;
25
print "Debug mode on\n" if $debug;
26
print "Perl version $]\n" if $debug;
27
 
28
BEGIN {
96 rodolico 29
   # HTTP headers if needed
30
   local $^W = 0;
31
   print "$ENV{'SERVER_PROTOCOL'}/200 OK\n" if $ENV{'PERLXS'} eq "PerlIS";
32
   print "Content-type: text/plain\n\n" if $ENV{'SERVER_PROTOCOL'};
74 rodolico 33
}
34
 
35
my ($several, @uptimes);
36
 
37
if (Win32::IsWinNT()) {
96 rodolico 38
   print "Windows NT\n\n" if $debug;
39
   push @uptimes, (&event_log || &tick_counts);
40
   print "eval error: $@\n" if $@ && $debug;
74 rodolico 41
}
42
else {
96 rodolico 43
   print "Windows 9x\n\n" if $debug;
44
   push @uptimes, (&system_da0 || &tick_counts);
74 rodolico 45
}
46
 
47
sub tick_counts {
96 rodolico 48
   print "Counting ticks\n" if $debug;
49
   my @ticks;
50
   my $ticks = Win32::GetTickCount() > 0
51
            ? Win32::GetTickCount()
52
           : Win32::GetTickCount() + 2**32;
53
   my $seconds = $ticks/1000;
54
   for (1..$max_results-1) {
55
      push @ticks, time()-$seconds;
56
      $seconds += 2**32/1000;
57
   }
58
   return @ticks, time()-$seconds;
74 rodolico 59
}
60
 
61
sub system_da0 {
96 rodolico 62
   my $file = "$ENV{'WINDIR'}\\system.da0";
63
   print "Checking $file\n" if $debug;
64
   my $stat = (stat $file)[9]; 
65
   print "Could not stat $file ($!)\n" if $debug && !$stat;
66
   return $stat || undef;
74 rodolico 67
}
68
 
69
sub event_log {
96 rodolico 70
   my $result = eval '
74 rodolico 71
        local $^W = 0;
96 rodolico 72
      use Win32::EventLog;
73
      my ($EventLog, $first, $count, $event, %data);
74
      Win32::EventLog::Open($EventLog , "System", "") || die ("EventLog Open() failed");
75
      $EventLog->GetOldest($first) || die ("EventLog GetOldest() failed");
76
      $EventLog->GetNumber($count) || die ("EventLog GetNumber() failed");
77
      print "Event log first=$first, count=$count\n" if $debug;
74 rodolico 78
 
96 rodolico 79
      $EventLog->Read((EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ),$first+$count,$event);
74 rodolico 80
 
96 rodolico 81
      for $i (0 .. $first+$count-1) {
82
         $EventLog->Read((EVENTLOG_SEQUENTIAL_READ|EVENTLOG_BACKWARDS_READ),0,$event)
83
             || die ("EventLog Read() failed at event $i");
74 rodolico 84
 
96 rodolico 85
         %data = %{$event};
86
         $data{"EventID"} = $data{"EventID"} & 0xffff;
74 rodolico 87
 
96 rodolico 88
          next unless $data{"EventID"} == 6005;
89
         print "Found event 6005\n" if $debug;
90
         return $data{"TimeGenerated"};
91
         print "This script is broken: it should never reach this line\n";
92
      }
93
      return undef;
94
   ';
95
   if ($@) {
96
      print "Eval error: $@\n";
97
      return undef;
98
   }
99
   else {
100
      return $result;
101
   }
74 rodolico 102
}
103
 
104
$several = @uptimes - 1;
105
foreach (@uptimes) {
96 rodolico 106
   print "up ", &time2days($_), " (since ", scalar localtime($_), ")\n";
107
   print "or:\n" if $several;
74 rodolico 108
}
109
 
110
print "... but who would believe that anyway?...\n" if $several;
111
 
112
sub time2days {
96 rodolico 113
   print "converting $_[0]\n" if $debug;
114
   my $days = (time() - $_[0])/(24*60*60);
115
   my $hours = ($days - int($days)) * 24;
116
   my $minutes = ($hours - int($hours)) * 60;
117
   my $day_st = $days >= 2 ? 'days' : 'day';
118
   return sprintf("%0d $day_st %02d:%02d", $days, $hours, $minutes);
74 rodolico 119
}
120
 
121
__END__
122
 
123
=head1 SYNOPSIS
124
 
125
perl uptime.pl [debug]
126
 
127
=head1 DESCRIPTION
128
 
129
Report machine uptime on Windows systems.
130
 
131
This script attempts to report the system uptime in a format similar
132
to the Unix uptime command. It only reports uptime, not users or
133
load statistics.
134
 
135
On NT it uses the event log. The event log service itself writes an
136
entry to it when it starts (ID 6005).
137
 
138
On Win95 it gets the create time of the system.da0 file (the system.dat
139
backup file which is recreated at system start).
140
 
141
If eihter of these methods fail (like on Win98), it uses the system tick 
142
counts. Since these can only hold about 49.7 days, it returns a list of 
143
possible uptimes, limited to C<$max_results> (5 by default). (Have you ever 
144
seen a Windows system up for more than 200 days? ;-) If yes, set 
145
C<$max_results> to a higher value).
146
 
147
The script can be used in CGI. It will print the needed headers automatically.
148
 
149
The latest version should always be available at
150
http://alma.ch/perl/scripts/uptime.pl
151
 
152
=head1 OPTIONS
153
 
154
If given any argument (at the command line or as a CGI argument), it is
155
considered as a 'debug' or 'verbose' option, and additional stuff is printed.
156
 
157
=head1 FEATURES (aka BUGS)
158
 
159
On NT, the uptime will be wrong if you restarted the event log service.
160
 
161
If you have a low limit on your event log file size or logged events, and
162
your system has been up for a long time, the event may not be available
163
anymore. The script will then use tick counts.
164
 
165
On Win95, the uptime will be wrong if the create time of your system.da0 file
166
is not the same as when your system booted. I don't see what could cause this
167
unless you overwrite the file, but there may be special cases. Let me know if
168
you find any.
169
 
170
On Win98, there seems to be no way other than tick counts. Let me know if you
171
find something better.
172
 
173
=head1 SCRIPT CATEGORIES
174
 
175
Win32
176
 
177
=head1 OSNAMES
178
 
179
MSWin32
180
 
181
=head1 AUTHOR
182
 
183
M. Ivkovic. email: C<perl -e "printf '%s@%s', 'mi.perl', 'alma.ch'">.
184
 
185
Others welcome to extend it to more operating systems which don't have an uptime 
186
command.
187
 
188
=head1 COPYRIGHT
189
 
190
Copyright M. Ivkovic, 1999. Same license as Perl itself.
191
 
192
=head1 README
193
 
194
Attempt to report machine uptime on various Windows systems.
195
 
196
=cut