home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / sh.zoo / sh.5 < prev   
Encoding:
Text File  |  1990-02-21  |  29.1 KB  |  1,316 lines

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