home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
inetlg71.zip
/
INETLOG.CMD
< prev
next >
Wrap
OS/2 REXX Batch file
|
2000-02-10
|
42KB
|
1,225 lines
/* INETLOG.CMD
Copyright 1996 - 2000 by Chuck McKinnis, Sandia Park, NM (USA) 04 Feb 2000
mckinnis@attglobal.net
Copyright 1995 by Jerry Levy, Marblehead, MA (USA) 03 Nov 95
jlevy@ibm.net
REXX Program to extract and totalize daily and monthly time-ons by
analyzing the IBM WARP Internet Dialer log or the InJoy dialer log */
Trace 'N'
version = '7.1'
what_r_we = 'INETLOG v'||version 'Copyright 1995 - 2000 by Chuck McKinnis and Jerry Levy'
Parse Upper Arg otherparms
/* Where are we ? */
Parse Source . . install_path .
install_path = Filespec('D',install_path) || Filespec('P',install_path)
ini_file = install_path || 'inetlog.ini'
cfg_file = install_path || 'inetcfg.cfg'
cfg_save = install_path || 'inetcfg.sav'
save_path = Directory()
our_path = Strip(install_path, 'T', '\')
our_path = Directory(our_path)
pmrexx_obj = SysSearchPath('PATH', 'PMREXX.EXE')
pmrexx = 0
If Wordpos('/PMREXX', otherparms) > 0 Then
Do
If pmrexx_obj <> '' Then
pmrexx = 1
Else
Do
Say 'PMREXX.EXE is not in your current PATH'
pmrexx = 0
End
End
Else
Do
If Wordpos('/NOPMREXX', otherparms) = 0 Then
Do
If pmrexx_obj <> '' Then
Do
Parse Source . . inetlog_program .
Address cmd '@START "Internet Log Analyzer" /PM /I' pmrexx_obj inetlog_program otherparms '/PMREXX'
Exit 0
End
Else
Do
Say 'PMREXX.EXE is not in your current PATH'
pmrexx = 0
End
End
pmrexx = 0
End
/* Right to freely use, modify, distribute granted but please acknowledge
source as a courtesy if you build upon it. Please pass on comments,
suggestions, problems to jlevy@ibm.net or mckinnis@attglobal.net
------------------------------------
Getting Started (See readme.txt)
Program History (See changes.txt)
Use of Command-line options: (See readme.txt)
----------------------------------- */
/* The following are acceptable command-line parameters for special runs.
Only one of these can be used in a run and case is ignored.
/NOPMREXX run without using PMREXX
The following are acceptable command-line parameters (case is ignored):
These parameters can be overridden on a run by run basis only.
/Q<uiet> run without output to screen, default is to output results
/C<ombined> output summary listing of both IGN and InJoy results
/COMBINEONLY output only summary listing of both IGN and InJoy results
*/
If Rxfuncquery('SysDropFuncs') Then
Do
Call Rxfuncadd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
Call SysLoadFuncs
End
If Rxfuncquery('RxExtra') Then
Do
Call Rxfuncadd 'RxExtra', 'RxExtras', 'RxExtra'
Call RxExtra 'LOAD'
End
Signal On Failure Name errhandler
Signal On Halt Name errhandler
Signal On Syntax Name errhandler
/*========MAIN PROGRAM=========*/
Call SysCls
Call Initialize_parms
If \ibm_dialer & \injoy_dialer Then
Do
Say 'You have not selected any logs to analyze'
Call Cleanup
End
If ibm_dialer Then
Do
/* gets, calculates, totalizes connect times.
Mostly a bunch of conditionals with a Call to a
data-formatting routine. All is stored in
variables for output all at once */
Call Analyze_logfile
save_quiet = quiet
If combineonly Then
quiet = 1
Call Outputter /* Outputs everything to console and to disk */
quiet = save_quiet
If \quiet & \combineonly & ibm_dialer & \pmrexx Then
answer = Say_message('IBM dialer analysis complete, Press any key to continue...')
End
save_quiet = quiet
If injoy_dialer Then
Do
injoy_parms = ''
If combineonly Then
quiet = 1
If quiet Then
injoy_parms = injoy_parms '/QUIET'
If pmrexx Then
injoy_parms = injoy_parms '/PMREXX'
irc = IJoyLog(injoy_parms)
If irc = 0 Then /* pick up any changes made by injoylog */
Call Read_config
End
quiet = save_quiet
If \quiet & \combineonly & combine & injoy_dialer & \pmrexx Then
answer = Say_message('InJoy analysis complete, Press any key to continue...')
If combine & irc = 0 Then
Call Combined_output
Call Cleanup /* Exits */
/*====END OF MAIN PROGRAM=======*/
Initialize_parms:
trace_save = Trace('N')
quiet = 0
combine = 0
combineonly = 0
Parse Value '' With c_parm
Do i = 1 To Words(otherparms)
Parse Value Word(otherparms, i) With key_word '=' key_value
Select
When Abbrev(key_word, '/COMBINEONLY') Then
c_parm = 'COMBINEONLY'
When Abbrev(key_word, '/C') Then
c_parm = 'COMBINE'
When Abbrev(key_word, '/Q') Then
quiet = 1
Otherwise Nop
End
End
If c_parm <> '' Then
Do
If Abbrev(c_parm, 'COMBINE') Then
combine = 1
If Abbrev(c_parm, 'COMBINEONLY') Then
combineonly = 1
End
Call Read_config
Call Check_config
If ibm_dialer Then
Do
/* Get path for connection log file and install directory */
x = Setlocal()
tcpip_etc_path = Value('ETC', ,'OS2ENVIRONMENT')
tcpip_etc_path = tcpip_etc_path || '\'
x = Endlocal()
dialer_ini = tcpip_etc_path || ibm_dialer_ini_file
Parse Value Log_file_parms(ibm_dialer_ini_file, dialer_ini) ,
With dialer_log_file dialer_log_size
log_file = dialer_log_file
/* Get full paths for output file and summary file */
output_file = data_path || ibm_output_file
summary_file = data_path || ibm_summary_file
Call Set_monthly_summary
/* initialize variables */
crlf = D2c(13) || D2c(10) /* carriage return + linefeed */
esc = D2c(27) /* Escape character */
time_stamp = '' /* Time stamp of each connect record */
Do i = 1 To 12 /* initialize months */
x = Right(i,2,'0')
month.x = Word('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec',i)
End
/* calculated variables
signons_each_day Accumulate number of connects daily
signons_each_month Accumulate number of connects monthly
time_on Time, each connect (minutes)
daily_time_on Accumulated minutes, daily
monthly_time_on Accumulated minutes, monthly */
/* More variables: these we initialize as follows: */
old_m = 0 /* Storage of a 2-digit month (eg 05 = May) */
old_d = 0 /* ... and a 2-digit day */
dcounter = 0 /* Counter increments each sign-on in a day */
mcounter = 0 /* Same for each sign-on in a month */
monthline. = '' /* Initialize both of these as null strings */
dayline. = '' /* These are for monthly and daily output strings */
/* A typical line generated in the connect.log upon disconnect looks like
either this for a dialer version preceding v1.45:
11/15 19:08:38 Disconnected after 00:06:20 0 errors 0 discards'
or this style for v. 1.45 and later:
1995/11/15 19:08:38 Disconnected after 00:06:20 0 errors 0 discards
We search for a key_phrase using the RexxUtil function SysFileSearch */
/* Word or phrase we'll search for */
key_phrase = 'Disconnected after'
user_phrase = 'dialed' /* word to search for account and userid */
/* Here is where we Check if the output file exists. If it does, we
overwrite it, and if not we create it. BUT.... we don't want to
do something stupid like try to erase a vital file or the connect
logfile... */
If \RxFileExists(log_file) Then
Do
Say 'Aborting.' log_file 'does not exist.'
Call Beep 1000,100
Call Cleanup
End
file1 = Translate(Filespec('N', log_file))
file2 = Translate(Filespec('N', output_file))
If file2 == 'CONNECT.LOG',
| file2 == 'IPDIALER.LOG',
| file2 == 'CONFIG.SYS',
| file2 == 'AUTOEXEC.BAT',
| file2 == file1 Then
Do
Say log_file 'was entered as the dialer log file name and'
Say output_file 'was entered as the INETLOG output file name.'
Say 'These files cannot have the same name, and the names'
Say '"CONNECT.LOG, IPDIALER.LOG, CONFIG.SYS, and AUTOEXEC.BAT"'
Say 'are not permitted as INETLOG output file names.'
Say crlf
Call Beep 1000,100
Call Cleanup /* Error, so Exit */
End
/* make sure that we have control of the log file */
rc = File_cmd(log_file, 'W')
If \ rc Then
Do Until rc
Say 'Log file' log_file 'returned' result
rc = File_cmd(log_file, 'C')
Say 'Unable to open' log_file
Say 'Press Esc to abort run'
answer = Say_message('Press any other key to wait 5 seconds')
If answer = esc Then
Call Cleanup
Call SysSleep 5
Call SysCls
rc = File_cmd(log_file, 'W')
End
rc = File_cmd(log_file, 'C')
/* Backup any output file of the same name if it exists, then erase orig. */
If RxFileExists(output_file) Then
Do
Parse Var output_file fname '.' ext
Address cmd '@COPY' output_file fname||'.bak > NUL'
Call SysFileDelete output_file
End
End
If injoy_dialer Then
Do
injoy_summary = data_path || injoy_summary_file
End
Trace (trace_save)
Return /* Initialize_parms */
/* read the config file */
Read_config:
trace_save = Trace('N')
Trace 'N'
If RxFileExists(cfg_file) Then /* do we have a config file */
input_file = cfg_file
Else
Do
If RxFileExists(cfg_save) Then
input_file = cfg_save
Else
Do
Call Config_sample /* use the sample values */
input_file = 'sample'
End
End
If input_file <> 'sample' Then
Call RxRead 'data.', input_file
Else
Call RxStemCopy 'cfg_sample.', 'data.'
config. = ''
config.0 = data.0
Do i = 1 To data.0
config.i = data.i
If Abbrev(data.i, ';') | Abbrev(data.i, '[') Then
Nop
Else
Do
Parse Var data.i key_id '=' key_value
key_id = Strip(key_id)
key_value = "'" || Strip(key_value) || "'"
Interpret key_id '=' key_value
End
End
Call Convert_ini ini_file /* update from an old ini file */
Trace(trace_save)
Return
/* convert or update config using an existing ini file */
Convert_ini:
trace_save = Trace('N')
Trace 'N'
Parse Arg ini_file
If RxFileExists(ini_file) ,
& File_cmd(ini_file, 'D') > File_cmd(input_file, 'D') Then
Do
ini_key = 'IGN InJoy DataPath DisplayDailyReport PauseAsScreenFills' ,
'WarnPercent ConnectDigits MinuteDigits HourDigits'
key_key = 'ibm_dialer injoy_dialer data_path daily_report one_screen_at_a_time' ,
'warn_pct sig_x sig_min sig_hr'
/* get all keys */
xrc = SysIni(ini_file, 'COMMON', 'ALL:', 'keys.')
If keys.0 > 0 Then
Do i = 1 To keys.0 /* get all the key values */
key_id = Word(key_key, Wordpos(keys.i, ini_key))
key_value = "'" || SysIni(ini_file, 'COMMON', keys.i) || "'"
Interpret key_id '=' key_value
End
ini_key = 'IniFileName OutputFileName SummaryFileName LastTimeStamp'
key_key = 'ibm_dialer_ini_file ibm_output_file ibm_summary_file ibm_last_time_stamp'
/* get all keys */
xrc = SysIni(ini_file, 'INETLOG', 'ALL:', 'keys.')
If keys.0 > 0 Then
Do i = 1 To keys.0 /* get all the key values */
key_id = Word(key_key, Wordpos(keys.i, ini_key))
key_value = "'" || SysIni(ini_file, 'INETLOG', keys.i) || "'"
Interpret key_id '=' key_value
End
ini_key = 'InJoyOutput InJoySummary'
key_key = 'injoy_output_file injoy_summary_file'
/* get all keys */
xrc = SysIni(ini_file, 'IJOYLOG', 'ALL:', 'keys.')
If keys.0 > 0 Then
Do i = 1 To keys.0 /* get all the key values */
key_id = keys.i
If Wordpos(key_id, ini_key) > 0 Then
Do
key_id = Word(key_key, Wordpos(keys.i, ini_key))
key_value = "'" || SysIni(ini_file, 'IJOYLOG', keys.i) || "'"
Interpret key_id '=' key_value
End
End
injoy_total_logs = SysIni(ini_file, 'IJOYLOG', 'InJoyLogs')
log_value = ''
acct_value = ''
user_value = ''
time_value = ''
Do i = 1 To injoy_total_logs
key = 'InJoyLog_' || i
log_value = log_value SysIni(ini_file, 'IJOYLOG', key)
If log_value = 'ERROR:' Then
log_value = Word(SysIni(ini_file, 'IJOYLOG', 'InJoyLog'), i)
key = 'InJoyAcct_' || i
acct_value = acct_value SysIni(ini_file, 'IJOYLOG', key)
If acct_value = 'ERROR:' Then
acct_value = Word(SysIni(ini_file, 'IJOYLOG', 'InJoyAcct'), i)
key = 'InJoyUser_' || i
user_value = user_value SysIni(ini_file, 'IJOYLOG', key)
If user_value = 'ERROR:' Then
user_value = Word(SysIni(ini_file, 'IJOYLOG', 'InJoyUser'), i)
key = 'InJoyTimeStamp_' || i
time_value = time_value SysIni(ini_file, 'IIJOYLOG', key)
If time_value = 'ERROR:' Then
time_value = Word(SysIni(ini_file, 'IJOYLOG', 'InJoyTimeStamp'), i)
End
key_id = 'injoy_logs'
Interpret key_id '=' "'" || Strip(log_value) || "'"
key_id = 'injoy_accts'
Interpret key_id '=' "'" || Strip(acct_value) || "'"
key_id = 'injoy_users'
Interpret key_id '=' "'" || Strip(user_value) || "'"
key_id = 'injoy_times'
Interpret key_id '=' "'" || Strip(time_value) || "'"
Call Write_config
Address cmd '@rename' ini_file 'inetini.sav > nul'
End
Trace(trace_save)
Return
/* write the config file */
Write_config:
trace_save = Trace('N')
Trace 'N'
If RxFileExists(cfg_file) Then /* do we have a config file */
Do
If RxFileExists(cfg_save) Then
Call SysFileDelete(cfg_save)
Address cmd '@rename' cfg_file Filespec('N', cfg_save) '> nul'
End
Do i = 1 To config.0
If Abbrev(config.i, ';') | Abbrev(config.i, '[') Then
Nop
Else
Do
Parse Var config.i key_id '=' key_value
key_id = Strip(key_id)
config.i = key_id '=' Value(key_id)
End
End
Call RxWrite 'config.', cfg_file
Trace(trace_save)
Return
/* check the config file */
Check_config:
trace_save = Trace('N')
Trace 'N'
/* path to data files */
If data_path = '' Then
Do
data_path = install_path || 'data\'
Call Write_config
End
/* create the data path sub-directory if needed */
If \RxFileExists(data_path || '*.*') Then
xrc = SysMkDir(Strip(data_path, , '\'))
/* IBM dialer support */
If ibm_dialer = '' Then
Do
Say 'Support the IBM dialer (y/N)?'
Parse Upper Pull ans .
key_value = Abbrev(ans, 'Y')
ibm_dialer = key_value
Call Write_config
End
/* InJoy dialer support */
If injoy_dialer = '' Then
Do
Say 'Support the InJoy dialer (y/N)?'
Parse Upper Pull ans .
key_value = Abbrev(ans, 'Y')
injoy_dialer = key_value
Call Write_config
End
/* process IBM dialer entries */
If ibm_dialer Then
Do
/* dialer ini file */
If ibm_dialer_ini_file = '' Then
Do
Say 'Please select your IBM dialer by number'
Say ' 1 - DIALER.EXE (1.67 and below)'
Say ' 2 - TCPDIAL.EXE (1.69 and above)'
Parse Upper Pull ans .
Select
When ans = 1 Then
key_value = 'dialer.ini'
When ans = 2 Then
key_value = 'tcpdial.ini'
Otherwise Do
Say 'You did not chose a supported dialer'
key_value = ''
End
End
ibm_dialer_ini_file = key_value
Call Write_config
End
End
/* process InJoy dialer entries */
If injoy_dialer Then
Do
If injoy_logs = '' Then
Do
/* get path to InJoy */
Say 'Enter the full path to the InJoy Dialer logs or hit enter to quit.'
Parse Upper Pull ans .
If ans <> '' Then
Do
/* get all *.log file names */
log_path = ans
rc = SysFileTree(log_path || '\*.log', 'logs.', 'FO')
/* loop through log file names to see the user wants them included */
If rc = 0 & logs.0 > 0 Then
Do i = 1 To logs.0
Say 'Found InJoy log file -' logs.i
Say 'Analyze this log (y/N)'
Parse Upper Pull ans
If Abbrev(ans, 'Y') Then
Do
injoy_logs = Space(injoy_logs logs.i)
End
End
Else
Do
Say 'Unable to locate any logs in InJoy log path -' ans
Say 'InJoy logs in' ans 'will not be processed.'
End
End
Else
Say 'InJoy logs will not be processed'
injoy_accts = ''
injoy_users = ''
injoy_times = ''
Do i = 1 To Words(injoy_logs)
joylog = Word(injoy_logs, i)
joyacct = Word(injoy_accts, i)
joyuser = Word(injoy_users, i)
joytime = Word(injoy_times, i)
If joyacct = '' Then
Do
Say 'Enter an account id for InJoy log (enter = none)'
Say joylog
Parse Pull joydata
If joydata = '' Then
joydata = 'none'
injoy_accts = Strip(injoy_accts joydata)
End
If joyuser = '' Then
Do
Say 'Enter an user id for InJoy log (enter = none)'
Say joylog
Say 'and account id -' joydata
Parse Pull joydata
If joydata = '' Then
joydata = 'none'
injoy_users = Strip(injoy_users joydata)
End
If joytime = '' Then
Do
joydata = 'T00000000000000'
injoy_times = Strip(injoy_times joydata)
End
End
Call Write_config
End
End
Trace(trace_save)
Return
Log_file_parms: Procedure
trace_save = Trace('N')
Parse Arg dialer_ini_name, dialer_ini
Select
When Translate(dialer_ini_name) = 'DIALER.INI' Then
Do
dlog_eparm = 'AdvLog'
dlog_nparm = 'Cfn'
dlog_sparm = 'Cfs'
End
When Translate(dialer_ini_name) = 'TCPDIAL.INI' Then
Do
dlog_eparm = 'Common'
dlog_nparm = 'LoggingCfn'
dlog_sparm = 'LoggingCfs'
End
Otherwise Do
Say 'Unable to recognize dialer ini file'
Call Cleanup
Exit
End
End
dialer_log_file = Strip(SysIni(dialer_ini, dlog_eparm, dlog_nparm),,'00'x)
dialer_log_size = C2d(Left(SysIni(dialer_ini, dlog_eparm, dlog_sparm),3))
Trace (trace_save)
Return dialer_log_file dialer_log_size
/* Now find all lines in connect.log that contain the key_phrase
string. A typical line generated in the connect.log after
disconnect is either this for a dialer version preceding v. 1.45:
11/15 19:08:38 Disconnected after 00:06:20 0 errors 0 discards
or this style for v. 1.45 and later:
1995/11/15 19:08:38 Disconnected after 00:06:20 0 errors 0 discards
which we would parse as follows:
date word2 word3 word4 connect_time */
Analyze_logfile:
trace_save = Trace('N')
Call SysFileSearch key_phrase, log_file, 'line.', 'N'
Call SysFileSearch user_phrase, log_file, 'user.', 'N'
/* this section will read backwards through the connection log file
data and attempt to assign account information and userid to each
connection log record */
k = user.0
Do i = line.0 To 1 By -1 While k > 0
Parse Var line.i disc_line_no .
acct_data = 'acctid=unknown userid=unknown'
j = i - 1
If j > 0 Then
Parse Var line.j prev_disc_line_no .
Else
prev_disc_line_no = 0
If k > 0 Then
Do
Parse Var user.k user_line_no . . acctid userid .
If disc_line_no > user_line_no & user_line_no > prev_disc_line_no Then
Do
acct_data = 'acctid=' || acctid 'userid=' || userid
k = k - 1
End
End
line.i = line.i acct_data
End
rc = 0
Do i = 1 To line.0
Parse Var line.i . date word2 word3 word4 connect_time remainder
If remainder = '' Then
Iterate i
Parse Var remainder . 'acctid=' acctid 'userid=' userid .
acctid = Strip(acctid)
userid = Strip(userid)
/* Date, excluding year if year is or is not present, is 5 chars: mm/dd */
date2 = Right(date,5)
/* Make all dates uniform. If more than mm/dd (5 chars) then year
is there. The length(date) - 6 = length of however many
characters are used for the year (4 now (e.g., 1995) but some
joker might change it to 2 (e.g., 95) We then add 1 char for the
/ separator + 1 */
If Length(date) > 5 Then
year = Substr((date), 1, Length(date) -6 ) || ' '
Else
year = ' ' /* If pre v1.45 Dialer, no year, pad 5 spaces */
/* Extract the month of a connection as a 2-dig number */
mm = Substr(date2, 1, 2)
dd = Substr(date2, 4, 2) /* ...and the day */
/* Extract for time stamp and save */
Parse Var word2 t_hr ':' t_min ':' t_sec
If year <> ' ' Then
t_yr = Strip(year)
Else
t_yr = ' '
time_stamp = 'T' || t_yr || mm || dd || t_hr || t_min || t_sec
/* Extract the number of hours on-line */
hrs = Substr(connect_time, 1, 2)
mins = Substr(connect_time, 4, 2) /*... and mins */
secs = Substr(connect_time, 7, 2) /*...and seconds */
If hrs < 0, /* If hrs is negative */
| mins < 0, /* or mins is negative */
|If secs < 0 Then
Call Errdst /* or secs is negative. Time change error? Abort */
/* Calculate time_on for that connection */
time_on = (60*hrs + mins + (1/60)*secs)
If time_stamp > last_time_stamp Then
Call Monthly_update
If old_d = 0 Then
Do /* for very first connection line */
old_m = mm
old_d = dd
old_y = year
signons_each_day = 1 /* reset to 1 */
signons_each_month = 1
/* This and next one are timeons in minutes */
daily_time_on = time_on
monthly_time_on = time_on
End
Else /* continue to accumulate times if same month and day */
If old_m = mm & old_d = dd & month <> 0 Then
Do
old_y = year
signons_each_day = signons_each_day + 1
signons_each_month = signons_each_month + 1
daily_time_on = daily_time_on + time_on
monthly_time_on = monthly_time_on + time_on
End
Else /* new day of same month */
If old_m = mm & old_d <> dd Then
Do
Call Prepare_data
dcounter = dcounter + 1
year.dcounter = year
year.mcounter = year
dayline.dcounter = year.dcounter month.old_m old_d d_signons d_mins d_hhmmss d_hrs
old_d = dd
old_y = year
signons_each_day = 1 /* Start counting over again */
signons_each_month = signons_each_month + 1
daily_time_on = time_on
monthly_time_on = monthly_time_on + time_on
End
Else /* for any new month, which by definition is also a new day */
If old_m <> mm & old_m <> 0 Then
Do
Call Prepare_data
dcounter = dcounter + 1
year.dcounter = old_y
dayline.dcounter = year.dcounter month.old_m old_d d_signons d_mins d_hhmmss d_hrs
mcounter = mcounter + 1
year.mcounter = old_y
monthline.mcounter = year.mcounter month.old_m m_signons m_mins m_hhmmss m_hrs
old_m = mm
old_d = dd
old_y = year
signons_each_day = 1
signons_each_month = 1
daily_time_on = time_on
monthly_time_on = time_on
End
End /* end of all these If's and Else If's of searching for
key_phrase in all possible lines in the connect.log */
/* Now, since last day and last month is done: */
Call Prepare_data
dcounter = dcounter + 1
year.dcounter = year
dayline.dcounter = year.dcounter month.old_m old_d d_signons d_mins d_hhmmss d_hrs
mcounter = mcounter + 1
year.mcounter = year
monthline.mcounter = year.mcounter month.old_m m_signons m_mins m_hhmmss m_hrs
/* save the last */
ibm_last_time_stamp = time_stamp
Call Write_config
Trace (trace_save)
return /* from Analyze_logfile */
Monthly_update:
s_yr = Strip(t_yr)
s_mo = Strip(mm)
If summary.acctid.userid.s_yr.s_mo <> '' Then
Do
Parse Var summary.acctid.userid.s_yr.s_mo s_yr s_mo s_stamp s_sess s_min .
If time_stamp > s_stamp Then
Do
s_sess = s_sess + 1
s_min = s_min + time_on
summary.acctid.userid.s_yr.s_mo = s_yr s_mo time_stamp s_sess s_min
End
End
Else
Do
x = monthly.0 + 1
monthly.x = acctid userid s_yr s_mo
monthly.0 = x
summary.acctid.userid.s_yr.s_mo = s_yr s_mo time_stamp '1' time_on
End
Return
Outputter:
/* Now output everything to console and to file */
/* get the screen size; rows is what we are interested in */
Parse Value SysTextScreenSize() With rows cols
Call Stream stdin, 'C', 'OPEN READ'
/* Tell us all */
intro = what_r_we
Call Say_out intro
If otherparms <> '' Then
Do
Call Say_out crlf || 'Running with parms =' otherparms
Call Lineout output_file crlf || 'Running with parms =' otherparms
End
Call Lineout output_file, intro
intro = crlf || 'Analysis of' log_file '(' || Date() '@' Time() || ')'
Call Say_out intro
Call Lineout output_file, intro
If daily_report Then
Call Say_out crlf || daily totals
Call Lineout output_file, crlf || daily totals
Do j = 1 To dcounter
If daily_report Then
Call Say_out dayline.j
Call Lineout output_file, dayline.j
If one_screen_at_a_time & daily_report & \quiet & \pmrexx then
If (j - rows + 6) // (rows - 5) = 0 Then
answer = Say_message(' Press any key to continue...')
End
If one_screen_at_a_time & daily_report & \quiet & \pmrexx then
If (j - rows + 6) // (rows - 5) > 5 Then
Do /* If at about 5 lines to end */
answer = Say_message(' Daily Totals done, press any key for Monthlies...')
/* If decision is to do a 'Press-Any-Key to continue', reset to 0 */
j = 0
End
If \ daily_report Then
j = 0
/* back up the summary file and delete it */
If RxFileExists(summary_file) Then
Do
Parse Var summary_file fname '.' ext
Address cmd '@COPY' summary_file fname || '.bak > NUL'
Call SysFileDelete summary_file
End
rc = File_cmd(summary_file,'W')
acct_user_save = ''
Call RxSort 'monthly.', 'A' /* sort the summary data */
Call Summary_sample /* get the header information */
/* insert the header info into the summary data */
Do k = summary_sample.0 To 1 By -1
Call RxStemInsert 'monthly.', 1, summary_sample.k
End
Do k = 1 To monthly.0
If Abbrev(monthly.k,'*') Then
Do /* write comments back out */
Call Lineout summary_file, monthly.k
Iterate k
End
Parse Var monthly.k acctid userid s_yr s_mo
acct_user = acctid userid
Call Lineout summary_file, acctid userid '*' summary.acctid.userid.s_yr.s_mo
Parse Var summary.acctid.userid.s_yr.s_mo . . . s_sess s_mins
m_sess = Format(s_sess, sig_x) || 'X'
m_mins = Format(s_mins, sig_min, 2) 'mins'
mo_hh = Format(Trunc(s_mins / 60),sig_hr)
mo_mm = Right(Trunc(s_mins // 60),2,'0')
mo_ss = Right(Trunc(60 * ((s_mins // 60) - Trunc(s_mins // 60))),2,'0')
m_hhmmss = ' '||mo_hh||':'||mo_mm||':'||mo_ss
m_hrs = Format((s_mins / 60), sig_hr, 2) 'hrs'
a_sess = s_mins / s_sess
If a_sess < 60 Then
a_sess = Format(a_sess,2,0) 'mins'
Else
a_sess = Format((a_sess / 60),2,2) 'hrs'
a_sess = '- Ave =' a_sess
monthline = s_yr month.s_mo m_sess m_mins m_hhmmss m_hrs a_sess
If acct_user <> acct_user_save Then
Do
intro = crlf || 'MONTHLY TOTALS for Account(' || acctid || ') Userid(' || userid || ')'
Call Say_out intro
Call Lineout output_file, intro
acct_user_save = acct_user
End
Call Lineout output_file, monthline
monthline = s_yr month.s_mo m_sess m_hrs a_sess
Call Say_out monthline
If one_screen_at_a_time & \quiet & \pmrexx Then
If (k + j - rows + 6) // (rows - 6) = 0 Then
answer = Say_message(' Press any key to continue...')
End
rc = File_cmd(summary_file,'C')
finished = crlf || 'End of analysis of' log_file
Call Say_out finished
Call Lineout output_file, finished
rc = SysFileTree(dialer_log_file, 'info.', 'F')
Parse Var info.1 . . log_file_size .
If dialer_log_size > 0 Then
Do
log_file_pct = Format((log_file_size / dialer_log_size) * 100,,0)
Call Say_out ''
Call Say_out 'The connection log file is at' log_file_pct || '% of the maximum'
Call Say_out 'size,' Format(dialer_log_size,,0) 'bytes, specified in the Dialer settings.'
If log_file_pct > warn_pct Then
Do
Call Say_out ''
Call Say_out 'You may want to consider running editing the'
Call Say_out dialer_log_file 'with the IBM tedit.exe'
Call Say_out ''
End
End
Return /* from Outputter */
Combined_output:
/* Combine output from IGN and InJoy and display */
If \injoy_dialer Then
Return
If quiet Then
Return
ign. = ''
ign.0 = 0
If ibm_dialer Then
Do
/* read the IBM dialer summary log */
If RxFileExists(summary_file) Then
Do
Call RxRead 'data.', summary_file
Do x = 1 To data.0
If \Abbrev(data.x,'*') & data.x <> '' Then
Do
Parse Var data.x acctid userid '*' s_yr s_mo s_time s_data
i = ign.0 + 1
ign.i = Space(acctid userid s_yr s_mo s_data)
ign.0 = i
End
End
End
End
i = ign.0 + 1 /* make an end of file record */
ign.i = Copies('FF'x, 8) Copies('FF'x, 8) Copies('FF'x, 4) 'FFFF'x
ign.0 = i
joy. = ''
joy.0 = 0
/* read the InJoy dialer summary file */
If RxFileExists(injoy_summary) Then
Do
Call RxRead 'data.', injoy_summary
Do x = 1 To data.0
If \Abbrev(data.x,'*') & data.x <> '' Then
Do
Parse Var data.x acctid userid '*' s_yr s_mo s_time s_data
acctid = Strip(acctid)
userid = Strip(userid)
s_yr = Strip(s_yr)
s_mo = Strip(s_mo)
i = joy.0 + 1
joy.i = Space(acctid userid s_yr s_mo s_data)
joy.0 = i
End
End
End
i = joy.0 + 1 /* make an end of file record */
joy.i = Copies('FF'x, 8) Copies('FF'x, 8) Copies('FF'x, 4) 'FFFF'x
joy.0 = i
combined. = ''
combined.0 = 0
i = 1
j = 1
Do While (i < ign.0) | (j < joy.0)
Parse Var ign.i i_acctid i_userid i_s_yr i_s_mo i_sess i_min
i_value = i_acctid || i_userid || i_s_yr || i_s_mo
Parse Var joy.j j_acctid j_userid j_s_yr j_s_mo j_sess j_min
j_value = j_acctid || j_userid || j_s_yr || j_s_mo
Select
When i_value = j_value Then
Do
t_sess = i_sess + j_sess
t_min = i_min + j_min
k = combined.0 + 1
combined.k = i_acctid i_userid i_s_yr i_s_mo t_sess t_min
combined.0 = k
i = i + 1
j = j + 1
End
When i_value < j_value Then
Do
k = combined.0 + 1
combined.k = i_acctid i_userid i_s_yr i_s_mo i_sess i_min
combined.0 = k
i = i + 1
End
When i_value > j_value Then
Do
k = combined.0 + 1
combined.k = j_acctid j_userid j_s_yr j_s_mo j_sess j_min
combined.0 = k
j = j + 1
End
Otherwise Nop
End
End
acct_user_save = ''
intro = what_r_we
Call Say_out intro
If otherparms <> '' Then
Do
Call Say_out crlf || 'Running with parms =' otherparms
End
intro = crlf || 'Analysis of combined IGN and InJoy log files (' || Date() '@' Time() || ')'
Call Say_out intro
Do k = 1 To combined.0
If Abbrev(combined.k,'*') Then
Iterate
Parse Var combined.k acctid userid s_yr s_mo s_sess s_mins
acct_user = acctid userid
m_sess = Format(s_sess, sig_x) || 'X'
m_mins = Format(s_mins, sig_min, 2) 'mins'
mo_hh = Format(Trunc(s_mins / 60),sig_hr)
mo_mm = Right(Trunc(s_mins // 60),2,'0')
mo_ss = Right(Trunc(60 * ((s_mins // 60) - Trunc(s_mins // 60))),2,'0')
m_hhmmss = ' ' || mo_hh || ':' || mo_mm || ':' || mo_ss
m_hrs = Format((s_mins / 60), sig_hr, 2) 'hrs'
a_sess = s_mins / s_sess
If a_sess < 60 Then
a_sess = Format(a_sess,2,0) 'mins'
Else
a_sess = Format((a_sess / 60),2,2) 'hrs'
a_sess = '- Ave =' a_sess
monthline = s_yr month.s_mo m_sess m_hrs a_sess
If acct_user <> acct_user_save Then
Do
intro = crlf || 'MONTHLY TOTALS for Account(' || acctid || ') Userid(' || userid || '}'
Call Say_out intro
acct_user_save = acct_user
End
Call Say_out monthline
If one_screen_at_a_time & \quiet &\pmrexx Then
If (k + j - rows + 6) // (rows - 6) = 0 Then
answer = Say_message(' Press any key to continue...')
End
rc = File_cmd(summary_file,'C')
finished = crlf || 'End of analysis of combined log files'
Call Say_out finished
Return /* from Combine_output */
Prepare_data:
/* Calculates and formats what is to be put into an output line */
/* Signons per day or month, as, e.g.: '4X' */
d_signons = Format(signons_each_day, sig_x)||'X'
m_signons = Format(signons_each_month, sig_x)||'X'
/* Minutes/day, minutes/month, hrs/day, hrs/month as, e.g.: '105.50 mins or hrs' */
d_mins = Format(daily_time_on, sig_min, 2) 'mins'
d_hrs = Format((daily_time_on/60), sig_hr, 2) 'hrs'
m_mins = Format(monthly_time_on, sig_min, 2) 'mins'
m_hrs = Format((monthly_time_on/60), sig_hr, 2) 'hrs'
/* minutes, seconds per day or month, as 2-digit numbers; hrs can exceed 2 digs */
dy_hh = Format(Trunc(daily_time_on/60),sig_hr)
dy_mm = Right(Trunc(daily_time_on//60),2,'0')
dy_ss = Right(Trunc(60*((daily_time_on//60) - Trunc(daily_time_on//60))),2,'0')
mo_hh = Format(Trunc(monthly_time_on/60),sig_hr)
mo_mm = Right(Trunc(monthly_time_on//60),2,'0')
mo_ss = Right(Trunc(60*((monthly_time_on//60) - Trunc(monthly_time_on//60))),2,'0')
/* hours, minutes, seconds per day or month, as, e.g.: '1:45:30'*/
d_hhmmss = ' '||dy_hh||':'||dy_mm||':'||dy_ss
m_hhmmss = ' '||mo_hh||':'||mo_mm||':'||mo_ss
Return /* Prepare_data */
Errdst: /* If error due to time change */
Say 'INETLOG has found a negative number for time-on-line'
Say 'in an entry in your' log_file 'file.'
Say ''
Say 'You may have reset your clock backwards while on line, e.g.,'
Say 'while changing from Summer time (Daylight Saving Time) to'
Say 'Winter time (Standard time).'
Say ''
Say 'To fix:'
Say ' 1. Open' log_file 'in your Tiny Editor (tedit.exe)'
Say ' 2. Edit any connection time(s) that have a minus sign.'
Say ' Example (for a typical one-hour summer-to-winter time correction):'
Say ''
Say ' change'
Say ' 1995/10/29 06:26:43 Disconnected after -00:-58:-4 0 errors 0 discards'
Say ' to'
Say ' 1995/10/29 06:26:43 Disconnected after 00:01:56 0 errors 0 discards'
Say ''
Say ' If the error was not from a summer-time change, make whatever'
Say ' correction seems reasonable to eliminate the offending minus'
Say ' signs (like just removing them).'
Say ''
Say ' 3. Save' log_file
Say ' 4. Run EOF2CRLF to remove the EOF characters'
Say ' added by the editor.'
Say 'Aborting . . .'
Call Cleanup
Return
Errhandler:
Call Beep 300, 500
Say 'Rexx error' rc 'in line' sigl||':' Errortext(rc)
Say Sourceline(sigl)
Call Cleanup
Return
Cleanup: /* Exit */
If \quiet & \pmrexx Then
answer = Say_message('Press any key to exit...')
Else
Call SysSleep 2
save_path = Directory(save_path)
Exit
Return /* for Cleanup */
Set_monthly_summary: /* set monthly summary */
trace_save = Trace('N')
monthly. = ''
monthly.0 = 0
summary. = ''
s_time = 'T00000000000000'
If RxFileExists(summary_file) Then
Do
Call RxRead 'data.', summary_file
Do i = 1 To data.0
If \ Abbrev(data.i,'*') & data.i <> '' Then
Do
Parse Var data.i acctid userid '*' s_yr s_mo s_time s_data
If s_yr = '' Then
Do
acctid = 'unknown'
userid = 'unknown'
Parse Var data.i s_yr s_mo s_data
End
acctid = Strip(acctid)
userid = Strip(userid)
s_yr = Strip(s_yr)
s_mo = Strip(s_mo)
j = monthly.0 + 1
monthly.j = acctid userid s_yr s_mo
monthly.0 = j
summary.acctid.userid.s_yr.s_mo = s_yr s_mo s_time s_data
End
End
Call RxSort 'monthly.0', 'A'
End
Else
s_time = 'T00000000000000' /* reset timestamp to get updates */
last_time_stamp = s_time
Trace (trace_save)
Return /* Set_monthly_summary */
/* performs common Stream commands and returns 1 or a date if successful */
File_cmd: Procedure Expose result
trace_save = Trace('N')
Trace 'N'
Parse Arg file_name, command
command = Translate(command)
Select
When command = 'X' Then
Do
result = Stream(file_name, 'C', 'QUERY EXISTS')
answer = (result <> '')
End
When command = 'C' Then
Do
result = Stream(file_name, 'C', 'CLOSE')
answer = Abbrev(result,'READY') | (result = '')
End
When command = 'W' Then
Do
result = Stream(file_name, 'C', 'OPEN WRITE')
answer = Abbrev(result,'READY')
End
When command = 'R' Then
Do
result = Stream(file_name, 'C', 'OPEN READ')
answer = Abbrev(result,'READY')
End
When command = 'D' Then
Do
result = Stream(file_name, 'C', 'QUERY DATETIME')
If result <> '' Then
Do
Parse Var result date time
date = Dateconv(Translate(date, '/', '-'), 'U', 'S')
Parse Var time hr ':' min ':' sec
answer = Strip(date) || Strip(hr) || Strip(min) || Strip(sec)
End
Else
answer = '00000000000000'
End
Otherwise answer = 0
End
Trace (trace_save)
Return answer
Say_out: /* performs output to the screen */
Procedure Expose quiet
trace_save = Trace('N')
If quiet Then
Return
Parse Arg line
Say line
Trace (trace_save)
Return
Say_message: /* performs message output and returns key entered */
Procedure Expose quiet
trace_save = Trace('N')
Parse Arg msg
Say msg
answer = SysGetKey('NOECHO')
Trace (trace_save)
Return answer
Summary_sample: Procedure Expose summary_sample.
trace_save = Trace('N')
Trace 'N'
data_queue = INetSmp('summary')
old_queue = Rxqueue('Set', data_queue)
summary_sample.0 = Queued()
Do i = 1 To summary_sample.0
Parse Pull summary_sample.i
End
rx_queue = Rxqueue('Delete', data_queue)
Trace(trace_save)
Return