$SEARCH 'KRMWNDW', '*IO.', '*INTERFACE.'$ { This file, KRMRPT.TEXT, contains the error and status reporting modules used by all other Kermit modules. The following modules reside in this file: ERR_CODES Error code definitions KRMRPT Error and status reporting procedures } { Module ERR_CODES defines the integer error code values that can be returned by a procedure to indicate whether it completed successfully, or, if not, what error occurred. Function ERRSTR returns the error message string associated with the error. All Kermit modules have access to ERR_CODES. } module err_codes; export const error_string_length = 80; { Maximum length of error strings } { Facility code definitions. These codes identify the facility generating the error. } cmdfac = 1*128; { command interpreter } trmfac = 2*128; { terminal emulation code } iofac = 3*128; { io error } krmfac = 4*128; { kermit protocol machine } { Status code definitions. Successful return codes are odd, those corresponding to error conditions are even. Returned by functions, etc. } success = 1; { Error condition status codes } { Codes returned by lookup_key } ambig_keyword = 2 + cmdfac; no_keyword = 4 + cmdfac; { Codes returned by parse } not_confirmed = 6 + cmdfac; integer_error = 8 + cmdfac; no_match = 10 + cmdfac; non_digit = 12 + cmdfac; { Non-digit character encountered } integer_overflow = 14 + cmdfac; { Integer overflow } null_string = 16 + cmdfac; { null string given as argument } parse_after_eol = 18 + cmdfac; { parse called after eol parsed } { Codes returned by read_break } back_past_field = 20 + cmdfac; abort_line = 22 + cmdfac; type error_string = string[ error_string_length ]; function errstr ( errcode : integer ) : error_string; $page$ implement function errstr ( errcode : integer ) : error_string; { Returns the error string associated with each error. } var s : error_string; begin case errcode of success: s := 'Success'; { Codes returned by lookup_key } ambig_keyword: s := 'Ambiguous keyword'; no_keyword: s := 'No keywords match this input'; { Codes returned by parse } not_confirmed: s := 'Not confirmed'; integer_error: s := 'Error reading integer'; no_match: s := 'No defined keywords match this input'; non_digit: s := 'Non-digit character encountered'; integer_overflow: s := 'Integer overflow'; null_string: s := 'Null string given as argument'; parse_after_eol: s := 'Parse called after end of line parsed'; { Codes returned by read_break } back_past_field: s := 'Input deleted past beginning of field'; abort_line: s := 'Line aborted by CTRL-U'; end; { case } errstr := s; end; { function errstr } end; { module err_codes } $PAGE$ { Module KRMRPT handles error and status reporting for the rest of Kermit. Basically, except for command echoing, anything that is displayed on the screen is put there by procedures in this module. These procedures do the proper text formatting, positioning, etc., and then call procedures in module WINDOWLIB (in file KRMWNDW.TEXT) to actually do the screen output. All other Kermit modules have access to KRMRPT. } module krmrpt; import windowlib, err_codes; export var help_window, command_window, error_window, stat_window : window_ptr; type { Packet transfer statistics record } kermit_statistics = record NumSendPacks : integer; { number of packets sent } NumRecvPacks : integer; { number of packets received } NumACKsent : integer; { number of ACKs we've sent } NumNAKsent : integer; { number of NAKs we've sent } NumACKrecv : integer; { number of ACKs we've received } NumNAKrecv : integer; { number of NAKs we've received } NumBADrecv : integer; { number of non-ACKs we've received when } { waiting for an ACK } RunTime: integer; { elapsed time for current transaction } ChInFile : integer; { number of characters in file } ChInPack : integer; { number of characters in packets } packet_overhead : integer; { percent overhead of packetizing } effrate : integer; { effective baud rate of transfer } end; { record } KermitStates = (FileData,RecvInit,SendInit,Break, FileHeader,EOFile,Complete,Abort); Transfer_type = (Transmit, Receive, Invalid); procedure set_logfile( var fnm : string ); procedure get_logfile( var fnm : string ); procedure report_status( var report : string ); procedure report_log( var report : string ); procedure report_error( code : integer; var where_msg : string ); procedure init_cmd_windows; procedure clear_status_window; procedure init_packet_display( runtype : transfer_type ); procedure report_send_packet( seq : integer ); procedure report_receive_file( var fnm : string ); procedure report_send_file( var fnm : string ); procedure report_packet_statistics( stats : kermit_statistics; runtype : transfer_type ); function check_error( code : integer; var where_msg : string ) : boolean; implement const send_packet_y = 2; packet_stat_x = 25; packet_stat_y = 4; stat_random_x = 0; stat_random_y = 14; file_report_x = 0; file_report_y = 0; var log_filename : string[50]; log_file : text; log_on : boolean; send_packet_x : integer; { window coords of send packet # } report : string[80]; rpos : integer; procedure set_logfile( var fnm : string ); begin if strlen(fnm) = 0 then begin log_on := false; log_filename := 'OFF'; end else begin log_on := true; log_filename := fnm; rewrite(log_file,log_filename); end; end; { procedure set_logfile } procedure get_logfile( var fnm : string ); begin fnm := log_filename; end; { procedure get_logfile } procedure report_status( var report : string ); begin writeln_window_string( stat_window, report ); end; { procedure report_status } procedure report_log( var report : string ); begin if log_on then writeln(log_file, report); end; { procedure report_status } procedure report_error( code : integer; var where_msg : string ); var report : string [80]; rpos : integer; begin setstrlen(report,0); strwrite(report,1,rpos,'?Error ',where_msg, ' - ', errstr(code)); clear_window(error_window); writeln_window_string( error_window, report ); end; { procedure report_error } $page$ procedure init_cmd_windows; begin stat_window := init_window(0,screen_x_max, 0,16); help_window := init_window(0,screen_x_max, 17,20); command_window := init_window(0,screen_x_max, 21,21); error_window := init_window(0,screen_x_max, 22,23); end; { procedure init_cmd_windows } procedure clear_status_window; begin clear_window(stat_window); end; { procedure clear_status_window } procedure init_packet_display( runtype : transfer_type ); var lab : string[80]; begin clear_window(stat_window); lab := 'Sending Packet # '; send_packet_x := strlen(lab); gotoxy_window(stat_window, 0, send_packet_y); writeln_window_string( stat_window, lab); clear_eol_window(stat_window); gotoxy_window( stat_window, 0, packet_stat_y ); setstrlen(report,0); strwrite(report,1,rpos,'Packets sent'); report_status(report); setstrlen(report,0); strwrite(report,1,rpos,'Packets received'); report_status(report); setstrlen(report,0); if runtype = transmit then strwrite(report,1,rpos,'Total chars. sent') else strwrite(report,1,rpos,'Total chars. rcvd'); report_status(report); setstrlen(report,0); if runtype = transmit then strwrite(report,1,rpos,'Data chars. sent') else strwrite(report,1,rpos,'Data chars. rcvd'); report_status(report); setstrlen(report,0); strwrite(report,1,rpos,'Overhead (%)'); report_status(report); setstrlen(report,0); strwrite(report,1,rpos,'Effective Rate'); report_status(report); setstrlen(report,0); strwrite(report,1,rpos,'Number of ACK'); report_status(report); setstrlen(report,0); strwrite(report,1,rpos,'Number of NAK'); report_status(report); IF (RunType = Transmit) THEN BEGIN setstrlen(report,0); strwrite(report,1,rpos,'Number of BAD'); report_status(report); END; gotoxy_window(stat_window, stat_random_x, stat_random_y); end; { procedure init_packet_display } procedure report_send_packet( seq : integer ); begin gotoxy_window(stat_window, send_packet_x, send_packet_y); setstrlen(report,0); strwrite(report,1,rpos,seq:1); write_window_string(stat_window, report); clear_eol_window(stat_window); gotoxy_window(stat_window, stat_random_x, stat_random_y); end; { report_send_packet } procedure report_send_file( var fnm : string ); begin gotoxy_window(stat_window, file_report_x, file_report_y); setstrlen(report,0); strwrite(report,1,rpos,'Sending file ',fnm); write_window_string(stat_window, report); clear_eol_window(stat_window); gotoxy_window(stat_window, stat_random_x, stat_random_y); end; { procedure report_send_file } procedure report_receive_file( var fnm : string ); begin gotoxy_window(stat_window, file_report_x, file_report_y); setstrlen(report,0); strwrite(report,1,rpos,'Receiving file ',fnm); write_window_string(stat_window, report); clear_eol_window(stat_window); gotoxy_window(stat_window, stat_random_x, stat_random_y); end; { procedure report_receive_file } procedure report_packet_statistics( stats : kermit_statistics; runtype : transfer_type ); var row : integer; procedure report_num( i : integer ); begin setstrlen(report,0); strwrite(report,1,rpos,i:5); gotoxy_window(stat_window, packet_stat_x, row); write_window_string(stat_window,report); row := row + 1; end; { procedure report_num } begin row := packet_stat_y; report_num(stats.NumSendPacks); report_num(stats.NumRecvPacks); report_num(stats.ChInPack); report_num(stats.ChInFile); report_num(stats.packet_overhead); report_num(stats.effrate); IF (RunType = Transmit) THEN BEGIN { for transmit } report_num(stats.NumACKrecv); report_num(stats.NumNAKrecv); report_num(stats.NumBADrecv); END { for transmit } ELSE BEGIN { for Receive } report_num(stats.NumACKsent); report_num(stats.NumNAKsent); END; { for Receive } gotoxy_window(stat_window, stat_random_x, stat_random_y); end; { procedure report_packet_statistics } $page$ { check_error Checks given condition code. Returns false if code is successful. If code is error code, prints associated error message and returns true. } function check_error( code : integer; var where_msg : string ) : boolean; var ret : boolean; begin ret := false; if not odd(code) { successful conditions are odd, failing (error) conditions are even } then begin report_error( code, where_msg ); ret := true; end; check_error := ret; end; { procedure check_error } end. { module krmrpt }