home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume10 / sh_dos / part06 < prev    next >
Text File  |  1990-02-13  |  30KB  |  1,324 lines

  1. Newsgroups: comp.sources.misc
  2. organization: ITM Sector, Data Logic Ltd. (A Raytheon Company)
  3. From: istewart@datlog.co.uk (Ian Stewartson)
  4. subject: v10i058: MSDOS Shell (sh) Implementation - Part 05 of 05
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 10, Issue 58
  8. Submitted-by: istewart@datlog.co.uk (Ian Stewartson)
  9. Archive-name: sh_dos/part06
  10.  
  11. #!/bin/sh
  12. # this is part 5 of a multipart archive
  13. # do not concatenate these parts, unpack them in order with /bin/sh
  14. # file shell/sh0.asm continued
  15. #
  16. CurArch=5
  17. if test ! -r s2_seq_.tmp
  18. then echo "Please unpack part 1 first!"
  19.      exit 1; fi
  20. ( read Scheck
  21.   if test "$Scheck" != $CurArch
  22.   then echo "Please unpack part $Scheck next!"
  23.        exit 1;
  24.   else exit 0; fi
  25. ) < s2_seq_.tmp || exit 1
  26. echo "x - Continuing file shell/sh0.asm"
  27. sed 's/^X//' << 'SHAR_EOF' >> shell/sh0.asm
  28. X    call    $GDT_src_load
  29. X
  30. X;
  31. X; Check for end of copy - BX contains the file handler for disk write
  32. X;
  33. X
  34. X$Write_loop:
  35. X    or    si, si
  36. X    je    $Write_Complete
  37. X
  38. X; OK - Copy next 0x4000 bytes - switch on device
  39. X
  40. X    mov    ax, word ptr cs: _SW_Mode
  41. X    dec    ax
  42. X    jz    $Write_disk
  43. X    dec    ax
  44. X    jz    $W_extend
  45. X    jmp    $W_expand
  46. X
  47. X; Write to disk
  48. X
  49. X$Write_disk:
  50. X    mov    ax, 04000H        ; Set up to write
  51. X    mov    cx, ax            ; Load count
  52. X    xor    dx, dx            ; Clear start address
  53. X    push    bx            ; Save FP
  54. X    push    si            ; Save count and Data Segment
  55. X
  56. X    int    021H            ; Write the data
  57. X
  58. X    pop    si            ; Restore Regs
  59. X    pop    bx
  60. X    jc    $Write_error        ; NO - abort
  61. X
  62. X$Write_Incr:
  63. X    dec    si            ; Decrement block count
  64. X    mov    ax, ds            ; Increment offset
  65. X    add    ax, 0400H
  66. X    mov    ds, ax
  67. X    jmp    $Write_loop
  68. X
  69. X; Write to extended memory
  70. X
  71. X$W_extend:
  72. X    call    $Write_extend
  73. X    jc    $Write_error        ; NO - abort
  74. X
  75. X    dec    si            ; Decrement block count
  76. X    call    $Inc_Extend
  77. X    jmp    $Write_loop
  78. X
  79. X; Write to expanded memory
  80. X;    BX - handler
  81. X;    SI - count
  82. X;    DS - source segment
  83. X;
  84. X$W_expand:
  85. X    call    $map_ems_page        ; Map in the current EMS page
  86. X    jnz    $Write_error
  87. X
  88. X    push    ds            ; Save DS and SI
  89. X    push    si
  90. X    mov    es, word ptr cs:_SW_EMSFrame    ; Set Dest Seg
  91. X    xor    si, si            ; Clear start
  92. X    xor    di, di
  93. X    mov    cx, 02000H        ; move 16K
  94. X    pushf                ; Save direction flag
  95. X    cld
  96. X    rep movsw
  97. X    popf                ; Restore direction flag
  98. X    pop    si            ; And DS, SI
  99. X    pop    ds
  100. X    jmp    $Write_Incr        ; Increment DS and dec SI
  101. X
  102. X;
  103. X; Error - abort.  The error code is in AH.
  104. X;
  105. X
  106. X$Write_error:
  107. X    mov    ds, word ptr cs:S_ds    ; Restore DS
  108. X    mov    al, ah
  109. X    xor    ah, ah
  110. X    mov    word ptr ds:_errno, ax    ; Save error code
  111. X    mov    ax, 0FFFEH
  112. X    jmp    $SA_spawn_Exit        ; Exit
  113. X
  114. X;
  115. X; Swap file is now written, set up environment
  116. X;
  117. X$Write_Complete:
  118. X    mov    ds, word ptr cs:exec_env    ; Load Env seg.
  119. X    xor    si, si                ; Clear start offset
  120. X
  121. X;
  122. X; Copy into Env Seg
  123. X;
  124. X
  125. X$Copy_Env:
  126. X    les    bx, dword ptr ss:[bp + 6]    ; Check for end of loop
  127. X    mov    ax, word ptr es:[bx + 0]
  128. X    or    ax, word ptr es:[bx + 2]
  129. X    je    $Copy_End
  130. X
  131. X;
  132. X; Save start address
  133. X;
  134. X    add    word ptr ss:[bp + 6], 4        ; Increment environment by 4
  135. X
  136. X    mov    cx, word ptr es:[bx + 0]    ; Load address of cur Env string
  137. X    mov    ax, word ptr es:[bx + 2]    ; into es:bx
  138. X    mov    es, ax
  139. X    mov    bx, cx
  140. X
  141. X;
  142. X; Copy this value
  143. X;
  144. X
  145. X$Copy_Val:
  146. X    mov    al, byte ptr es:[bx]    ; Copy across
  147. X    mov    byte ptr ds:[si], al
  148. X    inc    bx            ; Increment pointers
  149. X    inc    si
  150. X    or    al, al
  151. X    jne    $Copy_Val
  152. X    jmp    $Copy_Env
  153. X
  154. X;
  155. X; Set up exec parameter block     - DS is on stack
  156. X;
  157. X$Copy_End:
  158. X    xor    ax, ax
  159. X    mov    word ptr ds:[si], ax    ; Terminate environment
  160. X    add    si, 2
  161. X
  162. X;
  163. X; Set up new program length
  164. X;
  165. X    add    si, 16            ; Round up paras
  166. X    mov    dx, si            ; Save end offset in DX
  167. X    mov    bx, ds
  168. X
  169. X    mov    cl, 4
  170. X    shr    si, cl            ; # paras used by Env
  171. X    add    si, bx            ; End para number
  172. X
  173. X    mov    bx, word ptr cs:N_mcb    ; Load our MCB address in BX
  174. X    mov    ax, bx
  175. X    inc    ax
  176. X    sub    si, ax
  177. X    mov    cx, si            ; Save new max paras in CX
  178. X
  179. X;
  180. X; Use interrupt 4a to shrink memory.  First release all memory above us.
  181. X;
  182. X    push    ax
  183. X    push    cx            ; Save Max paras and location
  184. X    mov    ds, bx            ; Set up the segement for MCB
  185. X    mov    cx, word ptr ds:3    ; Get the MCB length
  186. X
  187. X; Are we the only one in the chain?
  188. X
  189. X    cmp    byte ptr ds:0, 'Z'    ; End of chain ?
  190. X    jz    $Shrink_First
  191. X
  192. X;
  193. X; Loop round releasing memory blocks
  194. X;
  195. X;    CX - original length of block;
  196. X;    DS - segement of the previous block
  197. X;
  198. X$Shrink_Next:
  199. X    mov    ax, ds            ; Move to the next block
  200. X    add    cx, ax
  201. X    inc    cx
  202. X    mov    ds, cx
  203. X
  204. X    cmp    byte ptr ds:0, 'Z'    ; End of chain ?
  205. X    jz    $Shrink_First
  206. X
  207. X    mov    cx, word ptr ds:3    ; Save the length of this block
  208. X
  209. X    mov    ax, ds            ; Advance to the block itself
  210. X    inc    ax
  211. X    mov    es, ax            ; Set up Block address
  212. X
  213. X    mov    ah, 049H
  214. X    int    021H
  215. X    jmp    $Shrink_Next
  216. X
  217. X;
  218. X;    Shrink the PSP segment
  219. X;
  220. X
  221. X$Shrink_First:
  222. X    pop    cx
  223. X    pop    ax
  224. X        mov    es, ax            ; Set PSP address
  225. X    mov    bx, cx            ; Set max length
  226. X    mov    ah, 04aH
  227. X    int    021H
  228. X
  229. X;
  230. X; Execute function
  231. X;
  232. X
  233. X    mov    word ptr cs: S_sp, sp    ; Save the current stack
  234. X    mov    word ptr cs: S_ss, ss
  235. X
  236. X;
  237. X; Move to the local stack so that it doesn't get overwritten.
  238. X;
  239. X    mov    ax, cs
  240. X    cli
  241. X    mov    sp, offset Local_Stack
  242. X    mov    ss, ax
  243. X    sti
  244. X
  245. X; Clear out Interrupts
  246. X
  247. X    mov    ah, 00bH        ; Check Keyboard status
  248. X    int    021H
  249. X
  250. X;
  251. X;  Check for interrupt 23 detected
  252. X;
  253. X    mov    ax, word ptr cs:_SW_intr
  254. X    xor    ax, ax
  255. X    jz    $I23_Cf            ; No - continue;
  256. X
  257. X;
  258. X; Interrupt 23 detected - abort
  259. X;
  260. X    mov    ax, cs            ; Set up for reload
  261. X    cli
  262. X    mov    sp, offset Local_Stack
  263. X    mov    ss, ax
  264. X    sti
  265. X
  266. X    mov    ds, word ptr cs:S_ds    ; Restore DS
  267. X    mov    word ptr ds:_errno, 4    ; Set to EINTR
  268. X    jmp    $Exec_Error
  269. X
  270. X;
  271. X; No interrupts - continue
  272. X;
  273. X$I23_Cf:
  274. X    mov    ax, cs            ; Set up segments
  275. X    mov    es, ax
  276. X    mov    ds, ax
  277. X
  278. X    mov    ax, 04b00H        ; Load and execute function
  279. X    mov    dx, offset _path_line    ; Load path
  280. X    mov    bx, offset exec_parms    ; Load the execute structure
  281. X    mov    byte ptr cs:InShell, 1    ; Set not In shell flag for Interrupt 23
  282. X    int    021H
  283. X    mov    byte ptr cs:InShell, 0    ; Set In shell flag for Interrupt 23
  284. X
  285. X; Disable interrupts while we restore the stack to the local one
  286. X
  287. X    mov    ax, cs
  288. X    cli
  289. X    mov    sp, offset Local_Stack
  290. X    mov    ss, ax
  291. X    sti
  292. X
  293. X;
  294. X; Did an error occur?
  295. X;
  296. X    jnc    $Exec_OK
  297. X
  298. X;
  299. X; Error
  300. X;
  301. X    mov    ds, word ptr cs:S_ds    ; Restore DS
  302. X    mov    ah, al
  303. X    call    far ptr __maperror    ; Map the error
  304. X
  305. X$Exec_Error:
  306. X    mov    ax, 0FFFFH
  307. X    jmp    $Exec_Complete
  308. X
  309. X;
  310. X; No - get the exit code and check for interrupts
  311. X;
  312. X
  313. X$Exec_OK:
  314. X    mov    ax, 04d00H
  315. X    int    021H
  316. X    dec    ah            ; Interrupt termination ?
  317. X    jnz    $Exec_OK1
  318. X
  319. X    inc    word ptr ds:_SW_intr    ; Set Interrupt 23 detected.
  320. X
  321. X$Exec_OK1:
  322. X    xor    ah, ah
  323. X
  324. X;
  325. X; Save the result code
  326. X;
  327. X
  328. X$Exec_Complete:
  329. X    mov    word ptr cs:Result, ax        ; Save response
  330. X
  331. X;
  332. X; Very Dangerous - Restore Environment
  333. X;
  334. X;     Seek to 0x4000 in file
  335. X;
  336. X    mov    bx, word ptr cs:_SW_fp        ; Load File Handler
  337. X    mov    ax, word ptr cs: _SW_Mode    ; Skip if not disk
  338. X    dec    ax
  339. X    jnz    $Seek_OK
  340. X
  341. X; Seek in file to skip 16K
  342. X
  343. X    mov    dx, 04000H
  344. X    call    $Seek_Disk
  345. X
  346. X;
  347. X;     Load from N_mcb:0x4000 to end of file.
  348. X;
  349. X
  350. X$Seek_OK:
  351. X    mov    si, word ptr cs:_SW_Blocks    ; Load number of transfers
  352. X    dec    si                ; Skip first block
  353. X
  354. X;
  355. X; set up ES register with start of load
  356. X;
  357. X    mov    ax, word ptr cs:N_mcb    ; Load the start address
  358. X    add    ax, 0400H
  359. X    mov    ds, ax
  360. X
  361. X; load up extended memory GDT for destination
  362. X
  363. X    call    $GDT_reload
  364. X    call    $Inc_Extend            ; Increment addresses by 16K
  365. X
  366. X;
  367. X; Check for end of copy    - BX - File Handler for disk
  368. X;
  369. X
  370. X$Read_loop:
  371. X    or    si, si
  372. X    je    $Read_Complete
  373. X
  374. X; OK - Copy next 0x4000 bytes - switch on device
  375. X
  376. X    mov    ax, word ptr cs: _SW_Mode
  377. X    dec    ax
  378. X    jz    $R_disk
  379. X    dec    ax
  380. X    jz    $R_extend
  381. X    jmp    $R_expand
  382. X
  383. X; Read from disk
  384. X
  385. X$R_disk:
  386. X    call    $Read_disk
  387. X    jmp    $Read_loop
  388. X
  389. X; Read from extended memory
  390. X
  391. X$R_extend:
  392. X    call    $Read_extend
  393. X    jmp    $Read_loop
  394. X
  395. X; Read from expanded memory
  396. X
  397. X$R_expand:
  398. X    call    $Read_EMS
  399. X    jmp    $Read_loop
  400. X
  401. X;
  402. X; Re-load is now complete, Restore original stack which has just been
  403. X; reloaded.  BX contains FP
  404. X;
  405. X
  406. X$Read_Complete:
  407. X    cli
  408. X    mov    sp, word ptr cs: S_sp        ; Save the current stack
  409. X    mov    ss, word ptr cs: S_ss
  410. X    sti
  411. X
  412. X;  Save exit code
  413. X
  414. X    push    word ptr cs:Result        ; Save response
  415. X
  416. X;
  417. X; Read in the first block - BX - File Handler
  418. X;
  419. X
  420. X    mov    ax, word ptr cs: _SW_Mode    ; Skip if not disk
  421. X    dec    ax
  422. X    jnz    $Seek1_OK
  423. X
  424. X; Seek to 0 in file
  425. X
  426. X    xor    dx, dx
  427. X    call    $Seek_Disk
  428. X
  429. X;
  430. X;     Load one block at N_mcb:0x0000
  431. X;
  432. X$Seek1_OK:
  433. X    mov    ds, word ptr cs:N_mcb        ; Load the start address
  434. X    call    $GDT_reload            ; Load the GDT for extend mem
  435. X
  436. X    mov    ax, word ptr cs: _SW_Mode    ; Skip if not disk
  437. X    dec    ax
  438. X    jz    $R1_Disk
  439. X    dec    ax
  440. X    jz    $R1_Extend
  441. X    jmp    $R1_Expand
  442. X
  443. X$R1_Disk:
  444. X    call    $Read_disk
  445. X    jmp    $Read1_OK
  446. X
  447. X$R1_Extend:
  448. X    call    $Read_extend
  449. X    jmp    $Read1_OK
  450. X
  451. X$R1_Expand:
  452. X    mov    si, word ptr cs:_SW_Blocks    ; Read first block
  453. X    call    $Read_EMS
  454. X
  455. X;
  456. X; Complete - load error code and return
  457. X;
  458. X
  459. X$Read1_OK:
  460. X    pop    ax
  461. X
  462. X;
  463. X; Exit function - Restore Control Interrupt handler
  464. X;
  465. X
  466. X$SA_spawn_Exit:
  467. X    push    ax                ; Save exit code
  468. X    mov    ax, 02523H            ; Set Control C Interrupt
  469. X    mov    ds, word ptr cs:_SW_I23_V_ES
  470. X    mov    dx, word ptr cs:_SW_I23_V_BX
  471. X    int    021H
  472. X
  473. X    mov    ax, 02523H            ; Set Divide Zero Interrupt
  474. X    mov    ds, word ptr cs:_SW_I0_V_ES
  475. X    mov    dx, word ptr cs:_SW_I0_V_BX
  476. X
  477. X;
  478. X
  479. X    mov    di, word ptr cs:S_di        ; Restore saved registers
  480. X    mov    si, word ptr cs:S_si
  481. X    mov    ds, word ptr cs:S_ds
  482. X
  483. X; If interrupt 23 detected - raise the flag
  484. X
  485. X    mov    ax, word ptr cs:_SW_intr    ; Set Interrupt 23 detected.
  486. X    or    ax, ax
  487. X    jz    $SA_Exit1
  488. X
  489. X    mov    ax, 02H
  490. X    push    ax                ; Set SIGINT
  491. X    call    _raise
  492. X    add    sp, 2
  493. X
  494. X$SA_Exit1:
  495. X    pop    ax                ; Restore result
  496. X    mov    sp,bp
  497. X    pop    bp
  498. X    ret
  499. X
  500. X_SA_spawn    endp
  501. X
  502. X;
  503. X; READ DISK FUNCTION
  504. X;
  505. X;    BX - file handler
  506. X;    SI - Block count
  507. X;    DS - Output data segement
  508. X;
  509. X
  510. X$Read_disk    proc    near
  511. X
  512. X    mov    ax, 03f00H        ; Set up to read
  513. X    mov    cx, 04000H        ; Load count
  514. X    xor    dx, dx            ; Clear start address
  515. X
  516. X    int    021H            ; Read the data
  517. X
  518. X    jnc    $Read_OK        ; NO - abort
  519. X    jmp    Load_Error        ; Abort - swap file error
  520. X
  521. X;
  522. X; Read OK - next block
  523. X;
  524. X
  525. X$Read_OK:
  526. X    dec    si            ; Decrement block count
  527. X    mov    ax, ds            ; Increment offset
  528. X    add    ax, 0400H
  529. X    mov    ds, ax
  530. X    ret
  531. X
  532. X$Read_disk    endp
  533. X
  534. X;
  535. X; READ EMS FUNCTION
  536. X;
  537. X;    BX - file handler
  538. X;    SI - Block count - counts from max
  539. X;    DS - Output data segement
  540. X;
  541. X
  542. X$Read_EMS    proc    near
  543. X
  544. X    call    $map_ems_page        ; Map in the current EMS page
  545. X    jnz    Load_Error
  546. X
  547. X    push    ds            ; Save DS and SI
  548. X    push    si
  549. X    mov    ax, ds
  550. X    mov    es, ax
  551. X    mov    ds, word ptr cs:_SW_EMSFrame    ; Set Dest Seg
  552. X    xor    si, si            ; Clear start
  553. X    xor    di, di
  554. X    mov    cx, 02000H        ; move 16K
  555. X    pushf                ; Save direction flag
  556. X    cld
  557. X    rep movsw
  558. X    popf                ; Restore direction flag
  559. X    pop    si            ; And DS, SI
  560. X    pop    ds
  561. X    jmp    $Read_OK        ; Increment DS and dec SI
  562. X
  563. X$Read_EMS    endp
  564. X
  565. X;
  566. X; MAP IN THE CURRENT EMS PAGE
  567. X;
  568. X;    BX - file handler
  569. X;    SI - Block count - counts from max
  570. X;    DS - Output data segement
  571. X;
  572. X
  573. X$map_ems_page    proc    near
  574. X
  575. X    push    bx            ; Need to save BX
  576. X    mov    ax, 04400h        ; Map into physical page zero
  577. X    mov    dx, bx            ; Set up handler
  578. X    mov    bx, word ptr cs: _SW_Blocks
  579. X    sub    bx, si
  580. X
  581. X    int    067H
  582. X    pop    bx
  583. X
  584. X    or    ah, ah
  585. X    ret
  586. X
  587. X$map_ems_page    endp
  588. X
  589. X;
  590. X; DISK SEEK FUNCTION
  591. X;
  592. X;    BX - file handler
  593. X;    DX - offset
  594. X;
  595. X$Seek_Disk    proc    near
  596. X
  597. X    mov    ax, 04200H        ; Set seek
  598. X    xor    cx, cx
  599. X    int    021H
  600. X    jc    Load_Error        ; Abort - swap file error
  601. X    ret
  602. X
  603. X$Seek_Disk    endp
  604. X
  605. X;
  606. X; PANIC - Abort
  607. X;
  608. X
  609. XLoad_Error    proc    near
  610. X
  611. X    mov    ax, 00900H
  612. X    mov    dx, offset Swap_PANIC
  613. X    mov    bx, cs
  614. X    mov    ds, bx
  615. X    int    021H
  616. X$Wait_L:
  617. X    sti
  618. X    hlt
  619. X    jmp    $Wait_L
  620. X
  621. XLoad_Error    endp
  622. X
  623. X;
  624. X;  WRITE EXTENDED MEMORY
  625. X;
  626. X;    SI - Block count
  627. X;
  628. X$Write_extend    proc    near
  629. X
  630. X    push    si            ; Save SI (block counter)
  631. X    mov    cx, 02000H        ; Copy a 16K block
  632. X    mov    ax, cs            ; Set up GDT address
  633. X    mov    es, ax
  634. X    mov    si, offset GD_table
  635. X
  636. X    mov    ah, 087H        ; EMS function
  637. X    int    015H
  638. X    pop    si
  639. X    ret
  640. X
  641. X$Write_extend    endp
  642. X
  643. X;
  644. X;  READ FROM EXTENDED MEMORY
  645. X;
  646. X;    SI - Block count
  647. X;
  648. X
  649. X$Read_extend    proc    near
  650. X
  651. X    call    $Write_extend
  652. X    jc    Load_Error        ; NO - abort
  653. X
  654. X    dec    si            ; Decrement block count
  655. X
  656. X$Read_extend    endp
  657. X
  658. X;
  659. X; INCREMENT Extended MEMORY GDT
  660. X;
  661. X;    AX - used
  662. X;
  663. X$Inc_Extend    proc    near
  664. X
  665. X    mov    ax, 04000H        ; Increment address by 16K
  666. X    add    word ptr cs:GDT_dest_low, ax
  667. X    adc    byte ptr cs:GDT_dest_high, 0
  668. X    add    word ptr cs:GDT_src_low, ax
  669. X    adc    byte ptr cs:GDT_src_high, 0
  670. X    ret
  671. X
  672. X$Inc_Extend    endp
  673. X
  674. X;
  675. X; LOAD SOURCE GDT ADDRESS
  676. X;
  677. X;    AX - low order
  678. X;    DL - high order
  679. X;
  680. X$GDT_src_load    proc    near
  681. X
  682. X
  683. X    mov    word ptr cs:GDT_src_low, ax
  684. X    mov    byte ptr cs:GDT_src_high, dl
  685. X    ret
  686. X
  687. X$GDT_src_load    endp
  688. X
  689. X;
  690. X; LOAD DESTINATION GDT ADDRESS
  691. X;
  692. X;    AX - low order
  693. X;    DL - high order
  694. X;
  695. X$GDT_dest_load    proc    near
  696. X
  697. X    mov    word ptr cs:GDT_dest_low, ax
  698. X    mov    byte ptr cs:GDT_dest_high, dl
  699. X    ret
  700. X
  701. X$GDT_dest_load    endp
  702. X
  703. X;
  704. X; LOAD the GDT for reloading
  705. X;
  706. X
  707. X$GDT_reload    proc    near
  708. X    mov    ax, word ptr cs:_SW_EMstart     ; Load Full start address
  709. X    mov    dl, byte ptr cs:_SW_EMstart + 2
  710. X    call    $GDT_src_load
  711. X
  712. X    mov    ax, word ptr cs:SW_LMstart     ; Load Full start address
  713. X    mov    dl, byte ptr cs:SW_LMstart + 2
  714. X    call    $GDT_dest_load
  715. X    ret
  716. X$GDT_reload    endp
  717. X
  718. X;
  719. X; CONTROL C INTERRUPT HANDLER - IGNORE
  720. X;
  721. X
  722. XSA_IRET        proc    far
  723. X    push    ax
  724. X    push    bp            ; Save the AX and DS registers
  725. X    push    ds
  726. X    mov    bp, seg SH0_TEXT    ; Get my segment
  727. X    mov    ds, bp
  728. X    inc    word ptr ds:_SW_intr    ; Set Interrupt 23 detected.
  729. X    cmp    byte ptr ds:InShell, 0    ; Are we in the shell ?
  730. X    jz    $SA_Ins
  731. X
  732. X; In another program - move the stack around
  733. X
  734. X    mov    bp, sp
  735. X    pop    ds            ; Unstack values
  736. X    pop    bp
  737. X    pop    ax
  738. X    stc
  739. X    ret
  740. X
  741. X
  742. X; In shell - ignore interrupt 23 for the moment
  743. X
  744. X$SA_Ins:
  745. X    pop    ds            ; Restore regs
  746. X    pop    bp
  747. X    pop    ax
  748. X    iret
  749. X
  750. XSA_IRET        endp
  751. X
  752. X;
  753. X; DIVIDE BY ZERO INTERRUPT HANDLER - Output message
  754. X;
  755. X
  756. XSA_DZERO    proc    far
  757. X
  758. X    mov    ax, 00900H
  759. X    mov    dx, offset Swap_DZERO
  760. X    mov    bx, cs
  761. X    mov    ds, bx
  762. X    int    021H
  763. X
  764. X    mov    ax, 04CFFh        ; Exit
  765. X    int    021H
  766. X
  767. XSA_DZERO    endp
  768. X
  769. X;
  770. X;  Start of overwrite area for environment.  Align on a paragraph
  771. X;
  772. X        ALIGN    16
  773. XEnv_OWrite:
  774. XSH0_TEXT    ends
  775. X        end
  776. SHAR_EOF
  777. echo "File shell/sh0.asm is complete"
  778. chmod 0644 shell/sh0.asm || echo "restore of shell/sh0.asm fails"
  779. set `wc -c shell/sh0.asm`;Sum=$1
  780. if test "$Sum" != "17894"
  781. then echo original size 17894, current size $Sum;fi
  782. echo "x - extracting shell/sh.h (Text)"
  783. sed 's/^X//' << 'SHAR_EOF' > shell/sh.h &&
  784. X/* MS-DOS SHELL - Header File
  785. X *
  786. X * MS-DOS SHELL - Copyright (c) 1990 Data Logic Limited and Charles Forsyth
  787. X *
  788. X * This code is based on (in part) the shell program written by Charles
  789. X * Forsyth and is subject to the following copyright restrictions:
  790. X *
  791. X * 1.  Redistribution and use in source and binary forms are permitted
  792. X *     provided that the above copyright notice is duplicated in the
  793. X *     source form and the copyright notice in file sh6.c is displayed
  794. X *     on entry to the program.
  795. X *
  796. X * 2.  The sources (or parts thereof) or objects generated from the sources
  797. X *     (or parts of sources) cannot be sold under any circumstances.
  798. X *
  799. X *    $Header: sh.h 1.1 90/01/29 17:46:51 MS_user Exp $
  800. X *
  801. X *    $Log:    sh.h $
  802. X * Revision 1.1  90/01/29  17:46:51  MS_user
  803. X * Initial revision
  804. X * 
  805. X * 
  806. X */
  807. X
  808. X#define    LINE_MAX    1000    /* Command line length            */
  809. X#define HISTORY_MAX    100    /* History array length            */
  810. X                /* Space for full file name        */
  811. X#define FFNAME_MAX    (PATH_MAX + NAME_MAX + 4)
  812. X#define CMD_LINE_MAX    127    /* Max command line length        */
  813. X#define SSAVE_IO_SIZE    4    /* Save IO array malloc increment    */
  814. X
  815. X#define    NPUSH        8    /* limit to input nesting        */
  816. X
  817. X#define    NOFILE        20    /* Number of open files            */
  818. X#define    NUFILE        10    /* Number of user-accessible files    */
  819. X#define    FDBASE        10    /* First file usable by Shell        */
  820. X
  821. X#define NL        '\n'
  822. X#define SP        ' '
  823. X#define    NOT        '^'
  824. X                /* Open in create mode            */
  825. X#define O_CMASK        (O_WRONLY | O_CREAT | O_TRUNC | O_TEXT)
  826. X                /* Open in create mode for a pipe    */
  827. X#define O_PMASK        (O_RDWR | O_CREAT | O_TRUNC | O_TEXT)
  828. X                /* Open in create mode for swap file    */
  829. X#define O_SMASK        (O_RDWR | O_CREAT | O_TRUNC | O_BINARY)
  830. X#define O_RMASK        (O_RDONLY | O_NOINHERIT | O_TEXT)
  831. X
  832. X/*
  833. X * shell components
  834. X */
  835. X
  836. X#define    QUOTE        0200
  837. X#define    CMASK        0377
  838. X#define    QMASK        (CMASK & ~QUOTE)
  839. X
  840. X#define    NOBLOCK        ((C_Op *)NULL)
  841. X#define    NOWORD        ((char *)NULL)
  842. X#define    NOWORDS        ((char **)NULL)
  843. X#define    NOPIPE        (-1)
  844. X
  845. X/*
  846. X * Description of a command or an operation on commands.
  847. X * Might eventually use a union.
  848. X */
  849. X
  850. Xtypedef struct op {
  851. X    int            type;        /* operation type, see below    */
  852. X    char        **words;    /* arguments to a command    */
  853. X    struct ioword    **ioact;    /* IO actions (eg, < > >>)    */
  854. X    struct op        *left;
  855. X    struct op        *right;
  856. X    char        *str;        /* identifier for case and for    */
  857. X} C_Op;
  858. X
  859. X#define    TCOM        1    /* command                */
  860. X#define    TPAREN        2    /* (c-list)                */
  861. X#define    TPIPE        3    /* a | b                */
  862. X#define    TLIST        4    /* a [&;] b                */
  863. X#define    TOR        5    /* ||                    */
  864. X#define    TAND        6    /* &&                    */
  865. X#define    TFOR        7    /* FOR                    */
  866. X#define    TDO        8    /* DO                    */
  867. X#define    TCASE        9    /* CASE                    */
  868. X#define    TIF        10    /* IF                    */
  869. X#define    TWHILE        11    /* WHILE                */
  870. X#define    TUNTIL        12    /* UNTIL                */
  871. X#define    TELIF        13    /* ELSE IF                */
  872. X#define    TPAT        14    /* pattern in case            */
  873. X#define    TBRACE        15    /* {c-list}                */
  874. X#define    TASYNC        16    /* c &                    */
  875. X#define    TFUNC        17    /* c () {c-list}            */
  876. X
  877. X/* Built in Command list */
  878. X
  879. Xstruct    builtin {
  880. X    char    *command;
  881. X    int        (*fn)(C_Op *);
  882. X};
  883. X
  884. X/*
  885. X * actions determining the environment of a process
  886. X */
  887. X
  888. X#define    FEXEC        0x0001    /* execute without forking        */
  889. X
  890. X/* MSDOS Memory Control Block chain structure */
  891. X
  892. X#pragma pack (1)
  893. Xstruct MCB_list    {
  894. X    char        MCB_type;    /* M or Z            */
  895. X    unsigned int    MCB_pid;    /* Process ID            */
  896. X    unsigned int    MCB_len;    /* MCB length            */
  897. X};
  898. X#pragma pack ()
  899. X
  900. X#define MCB_CON        'M'        /* More MCB's            */
  901. X#define MCB_END        'Z'        /* Last MCB's            */
  902. X
  903. X/* Externs for Swapper assembler function */
  904. X
  905. Xextern char        cmd_line[];    /* Command line            */
  906. Xextern char        path_line[];    /* Process path            */
  907. Xextern unsigned int    SW_intr;    /* interrupt pending        */
  908. Xextern unsigned int    SW_Blocks;    /* Number of blocks to read    */
  909. Xextern int        SW_fp;        /* File or EMS Handler        */
  910. Xextern unsigned int    SW_I0_V_BX;    /* Out interrupt Zero address    */
  911. Xextern unsigned int    SW_I0_V_ES;
  912. Xextern unsigned int    SW_I23_V_ES;    /* Our Interrupt 23 address    */
  913. Xextern unsigned int    SW_I23_V_BX;
  914. Xextern unsigned long    SW_EMstart;    /* Start addr of extend mem    */
  915. Xextern unsigned int    SW_Mode;    /* Type of swapping to do    */
  916. X                    /* 1 - disk            */
  917. X                    /* 2 - Extended    memory        */
  918. X                    /* 3 - Expanded    memory        */
  919. Xextern unsigned int    SW_EMSFrame;    /* EMS Frame segment        */
  920. X
  921. Xextern int        Swap_Mode;    /* Swapping mode        */
  922. X
  923. X/* If you change these values, change sh7, swap_device as well */
  924. X
  925. X#define SWAP_OFF    0x0000        /* No swapping            */
  926. X#define SWAP_DISK    0x0001        /* Disk only            */
  927. X#define SWAP_EXTEND    0x0002        /* Extended memory        */
  928. X#define SWAP_EXPAND    0x0004        /* Expanded memory        */
  929. X
  930. X/*
  931. X * flags to control evaluation of words
  932. X */
  933. X
  934. X#define    DOSUB        0x01    /* interpret $, `, and quotes        */
  935. X#define    DOBLANK        0x02    /* perform blank interpretation        */
  936. X#define    DOGLOB        0x04    /* interpret [?*            */
  937. X#define    DOKEY        0x08    /* move words with `=' to 2nd arg. list */
  938. X#define    DOTRIM        0x01    /* trim resulting string        */
  939. X
  940. X#define    DOALL        (DOSUB | DOBLANK | DOGLOB | DOKEY | DOTRIM)
  941. X
  942. Xextern char        *Copy_Right1;
  943. Xextern char        *Copy_Right2;
  944. Xextern char        **dolv;        /* $<numeric> values        */
  945. Xextern int        dolc;        /* $<numeric> count        */
  946. Xextern int        fn_area_number;    /* Next function area number    */
  947. Xextern int        exstat;
  948. Xextern char        gflg;
  949. Xextern int        talking;    /* interactive (talking-type    */
  950. Xextern int        execflg;
  951. Xextern int        multiline;    /* \n changed to ;        */
  952. Xextern int        *failpt;
  953. Xextern int        *errpt;
  954. Xextern int        inparse;    /* In parser flag        */
  955. Xextern int        Current_Event;    /* Current history event    */
  956. X
  957. X/*
  958. X * Break/Continue (in for and while), Return and Exit handler
  959. X */
  960. X
  961. Xtypedef struct brkcon {
  962. X    jmp_buf        brkpt;
  963. X    struct brkcon    *nextlev;
  964. X} Break_C;
  965. X                /* Values returned by longjmp        */
  966. X#define BC_LOAD        0    /* Load condition            */
  967. X#define BC_BREAK    1    /* Break condition            */
  968. X#define BC_CONTINUE    2    /* Continue condition            */
  969. X
  970. Xextern Break_C    *Break_List;    /* Break list for FOR/WHILE        */
  971. Xextern Break_C    *Return_List;    /* Return list for RETURN        */
  972. Xextern Break_C    *SShell_List;    /* SubShell list for EXIT        */
  973. Xextern bool    level0;        /* Level zero (read profile)        */
  974. Xextern bool    r_flag;        /* Read only shell            */
  975. Xextern bool    History_Enabled;
  976. X
  977. X/*
  978. X * Save Standard Input/Output/Error structure
  979. X */
  980. X
  981. Xtypedef struct save_io {
  982. X    int        depth;            /* Execute recursive depth    */
  983. X    int        fp[STDERR_FILENO + 1];    /* File handlers        */
  984. X} Save_IO;
  985. X
  986. Xextern Save_IO    *SSave_IO;        /* Save IO array        */
  987. Xextern int    NSave_IO_E;        /* Number of entries        */
  988. Xextern int    MSave_IO_E;        /* Max Number of entries    */
  989. X
  990. X/*
  991. X * Function tree processing
  992. X */
  993. X
  994. Xtypedef struct fun_op {
  995. X    struct fun_op    *next;        /* Link                */
  996. X    C_Op        *tree;        /* The tree itself        */
  997. X} Fun_Ops;
  998. X
  999. Xextern Fun_Ops    *fun_list;        /* List header            */
  1000. X
  1001. X/*
  1002. X * redirection
  1003. X */
  1004. X
  1005. Xtypedef struct ioword {
  1006. X    short    io_unit;    /* unit affected            */
  1007. X    short    io_flag;    /* action (below)            */
  1008. X    char    *io_name;    /* file name                */
  1009. X} IO_Actions;
  1010. X
  1011. X#define    IOREAD        1    /* <                    */
  1012. X#define    IOHERE        2    /* << (here file)            */
  1013. X#define    IOWRITE        4    /* >                    */
  1014. X#define    IOCAT        8    /* >>                    */
  1015. X#define    IOXHERE        16    /* ${}, ` in <<                */
  1016. X#define    IODUP        32    /* >&digit                */
  1017. X#define    IOCLOSE        64    /* >&-                    */
  1018. X
  1019. X#define    IODEFAULT    (-1)    /* token for default IO unit        */
  1020. X
  1021. X/*
  1022. X * parsing & execution environment
  1023. X */
  1024. X
  1025. Xtypedef struct env {
  1026. X    char    *cline;            /* Current line buffer        */
  1027. X    char    *linep;            /* Current pointer in line    */
  1028. X    char    *eline;            /* End of line pointer        */
  1029. X    struct io    *iobase;
  1030. X    struct io    *iop;
  1031. X    int        *errpt;
  1032. X    int        iofd;
  1033. X    struct env    *oenv;            /* Previous environment        */
  1034. X} Environ;
  1035. X
  1036. Xextern Environ        e;
  1037. X
  1038. X/*
  1039. X * here documents
  1040. X */
  1041. X
  1042. Xtypedef struct here {
  1043. X    char        *h_tag;
  1044. X    int            h_dosub;
  1045. X    IO_Actions        *h_iop;
  1046. X    struct here        *h_next;
  1047. X} Here_D;
  1048. X
  1049. X/*
  1050. X * flags:
  1051. X *
  1052. X * -a: Set all environment variables to exported
  1053. X * -e: Quit on error
  1054. X * -f: Disable file name expansion
  1055. X * -k: Look for name=value everywhere on command line
  1056. X * -n: No execution
  1057. X * -t: exit after reading and executing one command
  1058. X * -u: Abort if environment variable is not set
  1059. X * -v: Echo as read
  1060. X * -x: Trace
  1061. X */
  1062. X
  1063. X#define FL_TEST(x)    (flags & (1L << ((x) - 'a')))
  1064. X#define FL_SET(x)    flags |= (1L << ((x) - 'a'))
  1065. X#define FL_CLEAR(x)    flags &= (~(1L << ((x) - 'a')))
  1066. X
  1067. Xextern long    flags;
  1068. Xextern char    *null;        /* null value for variable        */
  1069. Xextern long    ourtrap;    /* Signal processing required        */
  1070. Xextern int    trapset;    /* trap pending                */
  1071. Xextern int    yynerrs;    /* yacc                    */
  1072. Xextern int    Execute_stack_depth;    /* execute function recursion    */
  1073. X                    /* depth            */
  1074. X
  1075. X/*
  1076. X * Variable list
  1077. X */
  1078. X
  1079. Xtypedef struct var {
  1080. X    char        *value;        /* Value            */
  1081. X    char        *name;        /* Name                */
  1082. X    struct var        *next;        /* Link                */
  1083. X    char        status;        /* Type, see below        */
  1084. X} Var_List;
  1085. X
  1086. X#define    COPYV        1    /* flag to setval, suggesting copy    */
  1087. X#define    RONLY        0x01    /* variable is read-only        */
  1088. X#define    EXPORT        0x02    /* variable is to be exported        */
  1089. X#define    GETCELL        0x04    /* name & value space was got with getcell */
  1090. X#define PONLY        0x08    /* PATH Value - no unset        */
  1091. X#define C_MSDOS        0x10    /* Convert to MSDOS format        */
  1092. X
  1093. Xextern Var_List    *vlist;        /* dictionary                */
  1094. Xextern Var_List **S_UL;        /* Start address update location    */
  1095. Xextern Var_List    *path;        /* search path for commands        */
  1096. Xextern Var_List    *ps1;        /* Prompt 1                */
  1097. Xextern Var_List    *ps2;        /* Prompt 2                */
  1098. Xextern Var_List    *ifs;        /* Interfield separators        */
  1099. Xextern Var_List    *C_dir;        /* Current directory            */
  1100. Xextern char    *last_prompt;    /* Last prompt output            */
  1101. Xextern char    *home;        /* Home string                */
  1102. Xextern char    *shell;        /* Shell string                */
  1103. Xextern char    *hsymbol;    /* Hash string                */
  1104. Xextern char    *msymbol;    /* Minus string                */
  1105. Xextern char    *spcl2;
  1106. Xextern char    *history_file;
  1107. X
  1108. X/*
  1109. X * SubShell Save Structure
  1110. X */
  1111. X
  1112. Xtypedef struct subshell {
  1113. X    int        depth;            /* Sub_Shell Depth        */
  1114. X    Var_List    *header;        /* Header start            */
  1115. X} S_SubShell;
  1116. X
  1117. Xextern S_SubShell    *SubShells;    /* Save Vars array        */
  1118. Xextern int        NSubShells;    /* Number of entries        */
  1119. Xextern int        MSubShells;    /* Max Number of entries    */
  1120. X
  1121. X/* io buffer */
  1122. X
  1123. Xtypedef struct iobuf {
  1124. X    unsigned int    id;        /* buffer id            */
  1125. X    char        buf[512];    /* buffer            */
  1126. X    char        *bufp;        /* pointer into buffer        */
  1127. X    char        *ebufp;        /* pointer to end of buffer    */
  1128. X} IO_Buf;
  1129. X
  1130. X/* possible arguments to an IO function */
  1131. X
  1132. Xtypedef struct ioarg {
  1133. X    char        *aword;
  1134. X    char        **awordlist;
  1135. X    int            afile;        /* file descriptor        */
  1136. X    unsigned int    afid;        /* buffer id            */
  1137. X    long        afpos;        /* file position        */
  1138. X    IO_Buf        *afbuf;        /* buffer for this file        */
  1139. X} IO_Args;
  1140. X
  1141. X#define AFID_NOBUF    (~0)
  1142. X#define AFID_ID        0
  1143. X
  1144. Xextern IO_Args    ioargstack[NPUSH];    /* IO argument stack        */
  1145. X
  1146. X/* an input generator's state */
  1147. X
  1148. Xtypedef struct io {
  1149. X    int            (*iofn)(struct io *);
  1150. X    IO_Args        *argp;
  1151. X    int            peekc;
  1152. X    char        prev;        /* previous character read by readc() */
  1153. X    char        nlcount;    /* for `'s            */
  1154. X    char        xchar;        /* for `'s            */
  1155. X    char        task;        /* reason for pushed IO        */
  1156. X    char        dflag;        /* Special processing flag    */
  1157. X} IO_State;
  1158. X
  1159. X#define DSA_NULL    0x00        /* No special processing req    */
  1160. X#define DSA_STAR    0x01        /* Special processing for "$*"    */
  1161. X#define DSA_AMP        0x02        /* Special processing for "$@"    */
  1162. X#define DSA_MODE    0x03        /* Mode flag            */
  1163. X#define DSA_END        0x04        /* Last word processing        */
  1164. X#define DSA_START    0x08        /* First word processed?    */
  1165. X#define DSA_START1    0x10        /* Subsequent word processed    */
  1166. X#define DSA_END1    0x20        /* End processing for word    */
  1167. X
  1168. Xextern IO_State        iostack[NPUSH];    /* IO Stack            */
  1169. X
  1170. X#define    XOTHER        0    /* none of the below            */
  1171. X#define    XDOLL        1    /* expanding ${}            */
  1172. X#define    XGRAVE        2    /* expanding `'s            */
  1173. X#define    XIO        3    /* file IO                */
  1174. X
  1175. X/* in substitution */
  1176. X
  1177. X#define    INSUB()            (e.iop->task == XGRAVE || e.iop->task == XDOLL)
  1178. X
  1179. X/*
  1180. X * IO control
  1181. X */
  1182. X
  1183. Xextern IO_Args        temparg;    /* temporary for PUSHIO */
  1184. X#define    PUSHIO(what,arg,gen)    ((temparg.what = (arg)), pushio(&temparg,(gen)))
  1185. X#define    RUN(what,arg,gen)    ((temparg.what = (arg)), run(&temparg,(gen)))
  1186. X
  1187. Xtypedef struct wdblock {
  1188. X    short    w_bsize;
  1189. X    short    w_nword;
  1190. X    char    *w_words[1];
  1191. X} Word_B;
  1192. X
  1193. Xextern Word_B    *wdlist;
  1194. Xextern Word_B    *iolist;
  1195. X
  1196. X/*
  1197. X * storage allocation
  1198. X */
  1199. X
  1200. Xextern int        areanum;    /* current allocation area */
  1201. X
  1202. X#define    NEW(type)    (type *)getcell (sizeof (type))
  1203. X#define    DELETE(obj)    freecell ((char *)obj)
  1204. X
  1205. X/* Functions */
  1206. X
  1207. Xextern void    main (int, char **);
  1208. Xextern void    setdash (void);
  1209. Xextern void    fail (void);
  1210. Xextern void    leave (void);
  1211. Xextern void    print_warn (char *, ...);
  1212. Xextern void    print_error (char *, ...);
  1213. Xextern bool    newenv (int);
  1214. Xextern void    quitenv (void);
  1215. Xextern char    *putn (int);
  1216. Xextern void    next (int);
  1217. Xextern void    onintr (int);
  1218. Xextern char    *space (int);
  1219. Xextern char    *strsave (char *, int);
  1220. Xextern void    sig (int);
  1221. Xextern void    runtrap (int);
  1222. Xextern Var_List    *lookup (char *, bool);
  1223. Xextern void    setval (Var_List *, char *);
  1224. Xextern void    s_vstatus (Var_List *, int);
  1225. Xextern bool    isassign (char *);
  1226. Xextern bool    assign (char *, int);
  1227. Xextern bool    gmatch (char *, char *, bool);
  1228. Xextern char    *getcell (unsigned int);
  1229. Xextern void    freecell (char *);
  1230. Xextern void    freearea (int);
  1231. Xextern void    setarea (char *, int);
  1232. Xextern int    getarea (char *);
  1233. Xextern C_Op    *yyparse (void);
  1234. Xextern int    execute (C_Op *, int, int, int);
  1235. Xextern int    run (IO_Args *, int (*)(IO_State *));
  1236. Xextern int    Getc (int);
  1237. Xextern void    unget (int);
  1238. Xextern int    eofc (void);
  1239. Xextern int    readc (void);
  1240. Xextern void    pushio (IO_Args *, int (*)(IO_State *));
  1241. Xextern int    nlchar (IO_State *);
  1242. Xextern int    wdchar (IO_State *);
  1243. Xextern int    dol_char (IO_State *);
  1244. Xextern int    strchar (IO_State *);
  1245. Xextern int    qstrchar (IO_State *);
  1246. Xextern int    filechar (IO_State *);
  1247. Xextern int    gravechar (IO_State *);
  1248. Xextern int    qgravechar (IO_State *);
  1249. Xextern int    linechar (IO_State *);
  1250. Xextern void    closeall (void);
  1251. Xextern int    remap (int);
  1252. Xextern int    openpipe (void);
  1253. Xextern void    closepipe (int);
  1254. Xextern void    markhere (char *, IO_Actions *);
  1255. Xextern void    gethere (void);
  1256. Xextern int    herein (char *, int);
  1257. Xextern void    scraphere (void);
  1258. Xextern void    freehere (int);
  1259. X
  1260. Xextern char    **eval (char **, int);
  1261. Xextern char    **makenv (void);
  1262. Xextern char    *evalstr (char *, int);
  1263. Xextern int    subgetc (char, int);
  1264. Xextern Word_B    *addword (char *, Word_B *);
  1265. Xextern char    **getwords (Word_B *);
  1266. Xextern void    put_prompt (char *);
  1267. Xextern bool    eqname (char *, char *);
  1268. Xextern bool    any (char, char *);
  1269. Xextern int    (*inbuilt (char *))();
  1270. Xextern char    *path_append (char *, char *, char *);
  1271. Xextern void    unset (char *, bool);
  1272. Xextern int    S_open (bool, char *, int, ...);
  1273. Xextern int    S_close (int, bool);
  1274. Xextern int    S_dup (int);
  1275. Xextern int    S_dup2 (int, int);
  1276. Xextern void    S_Remap (int, int);
  1277. Xextern void    S_Delete (int);
  1278. Xextern void    Getcwd (void);
  1279. Xextern char    *g_tempname (void);
  1280. Xextern void    S_puts (char *);
  1281. Xextern void    S_putc (int);
  1282. Xextern bool    check_rsh (char *);
  1283. Xextern int    O_for_execute (char *);
  1284. Xextern int    SA_spawn (char **);
  1285. Xextern char    *findeq (char *);
  1286. Xextern int    restore_std (int);
  1287. Xextern void    Load_History (void);
  1288. Xextern void    Dump_History (void);
  1289. Xextern void    Display_History (void);
  1290. Xextern void    Clear_History (void);
  1291. Xextern void    v1_puts (char *);
  1292. Xextern void    v1a_puts (char *);
  1293. Xextern void    v1_putc (char);
  1294. Xextern void    v1printf (char *, ...);
  1295. Xextern int    Get_stdin (IO_Args *);
  1296. Xextern int    Process_Escape (char **);
  1297. Xextern void    Add_History (bool);
  1298. Xextern void    Convert_Slashes (char *);
  1299. Xextern void    Print_ExTree (C_Op *);
  1300. Xextern Fun_Ops    *Fun_Search (char *);
  1301. Xextern void    Save_Function (C_Op *, bool);
  1302. Xextern int    getn (char *);
  1303. Xextern int    Create_NG_VL (void);
  1304. Xextern void    Delete_G_VL (void);
  1305. Xextern void    Restore_Dir (void);
  1306. Xextern void    Restore_Environment (int, int);
  1307. Xextern int    sort_compare (char **, char **);
  1308. Xextern int    Check_Script (char *);
  1309. SHAR_EOF
  1310. chmod 0644 shell/sh.h || echo "restore of shell/sh.h fails"
  1311. set `wc -c shell/sh.h`;Sum=$1
  1312. if test "$Sum" != "15317"
  1313. then echo original size 15317, current size $Sum;fi
  1314. rm -f s2_seq_.tmp
  1315. echo "You have unpacked the last part"
  1316. exit 0
  1317.  
  1318. -- 
  1319. Regards,
  1320.  
  1321. Ian Stewartson
  1322. Data Logic Ltd.
  1323.  
  1324.