{ ROSSYU.INC - Remote Operating System Sysop Sub-system, User file routines } overlay procedure validate_user; { Change user access time and level to 'validated' status } var temp_user_loc: integer; ed_fn: firstname; ed_ln: lastname; key: StrName; temp_user_rec: user_list; begin temp_user_loc := summ_rec.user_from; OK := (temp_user_loc <> user_loc) and (temp_user_loc > 0); if OK then begin GetRec(DatF, temp_user_loc, temp_user_rec); OK := ask('Validate ' + temp_user_rec.fn + ' ' + temp_user_rec.ln) end; if not OK then begin get_name(ed_fn, ed_ln); key := pad(ed_ln, len_ln) + pad(ed_fn, len_fn); FindKey(IdxF, temp_user_loc, key); if OK then GetRec(DatF, temp_user_loc, temp_user_rec) else writeln(USR, 'Name not found.') end; if OK and (temp_user_rec.access < user_rec.access) then begin temp_user_rec.access := val_acc; temp_user_rec.limit := val_time; PutRec(DatF, temp_user_loc, temp_user_rec); writeln(USR, temp_user_rec.fn, ' ', temp_user_rec.ln, ' validated.') end end; overlay procedure delete_user; { Delete user from file } var i, temp_user_loc: integer; del_fn: firstname; del_ln: lastname; key: StrName; temp_user_rec: user_list; begin get_name(del_fn, del_ln); key := pad(del_ln, len_ln) + pad(del_fn, len_fn); FindKey(IdxF, temp_user_loc, key); if OK then begin GetRec(DatF, temp_user_loc, temp_user_rec); if temp_user_rec.access < user_rec.access then if ask('Delete') then begin DeleteKey(IdxF, temp_user_loc, key); if OK then begin DeleteRec(DatF, temp_user_loc); writeln(USR, key, ' deleted.'); writeln(USR, 'Checking message summary file.'); for i := 1 to pred(FileSize(summ_file)) do begin { Delete messages pertaining to user } seek(summ_file, i); read(summ_file, summ_rec); if ((summ_rec.user_to = temp_user_loc) or (summ_rec.user_from = temp_user_loc)) then mesg_delete end end else writeln(USR, 'Name not found.') end end end; overlay procedure edit_user; { Display and edit user record } var i: integer; ed_fn: firstname; ed_ln: lastname; key: StrName; temp_user_rec: user_list; procedure display_user; var disp_case, disp_nois: char; str: StrTAD; begin ClrScr; with temp_user_rec do begin writeln(USR, 'Name : ', fn, ' ', ln); writeln(USR, 'Address : ', ad); writeln(USR, 'City : ', cy); writeln(USR, 'State : ', st); writeln(USR, 'Phone : ', ph); writeln(USR, 'Password : ', pw); writeln(USR, 'Acc. level: ', access); writeln(USR, 'Limit : ', limit); writeln(USR, 'Nulls : ', nulls); if shift_lock then disp_case := 'U' else disp_case := 'L'; writeln(USR, 'Shift lock: ', disp_case); if noisy then disp_nois := 'N' else disp_nois := 'Q'; writeln(USR, 'Pr. bell : ', disp_nois); writeln(USR, 'Help level: ', help_level); writeln(USR, 'Columns : ', columns); writeln(USR, 'Lines : ', lines); str := FormTAD(laston); writeln(USR, 'Last on : ', str); writeln(USR, 'On today : ', time_today); writeln(USR, 'On total : ', time_total); writeln(USR, 'Last high : ', lasthi); writeln(USR, 'Uploads : ', upload); writeln(USR, 'Downloads : ', download) end; GotoXY(1, 22) end; procedure accept(x, y: integer; var str: StrStd; len: integer; mode: Str10); var term: char; begin str := ''; GotoXY(x, y); GetStr(str, term, len, mode) end; procedure change_user; var temp: integer; str: StrStd; begin with temp_user_rec do begin { line 1: name } accept(13, 2, str, len_ad, 'E'); if str <> '' then ad := str; accept(13, 3, str, len_cy, 'E'); if str <> '' then cy := str; accept(13, 4, str, len_st, 'ES'); if str <> '' then st := str; accept(13, 5, str, len_ph, 'E'); if str <> '' then ph := str; accept(13, 6, str, len_pw, 'ES'); if str <> '' then pw := str; accept(13, 7, str, 3, 'E'); if str <> '' then begin temp := strint(str); if temp <= user_rec.access { Can't set higher than self } then access := temp end; accept(13, 8, str, 3, 'E'); if str <> '' then limit := strint(str); accept(13, 9, str, 1, 'E'); if str <> '' then nulls := strint(str); accept(13, 10, str, 1, 'ES'); if str <> '' then shift_lock := (str = 'U'); accept(13, 11, str, 1, 'ES'); if str <> '' then noisy := (str = 'N'); accept(13, 12, str, 1, 'ES'); if str <> '' then help_level := strint(str); accept(13, 13, str, 2, 'ES'); if str <> '' then columns := strint(str); accept(13, 14, str, 2, 'ES'); if str <> '' then lines := strint(str); { line 15: laston } accept(13, 16, str, 5, 'E'); if str <> '' then time_today := strint(str); accept(13, 17, str, 5, 'E'); if str <> '' then time_total := strint(str); accept(13, 18, str, 5, 'E'); if str <> '' then lasthi := strint(str); accept(13, 19, str, 5, 'E'); if str <> '' then upload := strint(str); accept(13, 20, str, 5, 'E'); if str <> '' then download := strint(str) end end; begin { edit_user } get_name(ed_fn, ed_ln); key := pad(ed_ln, len_ln) + pad(ed_fn, len_fn); SearchKey(IdxF, i, key); if OK then begin if i = user_loc then temp_user_rec := user_rec else GetRec(DatF, i, temp_user_rec); if temp_user_rec.access <= user_rec.access { Only edit users <= self } then begin display_user; while ask('Edit this user') do begin change_user; display_user end; if i = user_loc then user_rec := temp_user_rec else PutRec(DatF, i, temp_user_rec) end end else writeln(USR, 'Name not found.') end; overlay procedure rebuild_index; { Rebuild the user index file from the data file. In addition, this routine will recover the data file from certain types of damage. } var i, previous_rec, count_used, count_unused: integer; key: StrName; temp_user_rec: user_list; temp: file; begin writeln(USR, 'Rebuilding user index file.'); writeln(USR, 'User data file in record order:'); CloseIndex(IdxF); Assign(temp, user_indx + ext); Erase(temp); InitIndex; MakeIndex(IdxF, user_indx + ext, len_ln + len_fn, 0); previous_rec := -1; count_used := 0; count_unused := 0; with temp_user_rec do begin for i := 1 to pred(FileLen(DatF)) do begin GetRec(DatF, i, temp_user_rec); if used = 0 then begin key := pad(ln, len_ln) + pad(fn, len_fn); AddKey(IdxF, i, key); if OK then begin count_used := succ(count_used); writeln(USR, i:4, ' ', used:4, ' ', fn, ' ', ln) end else begin used := previous_rec; { Can't use DeleteRec since } previous_rec := i; { we're playing with pointers } PutRec(DatF, i, temp_user_rec); count_unused := succ(count_unused); writeln(USR, i:4, ' ', used:4, ' Duplicate record deleted') end end else begin used := previous_rec; previous_rec := i; PutRec(DatF, i, temp_user_rec); count_unused := succ(count_unused); writeln(USR, i:4, ' ', used:4, ' Free record') end end end; GetRec(DatF, 0, temp_user_rec); DatF.FirstFree := previous_rec; DatF.NumberFree := count_unused; PutRec(DatF, 0, temp_user_rec); { Normally ROS only closes files between sessions to improve operational speed, but since essential data files have just been modified, they will be closed and reopened to ensure file integrity. } CloseFile(DatF); CloseIndex(IdxF); OpenFile(DatF, user_data + ext, SizeOf(user_rec)); OpenIndex(IdxF, user_indx + ext, len_ln + len_fn, 0); writeln(USR); writeln(USR, FileLen(DatF), ' records, ', UsedRecs(DatF), ' users in file.') end;