Rev 741 | Rev 743 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 741 | Rev 742 | ||
---|---|---|---|
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-14 *) |
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 | ||
12 | (* IMPORTANT: *) |
12 | (* IMPORTANT: *) |
13 | (* When you compile this code with Turbo Pascal 7.01, *) |
13 | (* When you compile this code with Turbo Pascal 7.01, *) |
14 | (* it won't run on fast PCs (Runtime Error 200). *) |
14 | (* it won't run on fast PCs (Runtime Error 200). *) |
15 | (* The built EXE file needs to be patched. *) |
15 | (* The built EXE file needs to be patched. *) |
16 | (* The program "PatchCRT" by Kennedy Software *) |
16 | (* The program "PatchCRT" by Kennedy Software *) |
17 | (* WON'T work because it somehow breaks our "_Pause" function. *) |
17 | (* WON'T work because it somehow breaks our "_Pause" function. *) |
18 | (* Instead, use the tool "TPPATCH" by Andreas Bauer. *) |
18 | (* Instead, use the tool "TPPATCH" by Andreas Bauer. *) |
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-14'; |
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; |
30 | DESCEDIT_LINES = 10; |
30 | DESCEDIT_LINES = 10; |
31 | DESCEDIT_PADDING = 3; |
31 | DESCEDIT_PADDING = 3; |
32 | ACTIONMENU_SIZE = 5; |
32 | ACTIONMENU_SIZE = 5; |
33 | MAINMENU_WIDTH = 15; |
33 | MAINMENU_WIDTH = 15; |
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 | 39 | ||
40 | procedure _WriteOidFile(filename: string; oid: POid); |
40 | procedure _WriteOidFile(filename: string; oid: POid); |
41 | begin |
41 | begin |
42 | DrawStatusBar('Write file ' + filename + '...'); |
42 | DrawStatusBar('Write file ' + filename + '...'); |
43 | WriteOidFile(filename, oid); |
43 | WriteOidFile(filename, oid); |
44 | 44 | ||
45 | if DISKIO_SOUND_DEBUGGING then |
45 | if DISKIO_SOUND_DEBUGGING then |
46 | begin |
46 | begin |
47 | Sound(70); |
47 | Sound(70); |
48 | Delay(DISKIO_SOUND_DELAY - 10); |
48 | Delay(DISKIO_SOUND_DELAY - 10); |
49 | NoSound; |
49 | NoSound; |
50 | Delay(10); |
50 | Delay(10); |
51 | end; |
51 | end; |
52 | 52 | ||
53 | DrawStatusBar(DEFAULT_STATUSBAR); |
53 | DrawStatusBar(DEFAULT_STATUSBAR); |
54 | end; |
54 | end; |
55 | 55 | ||
56 | procedure _ReadOidFile(filename: string; oid: POid); |
56 | procedure _ReadOidFile(filename: string; oid: POid); |
57 | begin |
57 | begin |
58 | DrawStatusBar('Read file ' + filename + '...'); |
58 | DrawStatusBar('Read file ' + filename + '...'); |
59 | ReadOidFile(filename, oid); |
59 | ReadOidFile(filename, oid); |
60 | 60 | ||
61 | if DISKIO_SOUND_DEBUGGING then |
61 | if DISKIO_SOUND_DEBUGGING then |
62 | begin |
62 | begin |
63 | Sound(50); |
63 | Sound(50); |
64 | Delay(DISKIO_SOUND_DELAY - 10); |
64 | Delay(DISKIO_SOUND_DELAY - 10); |
65 | NoSound; |
65 | NoSound; |
66 | Delay(10); |
66 | Delay(10); |
67 | end; |
67 | end; |
68 | 68 | ||
69 | DrawStatusBar(DEFAULT_STATUSBAR); |
69 | DrawStatusBar(DEFAULT_STATUSBAR); |
70 | end; |
70 | end; |
71 | 71 | ||
72 | procedure _Pause; |
72 | procedure _Pause; |
73 | var |
73 | var |
74 | bakX, bakY: integer; |
74 | bakX, bakY: integer; |
75 | begin |
75 | begin |
76 | bakX := WhereX; |
76 | bakX := WhereX; |
77 | bakY := WhereY; |
77 | bakY := WhereY; |
78 | DrawStatusBar('Press any key to continue'); |
78 | DrawStatusBar('Press any key to continue'); |
79 | GoToXY(bakX, bakY); |
79 | GoToXY(bakX, bakY); |
80 | ReadKey; |
80 | ReadKey; |
81 | DrawStatusBar(DEFAULT_STATUSBAR); |
81 | DrawStatusBar(DEFAULT_STATUSBAR); |
82 | end; |
82 | end; |
83 | 83 | ||
84 | function _ShowASNIds(childOID: POID): string; |
84 | function _ShowASNIds(childOID: POID): string; |
85 | var |
85 | var |
86 | j, jmax: integer; |
86 | j, jmax: integer; |
87 | sTmp: string; |
87 | sTmp: string; |
88 | begin |
88 | begin |
89 | sTmp := ''; |
89 | sTmp := ''; |
90 | jmax := ListCount(childOID^.ASNIds)-1; |
90 | jmax := ListCount(childOID^.ASNIds)-1; |
91 | for j := 0 to jmax do |
91 | for j := 0 to jmax do |
92 | begin |
92 | begin |
93 | if j = 0 then sTmp := sTmp + ' ('; |
93 | if j = 0 then sTmp := sTmp + ' ('; |
94 | sTmp := sTmp + ListGetElement(childOID^.ASNIds, j); |
94 | sTmp := sTmp + ListGetElement(childOID^.ASNIds, j); |
95 | if j = jmax then |
95 | if j = jmax then |
96 | sTmp := sTmp + ')' |
96 | sTmp := sTmp + ')' |
97 | else |
97 | else |
98 | sTmp := sTmp + ', '; |
98 | sTmp := sTmp + ', '; |
99 | end; |
99 | end; |
100 | _ShowASNIds := sTmp; |
100 | _ShowASNIds := sTmp; |
101 | end; |
101 | end; |
102 | 102 | ||
103 | function AsnAlreadyExisting(oid: POID; asnid: string): boolean; |
103 | function AsnAlreadyExisting(oid: POID; asnid: string): boolean; |
104 | begin |
104 | begin |
105 | AsnAlreadyExisting := ListContains(oid^.AsnIds, asnid); |
105 | AsnAlreadyExisting := ListContains(oid^.AsnIds, asnid); |
106 | end; |
106 | end; |
107 | 107 | ||
108 | function AsnEditor(oid: POID): boolean; |
108 | function AsnEditor(oid: POID): boolean; |
109 | var |
109 | var |
110 | asnList: PStringList; |
110 | asnList: PStringList; |
111 | i: integer; |
111 | i: integer; |
112 | x, y, w, h: integer; |
112 | x, y, w, h: integer; |
113 | res: integer; |
113 | res: integer; |
114 | sInput: string; |
114 | sInput: string; |
115 | menuIdNew, menuIdSave, menuIdExit: integer; |
115 | menuIdNew, menuIdSave, menuIdExit: integer; |
116 | begin |
116 | begin |
117 | AsnEditor := false; |
117 | AsnEditor := false; |
118 | 118 | ||
119 | repeat |
119 | repeat |
120 | CreateList(asnList); |
120 | CreateList(asnList); |
121 | 121 | ||
122 | for i := 0 to ListCount(oid^.ASNIds)-1 do |
122 | for i := 0 to ListCount(oid^.ASNIds)-1 do |
123 | begin |
123 | begin |
124 | ListAppend(asnList, ListGetElement(oid^.ASNIDs, i)); |
124 | ListAppend(asnList, ListGetElement(oid^.ASNIDs, i)); |
125 | end; |
125 | end; |
126 | menuIdNew := ListAppend(asnList, '<NEW>'); |
126 | menuIdNew := ListAppend(asnList, '<NEW>'); |
127 | menuIdSave := ListAppend(asnList, '<SAVE>'); |
127 | menuIdSave := ListAppend(asnList, '<SAVE>'); |
128 | menuIdExit := ListAppend(asnList, '<CANCEL>'); |
128 | menuIdExit := ListAppend(asnList, '<CANCEL>'); |
129 | 129 | ||
130 | DrawStatusBar(DEFAULT_STATUSBAR); |
130 | DrawStatusBar(DEFAULT_STATUSBAR); |
131 | x := SINGLE_LINE_BOX_PADDING; |
131 | x := SINGLE_LINE_BOX_PADDING; |
132 | y := ScreenHeight div 2 - ASNEDIT_LINES div 2; |
132 | y := ScreenHeight div 2 - ASNEDIT_LINES div 2; |
133 | w := ScreenWidth - (SINGLE_LINE_BOX_PADDING-1)*2; |
133 | w := ScreenWidth - (SINGLE_LINE_BOX_PADDING-1)*2; |
134 | h := ASNEDIT_LINES; |
134 | h := ASNEDIT_LINES; |
135 | res := DrawSelectionList(x, y, w, h, |
135 | res := DrawSelectionList(x, y, w, h, |
136 | asnList, true, |
136 | asnList, true, |
137 | 'EDIT ASN.1 IDENTIFIERS', |
137 | 'EDIT ASN.1 IDENTIFIERS', |
138 | 2); |
138 | 2); |
139 | FreeList(asnList); |
139 | FreeList(asnList); |
140 | 140 | ||
141 | (* Change double-border to thin-border *) |
141 | (* Change double-border to thin-border *) |
142 | DrawThinBorder(x-1, y-1, w+2, h+2); |
142 | DrawThinBorder(x-1, y-1, w+2, h+2); |
143 | GoToXY(x+1, y-1); |
143 | GoToXY(x+1, y-1); |
144 | Write('EDIT ASN.1 IDENTIFIERS'); |
144 | Write('EDIT ASN.1 IDENTIFIERS'); |
145 | 145 | ||
146 | if res = -1 then |
146 | if res = -1 then |
147 | begin |
147 | begin |
148 | exit; |
148 | exit; |
149 | end |
149 | end |
150 | else if res = menuIdNew then |
150 | else if res = menuIdNew then |
151 | begin |
151 | begin |
152 | (* "NEW" item was selected *) |
152 | (* "NEW" item was selected *) |
153 | sInput := ''; |
153 | sInput := ''; |
154 | repeat |
154 | repeat |
155 | if QueryVal(sInput, |
155 | if QueryVal(sInput, |
156 | SINGLE_LINE_BOX_PADDING_INNER, |
156 | SINGLE_LINE_BOX_PADDING_INNER, |
157 | ScreenHeight div 2, |
157 | ScreenHeight div 2, |
158 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
158 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
159 | 1, |
159 | 1, |
160 | 'ADD SINGLE ASN.1 ID', |
160 | 'ADD SINGLE ASN.1 ID', |
161 | 2) then |
161 | 2) then |
162 | begin |
162 | begin |
163 | if sInput = '' then continue; |
163 | if sInput = '' then continue; |
164 | if not ASN1IDValid(sInput) then |
164 | if not ASN1IDValid(sInput) then |
165 | begin |
165 | begin |
166 | ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true); |
166 | ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true); |
167 | _Pause; |
167 | _Pause; |
168 | end |
168 | end |
169 | else if AsnAlreadyExisting(oid, sInput) then |
169 | else if AsnAlreadyExisting(oid, sInput) then |
170 | begin |
170 | begin |
171 | ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true); |
171 | ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true); |
172 | _Pause; |
172 | _Pause; |
173 | end |
173 | end |
174 | else |
174 | else |
175 | begin |
175 | begin |
176 | ListAppend(oid^.ASNIDs, sInput); |
176 | ListAppend(oid^.ASNIDs, sInput); |
177 | break; |
177 | break; |
178 | end; |
178 | end; |
179 | end |
179 | end |
180 | else break; |
180 | else break; |
181 | until false; |
181 | until false; |
182 | end |
182 | end |
183 | else if res = menuIdSave then |
183 | else if res = menuIdSave then |
184 | begin |
184 | begin |
185 | (* "SAVE" item was selected *) |
185 | (* "SAVE" item was selected *) |
186 | AsnEditor := true; |
186 | AsnEditor := true; |
187 | Exit; |
187 | Exit; |
188 | end |
188 | end |
189 | else if res = menuIdExit then |
189 | else if res = menuIdExit then |
190 | begin |
190 | begin |
191 | (* "CANCEL" item was selected *) |
191 | (* "CANCEL" item was selected *) |
192 | AsnEditor := false; |
192 | AsnEditor := false; |
193 | Exit; |
193 | Exit; |
194 | end |
194 | end |
195 | else |
195 | else |
196 | begin |
196 | begin |
197 | DrawStatusBar('Note: Remove the text to delete the ASN.1 identifier'); |
197 | DrawStatusBar('Note: Remove the text to delete the ASN.1 identifier'); |
198 | sInput := ListGetElement(oid^.ASNIDs, res); |
198 | sInput := ListGetElement(oid^.ASNIDs, res); |
199 | repeat |
199 | repeat |
200 | if QueryVal(sInput, |
200 | if QueryVal(sInput, |
201 | SINGLE_LINE_BOX_PADDING_INNER, |
201 | SINGLE_LINE_BOX_PADDING_INNER, |
202 | ScreenHeight div 2, |
202 | ScreenHeight div 2, |
203 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
203 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
204 | 1, |
204 | 1, |
205 | 'EDIT SINGLE ASN.1 ID', |
205 | 'EDIT SINGLE ASN.1 ID', |
206 | 2) then |
206 | 2) then |
207 | begin |
207 | begin |
208 | if sInput = '' then |
208 | if sInput = '' then |
209 | begin |
209 | begin |
210 | (* Empty input = Delete ASN.1 ID *) |
210 | (* Empty input = Delete ASN.1 ID *) |
211 | ListDeleteElementByIndex(oid^.ASNIDs, res); |
211 | ListDeleteElementByIndex(oid^.ASNIDs, res); |
212 | break; |
212 | break; |
213 | end |
213 | end |
214 | else if not ASN1IDValid(sInput) then |
214 | else if not ASN1IDValid(sInput) then |
215 | begin |
215 | begin |
216 | ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true); |
216 | ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true); |
217 | _Pause; |
217 | _Pause; |
218 | end |
218 | end |
219 | else if AsnAlreadyExisting(oid, sInput) and |
219 | else if AsnAlreadyExisting(oid, sInput) and |
220 | not (ListGetElement(oid^.ASNIDs, res) = sInput) then |
220 | not (ListGetElement(oid^.ASNIDs, res) = sInput) then |
221 | begin |
221 | begin |
222 | ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true); |
222 | ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true); |
223 | _Pause; |
223 | _Pause; |
224 | end |
224 | end |
225 | else |
225 | else |
226 | begin |
226 | begin |
227 | ListSetElement(oid^.ASNIDs, res, sInput); |
227 | ListSetElement(oid^.ASNIDs, res, sInput); |
228 | break; |
228 | break; |
229 | end; |
229 | end; |
230 | end |
230 | end |
231 | else break; |
231 | else break; |
232 | until false; |
232 | until false; |
233 | end; |
233 | end; |
234 | until false; |
234 | until false; |
235 | end; |
235 | end; |
236 | 236 | ||
237 | function DescEditor(oid: POID): boolean; |
237 | function DescEditor(oid: POID): boolean; |
238 | var |
238 | var |
239 | sInput: string; |
239 | sInput: string; |
240 | begin |
240 | begin |
241 | DescEditor := false; |
241 | DescEditor := false; |
242 | 242 | ||
243 | DrawStatusBar('Note: Press Ctrl+Return for a line-break.'); |
243 | DrawStatusBar('Note: Press Ctrl+Return for a line-break.'); |
244 | sInput := oid^.description; |
244 | sInput := oid^.description; |
245 | if QueryVal(sInput, |
245 | if QueryVal(sInput, |
246 | DESCEDIT_PADDING, |
246 | DESCEDIT_PADDING, |
247 | ScreenHeight div 2 - DESCEDIT_LINES div 2, |
247 | ScreenHeight div 2 - DESCEDIT_LINES div 2, |
248 | ScreenWidth - (DESCEDIT_PADDING-1)*2, |
248 | ScreenWidth - (DESCEDIT_PADDING-1)*2, |
249 | DESCEDIT_LINES, |
249 | DESCEDIT_LINES, |
250 | 'EDIT DESCRIPTION', |
250 | 'EDIT DESCRIPTION', |
251 | 2) then |
251 | 2) then |
252 | begin |
252 | begin |
253 | oid^.description := sInput; |
253 | oid^.description := sInput; |
254 | DescEditor := true; (* request caller to save <oid> *) |
254 | DescEditor := true; (* request caller to save <oid> *) |
255 | end; |
255 | end; |
256 | end; |
256 | end; |
257 | 257 | ||
258 | function NextPossibleFileID: string; |
258 | function NextPossibleFileID: string; |
259 | var |
259 | var |
260 | DirInfo: SearchRec; |
260 | DirInfo: SearchRec; |
261 | list: PStringList; |
261 | list: PStringList; |
262 | iId: LongInt; |
262 | iId: LongInt; |
263 | sId: string; |
263 | sId: string; |
264 | begin |
264 | begin |
265 | (* Put all found files into a list *) |
265 | (* Put all found files into a list *) |
266 | CreateList(list); |
266 | CreateList(list); |
267 | FindFirst('????????.OID', Archive, DirInfo); |
267 | FindFirst('????????.OID', Archive, DirInfo); |
268 | while DosError = 0 do |
268 | while DosError = 0 do |
269 | begin |
269 | begin |
270 | sId := Copy(DirInfo.Name, 1, 8); |
270 | sId := Copy(DirInfo.Name, 1, 8); |
271 | ListAppend(list, sId); |
271 | ListAppend(list, sId); |
272 | FindNext(DirInfo); |
272 | FindNext(DirInfo); |
273 | end; |
273 | end; |
274 | 274 | ||
275 | (* Search for the first non existing item in the list *) |
275 | (* Search for the first non existing item in the list *) |
276 | sId := ''; |
276 | sId := ''; |
277 | for iId := 0 to 99999999 do |
277 | for iId := 0 to 99999999 do |
278 | begin |
278 | begin |
279 | sId := ZeroPad(iId, 8); |
279 | sId := ZeroPad(iId, 8); |
280 | if not ListContains(list, sId) then break; |
280 | if not ListContains(list, sId) then break; |
281 | end; |
281 | end; |
282 | NextPossibleFileId := sId; |
282 | NextPossibleFileId := sId; |
283 | FreeList(list); |
283 | FreeList(list); |
284 | end; |
284 | end; |
285 | 285 | ||
286 | function NumIdAlreadyExisting(parentOID: POID; sInput: string): boolean; |
286 | function NumIdAlreadyExisting(parentOID: POID; sInput: string): boolean; |
287 | var |
287 | var |
288 | searchDotNotation: string; |
288 | searchDotNotation: string; |
289 | sTmp: string; |
289 | sTmp: string; |
290 | i: integer; |
290 | i: integer; |
291 | begin |
291 | begin |
292 | if parentOID^.DotNotation = '' then |
292 | if parentOID^.DotNotation = '' then |
293 | searchDotNotation := sInput |
293 | searchDotNotation := sInput |
294 | else |
294 | else |
295 | searchDotNotation := parentOID^.DotNotation + '.' + sInput; |
295 | searchDotNotation := parentOID^.DotNotation + '.' + sInput; |
296 | for i := 0 to ListCount(parentOID^.SubIds)-1 do |
296 | for i := 0 to ListCount(parentOID^.SubIds)-1 do |
297 | begin |
297 | begin |
298 | sTmp := ListGetElement(parentOID^.SubIds, i); |
298 | sTmp := ListGetElement(parentOID^.SubIds, i); |
299 | if DotNotationPart(sTmp) = searchDotNotation then |
299 | if DotNotationPart(sTmp) = searchDotNotation then |
300 | begin |
300 | begin |
301 | NumIdAlreadyExisting := true; |
301 | NumIdAlreadyExisting := true; |
302 | exit; |
302 | exit; |
303 | end; |
303 | end; |
304 | end; |
304 | end; |
305 | NumIdAlreadyExisting := false; |
305 | NumIdAlreadyExisting := false; |
306 | end; |
306 | end; |
307 | 307 | ||
308 | function NumIdEditor(oid: POID; parentOID: POID): boolean; |
308 | function NumIdEditor(oid: POID; parentOID: POID): boolean; |
309 | var |
309 | var |
310 | sInput: string; |
310 | sInput: string; |
311 | begin |
311 | begin |
312 | NumIdEditor := false; |
312 | NumIdEditor := false; |
313 | sInput := ''; |
313 | sInput := ''; |
314 | 314 | ||
315 | repeat |
315 | repeat |
316 | if QueryVal(sInput, |
316 | if QueryVal(sInput, |
317 | SINGLE_LINE_BOX_PADDING_INNER, |
317 | SINGLE_LINE_BOX_PADDING_INNER, |
318 | ScreenHeight div 2, |
318 | ScreenHeight div 2, |
319 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
319 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
320 | 1, |
320 | 1, |
321 | 'ENTER NUMERIC ID', |
321 | 'ENTER NUMERIC ID', |
322 | 2) then |
322 | 2) then |
323 | begin |
323 | begin |
324 | if sInput = '' then continue; |
324 | if sInput = '' then continue; |
325 | if not IsPositiveInteger(sInput) then |
325 | if not IsPositiveInteger(sInput) then |
326 | begin |
326 | begin |
327 | ShowMessage('Invalid numeric ID (must be a positive integer)', 'ERROR', true); |
327 | ShowMessage('Invalid numeric ID (must be a positive integer)', 'ERROR', true); |
328 | _Pause; |
328 | _Pause; |
329 | end |
329 | end |
330 | else if (parentOID^.DotNotation='') and (StrToInt(sInput) > 2) then |
330 | else if (parentOID^.DotNotation='') and (StrToInt(sInput) > 2) then |
331 | begin |
331 | begin |
332 | ShowMessage('Invalid numeric ID (root arc can only be 0, 1, or 2)', 'ERROR', true); |
332 | ShowMessage('Invalid numeric ID (root arc can only be 0, 1, or 2)', 'ERROR', true); |
333 | _Pause; |
333 | _Pause; |
334 | end |
334 | end |
335 | else if ((parentOID^.DotNotation='0') or (parentOID^.DotNotation='1')) and (StrToInt(sInput) > 39) then |
335 | else if ((parentOID^.DotNotation='0') or (parentOID^.DotNotation='1')) and (StrToInt(sInput) > 39) then |
336 | begin |
336 | begin |
337 | ShowMessage('Invalid numeric ID (root 0 and 1 must have sub-arc of 0..39)', 'ERROR', true); |
337 | ShowMessage('Invalid numeric ID (root 0 and 1 must have sub-arc of 0..39)', 'ERROR', true); |
338 | _Pause; |
338 | _Pause; |
339 | end |
339 | end |
340 | else if NumIdAlreadyExisting(parentOID, sInput) then |
340 | else if NumIdAlreadyExisting(parentOID, sInput) then |
341 | begin |
341 | begin |
342 | ShowMessage('This numeric ID is already used in this arc', 'ERROR', true); |
342 | ShowMessage('This numeric ID is already used in this arc', 'ERROR', true); |
343 | _Pause; |
343 | _Pause; |
344 | end |
344 | end |
345 | else |
345 | else |
346 | begin |
346 | begin |
347 | if parentOID^.DotNotation = '' then |
347 | if parentOID^.DotNotation = '' then |
348 | oid^.DotNotation := sInput |
348 | oid^.DotNotation := sInput |
349 | else |
349 | else |
350 | oid^.DotNotation := parentOID^.DotNotation + '.' + sInput; |
350 | oid^.DotNotation := parentOID^.DotNotation + '.' + sInput; |
351 | NumIdEditor := true; (* request caller to save <oid> *) |
351 | NumIdEditor := true; (* request caller to save <oid> *) |
352 | Exit; |
352 | Exit; |
353 | end; |
353 | end; |
354 | end |
354 | end |
355 | else |
355 | else |
356 | begin |
356 | begin |
357 | Exit; |
357 | Exit; |
358 | end; |
358 | end; |
359 | until false; |
359 | until false; |
360 | end; |
360 | end; |
361 | 361 | ||
362 | function NewOidEditor(oid: POID): boolean; |
362 | function NewOidEditor(oid: POID): boolean; |
363 | var |
363 | var |
364 | newfilename: string; |
364 | newfilename: string; |
365 | newOID: POID; |
365 | newOID: POID; |
366 | begin |
366 | begin |
367 | NewOidEditor := false; |
367 | NewOidEditor := false; |
368 | 368 | ||
369 | CreateOidDef(newOID); |
369 | CreateOidDef(newOID); |
370 | newOID^.FileId := NextPossibleFileID; |
370 | newOID^.FileId := NextPossibleFileID; |
371 | newOID^.Parent := oid^.FileId + oid^.DotNotation; |
371 | newOID^.Parent := oid^.FileId + oid^.DotNotation; |
372 | if NumIdEditor(newOID, oid) and |
372 | if NumIdEditor(newOID, oid) and |
373 | AsnEditor(newOID) and |
373 | AsnEditor(newOID) and |
374 | DescEditor(newOID) then |
374 | DescEditor(newOID) then |
375 | begin |
375 | begin |
376 | newfilename := newOID^.FileId + '.OID'; |
376 | newfilename := newOID^.FileId + '.OID'; |
377 | _WriteOidFile(newfilename, newOID); |
377 | _WriteOidFile(newfilename, newOID); |
378 | 378 | ||
379 | (* Add link to original file and enable the saving of it *) |
379 | (* Add link to original file and enable the saving of it *) |
380 | ListAppend(oid^.SubIds, newOID^.FileId + newOID^.DotNotation); |
380 | ListAppend(oid^.SubIds, newOID^.FileId + newOID^.DotNotation); |
381 | NewOidEditor := true; (* request caller to save <oid> *) |
381 | NewOidEditor := true; (* request caller to save <oid> *) |
382 | end; |
382 | end; |
383 | FreeOidDef(newOID); |
383 | FreeOidDef(newOID); |
384 | end; |
384 | end; |
385 | 385 | ||
386 | procedure DeleteChildrenRecursive(oid: POID); |
386 | procedure DeleteChildrenRecursive(oid: POID); |
387 | var |
387 | var |
388 | i: integer; |
388 | i: integer; |
389 | childOID: POID; |
389 | childOID: POID; |
390 | filenameChild: string; |
390 | filenameChild: string; |
391 | begin |
391 | begin |
392 | for i := 0 to ListCount(oid^.SubIds)-1 do |
392 | for i := 0 to ListCount(oid^.SubIds)-1 do |
393 | begin |
393 | begin |
394 | filenameChild := FileIdPart(ListGetElement(oid^.SubIds, i)) + '.OID'; |
394 | filenameChild := FileIdPart(ListGetElement(oid^.SubIds, i)) + '.OID'; |
395 | if FileExists(filenameChild) then |
395 | if FileExists(filenameChild) then |
396 | begin |
396 | begin |
397 | CreateOidDef(childOID); |
397 | CreateOidDef(childOID); |
398 | _ReadOidFile(filenameChild, childOID); |
398 | _ReadOidFile(filenameChild, childOID); |
399 | DeleteChildrenRecursive(childOID); |
399 | DeleteChildrenRecursive(childOID); |
400 | FreeOidDef(childOID); |
400 | FreeOidDef(childOID); |
401 | DeleteFile(filenameChild); |
401 | DeleteFile(filenameChild); |
402 | end; |
402 | end; |
403 | end; |
403 | end; |
404 | ListClear(oid^.SubIds); |
404 | ListClear(oid^.SubIds); |
405 | end; |
405 | end; |
406 | 406 | ||
407 | procedure DeleteOidRecursive(selfOID: POID); |
407 | procedure DeleteOidRecursive(selfOID: POID); |
408 | var |
408 | var |
409 | i: integer; |
409 | i: integer; |
410 | parentOID: POID; |
410 | parentOID: POID; |
411 | filenameSelf, filenameParent: string; |
411 | filenameSelf, filenameParent: string; |
412 | begin |
412 | begin |
413 | (* Remove all children and their files recursively *) |
413 | (* Remove all children and their files recursively *) |
414 | DeleteChildrenRecursive(selfOID); |
414 | DeleteChildrenRecursive(selfOID); |
415 | 415 | ||
416 | (* Remove forward reference in parent OID *) |
416 | (* Remove forward reference in parent OID *) |
417 | filenameParent := FileIdPart(selfOID^.Parent) + '.OID'; |
417 | filenameParent := FileIdPart(selfOID^.Parent) + '.OID'; |
418 | if FileExists(filenameParent) then |
418 | if FileExists(filenameParent) then |
419 | begin |
419 | begin |
420 | CreateOidDef(parentOID); |
420 | CreateOidDef(parentOID); |
421 | _ReadOidFile(filenameParent, parentOID); |
421 | _ReadOidFile(filenameParent, parentOID); |
422 | if ListDeleteElementByValue(parentOID^.SubIds, selfOID^.FileId + selfOID^.DotNotation) then |
422 | if ListDeleteElementByValue(parentOID^.SubIds, selfOID^.FileId + selfOID^.DotNotation) then |
423 | begin |
423 | begin |
424 | _WriteOidFile(filenameParent, parentOID); |
424 | _WriteOidFile(filenameParent, parentOID); |
425 | end; |
425 | end; |
426 | FreeOidDef(parentOID); |
426 | FreeOidDef(parentOID); |
427 | end; |
427 | end; |
428 | 428 | ||
429 | (* Delete own file *) |
429 | (* Delete own file *) |
430 | filenameSelf := selfOID^.FileId + '.OID'; |
430 | filenameSelf := selfOID^.FileId + '.OID'; |
431 | if FileExists(filenameSelf) then |
431 | if FileExists(filenameSelf) then |
432 | begin |
432 | begin |
433 | DeleteFile(filenameSelf); |
433 | DeleteFile(filenameSelf); |
434 | end; |
434 | end; |
435 | end; |
435 | end; |
436 | 436 | ||
437 | function _DeleteConfirmation: boolean; |
437 | function _DeleteConfirmation: boolean; |
438 | var |
438 | var |
439 | sc: Char; |
439 | sc: Char; |
440 | begin |
440 | begin |
441 | repeat |
441 | repeat |
442 | ShowMessage('Are you sure you want to delete this OID? (Y/N)', 'DELETE OID', true); |
442 | ShowMessage('Are you sure you want to delete this OID? (Y/N)', 'DELETE OID', true); |
443 | DrawStatusBar('Y=Yes, N=No'); |
443 | DrawStatusBar('Y=Yes, N=No'); |
444 | 444 | ||
445 | sc := ReadKey; |
445 | sc := ReadKey; |
446 | if sc = #0 then |
446 | if sc = #0 then |
447 | begin |
447 | begin |
448 | (* Extended key. Nothing we care about. *) |
448 | (* Extended key. Nothing we care about. *) |
449 | ReadKey; |
449 | ReadKey; |
450 | continue; |
450 | continue; |
451 | end; |
451 | end; |
452 | 452 | ||
453 | if UpCase(sc) = 'Y' then |
453 | if UpCase(sc) = 'Y' then |
454 | begin |
454 | begin |
455 | _DeleteConfirmation := true; |
455 | _DeleteConfirmation := true; |
456 | break; |
456 | break; |
457 | end |
457 | end |
458 | else if UpCase(sc) = 'N' then |
458 | else if UpCase(sc) = 'N' then |
459 | begin |
459 | begin |
460 | _DeleteConfirmation := false; |
460 | _DeleteConfirmation := false; |
461 | break; |
461 | break; |
462 | end; |
462 | end; |
463 | until false; |
463 | until false; |
464 | end; |
464 | end; |
465 | 465 | ||
466 | procedure _DrawOidTitleBar(filename: string; oid: POID); |
466 | procedure _DrawOidTitleBar(filename: string; oid: POID); |
467 | begin |
467 | begin |
468 | if oid^.DotNotation = '' then |
468 | if oid^.DotNotation = '' then |
469 | DrawTitleBar('OID ROOT', TITLEBAR_LEFT_TEXT, filename) |
469 | DrawTitleBar('OID ROOT', TITLEBAR_LEFT_TEXT, filename) |
470 | else |
470 | else |
471 | DrawTitleBar('OID ' + oid^.DotNotation, TITLEBAR_LEFT_TEXT, filename); |
471 | DrawTitleBar('OID ' + oid^.DotNotation, TITLEBAR_LEFT_TEXT, filename); |
472 | end; |
472 | end; |
473 | 473 | ||
474 | procedure DisplayOIDFile(filename: string); |
474 | procedure DisplayOIDFile(filename: string); |
475 | var |
475 | var |
476 | isRoot: boolean; |
476 | isRoot: boolean; |
477 | oid, tmpOID: POID; |
477 | oid, tmpOID: POID; |
478 | i, menuX, menuY: integer; |
478 | i, menuX, menuY: integer; |
479 | linesLeft, linesRequired: integer; |
479 | linesLeft, linesRequired: integer; |
480 | sTmp, subfile: string; |
480 | sTmp, subfile: string; |
481 | subsel, subfiles: PStringList; |
481 | subsel, subfiles: PStringList; |
482 | subselres: integer; |
482 | subselres: integer; |
483 | exitRequest: boolean; |
483 | exitRequest: boolean; |
484 | menuIdExit, menuIdAsnEdit, menuIdDescEdit, menuIdAdd, menuIdDelete: integer; |
484 | menuIdExit, menuIdAsnEdit, menuIdDescEdit, menuIdAdd, menuIdDelete: integer; |
485 | begin |
485 | begin |
486 | exitRequest := false; |
486 | exitRequest := false; |
487 | repeat |
487 | repeat |
488 | if not FileExists(filename) then |
488 | if not FileExists(filename) then |
489 | begin |
489 | begin |
490 | ShowMessage('File ' + filename + ' not found', 'ERROR', true); |
490 | ShowMessage('File ' + filename + ' not found', 'ERROR', true); |
491 | _Pause; |
491 | _Pause; |
492 | exit; |
492 | exit; |
493 | end; |
493 | end; |
494 | 494 | ||
495 | CreateOidDef(oid); |
495 | CreateOidDef(oid); |
496 | _ReadOidFile(filename, oid); |
496 | _ReadOidFile(filename, oid); |
497 | 497 | ||
498 | (* Print OID information *) |
498 | (* Print OID information *) |
499 | 499 | ||
500 | ClrScr; |
500 | ClrScr; |
501 | _DrawOidTitleBar(filename, oid); |
501 | _DrawOidTitleBar(filename, oid); |
502 | DrawStatusBar(DEFAULT_STATUSBAR); |
502 | DrawStatusBar(DEFAULT_STATUSBAR); |
503 | GotoXY(1,2); |
503 | GotoXY(1,2); |
504 | 504 | ||
505 | if oid^.DotNotation <> '' then |
505 | if oid^.DotNotation <> '' then |
506 | begin |
506 | begin |
507 | WriteLn('Dot-Notation:'); |
507 | WriteLn('Dot-Notation:'); |
508 | WriteLn(oid^.DotNotation); |
508 | WriteLn(oid^.DotNotation); |
509 | WriteLn(''); |
509 | WriteLn(''); |
510 | end; |
510 | end; |
511 | 511 | ||
512 | if Trim(oid^.Description) <> '' then |
512 | if Trim(oid^.Description) <> '' then |
513 | begin |
513 | begin |
514 | WriteLn('Description:'); |
514 | WriteLn('Description:'); |
515 | WriteLn(oid^.Description); |
515 | WriteLn(oid^.Description); |
516 | WriteLn(''); |
516 | WriteLn(''); |
517 | end; |
517 | end; |
518 | 518 | ||
519 | menuX := WhereX + 1; |
519 | menuX := WhereX + 1; |
520 | menuY := ScreenHeight - ACTIONMENU_SIZE - 1; |
520 | menuY := ScreenHeight - ACTIONMENU_SIZE - 1; |
521 | 521 | ||
522 | if ListCount(oid^.ASNIDs) > 0 then |
522 | if ListCount(oid^.ASNIDs) > 0 then |
523 | begin |
523 | begin |
524 | linesLeft := menuY - WhereY - 1; |
524 | linesLeft := menuY - WhereY - 1; |
525 | linesRequired := 1 + ListCount(oid^.ASNIds); |
525 | linesRequired := 1 + ListCount(oid^.ASNIds); |
526 | 526 | ||
527 | if LinesLeft < LinesRequired then |
527 | if LinesLeft < LinesRequired then |
528 | begin |
528 | begin |
529 | (* Compact display of ASN.1 identifiers *) |
529 | (* Compact display of ASN.1 identifiers *) |
530 | Write('ASN.1-Identifiers: '); |
530 | Write('ASN.1-Identifiers: '); |
531 | for i := 0 to ListCount(oid^.ASNIds)-1 do |
531 | for i := 0 to ListCount(oid^.ASNIds)-1 do |
532 | begin |
532 | begin |
533 | if i > 0 then Write(', '); |
533 | if i > 0 then Write(', '); |
534 | Write(ListGetElement(oid^.ASNIds, i)); |
534 | Write(ListGetElement(oid^.ASNIds, i)); |
535 | end; |
535 | end; |
536 | WriteLn(''); |
536 | WriteLn(''); |
537 | end |
537 | end |
538 | else |
538 | else |
539 | begin |
539 | begin |
540 | (* Long display of ASN.1 identifiers *) |
540 | (* Long display of ASN.1 identifiers *) |
541 | WriteLn('ASN.1-Identifiers:'); |
541 | WriteLn('ASN.1-Identifiers:'); |
542 | for i := 0 to ListCount(oid^.ASNIds)-1 do |
542 | for i := 0 to ListCount(oid^.ASNIds)-1 do |
543 | begin |
543 | begin |
544 | WriteLn('- '+ListGetElement(oid^.ASNIds, i)); |
544 | WriteLn('- '+ListGetElement(oid^.ASNIds, i)); |
545 | end; |
545 | end; |
546 | WriteLn(''); |
546 | WriteLn(''); |
547 | end; |
547 | end; |
548 | end; |
548 | end; |
549 | 549 | ||
550 | (* Now prepare the menu entries *) |
550 | (* Now prepare the menu entries *) |
551 | 551 | ||
552 | CreateList(subsel); (* Contains the human readable OID name *) |
552 | CreateList(subsel); (* Contains the human readable OID name *) |
553 | CreateList(subfiles); (* Contains the file name *) |
553 | CreateList(subfiles); (* Contains the file name *) |
554 | 554 | ||
555 | if oid^.Parent = '' then |
555 | if oid^.Parent = '' then |
556 | begin |
556 | begin |
557 | isRoot := true; |
557 | isRoot := true; |
558 | end |
558 | end |
559 | else |
559 | else |
560 | begin |
560 | begin |
561 | isRoot := DotNotationPart(oid^.Parent) = oid^.DotNotation; |
561 | isRoot := DotNotationPart(oid^.Parent) = oid^.DotNotation; |
562 | end; |
562 | end; |
563 | 563 | ||
564 | if (oid^.Parent <> '') and not isRoot then |
564 | if (oid^.Parent <> '') and not isRoot then |
565 | begin |
565 | begin |
566 | sTmp := oid^.Parent; |
566 | sTmp := oid^.Parent; |
567 | subfile := FileIdPart(sTmp) + '.OID'; |
567 | subfile := FileIdPart(sTmp) + '.OID'; |
568 | if FileExists(subfile) then |
568 | if FileExists(subfile) then |
569 | begin |
569 | begin |
570 | CreateOidDef(tmpOID); |
570 | CreateOidDef(tmpOID); |
571 | _ReadOidFile(subfile, tmpOID); |
571 | _ReadOidFile(subfile, tmpOID); |
572 | ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID)); |
572 | ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID)); |
573 | FreeOidDef(tmpOID); |
573 | FreeOidDef(tmpOID); |
574 | end |
574 | end |
575 | else |
575 | else |
576 | begin |
576 | begin |
577 | ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)'); |
577 | ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)'); |
578 | end; |
578 | end; |
579 | ListAppend(subfiles, subfile); |
579 | ListAppend(subfiles, subfile); |
580 | end; |
580 | end; |
581 | 581 | ||
582 | if isRoot then |
582 | if isRoot then |
583 | begin |
583 | begin |
584 | menuIdExit := ListAppend(subsel, 'Back to main menu'); |
584 | menuIdExit := ListAppend(subsel, 'Back to main menu'); |
585 | ListAppend(subfiles, ''); |
585 | ListAppend(subfiles, ''); |
586 | end |
586 | end |
587 | else menuIdExit := -99; |
587 | else menuIdExit := -99; |
588 | 588 | ||
589 | for i := 0 to ListCount(oid^.SubIds)-1 do |
589 | for i := 0 to ListCount(oid^.SubIds)-1 do |
590 | begin |
590 | begin |
591 | sTmp := ListGetElement(oid^.SubIds, i); |
591 | sTmp := ListGetElement(oid^.SubIds, i); |
592 | subfile := FileIdPart(sTmp) + '.OID'; |
592 | subfile := FileIdPart(sTmp) + '.OID'; |
593 | if FileExists(subfile) then |
593 | if FileExists(subfile) then |
594 | begin |
594 | begin |
595 | CreateOidDef(tmpOID); |
595 | CreateOidDef(tmpOID); |
596 | _ReadOidFile(subfile, tmpOID); |
596 | _ReadOidFile(subfile, tmpOID); |
597 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID)); |
597 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + _ShowASNIds(tmpOID)); |
598 | FreeOidDef(tmpOID); |
598 | FreeOidDef(tmpOID); |
599 | end |
599 | end |
600 | else |
600 | else |
601 | begin |
601 | begin |
602 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)'); |
602 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + ' (FILE NOT FOUND)'); |
603 | end; |
603 | end; |
604 | ListAppend(subfiles, subfile); |
604 | ListAppend(subfiles, subfile); |
605 | end; |
605 | end; |
606 | 606 | ||
607 | if oid^.DotNotation <> '' then |
607 | if oid^.DotNotation <> '' then |
608 | begin |
608 | begin |
609 | menuIdAsnEdit := ListAppend(subsel, 'Edit ASN.1 identifiers'); |
609 | menuIdAsnEdit := ListAppend(subsel, 'Edit ASN.1 identifiers'); |
610 | ListAppend(subfiles, ''); |
610 | ListAppend(subfiles, ''); |
611 | end |
611 | end |
612 | else menuIdAsnEdit := -99; |
612 | else menuIdAsnEdit := -99; |
613 | 613 | ||
614 | menuIdDescEdit := ListAppend(subsel, 'Edit description'); |
614 | menuIdDescEdit := ListAppend(subsel, 'Edit description'); |
615 | ListAppend(subfiles, ''); |
615 | ListAppend(subfiles, ''); |
616 | 616 | ||
617 | menuIdAdd := ListAppend(subsel, 'Add child'); |
617 | menuIdAdd := ListAppend(subsel, 'Add child'); |
618 | ListAppend(subfiles, ''); |
618 | ListAppend(subfiles, ''); |
619 | 619 | ||
620 | if not isRoot then |
620 | if not isRoot then |
621 | begin |
621 | begin |
622 | menuIdDelete := ListAppend(subsel, 'Delete OID'); |
622 | menuIdDelete := ListAppend(subsel, 'Delete OID'); |
623 | ListAppend(subfiles, ''); |
623 | ListAppend(subfiles, ''); |
624 | end |
624 | end |
625 | else menuIdDelete := -99; |
625 | else menuIdDelete := -99; |
626 | 626 | ||
627 | (* Show menu *) |
627 | (* Show menu *) |
628 | 628 | ||
629 | subselres := DrawSelectionList(menuX, menuY, |
629 | subselres := DrawSelectionList(menuX, menuY, |
630 | ScreenWidth-2, |
630 | ScreenWidth-2, |
631 | ACTIONMENU_SIZE, |
631 | ACTIONMENU_SIZE, |
632 | subsel, |
632 | subsel, |
633 | true, |
633 | true, |
634 | 'SELECT ACTION', |
634 | 'SELECT ACTION', |
635 | 1); |
635 | 1); |
636 | 636 | ||
637 | (* Process user selection *) |
637 | (* Process user selection *) |
638 | 638 | ||
639 | if subselres = -1 then |
639 | if subselres = -1 then |
640 | begin |
640 | begin |
641 | exitRequest := true; |
641 | exitRequest := true; |
642 | end |
642 | end |
643 | else if subselres = menuIdAsnEdit then |
643 | else if subselres = menuIdAsnEdit then |
644 | begin |
644 | begin |
645 | if AsnEditor(oid) then |
645 | if AsnEditor(oid) then |
646 | _WriteOidFile(filename, oid); |
646 | _WriteOidFile(filename, oid); |
647 | end |
647 | end |
648 | else if subselres = menuIdDescEdit then |
648 | else if subselres = menuIdDescEdit then |
649 | begin |
649 | begin |
650 | if DescEditor(oid) then |
650 | if DescEditor(oid) then |
651 | _WriteOidFile(filename, oid); |
651 | _WriteOidFile(filename, oid); |
652 | end |
652 | end |
653 | else if subselres = menuIdAdd then |
653 | else if subselres = menuIdAdd then |
654 | begin |
654 | begin |
655 | if NewOidEditor(oid) then |
655 | if NewOidEditor(oid) then |
656 | _WriteOidFile(filename, oid); |
656 | _WriteOidFile(filename, oid); |
657 | end |
657 | end |
658 | else if subselres = menuIdDelete then |
658 | else if subselres = menuIdDelete then |
659 | begin |
659 | begin |
660 | if _DeleteConfirmation then |
660 | if _DeleteConfirmation then |
661 | begin |
661 | begin |
662 | sTmp := FileIdPart(oid^.Parent) + '.OID'; |
662 | sTmp := FileIdPart(oid^.Parent) + '.OID'; |
663 | DeleteOidRecursive(oid); |
663 | DeleteOidRecursive(oid); |
664 | if FileExists(sTmp) then |
664 | if FileExists(sTmp) then |
665 | begin |
665 | begin |
666 | filename := sTmp; |
666 | filename := sTmp; |
667 | end |
667 | end |
668 | else |
668 | else |
669 | begin |
669 | begin |
670 | ShowMessage('Parent file ' + filename + ' not found', 'ERROR', true); |
670 | ShowMessage('Parent file ' + filename + ' not found', 'ERROR', true); |
671 | _Pause; |
671 | _Pause; |
672 | exitRequest := true; |
672 | exitRequest := true; |
673 | end; |
673 | end; |
674 | end; |
674 | end; |
675 | end |
675 | end |
676 | else if subselres = menuIdExit then |
676 | else if subselres = menuIdExit then |
677 | begin |
677 | begin |
678 | exitRequest := true; |
678 | exitRequest := true; |
679 | end |
679 | end |
680 | else |
680 | else |
681 | begin |
681 | begin |
682 | (* Normal OID *) |
682 | (* Normal OID *) |
683 | sTmp := ListGetElement(subfiles, subselres); |
683 | sTmp := ListGetElement(subfiles, subselres); |
684 | if FileExists(sTmp) then |
684 | if FileExists(sTmp) then |
685 | begin |
685 | begin |
686 | filename := sTmp; |
686 | filename := sTmp; |
687 | end |
687 | end |
688 | else |
688 | else |
689 | begin |
689 | begin |
690 | ShowMessage('File ' + filename + ' not found', 'ERROR', true); |
690 | ShowMessage('File ' + filename + ' not found', 'ERROR', true); |
691 | _Pause; |
691 | _Pause; |
692 | end; |
692 | end; |
693 | end; |
693 | end; |
694 | FreeList(subsel); |
694 | FreeList(subsel); |
695 | FreeList(subfiles); |
695 | FreeList(subfiles); |
696 | 696 | ||
697 | FreeOidDef(oid); |
697 | FreeOidDef(oid); |
698 | until exitRequest; |
698 | until exitRequest; |
699 | end; |
699 | end; |
700 | 700 | ||
701 | procedure CreateInitOIDFile(filename: string); |
701 | procedure CreateRootOIDFile(filename: string); |
702 | var |
702 | var |
703 | oid: POID; |
703 | oid: POID; |
704 | begin |
704 | begin |
705 | CreateOidDef(oid); |
705 | CreateOidDef(oid); |
706 | oid^.Description := 'This is the root of the OID tree.' +#13#10 + |
706 | oid^.Description := 'This is the root of the OID tree.' +#13#10 + |
707 | #13#10 + |
707 | #13#10 + |
708 | 'Valid subsequent arcs are per definition:' + #13#10 + |
708 | 'Valid subsequent arcs are per definition:' + #13#10 + |
709 | '- 0 (itu-t)' + #13#10 + |
709 | '- 0 (itu-t)' + #13#10 + |
710 | '- 1 (iso)' + #13#10 + |
710 | '- 1 (iso)' + #13#10 + |
711 | '- 2 (joint-iso-itu-t)'; |
711 | '- 2 (joint-iso-itu-t)'; |
712 | oid^.FileId := ZeroPad(0, 8); |
712 | oid^.FileId := ZeroPad(0, 8); |
713 | oid^.DotNotation := ''; |
713 | oid^.DotNotation := ''; |
714 | oid^.Parent := ZeroPad(0, 8); |
714 | oid^.Parent := ZeroPad(0, 8); |
715 | _WriteOidFile(filename, oid); |
715 | _WriteOidFile(filename, oid); |
716 | FreeOidDef(oid); |
716 | FreeOidDef(oid); |
717 | end; |
717 | end; |
718 | 718 | ||
719 | function _GetInitFile: string; |
719 | function _GetRootFile(ShowErrorMessage: boolean): string; |
720 | var |
720 | var |
721 | initFile: string; |
721 | rootFile: string; |
722 | begin |
722 | begin |
723 | initFile := ZeroPad(0, 8) + '.OID'; |
723 | rootFile := ZeroPad(0, 8) + '.OID'; |
724 | if not FileExists(initFile) then |
724 | if not FileExists(rootFile) then |
725 | begin |
725 | begin |
- | 726 | {$I-} |
|
726 | CreateInitOIDFile(initFile); |
727 | CreateRootOIDFile(rootFile); |
- | 728 | {$I+} |
|
- | 729 | end; |
|
- | 730 | if not FileExists(rootFile) then |
|
- | 731 | begin |
|
- | 732 | _GetRootFile := ''; |
|
- | 733 | if ShowErrorMessage then |
|
- | 734 | begin |
|
- | 735 | ShowMessage('Cannot create ' + rootfile + '! Is disk read-only?', 'ERROR', true); |
|
- | 736 | _Pause; |
|
- | 737 | end; |
|
- | 738 | end |
|
- | 739 | else |
|
- | 740 | begin |
|
- | 741 | _GetRootFile := rootFile; |
|
727 | end; |
742 | end; |
728 | _GetInitFile := initFile; |
- | |
729 | end; |
743 | end; |
730 | 744 | ||
731 | procedure OP_ManageOIDs; |
745 | procedure OP_ManageOIDs; |
- | 746 | var |
|
- | 747 | rootfile: string; |
|
732 | begin |
748 | begin |
733 | ClrScr; |
749 | ClrScr; |
734 | DrawTitleBar('Manage Object Identifiers', TITLEBAR_LEFT_TEXT, ''); |
750 | DrawTitleBar('Manage Object Identifiers', TITLEBAR_LEFT_TEXT, ''); |
735 | DrawStatusBar('Loading data... please wait...'); |
751 | DrawStatusBar('Loading data... please wait...'); |
736 | 752 | ||
- | 753 | (* This will try creating a new root file if it does not exist *) |
|
- | 754 | rootfile := _GetRootFile(true); |
|
- | 755 | if rootfile = '' then Exit; |
|
- | 756 | ||
737 | DisplayOIDFile(_GetInitFile); |
757 | DisplayOIDFile(rootfile); |
738 | end; |
758 | end; |
739 | 759 | ||
740 | procedure OP_ManageRAs; |
760 | procedure OP_ManageRAs; |
741 | begin |
761 | begin |
742 | ClrScr; |
762 | ClrScr; |
743 | DrawTitleBar('Manage Registration Authorities', TITLEBAR_LEFT_TEXT, ''); |
763 | DrawTitleBar('Manage Registration Authorities', TITLEBAR_LEFT_TEXT, ''); |
744 | DrawStatusBar(''); |
764 | DrawStatusBar(''); |
745 | 765 | ||
746 | (* TODO: Implement "Manage RAs" feature *) |
766 | (* TODO: Implement "Manage RAs" feature *) |
747 | end; |
767 | end; |
748 | 768 | ||
749 | procedure OP_ReturnToMSDOS; |
769 | procedure OP_ReturnToMSDOS; |
750 | begin |
770 | begin |
751 | ClrScr; |
771 | ClrScr; |
752 | WriteLn('Thank you for using OIDplus for DOS.'); |
772 | WriteLn('Thank you for using OIDplus for DOS.'); |
753 | WRiteLn(''); |
773 | WRiteLn(''); |
754 | end; |
774 | end; |
755 | 775 | ||
756 | function _GetTreeViewLine(oid: POID; indent: integer): string; |
776 | function _GetTreeViewLine(oid: POID; indent: integer): string; |
757 | var |
777 | var |
758 | i: integer; |
778 | i: integer; |
759 | sTmp: string; |
779 | sTmp: string; |
760 | begin |
780 | begin |
761 | (* Build line *) |
781 | (* Build line *) |
762 | sTmp := RepeatStr(' ', indent*TREEVIEW_INDENT); |
782 | sTmp := RepeatStr(' ', indent*TREEVIEW_INDENT); |
763 | if oid^.DotNotation = '' then |
783 | if oid^.DotNotation = '' then |
764 | sTmp := sTmp + 'Object Identifiers' |
784 | sTmp := sTmp + 'Object Identifiers' |
765 | else |
785 | else |
766 | sTmp := sTmp + oid^.DotNotation; |
786 | sTmp := sTmp + oid^.DotNotation; |
767 | sTmp := sTmp + _ShowAsnIds(oid); |
787 | sTmp := sTmp + _ShowAsnIds(oid); |
768 | if TREEVIEW_INCLUDE_DESC then |
788 | if TREEVIEW_INCLUDE_DESC then |
769 | begin |
789 | begin |
770 | if Trim(oid^.Description) <> '' then |
790 | if Trim(oid^.Description) <> '' then |
771 | begin |
791 | begin |
772 | sTmp := sTmp + ': ' + oid^.Description; |
792 | sTmp := sTmp + ': ' + oid^.Description; |
773 | end; |
793 | end; |
774 | end; |
794 | end; |
775 | for i := 1 to Length(sTmp) do |
795 | for i := 1 to Length(sTmp) do |
776 | begin |
796 | begin |
777 | if (sTmp[i]=#13) or (sTmp[i]=#10) then sTmp[i] := ' '; |
797 | if (sTmp[i]=#13) or (sTmp[i]=#10) then sTmp[i] := ' '; |
778 | end; |
798 | end; |
779 | if Length(sTmp) > TREEVIEW_WIDTH then |
799 | if Length(sTmp) > TREEVIEW_WIDTH then |
780 | begin |
800 | begin |
781 | sTmp := Copy(sTmp, 1, TREEVIEW_WIDTH-3) + '...'; |
801 | sTmp := Copy(sTmp, 1, TREEVIEW_WIDTH-3) + '...'; |
782 | end; |
802 | end; |
783 | _GetTreeViewLine := sTmp; |
803 | _GetTreeViewLine := sTmp; |
784 | end; |
804 | end; |
785 | 805 | ||
786 | procedure _RecTreeExport(oid: POID; var F: Text; indent: integer); |
806 | procedure _RecTreeExport(oid: POID; var F: Text; indent: integer); |
787 | var |
807 | var |
788 | i: integer; |
808 | i: integer; |
789 | sTmp: string; |
809 | sTmp: string; |
790 | suboid: POID; |
810 | suboid: POID; |
791 | childFilename: string; |
811 | childFilename: string; |
792 | begin |
812 | begin |
793 | sTmp := _GetTreeViewLine(oid, indent); |
813 | sTmp := _GetTreeViewLine(oid, indent); |
794 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
814 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
795 | WriteLn(F, sTmp); |
815 | WriteLn(F, sTmp); |
796 | 816 | ||
797 | (* Recursively call children *) |
817 | (* Recursively call children *) |
798 | for i := 0 to ListCount(oid^.SubIds)-1 do |
818 | for i := 0 to ListCount(oid^.SubIds)-1 do |
799 | begin |
819 | begin |
800 | sTmp := ListGetElement(oid^.SubIds, i); |
820 | sTmp := ListGetElement(oid^.SubIds, i); |
801 | CreateOidDef(suboid); |
821 | CreateOidDef(suboid); |
802 | childFilename := FileIdPart(sTmp) + '.OID'; |
822 | childFilename := FileIdPart(sTmp) + '.OID'; |
803 | if FileExists(childFilename) then |
823 | if FileExists(childFilename) then |
804 | begin |
824 | begin |
805 | _ReadOidFile(childFilename, suboid); |
825 | _ReadOidFile(childFilename, suboid); |
806 | _RecTreeExport(suboid, F, indent+1); |
826 | _RecTreeExport(suboid, F, indent+1); |
807 | FreeOidDef(suboid); |
827 | FreeOidDef(suboid); |
808 | end |
828 | end |
809 | else |
829 | else |
810 | begin |
830 | begin |
811 | sTmp := 'ERROR: FILE ' + childFilename + ' CONTAINING CHILD OID ' + DotNotationPart(sTmp) + ' WAS NOT FOUND!'; |
831 | sTmp := 'ERROR: FILE ' + childFilename + ' CONTAINING CHILD OID ' + DotNotationPart(sTmp) + ' WAS NOT FOUND!'; |
812 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
832 | sTmp := TrimLineToWidth(sTmp, TREEVIEW_WIDTH); |
813 | WriteLn(F, sTmp); |
833 | WriteLn(F, sTmp); |
814 | end; |
834 | end; |
815 | end; |
835 | end; |
816 | end; |
836 | end; |
817 | 837 | ||
818 | procedure OP_TreeView; |
838 | procedure OP_TreeView; |
819 | var |
839 | var |
820 | F: Text; |
840 | F: Text; |
821 | rootoid: POID; |
841 | rootoid: POID; |
- | 842 | rootfile: string; |
|
822 | begin |
843 | begin |
823 | ClrScr; |
844 | ClrScr; |
824 | DrawTitleBar('TreeView Export', TITLEBAR_LEFT_TEXT, ''); |
845 | DrawTitleBar('TreeView Export', TITLEBAR_LEFT_TEXT, ''); |
825 | DrawStatusBar('Exporting data... please wait...'); |
846 | DrawStatusBar('Exporting data... please wait...'); |
826 | 847 | ||
- | 848 | (* This will try creating a new root file if it does not exist *) |
|
- | 849 | rootfile := _GetRootFile(true);; |
|
- | 850 | if rootfile = '' then Exit; |
|
- | 851 | ||
827 | Assign(F, 'OIDTREE.TXT'); |
852 | Assign(F, 'OIDTREE.TXT'); |
828 | Rewrite(F); |
853 | Rewrite(F); |
829 | 854 | ||
830 | CreateOidDef(rootoid); |
855 | CreateOidDef(rootoid); |
831 | _ReadOidFile(_GetInitFile, rootoid); |
856 | _ReadOidFile(rootfile, rootoid); |
832 | _RecTreeExport(rootoid, F, 0); |
857 | _RecTreeExport(rootoid, F, 0); |
833 | FreeOidDef(rootoid); |
858 | FreeOidDef(rootoid); |
834 | 859 | ||
835 | DrawStatusBar(DEFAULT_STATUSBAR); |
860 | DrawStatusBar(DEFAULT_STATUSBAR); |
836 | ShowMessage('TreeView successfully exported as OIDTREE.TXT', 'TREEVIEW EXPORT', true); |
861 | ShowMessage('TreeView successfully exported as OIDTREE.TXT', 'TREEVIEW EXPORT', true); |
837 | _Pause; |
862 | _Pause; |
838 | 863 | ||
839 | Close(F); |
864 | Close(F); |
840 | end; |
865 | end; |
841 | 866 | ||
842 | procedure OP_MainMenu; |
867 | procedure OP_MainMenu; |
843 | var |
868 | var |
844 | menu: PStringList; |
869 | menu: PStringList; |
845 | menuRes, menuLeft, menuTop: integer; |
870 | menuRes, menuLeft, menuTop: integer; |
846 | menuIdOID, menuIdRA, menuIdTree, menuIdExit: integer; |
871 | menuIdOID, menuIdRA, menuIdTree, menuIdExit: integer; |
847 | begin |
872 | begin |
848 | repeat |
873 | repeat |
849 | ClrScr; |
874 | ClrScr; |
850 | 875 | ||
851 | DrawTitleBar('Welcome to OIDplus for DOS', '', ''); |
876 | DrawTitleBar('Welcome to OIDplus for DOS', '', ''); |
852 | DrawStatusBar(DEFAULT_STATUSBAR); |
877 | DrawStatusBar(DEFAULT_STATUSBAR); |
853 | GoToXY(ScreenWidth-Length(VERSIONINFO), ScreenHeight-1); |
878 | GoToXY(ScreenWidth-Length(VERSIONINFO), ScreenHeight-1); |
854 | Write(VERSIONINFO); |
879 | Write(VERSIONINFO); |
855 | 880 | ||
856 | CreateList(menu); |
881 | CreateList(menu); |
857 | 882 | ||
858 | menuIdOID := ListAppend(menu, 'Manage OIDs'); |
883 | menuIdOID := ListAppend(menu, 'Manage OIDs'); |
859 | menuIdRA := -99; (*ListAppend(menu, 'Manage RAs');*) |
884 | menuIdRA := -99; (*ListAppend(menu, 'Manage RAs');*) |
860 | menuIdTree := ListAppend(menu, 'Export TreeView'); |
885 | menuIdTree := ListAppend(menu, 'Export TreeView'); |
861 | menuIdExit := ListAppend(menu, 'Return to DOS'); |
886 | menuIdExit := ListAppend(menu, 'Return to DOS'); |
862 | 887 | ||
863 | menuLeft := round(ScreenWidth/2 -MAINMENU_WIDTH/2); |
888 | menuLeft := round(ScreenWidth/2 -MAINMENU_WIDTH/2); |
864 | menuTop := round(ScreenHeight/2-MAINMENU_HEIGHT/2); |
889 | menuTop := round(ScreenHeight/2-MAINMENU_HEIGHT/2); |
865 | menuRes := DrawSelectionList(menuLeft, menuTop, |
890 | menuRes := DrawSelectionList(menuLeft, menuTop, |
866 | MAINMENU_WIDTH, MAINMENU_HEIGHT, |
891 | MAINMENU_WIDTH, MAINMENU_HEIGHT, |
867 | menu, true, 'MAIN MENU', 2); |
892 | menu, true, 'MAIN MENU', 2); |
868 | FreeList(menu); |
893 | FreeList(menu); |
869 | 894 | ||
870 | if menuRes = menuIdOID then |
895 | if menuRes = menuIdOID then |
871 | begin |
896 | begin |
872 | OP_ManageOIDs; |
897 | OP_ManageOIDs; |
873 | end |
898 | end |
874 | else if menuRes = menuIdRA then |
899 | else if menuRes = menuIdRA then |
875 | begin |
900 | begin |
876 | OP_ManageRAs; |
901 | OP_ManageRAs; |
877 | end |
902 | end |
878 | else if menuRes = menuIdTree then |
903 | else if menuRes = menuIdTree then |
879 | begin |
904 | begin |
880 | OP_Treeview; |
905 | OP_Treeview; |
881 | end; |
906 | end; |
882 | until (menuRes = menuIdExit) or (MAINMENU_ALLOW_ESC and (menuRes = -1)); |
907 | until (menuRes = menuIdExit) or (MAINMENU_ALLOW_ESC and (menuRes = -1)); |
883 | 908 | ||
884 | OP_ReturnToMSDOS; |
909 | OP_ReturnToMSDOS; |
885 | end; |
910 | end; |
886 | 911 | ||
887 | begin |
912 | begin |
888 | OP_MainMenu; |
913 | OP_MainMenu; |
889 | end. |
914 | end. |
890 | 915 |