Rev 743 | Rev 745 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 743 | Rev 744 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | program OIDPLUS; |
1 | program OIDPLUS; |
2 | 2 | ||
3 | (************************************************) |
3 | (************************************************) |
4 | (* OIDPLUS.PAS *) |
4 | (* OIDPLUS.PAS *) |
5 | (* Author: Daniel Marschall *) |
5 | (* Author: Daniel Marschall *) |
6 | (* Revision: 2022-02-14 *) |
6 | (* Revision: 2022-02-15 *) |
7 | (* License: Apache 2.0 *) |
7 | (* License: Apache 2.0 *) |
8 | (* This file contains: *) |
8 | (* This file contains: *) |
9 | (* - "OIDplus for DOS" program *) |
9 | (* - "OIDplus for DOS" program *) |
10 | (************************************************) |
10 | (************************************************) |
11 | 11 | ||
Line 19... | Line 19... | ||
19 | 19 | ||
20 | uses |
20 | uses |
21 | Dos, Crt, StrList, VtsFuncs, VtsCui, OidFile, OidUtils; |
21 | Dos, Crt, StrList, VtsFuncs, VtsCui, OidFile, OidUtils; |
22 | 22 | ||
23 | const |
23 | const |
24 | VERSIONINFO = 'Revision: 2022-02-14'; |
24 | VERSIONINFO = 'Revision: 2022-02-15'; |
25 | DEFAULT_STATUSBAR = '(C)2020-2022 ViaThinkSoft. Licensed under the terms of the Apache 2.0 license.'; |
25 | DEFAULT_STATUSBAR = '(C)2020-2022 ViaThinkSoft. Licensed under the terms of the Apache 2.0 license.'; |
26 | TITLEBAR_LEFT_TEXT = 'OIDplus'; |
26 | TITLEBAR_LEFT_TEXT = 'OIDplus'; |
27 | DISKIO_SOUND_DEBUGGING = false; |
27 | DISKIO_SOUND_DEBUGGING = false; |
28 | DISKIO_SOUND_DELAY = 500; |
28 | DISKIO_SOUND_DELAY = 500; |
29 | ASNEDIT_LINES = 10; |
29 | ASNEDIT_LINES = 10; |
Line 34... | Line 34... | ||
34 | MAINMENU_HEIGHT = 3; |
34 | MAINMENU_HEIGHT = 3; |
35 | MAINMENU_ALLOW_ESC = false; |
35 | MAINMENU_ALLOW_ESC = false; |
36 | TREEVIEW_INDENT = 0; |
36 | TREEVIEW_INDENT = 0; |
37 | TREEVIEW_INCLUDE_DESC = true; |
37 | TREEVIEW_INCLUDE_DESC = true; |
38 | TREEVIEW_WIDTH = 80; |
38 | TREEVIEW_WIDTH = 80; |
- | 39 | OID_EXTENSION = '.OID'; |
|
- | 40 | TREEVIEW_FILENAME = 'OIDTREE.TXT'; |
|
39 | 41 | ||
40 | procedure _Pause; |
42 | procedure _Pause; |
41 | var |
43 | var |
42 | bakX, bakY: integer; |
44 | bakX, bakY: integer; |
43 | begin |
45 | begin |
Line 278... | Line 280... | ||
278 | iId: LongInt; |
280 | iId: LongInt; |
279 | sId: string; |
281 | sId: string; |
280 | begin |
282 | begin |
281 | (* Put all found files into a list *) |
283 | (* Put all found files into a list *) |
282 | CreateList(list); |
284 | CreateList(list); |
283 | FindFirst('????????.OID', Archive, DirInfo); |
285 | FindFirst(RepeatStr('?',8)+OID_EXTENSION, Archive, DirInfo); |
284 | while DosError = 0 do |
286 | while DosError = 0 do |
285 | begin |
287 | begin |
286 | sId := Copy(DirInfo.Name, 1, 8); |
288 | sId := Copy(DirInfo.Name, 1, 8); |
287 | ListAppend(list, sId); |
289 | ListAppend(list, sId); |
288 | FindNext(DirInfo); |
290 | FindNext(DirInfo); |
Line 387... | Line 389... | ||
387 | newOID^.Parent := oid^.FileId + oid^.DotNotation; |
389 | newOID^.Parent := oid^.FileId + oid^.DotNotation; |
388 | if NumIdEditor(newOID, oid) and |
390 | if NumIdEditor(newOID, oid) and |
389 | AsnEditor(newOID) and |
391 | AsnEditor(newOID) and |
390 | DescEditor(newOID) then |
392 | DescEditor(newOID) then |
391 | begin |
393 | begin |
392 | newfilename := newOID^.FileId + '.OID'; |
394 | newfilename := newOID^.FileId + OID_EXTENSION; |
393 | if _WriteOidFile(newfilename, newOID, true) then |
395 | if _WriteOidFile(newfilename, newOID, true) then |
394 | begin |
396 | begin |
395 | (* Add link to original file and enable the saving of it *) |
397 | (* Add link to original file and enable the saving of it *) |
396 | ListAppend(oid^.SubIds, newOID^.FileId + newOID^.DotNotation); |
398 | ListAppend(oid^.SubIds, newOID^.FileId + newOID^.DotNotation); |
397 | NewOidEditor := true; (* request caller to save <oid> *) |
399 | NewOidEditor := true; (* request caller to save <oid> *) |
Line 406... | Line 408... | ||
406 | childOID: POID; |
408 | childOID: POID; |
407 | filenameChild: string; |
409 | filenameChild: string; |
408 | begin |
410 | begin |
409 | for i := 0 to ListCount(oid^.SubIds)-1 do |
411 | for i := 0 to ListCount(oid^.SubIds)-1 do |
410 | begin |
412 | begin |
411 | filenameChild := FileIdPart(ListGetElement(oid^.SubIds, i)) + '.OID'; |
413 | filenameChild := FileIdPart(ListGetElement(oid^.SubIds, i)) + OID_EXTENSION; |
412 | if FileExists(filenameChild) then |
414 | if FileExists(filenameChild) then |
413 | begin |
415 | begin |
414 | CreateOidDef(childOID); |
416 | CreateOidDef(childOID); |
415 | if _ReadOidFile(filenameChild, childOID, false) then |
417 | if _ReadOidFile(filenameChild, childOID, false) and |
- | 418 | (childOID^.Parent = oid^.FileId + oid^.DotNotation) then |
|
416 | begin |
419 | begin |
417 | DeleteChildrenRecursive(childOID); |
420 | DeleteChildrenRecursive(childOID); |
418 | end; |
421 | end; |
419 | FreeOidDef(childOID); |
422 | FreeOidDef(childOID); |
420 | DeleteFile(filenameChild); |
423 | DeleteFile(filenameChild); |
Line 432... | Line 435... | ||
432 | (* Remove all children and their files recursively *) |
435 | (* Remove all children and their files recursively *) |
433 | DeleteChildrenRecursive(selfOID); |
436 | DeleteChildrenRecursive(selfOID); |
434 | 437 | ||
435 | (* Remove forward reference in parent OID *) |
438 | (* Remove forward reference in parent OID *) |
436 | (* (this is the most important part) *) |
439 | (* (this is the most important part) *) |
437 | filenameParent := FileIdPart(selfOID^.Parent) + '.OID'; |
440 | filenameParent := FileIdPart(selfOID^.Parent) + OID_EXTENSION; |
438 | if FileExists(filenameParent) then |
441 | if FileExists(filenameParent) then |
439 | begin |
442 | begin |
440 | CreateOidDef(parentOID); |
443 | CreateOidDef(parentOID); |
441 | if _ReadOidFile(filenameParent, parentOID, true) then |
444 | if _ReadOidFile(filenameParent, parentOID, true) then |
442 | begin |
445 | begin |
Line 447... | Line 450... | ||
447 | end; |
450 | end; |
448 | FreeOidDef(parentOID); |
451 | FreeOidDef(parentOID); |
449 | end; |
452 | end; |
450 | 453 | ||
451 | (* Delete own file *) |
454 | (* Delete own file *) |
452 | filenameSelf := selfOID^.FileId + '.OID'; |
455 | filenameSelf := selfOID^.FileId + OID_EXTENSION; |
453 | if FileExists(filenameSelf) then |
456 | if FileExists(filenameSelf) then |
454 | begin |
457 | begin |
455 | DeleteFile(filenameSelf); |
458 | DeleteFile(filenameSelf); |
456 | end; |
459 | end; |
457 | end; |
460 | end; |
Line 567... | Line 570... | ||
567 | end; |
570 | end; |
568 | end; |
571 | end; |
569 | 572 | ||
570 | (* Now prepare the menu entries *) |
573 | (* Now prepare the menu entries *) |
571 | 574 | ||
572 | CreateList(subsel); (* Contains the human readable OID name *) |
575 | CreateList(subsel); (* Contains the human-readable OID name *) |
573 | CreateList(subfiles); (* Contains the file name *) |
576 | CreateList(subfiles); (* Contains the file name *) |
574 | 577 | ||
575 | if oid^.Parent = '' then |
578 | if oid^.Parent = '' then |
576 | begin |
579 | begin |
577 | isRoot := true; |
580 | isRoot := true; |
Line 582... | Line 585... | ||
582 | end; |
585 | end; |
583 | 586 | ||
584 | if (oid^.Parent <> '') and not isRoot then |
587 | if (oid^.Parent <> '') and not isRoot then |
585 | begin |
588 | begin |
586 | sTmp := oid^.Parent; |
589 | sTmp := oid^.Parent; |
587 | subfile := FileIdPart(sTmp) + '.OID'; |
590 | subfile := FileIdPart(sTmp) + OID_EXTENSION; |
588 | if FileExists(subfile) then |
591 | if FileExists(subfile) then |
589 | begin |
592 | begin |
590 | CreateOidDef(tmpOID); |
593 | CreateOidDef(tmpOID); |
591 | if _ReadOidFile(subfile, tmpOID, true) then |
594 | if not _ReadOidFile(subfile, tmpOID, true) then |
592 | ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID)) |
- | |
593 | else |
595 | begin |
594 | ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + ' (READ ERROR)'); |
596 | ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + ' (READ ERROR)'); |
- | 597 | ListAppend(subfiles, 'ERROR: '+subfile+' Read error or file invalid'); |
|
- | 598 | end |
|
- | 599 | else |
|
- | 600 | begin |
|
- | 601 | ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID)); |
|
- | 602 | ListAppend(subfiles, subfile); |
|
- | 603 | end; |
|
595 | FreeOidDef(tmpOID); |
604 | FreeOidDef(tmpOID); |
596 | end |
605 | end |
597 | else |
606 | else |
598 | begin |
607 | begin |
599 | ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)'); |
608 | ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)'); |
- | 609 | ListAppend(subfiles, 'ERROR: File '+subfile+' was not found'); |
|
600 | end; |
610 | end; |
601 | ListAppend(subfiles, subfile); |
- | |
602 | end; |
611 | end; |
603 | 612 | ||
604 | if isRoot then |
613 | if isRoot then |
605 | begin |
614 | begin |
606 | menuIdExit := ListAppend(subsel, 'Back to main menu'); |
615 | menuIdExit := ListAppend(subsel, 'Back to main menu'); |
Line 609... | Line 618... | ||
609 | else menuIdExit := -99; |
618 | else menuIdExit := -99; |
610 | 619 | ||
611 | for i := 0 to ListCount(oid^.SubIds)-1 do |
620 | for i := 0 to ListCount(oid^.SubIds)-1 do |
612 | begin |
621 | begin |
613 | sTmp := ListGetElement(oid^.SubIds, i); |
622 | sTmp := ListGetElement(oid^.SubIds, i); |
614 | subfile := FileIdPart(sTmp) + '.OID'; |
623 | subfile := FileIdPart(sTmp) + OID_EXTENSION; |
615 | if FileExists(subfile) then |
624 | if FileExists(subfile) then |
616 | begin |
625 | begin |
617 | CreateOidDef(tmpOID); |
626 | CreateOidDef(tmpOID); |
618 | if _ReadOidFile(subfile, tmpOID, true) then |
627 | if not _ReadOidFile(subfile, tmpOID, true) then |
619 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID)) |
- | |
620 | else |
628 | begin |
621 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (READ ERROR)'); |
629 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (READ ERROR)'); |
- | 630 | ListAppend(subfiles, 'ERROR: Read error at file '+subfile+', or file is invalid.'); |
|
- | 631 | end |
|
- | 632 | else if tmpOID^.Parent <> oid^.FileId + oid^.DotNotation then |
|
- | 633 | begin |
|
- | 634 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (BAD BACKREF)'); |
|
- | 635 | ListAppend(subfiles, 'ERROR: File '+subfile+' has a wrong back-reference.'); |
|
- | 636 | end |
|
- | 637 | else |
|
- | 638 | begin |
|
- | 639 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID)); |
|
- | 640 | ListAppend(subfiles, subfile); |
|
- | 641 | end; |
|
622 | FreeOidDef(tmpOID); |
642 | FreeOidDef(tmpOID); |
623 | end |
643 | end |
624 | else |
644 | else |
625 | begin |
645 | begin |
626 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)'); |
646 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)'); |
- | 647 | ListAppend(subfiles, 'ERROR: File '+subfile+' was not found'); |
|
627 | end; |
648 | end; |
628 | ListAppend(subfiles, subfile); |
- | |
629 | end; |
649 | end; |
630 | 650 | ||
631 | if oid^.DotNotation <> '' then |
651 | if oid^.DotNotation <> '' then |
632 | begin |
652 | begin |
633 | menuIdAsnEdit := ListAppend(subsel, 'Edit ASN.1 identifiers'); |
653 | menuIdAsnEdit := ListAppend(subsel, 'Edit ASN.1 identifiers'); |
Line 681... | Line 701... | ||
681 | end |
701 | end |
682 | else if subselres = menuIdDelete then |
702 | else if subselres = menuIdDelete then |
683 | begin |
703 | begin |
684 | if _DeleteConfirmation then |
704 | if _DeleteConfirmation then |
685 | begin |
705 | begin |
686 | sTmp := FileIdPart(oid^.Parent) + '.OID'; |
706 | sTmp := FileIdPart(oid^.Parent) + OID_EXTENSION; |
687 | DeleteOidRecursive(oid); |
707 | DeleteOidRecursive(oid); |
688 | if FileExists(sTmp) then |
708 | if FileExists(sTmp) then |
689 | begin |
709 | begin |
690 | filename := sTmp; |
710 | filename := sTmp; |
691 | end |
711 | end |
692 | else |
712 | else |
693 | begin |
713 | begin |
694 | ShowMessage('Parent file ' + sTmp + ' not found', 'ERROR', true); |
714 | ShowMessage('Parent file ' + sTmp + ' was not found', 'ERROR', true); |
695 | _Pause; |
715 | _Pause; |
696 | exitRequest := true; |
716 | exitRequest := true; |
697 | end; |
717 | end; |
698 | end; |
718 | end; |
699 | end |
719 | end |
Line 702... | Line 722... | ||
702 | exitRequest := true; |
722 | exitRequest := true; |
703 | end |
723 | end |
704 | else |
724 | else |
705 | begin |
725 | begin |
706 | (* Normal OID *) |
726 | (* Normal OID *) |
- | 727 | (* Above we already checked if the files are valild and existing *) |
|
707 | sTmp := ListGetElement(subfiles, subselres); |
728 | sTmp := ListGetElement(subfiles, subselres); |
708 | if FileExists(sTmp) then |
729 | if Copy(sTmp, 1, Length('ERROR: ')) = 'ERROR: ' then |
709 | begin |
730 | begin |
- | 731 | Delete(sTmp, 1, Length('ERROR: ')); |
|
- | 732 | ShowMessage(sTmp, 'ERROR', true); |
|
710 | filename := sTmp; |
733 | _Pause; |
711 | end |
734 | end |
712 | else |
735 | else |
713 | begin |
736 | begin |
714 | ShowMessage('File ' + sTmp + ' not found', 'ERROR', true); |
- | |
715 | _Pause; |
737 | filename := sTmp; |
716 | end; |
738 | end; |
717 | end; |
739 | end; |
718 | FreeList(subsel); |
740 | FreeList(subsel); |
719 | FreeList(subfiles); |
741 | FreeList(subfiles); |
720 | 742 | ||
Line 742... | Line 764... | ||
742 | 764 | ||
743 | function _GetRootFile(ShowErrorMessage: boolean): string; |
765 | function _GetRootFile(ShowErrorMessage: boolean): string; |
744 | var |
766 | var |
745 | rootFile: string; |
767 | rootFile: string; |
746 | begin |
768 | begin |
747 | rootFile := ZeroPad(0, 8) + '.OID'; |
769 | rootFile := ZeroPad(0, 8) + OID_EXTENSION; |
748 | _GetRootFile := rootFile; |
770 | _GetRootFile := rootFile; |
749 | if not FileExists(rootFile) then |
771 | if not FileExists(rootFile) then |
750 | begin |
772 | begin |
751 | if not CreateRootOIDFile(rootFile, ShowErrorMessage) then |
773 | if not CreateRootOIDFile(rootFile, ShowErrorMessage) then |
752 | begin |
774 | begin |
Line 809... | Line 831... | ||
809 | end; |
831 | end; |
810 | for i := 1 to Length(sTmp) do |
832 | for i := 1 to Length(sTmp) do |
811 | begin |
833 | begin |
812 | if (sTmp[i]=#13) or (sTmp[i]=#10) then sTmp[i] := ' '; |
834 | if (sTmp[i]=#13) or (sTmp[i]=#10) then sTmp[i] := ' '; |
813 | end; |
835 | end; |
814 | if Length(sTmp) > TREEVIEW_WIDTH then |
- | |
815 | begin |
- | |
816 | sTmp := Copy(sTmp, 1, TREEVIEW_WIDTH-3) + '...'; |
836 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
817 | end; |
- | |
818 | _GetTreeViewLine := sTmp; |
837 | _GetTreeViewLine := sTmp; |
819 | end; |
838 | end; |
820 | 839 | ||
821 | procedure _RecTreeExport(oid: POID; var F: Text; indent: integer); |
840 | procedure _RecTreeExport(oid: POID; var F: Text; indent: integer); |
822 | var |
841 | var |
Line 832... | Line 851... | ||
832 | (* Recursively call children *) |
851 | (* Recursively call children *) |
833 | for i := 0 to ListCount(oid^.SubIds)-1 do |
852 | for i := 0 to ListCount(oid^.SubIds)-1 do |
834 | begin |
853 | begin |
835 | sTmp := ListGetElement(oid^.SubIds, i); |
854 | sTmp := ListGetElement(oid^.SubIds, i); |
836 | CreateOidDef(suboid); |
855 | CreateOidDef(suboid); |
837 | childFilename := FileIdPart(sTmp) + '.OID'; |
856 | childFilename := FileIdPart(sTmp) + OID_EXTENSION; |
838 | if not FileExists(childFilename) then |
857 | if not FileExists(childFilename) then |
839 | begin |
858 | begin |
840 | sTmp := 'ERROR: ' + childFilename + ' FILE MISSING (CONTAINS ' + DotNotationPart(sTmp) + ')!'; |
859 | sTmp := 'ERROR: MISSING ' + childFilename + ' (SHALL CONTAIN ' + DotNotationPart(sTmp) + ')!'; |
841 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
860 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
842 | WriteLn(F, sTmp); |
861 | WriteLn(F, sTmp); |
843 | end |
862 | end |
844 | else if not _ReadOidFile(childFilename, suboid, false) then |
863 | else if not _ReadOidFile(childFilename, suboid, false) then |
845 | begin |
864 | begin |
846 | sTmp := 'ERROR: ' + childFilename + ' READ ERROR (CONTAINS ' + DotNotationPart(sTmp) + ')!'; |
865 | sTmp := 'ERROR: READ ERROR AT ' + childFilename + ' (SHALL CONTAIN ' + DotNotationPart(sTmp) + ')!'; |
- | 866 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
|
- | 867 | WriteLn(F, sTmp); |
|
- | 868 | end |
|
- | 869 | else if suboid^.Parent <> oid^.FileId + oid^.DotNotation then |
|
- | 870 | begin |
|
- | 871 | (* This can happen if a file is missing, and then another OID gets this filename since the number seems to be free *) |
|
- | 872 | sTmp := 'ERROR: BAD BACKREF AT ' + childFilename + ' (SHALL CONTAIN ' + DotNotationPart(sTmp) + ')!'; |
|
847 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
873 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
848 | WriteLn(F, sTmp); |
874 | WriteLn(F, sTmp); |
849 | end |
875 | end |
850 | else |
876 | else |
851 | begin |
877 | begin |
Line 872... | Line 898... | ||
872 | begin |
898 | begin |
873 | DrawStatusBar(DEFAULT_STATUSBAR); |
899 | DrawStatusBar(DEFAULT_STATUSBAR); |
874 | Exit; |
900 | Exit; |
875 | end; |
901 | end; |
876 | 902 | ||
877 | Assign(F, 'OIDTREE.TXT'); |
903 | Assign(F, TREEVIEW_FILENAME); |
878 | {$I-} |
904 | {$I-} |
879 | Rewrite(F); |
905 | Rewrite(F); |
880 | {$I+} |
906 | {$I+} |
881 | if IoResult <> 0 then |
907 | if IoResult <> 0 then |
882 | begin |
908 | begin |
883 | (* Can happen if disk is read-only (Runtime Error 150) *) |
909 | (* Can happen if disk is read-only (Runtime Error 150) *) |
884 | ShowMessage('Cannot open OIDTREE.TXT for writing.', 'ERROR', true); |
910 | ShowMessage('Cannot open '+TREEVIEW_FILENAME+' for writing.', 'ERROR', true); |
885 | _Pause; |
911 | _Pause; |
886 | DrawStatusBar(DEFAULT_STATUSBAR); |
912 | DrawStatusBar(DEFAULT_STATUSBAR); |
887 | Exit; |
913 | Exit; |
888 | end; |
914 | end; |
889 | 915 | ||
Line 899... | Line 925... | ||
899 | Close(F); |
925 | Close(F); |
900 | 926 | ||
901 | DrawStatusBar(DEFAULT_STATUSBAR); |
927 | DrawStatusBar(DEFAULT_STATUSBAR); |
902 | if res then |
928 | if res then |
903 | begin |
929 | begin |
904 | ShowMessage('TreeView successfully exported as OIDTREE.TXT', 'TREEVIEW EXPORT', true); |
930 | ShowMessage('TreeView successfully exported as '+TREEVIEW_FILENAME, 'TREEVIEW EXPORT', true); |
905 | _Pause; |
931 | _Pause; |
906 | end; |
932 | end; |
907 | end; |
933 | end; |
908 | 934 | ||
909 | procedure OP_MainMenu; |
935 | procedure OP_MainMenu; |