Rev 737 | Rev 739 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
733 | daniel-mar | 1 | program OIDPLUS; |
2 | |||
3 | (************************************************) |
||
4 | (* OIDPLUS.PAS *) |
||
5 | (* Author: Daniel Marschall *) |
||
734 | daniel-mar | 6 | (* Revision: 2022-02-14 *) |
733 | daniel-mar | 7 | (* License: Apache 2.0 *) |
8 | (* This file contains: *) |
||
9 | (* - "OIDplus for DOS" program *) |
||
10 | (************************************************) |
||
11 | |||
12 | uses |
||
13 | Dos, Crt, StrList, VtsFuncs, VtsCui, OidFile, OidUtils; |
||
14 | |||
15 | const |
||
735 | daniel-mar | 16 | VERSIONINFO = 'Revision: 2022-02-14'; |
17 | DEFAULT_STATUSBAR = '(C)2020-2022 ViaThinkSoft. Licensed under the terms of the Apache 2.0 license.'; |
||
733 | daniel-mar | 18 | DISKIO_SOUND_DEBUGGING = false; |
735 | daniel-mar | 19 | DISKIO_SOUND_DELAY = 500; |
20 | ASNEDIT_LINES = 10; |
||
21 | DESCEDIT_LINES = 10; |
||
22 | DESCEDIT_PADDING = 3; |
||
23 | ACTIONMENU_SIZE = 5; |
||
24 | MAINMENU_WIDTH = 15; |
||
25 | MAINMENU_HEIGHT = 3; |
||
26 | MAINMENU_ALLOW_ESC = false; |
||
738 | daniel-mar | 27 | TITLEBAR_LEFT_TEXT = 'OIDplus'; |
733 | daniel-mar | 28 | |
29 | procedure _WriteOidFile(filename: string; oid: POid); |
||
30 | begin |
||
31 | DrawStatusBar('Write file ' + filename + '...'); |
||
32 | WriteOidFile(filename, oid); |
||
33 | |||
34 | if DISKIO_SOUND_DEBUGGING then |
||
35 | begin |
||
36 | Sound(70); |
||
37 | Delay(DISKIO_SOUND_DELAY - 10); |
||
38 | NoSound; |
||
39 | Delay(10); |
||
40 | end; |
||
41 | |||
42 | DrawStatusBar(DEFAULT_STATUSBAR); |
||
43 | end; |
||
44 | |||
45 | procedure _ReadOidFile(filename: string; oid: POid); |
||
46 | begin |
||
47 | DrawStatusBar('Read file ' + filename + '...'); |
||
48 | ReadOidFile(filename, oid); |
||
49 | |||
50 | if DISKIO_SOUND_DEBUGGING then |
||
51 | begin |
||
52 | Sound(50); |
||
53 | Delay(DISKIO_SOUND_DELAY - 10); |
||
54 | NoSound; |
||
55 | Delay(10); |
||
56 | end; |
||
57 | |||
58 | DrawStatusBar(DEFAULT_STATUSBAR); |
||
59 | end; |
||
60 | |||
61 | procedure _Pause; |
||
62 | var |
||
63 | bakX, bakY: integer; |
||
64 | begin |
||
65 | bakX := WhereX; |
||
66 | bakY := WhereY; |
||
67 | DrawStatusBar('Press any key to continue'); |
||
68 | GoToXY(bakX, bakY); |
||
69 | ReadKey; |
||
70 | DrawStatusBar(DEFAULT_STATUSBAR); |
||
71 | end; |
||
72 | |||
73 | function _ShowASNIds(subfile: string): string; |
||
74 | var |
||
735 | daniel-mar | 75 | childOID: POID; |
733 | daniel-mar | 76 | j, jmax: integer; |
77 | sTmp: string; |
||
78 | begin |
||
79 | sTmp := ''; |
||
735 | daniel-mar | 80 | CreateOidDef(childOID); |
81 | _ReadOidFile(subfile, childOID); |
||
82 | jmax := ListCount(childOID^.ASNIds)-1; |
||
733 | daniel-mar | 83 | for j := 0 to jmax do |
84 | begin |
||
85 | if j = 0 then sTmp := sTmp + ' ('; |
||
735 | daniel-mar | 86 | sTmp := sTmp + ListGetElement(childOID^.ASNIds, j); |
733 | daniel-mar | 87 | if j = jmax then |
88 | sTmp := sTmp + ')' |
||
89 | else |
||
90 | sTmp := sTmp + ', '; |
||
91 | end; |
||
735 | daniel-mar | 92 | FreeOidDef(childOID); |
733 | daniel-mar | 93 | _ShowASNIds := sTmp; |
94 | end; |
||
95 | |||
96 | function AsnAlreadyExisting(oid: POID; asnid: string): boolean; |
||
97 | var |
||
98 | sTmp: string; |
||
99 | i: integer; |
||
100 | begin |
||
101 | for i := 0 to ListCount(oid^.AsnIds)-1 do |
||
102 | begin |
||
103 | sTmp := ListGetElement(oid^.AsnIds, i); |
||
104 | if sTmp = asnid then |
||
105 | begin |
||
106 | AsnAlreadyExisting := true; |
||
107 | exit; |
||
108 | end; |
||
109 | end; |
||
110 | AsnAlreadyExisting := false; |
||
111 | end; |
||
112 | |||
113 | function AsnEditor(oid: POID): boolean; |
||
114 | var |
||
115 | asnList: PStringList; |
||
116 | i: integer; |
||
117 | x, y, w, h: integer; |
||
118 | res: integer; |
||
119 | sInput: string; |
||
735 | daniel-mar | 120 | menuIdNew, menuIdSave, menuIdExit: integer; |
733 | daniel-mar | 121 | begin |
122 | AsnEditor := false; |
||
123 | |||
124 | repeat |
||
735 | daniel-mar | 125 | CreateList(asnList); |
733 | daniel-mar | 126 | |
127 | for i := 0 to ListCount(oid^.ASNIds)-1 do |
||
128 | begin |
||
129 | ListAppend(asnList, ListGetElement(oid^.ASNIDs, i)); |
||
130 | end; |
||
735 | daniel-mar | 131 | menuIdNew := ListAppend(asnList, '<NEW>'); |
132 | menuIdSave := ListAppend(asnList, '<SAVE>'); |
||
133 | menuIdExit := ListAppend(asnList, '<CANCEL>'); |
||
733 | daniel-mar | 134 | |
135 | DrawStatusBar(DEFAULT_STATUSBAR); |
||
136 | x := SINGLE_LINE_BOX_PADDING; |
||
137 | y := ScreenHeight div 2 - ASNEDIT_LINES div 2; |
||
138 | w := ScreenWidth - (SINGLE_LINE_BOX_PADDING-1)*2; |
||
139 | h := ASNEDIT_LINES; |
||
140 | res := DrawSelectionList(x, y, w, h, |
||
141 | asnList, true, |
||
142 | 'EDIT ASN.1 IDENTIFIERS', |
||
143 | 2); |
||
735 | daniel-mar | 144 | FreeList(asnList); |
733 | daniel-mar | 145 | |
146 | (* Change double-border to thin-border *) |
||
147 | DrawThinBorder(x-1, y-1, w+2, h+2); |
||
148 | GoToXY(x+1, y-1); |
||
149 | Write('EDIT ASN.1 IDENTIFIERS'); |
||
150 | |||
151 | if res = -1 then |
||
152 | begin |
||
153 | exit; |
||
154 | end |
||
735 | daniel-mar | 155 | else if res = menuIdNew then |
733 | daniel-mar | 156 | begin |
157 | (* "NEW" item was selected *) |
||
158 | sInput := ''; |
||
159 | repeat |
||
160 | if QueryVal(sInput, |
||
161 | SINGLE_LINE_BOX_PADDING_INNER, |
||
162 | ScreenHeight div 2, |
||
163 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
||
164 | 1, |
||
165 | 'ADD SINGLE ASN.1 ID', |
||
166 | 2) then |
||
167 | begin |
||
168 | if sInput = '' then continue; |
||
169 | if not ASN1IDValid(sInput) then |
||
170 | begin |
||
171 | ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true); |
||
172 | _Pause; |
||
173 | end |
||
174 | else if AsnAlreadyExisting(oid, sInput) then |
||
175 | begin |
||
176 | ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true); |
||
177 | _Pause; |
||
178 | end |
||
179 | else |
||
180 | begin |
||
181 | ListAppend(oid^.ASNIDs, sInput); |
||
182 | break; |
||
183 | end; |
||
184 | end |
||
185 | else break; |
||
186 | until false; |
||
187 | end |
||
735 | daniel-mar | 188 | else if res = menuIdSave then |
733 | daniel-mar | 189 | begin |
190 | (* "SAVE" item was selected *) |
||
191 | AsnEditor := true; |
||
192 | Exit; |
||
193 | end |
||
735 | daniel-mar | 194 | else if res = menuIdExit then |
733 | daniel-mar | 195 | begin |
196 | (* "CANCEL" item was selected *) |
||
197 | AsnEditor := false; |
||
198 | Exit; |
||
199 | end |
||
200 | else |
||
201 | begin |
||
202 | DrawStatusBar('Note: Remove the text to delete the ASN.1 identifier'); |
||
203 | sInput := ListGetElement(oid^.ASNIDs, res); |
||
204 | repeat |
||
205 | if QueryVal(sInput, |
||
206 | SINGLE_LINE_BOX_PADDING_INNER, |
||
207 | ScreenHeight div 2, |
||
208 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
||
209 | 1, |
||
210 | 'EDIT SINGLE ASN.1 ID', |
||
211 | 2) then |
||
212 | begin |
||
213 | if sInput = '' then |
||
214 | begin |
||
215 | (* Empty input = Delete ASN.1 ID *) |
||
737 | daniel-mar | 216 | ListDeleteElementByIndex(oid^.ASNIDs, res); |
733 | daniel-mar | 217 | break; |
218 | end |
||
219 | else if not ASN1IDValid(sInput) then |
||
220 | begin |
||
221 | ShowMessage('Invalid ASN1.ID! (Require -, a..z, A..Z, 0..9, begin with a-z)', 'ERROR', true); |
||
222 | _Pause; |
||
223 | end |
||
224 | else if AsnAlreadyExisting(oid, sInput) and |
||
225 | not (ListGetElement(oid^.ASNIDs, res) = sInput) then |
||
226 | begin |
||
227 | ShowMessage('ASN.1 identifier is already existing on this arc', 'ERROR', true); |
||
228 | _Pause; |
||
229 | end |
||
230 | else |
||
231 | begin |
||
232 | ListSetElement(oid^.ASNIDs, res, sInput); |
||
233 | break; |
||
234 | end; |
||
235 | end |
||
236 | else break; |
||
237 | until false; |
||
238 | end; |
||
239 | until false; |
||
240 | end; |
||
241 | |||
242 | function DescEditor(oid: POID): boolean; |
||
243 | var |
||
244 | sInput: string; |
||
245 | begin |
||
246 | DescEditor := false; |
||
247 | |||
248 | DrawStatusBar('Note: Press Ctrl+Return for a line-break.'); |
||
249 | sInput := oid^.description; |
||
250 | if QueryVal(sInput, |
||
251 | DESCEDIT_PADDING, |
||
252 | ScreenHeight div 2 - DESCEDIT_LINES div 2, |
||
253 | ScreenWidth - (DESCEDIT_PADDING-1)*2, |
||
254 | DESCEDIT_LINES, |
||
255 | 'EDIT DESCRIPTION', |
||
256 | 2) then |
||
257 | begin |
||
258 | oid^.description := sInput; |
||
734 | daniel-mar | 259 | DescEditor := true; (* request caller to save @oid *) |
733 | daniel-mar | 260 | end; |
261 | end; |
||
262 | |||
263 | function NextPossibleFileID: string; |
||
264 | var |
||
265 | DirInfo: SearchRec; |
||
266 | list: PStringList; |
||
267 | iId: LongInt; |
||
268 | sId: string; |
||
269 | begin |
||
270 | (* Put all found files into a list *) |
||
735 | daniel-mar | 271 | CreateList(list); |
733 | daniel-mar | 272 | FindFirst('????????.OID', Archive, DirInfo); |
273 | while DosError = 0 do |
||
274 | begin |
||
275 | sId := Copy(DirInfo.Name, 1, 8); |
||
276 | ListAppend(list, sId); |
||
277 | FindNext(DirInfo); |
||
278 | end; |
||
279 | |||
280 | (* Search for the first non existing item in the list *) |
||
281 | sId := ''; |
||
282 | for iId := 0 to 99999999 do |
||
283 | begin |
||
284 | sId := ZeroPad(iId, 8); |
||
285 | if not ListContains(list, sId) then break; |
||
286 | end; |
||
287 | NextPossibleFileId := sId; |
||
288 | FreeList(list); |
||
289 | end; |
||
290 | |||
291 | function NumIdAlreadyExisting(parentOID: POID; sInput: string): boolean; |
||
292 | var |
||
293 | searchDotNotation: string; |
||
294 | sTmp: string; |
||
295 | i: integer; |
||
296 | begin |
||
297 | if parentOID^.DotNotation = '' then |
||
298 | searchDotNotation := sInput |
||
299 | else |
||
300 | searchDotNotation := parentOID^.DotNotation + '.' + sInput; |
||
301 | for i := 0 to ListCount(parentOID^.SubIds)-1 do |
||
302 | begin |
||
303 | sTmp := ListGetElement(parentOID^.SubIds, i); |
||
735 | daniel-mar | 304 | if DotNotationPart(sTmp) = searchDotNotation then |
733 | daniel-mar | 305 | begin |
306 | NumIdAlreadyExisting := true; |
||
307 | exit; |
||
308 | end; |
||
309 | end; |
||
310 | NumIdAlreadyExisting := false; |
||
311 | end; |
||
312 | |||
313 | function NumIdEditor(oid: POID; parentOID: POID): boolean; |
||
314 | var |
||
315 | sInput: string; |
||
316 | begin |
||
317 | NumIdEditor := false; |
||
318 | sInput := ''; |
||
319 | |||
320 | repeat |
||
321 | if QueryVal(sInput, |
||
322 | SINGLE_LINE_BOX_PADDING_INNER, |
||
323 | ScreenHeight div 2, |
||
324 | ScreenWidth - (SINGLE_LINE_BOX_PADDING_INNER-1)*2, |
||
325 | 1, |
||
326 | 'ENTER NUMERIC ID', |
||
327 | 2) then |
||
328 | begin |
||
329 | if sInput = '' then continue; |
||
330 | if not IsNumeric(sInput) then |
||
331 | begin |
||
332 | ShowMessage('Invalid numeric ID (must be a positive integer)', 'ERROR', true); |
||
333 | _Pause; |
||
334 | end |
||
335 | else if (parentOID^.DotNotation='') and (StrToInt(sInput) > 2) then |
||
336 | begin |
||
337 | ShowMessage('Invalid numeric ID (root arc can only be 0, 1, or 2)', 'ERROR', true); |
||
338 | _Pause; |
||
339 | end |
||
340 | else if ((parentOID^.DotNotation='0') or (parentOID^.DotNotation='1')) and (StrToInt(sInput) > 39) then |
||
341 | begin |
||
342 | ShowMessage('Invalid numeric ID (root 0 and 1 must have sub-arc of 0..39)', 'ERROR', true); |
||
343 | _Pause; |
||
344 | end |
||
345 | else if NumIdAlreadyExisting(parentOID, sInput) then |
||
346 | begin |
||
347 | ShowMessage('This numeric ID is already used in this arc', 'ERROR', true); |
||
348 | _Pause; |
||
349 | end |
||
350 | else |
||
351 | begin |
||
352 | if parentOID^.DotNotation = '' then |
||
353 | oid^.DotNotation := sInput |
||
354 | else |
||
355 | oid^.DotNotation := parentOID^.DotNotation + '.' + sInput; |
||
734 | daniel-mar | 356 | NumIdEditor := true; (* request caller to save @oid *) |
733 | daniel-mar | 357 | Exit; |
358 | end; |
||
359 | end |
||
360 | else |
||
361 | begin |
||
362 | Exit; |
||
363 | end; |
||
364 | until false; |
||
365 | end; |
||
366 | |||
367 | function NewOidEditor(oid: POID): boolean; |
||
368 | var |
||
369 | newfilename: string; |
||
735 | daniel-mar | 370 | newOID: POID; |
733 | daniel-mar | 371 | begin |
372 | NewOidEditor := false; |
||
373 | |||
735 | daniel-mar | 374 | CreateOidDef(newOID); |
375 | newOID^.FileId := NextPossibleFileID; |
||
376 | newOID^.Parent := oid^.FileId + oid^.DotNotation; |
||
377 | if NumIdEditor(newOID, oid) and |
||
378 | AsnEditor(newOID) and |
||
379 | DescEditor(newOID) then |
||
734 | daniel-mar | 380 | begin |
735 | daniel-mar | 381 | newfilename := newOID^.FileId + '.OID'; |
382 | _WriteOidFile(newfilename, newOID); |
||
733 | daniel-mar | 383 | |
734 | daniel-mar | 384 | (* Add link to original file and enable the saving of it *) |
735 | daniel-mar | 385 | ListAppend(oid^.SubIds, newOID^.FileId + newOID^.DotNotation); |
734 | daniel-mar | 386 | NewOidEditor := true; (* request caller to save @oid *) |
387 | end; |
||
735 | daniel-mar | 388 | FreeOidDef(newOID); |
733 | daniel-mar | 389 | end; |
390 | |||
391 | procedure DeleteChildrenRecursive(oid: POID); |
||
392 | var |
||
393 | i: integer; |
||
735 | daniel-mar | 394 | childOID: POID; |
733 | daniel-mar | 395 | filenameChild: string; |
396 | begin |
||
397 | for i := 0 to ListCount(oid^.SubIds)-1 do |
||
398 | begin |
||
735 | daniel-mar | 399 | filenameChild := FileIdPart(ListGetElement(oid^.SubIds, i)) + '.OID'; |
400 | CreateOidDef(childOID); |
||
401 | _ReadOidFile(filenameChild, childOID); |
||
402 | DeleteChildrenRecursive(childOID); |
||
403 | FreeOidDef(childOID); |
||
733 | daniel-mar | 404 | DeleteFile(filenameChild); |
405 | end; |
||
406 | ListClear(oid^.SubIds); |
||
407 | end; |
||
408 | |||
409 | procedure DeleteOidRecursive(selfOID: POID); |
||
410 | var |
||
411 | i: integer; |
||
735 | daniel-mar | 412 | parentOID: POID; |
733 | daniel-mar | 413 | filenameSelf, filenameParent: string; |
414 | begin |
||
415 | (* Remove all children and their files recursively *) |
||
416 | DeleteChildrenRecursive(selfOID); |
||
417 | |||
418 | (* Remove forward reference in parent OID *) |
||
735 | daniel-mar | 419 | filenameParent := FileIdPart(selfOID^.Parent) + '.OID'; |
420 | CreateOidDef(parentOID); |
||
421 | _ReadOidFile(filenameParent, parentOID); |
||
737 | daniel-mar | 422 | if ListDeleteElementByValue(parentOID^.SubIds, selfOID^.FileId + selfOID^.DotNotation) then |
733 | daniel-mar | 423 | begin |
737 | daniel-mar | 424 | _WriteOidFile(filenameParent, parentOID); |
733 | daniel-mar | 425 | end; |
735 | daniel-mar | 426 | FreeOidDef(parentOID); |
733 | daniel-mar | 427 | |
428 | (* Delete own file *) |
||
737 | daniel-mar | 429 | filenameSelf := selfOID^.FileId + '.OID'; |
733 | daniel-mar | 430 | DeleteFile(filenameSelf); |
431 | end; |
||
432 | |||
735 | daniel-mar | 433 | function _DeleteConfirmation: boolean; |
434 | var |
||
435 | sc: Char; |
||
436 | begin |
||
437 | repeat |
||
438 | ShowMessage('Are you sure you want to delete this OID? (Y/N)', 'DELETE OID', true); |
||
737 | daniel-mar | 439 | DrawStatusBar('Y=Yes, N=No'); |
735 | daniel-mar | 440 | |
441 | sc := ReadKey; |
||
442 | if sc = #0 then |
||
443 | begin |
||
444 | (* Extended key. Nothing we care about. *) |
||
445 | ReadKey; |
||
446 | continue; |
||
447 | end; |
||
448 | |||
449 | if UpCase(sc) = 'Y' then |
||
450 | begin |
||
451 | _DeleteConfirmation := true; |
||
452 | break; |
||
737 | daniel-mar | 453 | end |
454 | else if UpCase(sc) = 'N' then |
||
735 | daniel-mar | 455 | begin |
456 | _DeleteConfirmation := false; |
||
457 | break; |
||
458 | end; |
||
459 | until false; |
||
460 | end; |
||
461 | |||
737 | daniel-mar | 462 | procedure _DrawOidTitleBar(filename: string; oid: POID); |
463 | begin |
||
464 | if oid^.DotNotation = '' then |
||
738 | daniel-mar | 465 | DrawTitleBar('OID ROOT', TITLEBAR_LEFT_TEXT, filename) |
737 | daniel-mar | 466 | else |
738 | daniel-mar | 467 | DrawTitleBar('OID ' + oid^.DotNotation, TITLEBAR_LEFT_TEXT, filename); |
737 | daniel-mar | 468 | end; |
469 | |||
733 | daniel-mar | 470 | procedure DisplayOIDFile(filename: string); |
471 | var |
||
472 | isRoot: boolean; |
||
735 | daniel-mar | 473 | oid: POID; |
733 | daniel-mar | 474 | i, menuX, menuY: integer; |
475 | linesLeft, linesRequired: integer; |
||
476 | sTmp, subfile: string; |
||
477 | subsel, subfiles: PStringList; |
||
478 | subselres: integer; |
||
735 | daniel-mar | 479 | exitRequest: boolean; |
480 | menuIdExit, menuIdAsnEdit, menuIdDescEdit, menuIdAdd, menuIdDelete: integer; |
||
733 | daniel-mar | 481 | begin |
735 | daniel-mar | 482 | exitRequest := false; |
733 | daniel-mar | 483 | repeat |
735 | daniel-mar | 484 | CreateOidDef(oid); |
485 | _ReadOidFile(filename, oid); |
||
733 | daniel-mar | 486 | |
487 | (* Print OID information *) |
||
488 | |||
489 | ClrScr; |
||
737 | daniel-mar | 490 | _DrawOidTitleBar(filename, oid); |
733 | daniel-mar | 491 | DrawStatusBar(DEFAULT_STATUSBAR); |
492 | GotoXY(1,2); |
||
493 | |||
735 | daniel-mar | 494 | if oid^.DotNotation <> '' then |
733 | daniel-mar | 495 | begin |
496 | WriteLn('Dot-Notation:'); |
||
735 | daniel-mar | 497 | WriteLn(oid^.DotNotation); |
733 | daniel-mar | 498 | WriteLn(''); |
499 | end; |
||
500 | |||
735 | daniel-mar | 501 | if Trim(oid^.Description) <> '' then |
733 | daniel-mar | 502 | begin |
503 | WriteLn('Description:'); |
||
735 | daniel-mar | 504 | WriteLn(oid^.Description); |
733 | daniel-mar | 505 | WriteLn(''); |
506 | end; |
||
507 | |||
508 | menuX := WhereX + 1; |
||
735 | daniel-mar | 509 | menuY := ScreenHeight - ACTIONMENU_SIZE - 1; |
733 | daniel-mar | 510 | |
735 | daniel-mar | 511 | if ListCount(oid^.ASNIDs) > 0 then |
733 | daniel-mar | 512 | begin |
513 | linesLeft := menuY - WhereY - 1; |
||
735 | daniel-mar | 514 | linesRequired := 1 + ListCount(oid^.ASNIds); |
733 | daniel-mar | 515 | |
516 | if LinesLeft < LinesRequired then |
||
517 | begin |
||
518 | (* Compact display of ASN.1 identifiers *) |
||
519 | Write('ASN.1-Identifiers: '); |
||
735 | daniel-mar | 520 | for i := 0 to ListCount(oid^.ASNIds)-1 do |
733 | daniel-mar | 521 | begin |
522 | if i > 0 then Write(', '); |
||
735 | daniel-mar | 523 | Write(ListGetElement(oid^.ASNIds, i)); |
733 | daniel-mar | 524 | end; |
525 | WriteLn(''); |
||
526 | end |
||
527 | else |
||
528 | begin |
||
529 | (* Long display of ASN.1 identifiers *) |
||
530 | WriteLn('ASN.1-Identifiers:'); |
||
735 | daniel-mar | 531 | for i := 0 to ListCount(oid^.ASNIds)-1 do |
733 | daniel-mar | 532 | begin |
735 | daniel-mar | 533 | WriteLn('- '+ListGetElement(oid^.ASNIds, i)); |
733 | daniel-mar | 534 | end; |
535 | WriteLn(''); |
||
536 | end; |
||
537 | end; |
||
538 | |||
539 | (* Now prepare the menu entries *) |
||
540 | |||
737 | daniel-mar | 541 | CreateList(subsel); (* Contains the human readable OID name *) |
542 | CreateList(subfiles); (* Contains the file name *) |
||
733 | daniel-mar | 543 | |
735 | daniel-mar | 544 | if oid^.Parent = '' then |
733 | daniel-mar | 545 | begin |
546 | isRoot := true; |
||
547 | end |
||
548 | else |
||
549 | begin |
||
735 | daniel-mar | 550 | isRoot := DotNotationPart(oid^.Parent) = oid^.DotNotation; |
733 | daniel-mar | 551 | end; |
552 | |||
735 | daniel-mar | 553 | if (oid^.Parent <> '') and not isRoot then |
733 | daniel-mar | 554 | begin |
735 | daniel-mar | 555 | sTmp := oid^.Parent; |
556 | subfile := FileIdPart(sTmp) + '.OID'; |
||
557 | ListAppend(subsel, 'Go to parent ' + DotNotationPart(sTmp) + _ShowASNIds(subfile)); |
||
733 | daniel-mar | 558 | ListAppend(subfiles, subfile); |
559 | end; |
||
560 | |||
561 | if isRoot then |
||
562 | begin |
||
735 | daniel-mar | 563 | menuIdExit := ListAppend(subsel, 'Back to main menu'); |
564 | ListAppend(subfiles, ''); |
||
565 | end |
||
566 | else menuIdExit := -99; |
||
733 | daniel-mar | 567 | |
735 | daniel-mar | 568 | for i := 0 to ListCount(oid^.SubIds)-1 do |
733 | daniel-mar | 569 | begin |
735 | daniel-mar | 570 | sTmp := ListGetElement(oid^.SubIds, i); |
571 | subfile := FileIdPart(sTmp) + '.OID'; |
||
572 | ListAppend(subsel, 'Go to child ' + DotNotationPart(sTmp) + _ShowASNIds(subfile)); |
||
733 | daniel-mar | 573 | ListAppend(subfiles, subfile); |
574 | end; |
||
575 | |||
735 | daniel-mar | 576 | if oid^.DotNotation <> '' then |
733 | daniel-mar | 577 | begin |
735 | daniel-mar | 578 | menuIdAsnEdit := ListAppend(subsel, 'Edit ASN.1 identifiers'); |
579 | ListAppend(subfiles, ''); |
||
580 | end |
||
581 | else menuIdAsnEdit := -99; |
||
733 | daniel-mar | 582 | |
735 | daniel-mar | 583 | menuIdDescEdit := ListAppend(subsel, 'Edit description'); |
584 | ListAppend(subfiles, ''); |
||
733 | daniel-mar | 585 | |
735 | daniel-mar | 586 | menuIdAdd := ListAppend(subsel, 'Add child'); |
587 | ListAppend(subfiles, ''); |
||
733 | daniel-mar | 588 | |
589 | if not isRoot then |
||
590 | begin |
||
735 | daniel-mar | 591 | menuIdDelete := ListAppend(subsel, 'Delete OID'); |
592 | ListAppend(subfiles, ''); |
||
593 | end |
||
594 | else menuIdDelete := -99; |
||
733 | daniel-mar | 595 | |
734 | daniel-mar | 596 | (* Show menu *) |
597 | |||
733 | daniel-mar | 598 | subselres := DrawSelectionList(menuX, menuY, |
599 | ScreenWidth-2, |
||
735 | daniel-mar | 600 | ACTIONMENU_SIZE, |
733 | daniel-mar | 601 | subsel, |
602 | true, |
||
603 | 'SELECT ACTION', |
||
604 | 1); |
||
734 | daniel-mar | 605 | |
606 | (* Process user selection *) |
||
607 | |||
733 | daniel-mar | 608 | if subselres = -1 then |
609 | begin |
||
735 | daniel-mar | 610 | exitRequest := true; |
733 | daniel-mar | 611 | end |
735 | daniel-mar | 612 | else if subselres = menuIdAsnEdit then |
733 | daniel-mar | 613 | begin |
735 | daniel-mar | 614 | if AsnEditor(oid) then |
615 | _WriteOidFile(filename, oid); |
||
616 | end |
||
617 | else if subselres = menuIdDescEdit then |
||
618 | begin |
||
619 | if DescEditor(oid) then |
||
620 | _WriteOidFile(filename, oid); |
||
621 | end |
||
622 | else if subselres = menuIdAdd then |
||
623 | begin |
||
624 | if NewOidEditor(oid) then |
||
625 | _WriteOidFile(filename, oid); |
||
626 | end |
||
627 | else if subselres = menuIdDelete then |
||
628 | begin |
||
629 | if _DeleteConfirmation then |
||
733 | daniel-mar | 630 | begin |
735 | daniel-mar | 631 | filename := FileIdPart(oid^.Parent) + '.OID'; |
632 | DeleteOidRecursive(oid); |
||
733 | daniel-mar | 633 | end; |
735 | daniel-mar | 634 | end |
635 | else if subselres = menuIdExit then |
||
636 | begin |
||
637 | exitRequest := true; |
||
638 | end |
||
639 | else |
||
640 | begin |
||
641 | (* Normal OID *) |
||
642 | filename := ListGetElement(subfiles, subselres); |
||
733 | daniel-mar | 643 | end; |
644 | FreeList(subsel); |
||
645 | FreeList(subfiles); |
||
646 | |||
735 | daniel-mar | 647 | FreeOidDef(oid); |
648 | until exitRequest; |
||
733 | daniel-mar | 649 | end; |
650 | |||
651 | procedure CreateInitOIDFile(filename: string); |
||
652 | var |
||
735 | daniel-mar | 653 | oid: POID; |
733 | daniel-mar | 654 | begin |
735 | daniel-mar | 655 | CreateOidDef(oid); |
656 | oid^.Description := 'This is the root of the OID tree.' +#13#10 + |
||
657 | #13#10 + |
||
658 | 'Valid subsequent arcs are per definition:' + #13#10 + |
||
659 | '- 0 (itu-t)' + #13#10 + |
||
660 | '- 1 (iso)' + #13#10 + |
||
661 | '- 2 (joint-iso-itu-t)'; |
||
737 | daniel-mar | 662 | oid^.FileId := ZeroPad(0, 8); |
735 | daniel-mar | 663 | oid^.DotNotation := ''; |
737 | daniel-mar | 664 | oid^.Parent := ZeroPad(0, 8); |
735 | daniel-mar | 665 | _WriteOidFile(filename, oid); |
666 | FreeOidDef(oid); |
||
733 | daniel-mar | 667 | end; |
668 | |||
669 | procedure OP_ManageOIDs; |
||
735 | daniel-mar | 670 | var |
671 | initFile: string; |
||
733 | daniel-mar | 672 | begin |
673 | ClrScr; |
||
738 | daniel-mar | 674 | DrawTitleBar('Manage Object Identifiers', TITLEBAR_LEFT_TEXT, ''); |
675 | DrawStatusBar('Loading data... please wait...'); |
||
733 | daniel-mar | 676 | |
735 | daniel-mar | 677 | initFile := ZeroPad(0, 8) + '.OID'; |
678 | if not FileExists(initFile) then |
||
733 | daniel-mar | 679 | begin |
735 | daniel-mar | 680 | CreateInitOIDFile(initFile); |
733 | daniel-mar | 681 | end; |
735 | daniel-mar | 682 | DisplayOIDFile(initFile); |
733 | daniel-mar | 683 | end; |
684 | |||
685 | procedure OP_ManageRAs; |
||
686 | begin |
||
687 | ClrScr; |
||
738 | daniel-mar | 688 | DrawTitleBar('Manage Registration Authorities', TITLEBAR_LEFT_TEXT, ''); |
733 | daniel-mar | 689 | DrawStatusBar(''); |
690 | |||
691 | (* TODO: Implement "Manage RAs" feature *) |
||
692 | end; |
||
693 | |||
694 | procedure OP_ReturnToMSDOS; |
||
695 | begin |
||
696 | ClrScr; |
||
697 | end; |
||
698 | |||
699 | procedure OP_MainMenu; |
||
700 | var |
||
701 | menu: PStringList; |
||
702 | menuRes, menuLeft, menuTop: integer; |
||
735 | daniel-mar | 703 | menuIdOID, menuIdRA, menuIdExit: integer; |
733 | daniel-mar | 704 | begin |
705 | repeat |
||
706 | ClrScr; |
||
707 | |||
738 | daniel-mar | 708 | DrawTitleBar('Welcome to OIDplus for DOS', '', ''); |
733 | daniel-mar | 709 | DrawStatusBar(DEFAULT_STATUSBAR); |
710 | GoToXY(ScreenWidth-Length(VERSIONINFO), ScreenHeight-1); |
||
711 | Write(VERSIONINFO); |
||
712 | |||
735 | daniel-mar | 713 | CreateList(menu); |
714 | |||
715 | menuIdOID := ListAppend(menu, 'Manage OIDs'); |
||
716 | menuIdRA := -99; (*ListAppend(menu, 'Manage RAs');*) |
||
717 | menuIdExit := ListAppend(menu, 'Return to DOS'); |
||
718 | |||
719 | menuLeft := round(ScreenWidth/2 -MAINMENU_WIDTH/2); |
||
720 | menuTop := round(ScreenHeight/2-MAINMENU_HEIGHT/2); |
||
721 | menuRes := DrawSelectionList(menuLeft, menuTop, |
||
722 | MAINMENU_WIDTH, MAINMENU_HEIGHT, |
||
723 | menu, true, 'MAIN MENU', 2); |
||
733 | daniel-mar | 724 | FreeList(menu); |
725 | |||
735 | daniel-mar | 726 | if menuRes = menuIdOID then |
733 | daniel-mar | 727 | begin |
728 | OP_ManageOIDs; |
||
735 | daniel-mar | 729 | end |
730 | else if menuRes = menuIdRA then |
||
733 | daniel-mar | 731 | begin |
732 | OP_ManageRAs; |
||
733 | end; |
||
735 | daniel-mar | 734 | until (menuRes = menuIdExit) or (MAINMENU_ALLOW_ESC and (menuRes = -1)); |
733 | daniel-mar | 735 | |
736 | OP_ReturnToMSDOS; |
||
737 | end; |
||
738 | |||
739 | begin |
||
740 | OP_MainMenu; |
||
741 | end. |