Full Code of FDOS/freecom for AI

master ec6c63f13be0 cached
750 files
2.6 MB
706.2k tokens
724 symbols
1 requests
Download .txt
Showing preview only (2,822K chars total). Download the full file or copy to clipboard to get everything.
Repository: FDOS/freecom
Branch: master
Commit: ec6c63f13be0
Files: 750
Total size: 2.6 MB

Directory structure:
gitextract_1pnn224c/

├── .gitattributes
├── .github/
│   ├── actions/
│   │   ├── build/
│   │   │   └── action.yml
│   │   └── upx-inst/
│   │       └── action.yml
│   └── workflows/
│       └── ci-build.yml
├── .gitignore
├── FILE_ID.DIZ
├── README.md
├── VERSION.TXT
├── build.bat
├── build.sh
├── buildall.bat
├── ci_build.sh
├── ci_prereq.sh
├── ci_test.sh
├── clean.bat
├── clean.sh
├── cmd/
│   ├── alias.c
│   ├── beep.c
│   ├── break.c
│   ├── call.c
│   ├── cdd.c
│   ├── chcp.c
│   ├── chdir.c
│   ├── cls.c
│   ├── cmd.m1
│   ├── cmd.m2
│   ├── copy.c
│   ├── ctty.c
│   ├── date.c
│   ├── del.c
│   ├── depend.mk
│   ├── dir.c
│   ├── dirs.c
│   ├── doskey.c
│   ├── echo.c
│   ├── exit.c
│   ├── exit2.c
│   ├── fddebug.c
│   ├── for.c
│   ├── goto.c
│   ├── history.c
│   ├── if.c
│   ├── lfnfor.c
│   ├── makefile
│   ├── makefile.mak
│   ├── memory.c
│   ├── mkdir.c
│   ├── path.c
│   ├── pause.c
│   ├── popd.c
│   ├── prompt.c
│   ├── pushd.c
│   ├── rem.c
│   ├── ren.c
│   ├── rmdir.c
│   ├── set.c
│   ├── shift.c
│   ├── time.c
│   ├── truename.c
│   ├── type.c
│   ├── verify.c
│   └── which.c
├── command.lsm
├── config.b
├── config.h
├── config.std
├── criter/
│   ├── context.x
│   ├── criter.asm
│   ├── criter.txt
│   ├── dmy_cbrk.asm
│   ├── files.txt
│   ├── makefile
│   ├── makefile.mak
│   ├── resource.id
│   └── resource.inc
├── docs/
│   ├── HELP.EN
│   ├── _config.yml
│   ├── c0.txt
│   ├── cmt1.txt
│   ├── cmt10.txt
│   ├── cmt2.txt
│   ├── cmt3.txt
│   ├── cmt4.txt
│   ├── cmt5.txt
│   ├── cmt6.txt
│   ├── cmt7.txt
│   ├── cmt8.txt
│   ├── comments.txt
│   ├── compile.txt
│   ├── contrib.txt
│   ├── download.txt
│   ├── faq.txt
│   ├── files.txt
│   ├── history.txt
│   ├── html/
│   │   ├── build48.html
│   │   └── commands/
│   │       ├── FreeCOM.html
│   │       ├── appendix.html
│   │       ├── cmd.html
│   │       ├── db2html
│   │       ├── info
│   │       ├── parse.pl
│   │       └── parseHTML
│   ├── index.md
│   ├── k-swap.txt
│   ├── language.txt
│   ├── loadhigh.txt
│   ├── localize.txt
│   ├── module.txt
│   ├── notes.txt
│   ├── piping.txt
│   ├── pt_br/
│   │   ├── config.h
│   │   ├── config.mak
│   │   ├── download.txt
│   │   ├── file_id.diz
│   │   └── readme
│   ├── ptchldrv.txt
│   ├── resource.txt
│   ├── todo.txt
│   ├── upload.txt
│   └── vspawn.txt
├── err_fcts.h
├── include/
│   ├── batch.h
│   ├── cmdline.h
│   ├── command.h
│   ├── context.h
│   ├── crossjmp.h
│   ├── cswap.h
│   ├── datefunc.h
│   ├── debug.h
│   ├── infores.h
│   ├── keys.h
│   ├── kswap.h
│   ├── large.inc
│   ├── lfnfuncs.h
│   ├── medium.inc
│   ├── misc.h
│   ├── model.inc
│   ├── module.h
│   ├── mux_ae.h
│   ├── nls.h
│   ├── openf.h
│   ├── res.h
│   ├── resource.h
│   ├── small.inc
│   ├── strings.typ
│   ├── stuff.inc
│   └── timefunc.h
├── lib/
│   ├── absfile.c
│   ├── almemblk.c
│   ├── alprmblk.c
│   ├── alsysblk.c
│   ├── app_get.c
│   ├── app_set.c
│   ├── beep_l.c
│   ├── beep_n.c
│   ├── brk_get.c
│   ├── brk_set.c
│   ├── c16.mac
│   ├── cbreak.c
│   ├── cbs.c
│   ├── cd_dir.c
│   ├── cgetch.c
│   ├── cgettime.c
│   ├── chgctxt.c
│   ├── chgdrv.c
│   ├── chgenv.c
│   ├── chgenvc.c
│   ├── chgenvr.c
│   ├── cmdinput.c
│   ├── comfile.c
│   ├── compfile.c
│   ├── critend.c
│   ├── critrchk.c
│   ├── ctxt.c
│   ├── ctxt_adr.c
│   ├── ctxt_as.c
│   ├── ctxt_chg.c
│   ├── ctxt_clr.c
│   ├── ctxt_get.c
│   ├── ctxt_inf.c
│   ├── ctxt_mk.c
│   ├── ctxt_mkb.c
│   ├── ctxt_mkn.c
│   ├── ctxt_pop.c
│   ├── ctxt_psh.c
│   ├── ctxt_rnu.c
│   ├── ctxt_set.c
│   ├── ctxt_ss.c
│   ├── ctxt_vw.c
│   ├── curdatel.c
│   ├── curtime.c
│   ├── cwd.c
│   ├── dateget.c
│   ├── dateset.c
│   ├── dbg_c.c
│   ├── dbg_mem.c
│   ├── dbg_prnt.c
│   ├── dbg_s.c
│   ├── dbg_sn.c
│   ├── delay.c
│   ├── depend.mk
│   ├── devopen.c
│   ├── dfn_err.c
│   ├── dispcnt.c
│   ├── dispexit.c
│   ├── drvnum.c
│   ├── efct_001.c
│   ├── err1.c
│   ├── err10.c
│   ├── err11.c
│   ├── err12.c
│   ├── err13.c
│   ├── err14.c
│   ├── err15.c
│   ├── err16.c
│   ├── err17.c
│   ├── err18.c
│   ├── err19.c
│   ├── err2.c
│   ├── err20.c
│   ├── err21.c
│   ├── err22.c
│   ├── err23.c
│   ├── err24.c
│   ├── err25.c
│   ├── err26.c
│   ├── err27.c
│   ├── err28.c
│   ├── err29.c
│   ├── err3.c
│   ├── err30.c
│   ├── err31.c
│   ├── err32.c
│   ├── err33.c
│   ├── err34.c
│   ├── err35.c
│   ├── err36.c
│   ├── err37.c
│   ├── err38.c
│   ├── err39.c
│   ├── err4.c
│   ├── err40.c
│   ├── err41.c
│   ├── err42.c
│   ├── err43.c
│   ├── err44.c
│   ├── err45.c
│   ├── err46.c
│   ├── err47.c
│   ├── err48.c
│   ├── err49.c
│   ├── err5.c
│   ├── err50.c
│   ├── err51.c
│   ├── err52.c
│   ├── err53.c
│   ├── err54.c
│   ├── err55.c
│   ├── err56.c
│   ├── err57.c
│   ├── err58.c
│   ├── err59.c
│   ├── err6.c
│   ├── err60.c
│   ├── err61.c
│   ├── err62.c
│   ├── err63.c
│   ├── err64.c
│   ├── err65.c
│   ├── err66.c
│   ├── err67.c
│   ├── err68.c
│   ├── err69.c
│   ├── err7.c
│   ├── err70.c
│   ├── err71.c
│   ├── err72.c
│   ├── err73.c
│   ├── err74.c
│   ├── err75.c
│   ├── err76.c
│   ├── err77.c
│   ├── err78.c
│   ├── err79.c
│   ├── err8.c
│   ├── err80.c
│   ├── err81.c
│   ├── err82.c
│   ├── err83.c
│   ├── err84.c
│   ├── err85.c
│   ├── err86.c
│   ├── err87.c
│   ├── err9.c
│   ├── err_fcts.mk
│   ├── err_fcts.src
│   ├── exec.c
│   ├── exec1.c
│   ├── farread.c
│   ├── fdattr.c
│   ├── fdevopen.c
│   ├── fdsattr.c
│   ├── filecomp.c
│   ├── files.txt
│   ├── fillcomp.c
│   ├── find.c
│   ├── freep.c
│   ├── frsysblk.c
│   ├── fstpcpy.c
│   ├── gallstr.c
│   ├── get1mcb.c
│   ├── getenv.c
│   ├── goxy.c
│   ├── grabfcom.c
│   ├── gumblink.c
│   ├── hdlrctxt.c
│   ├── hist_get.c
│   ├── hist_set.c
│   ├── inputdos.c
│   ├── is_empty.c
│   ├── is_fnamc.c
│   ├── is_fnstr.c
│   ├── is_pchr.c
│   ├── isadev.c
│   ├── keyprsd.c
│   ├── kswap_c.c
│   ├── lastdget.c
│   ├── lastdset.c
│   ├── leadopt.c
│   ├── lfnfuncs.c
│   ├── lib.m1
│   ├── lib.m2
│   ├── lowexec.asm
│   ├── ltrimcl.c
│   ├── ltrimsp.c
│   ├── lwr1wd.c
│   ├── makefile
│   ├── makefile.mak
│   ├── match.c
│   ├── messages.c
│   ├── mk_rddir.c
│   ├── mktmpfil.c
│   ├── msg_dflt.c
│   ├── msg_dps.c
│   ├── msg_fstr.c
│   ├── msg_get.c
│   ├── msg_gpt.c
│   ├── msg_mkey.c
│   ├── msg_prmp.c
│   ├── mux_ae.c
│   ├── myperror.c
│   ├── nls.c
│   ├── nls_date.c
│   ├── nls_time.c
│   ├── num_fmt.c
│   ├── onoff.c
│   ├── openf.c
│   ├── optsb.c
│   ├── optsi.c
│   ├── optss.c
│   ├── parsenum.c
│   ├── pr_date.c
│   ├── pr_prmpt.c
│   ├── pr_time.c
│   ├── prf.c
│   ├── prprompt.c
│   ├── readcmd.c
│   ├── realnum.c
│   ├── res.c
│   ├── res_r.c
│   ├── res_vald.c
│   ├── res_w.c
│   ├── resfile.c
│   ├── rmtmpfil.c
│   ├── rtrimcl.c
│   ├── rtrimsp.c
│   ├── salloc.c
│   ├── samefile.c
│   ├── scancmd.c
│   ├── scanerr.pl
│   ├── scanopt.c
│   ├── session.c
│   ├── showcmds.c
│   ├── skqwd.c
│   ├── spfnam.c
│   ├── split.c
│   ├── sumblink.c
│   ├── timeget.c
│   ├── timeset.c
│   ├── tmpnam.c
│   ├── trimcl.c
│   ├── trimsp.c
│   ├── truepath.c
│   ├── truncate.c
│   ├── txtlend.c
│   ├── unquote.c
│   ├── vcgetch.c
│   ├── vcgetstr.c
│   └── where.c
├── license
├── makefile
├── mkdist.bat
├── mkfiles/
│   ├── bc5.mak
│   ├── gcc.mak
│   ├── tc2.mak
│   ├── turbocpp.mak
│   └── watcom.mak
├── scripts/
│   ├── complng.pl
│   ├── compsyms.pl
│   ├── director.bat
│   ├── disp_cmd.asm
│   ├── echolib.bat
│   ├── echoto.bat
│   ├── fetchseg.pl
│   ├── findstrg.pl
│   ├── makecmd.bat
│   ├── mkxref.pl
│   ├── rmfiles.bat
│   └── sav.btm
├── shell/
│   ├── batch.c
│   ├── cb_catch.asm
│   ├── cmdtable.c
│   ├── command.c
│   ├── command.ld
│   ├── command.m1
│   ├── command.m2
│   ├── cswap.asm
│   ├── cswapc.c
│   ├── depend.mk
│   ├── dummies.asm
│   ├── expalias.c
│   ├── init.c
│   ├── kswap.c
│   ├── loadhigh.c
│   ├── makefile
│   ├── makefile.mak
│   ├── module.c
│   ├── redir.c
│   ├── termhook.asm
│   ├── ver.c
│   ├── wlinker.bat
│   ├── xms_2e.asm
│   ├── xms_brk.asm
│   └── xms_crit.asm
├── strings/
│   ├── CHANGED
│   ├── DEFAULT.err
│   ├── DEFAULT.lng
│   ├── depend.mk
│   ├── dutch.err
│   ├── dutch.lng
│   ├── english.err
│   ├── english.lng
│   ├── finnish.err
│   ├── finnish.lng
│   ├── fixstrs.c
│   ├── french.err
│   ├── french.lng
│   ├── german.err
│   ├── german.lng
│   ├── indent.pro
│   ├── italian.err
│   ├── italian.lng
│   ├── makefile
│   ├── makefile.mak
│   ├── polish.err
│   ├── polish.lng
│   ├── pt.err
│   ├── pt.lng
│   ├── pt_br.err
│   ├── pt_br.lng
│   ├── russian.err
│   ├── russian.lng
│   ├── serbian.err
│   ├── serbian.lng
│   ├── slovene.err
│   ├── slovene.lng
│   ├── spanish.err
│   ├── spanish.lng
│   ├── strings/
│   │   └── makefile.mak
│   ├── swedish.err
│   ├── swedish.lng
│   ├── turkish.err
│   ├── turkish.lng
│   ├── ukr.err
│   ├── ukr.lng
│   ├── yu437.err
│   └── yu437.lng
├── suppl/
│   ├── algnbyte.h
│   ├── algndflt.h
│   ├── appname.h
│   ├── clnsuppl.bat
│   ├── cntry.h
│   ├── compat/
│   │   ├── conio.h
│   │   ├── dos.h
│   │   ├── io.h
│   │   └── process.h
│   ├── dfn.h
│   ├── dynstr.h
│   ├── environ.h
│   ├── errcodes.h
│   ├── external.h
│   ├── fmemory.h
│   ├── getopt.h
│   ├── makefile.mak
│   ├── mcb.h
│   ├── msglib.h
│   ├── msgs.h
│   ├── nls.h
│   ├── nls_c.h
│   ├── nls_f.h
│   ├── p-bc.h
│   ├── p-gcc.h
│   ├── p-mc.h
│   ├── p-pac.h
│   ├── p-watcom.h
│   ├── portable.h
│   ├── psp.h
│   ├── readme.txt
│   ├── regproto.h
│   ├── src/
│   │   ├── _getdcwd.c
│   │   ├── addu.c
│   │   ├── app_ievx.c
│   │   ├── app_ini_.c
│   │   ├── app_init.c
│   │   ├── app_name.c
│   │   ├── app_namx.c
│   │   ├── app_vars.c
│   │   ├── appname.loc
│   │   ├── bugs
│   │   ├── byte2par.c
│   │   ├── cntry.c
│   │   ├── copying
│   │   ├── copying.lb
│   │   ├── dbgf_chg.c
│   │   ├── dbgf_cl.c
│   │   ├── dbgf_cle.c
│   │   ├── dbgf_clg.c
│   │   ├── dbgf_dl.c
│   │   ├── dbgf_dpl.c
│   │   ├── dbgf_et.c
│   │   ├── dbgf_ext.c
│   │   ├── dbgf_fl.c
│   │   ├── dbgf_flg.c
│   │   ├── dbgf_ien.c
│   │   ├── dbgf_lgh.c
│   │   ├── dbgf_lgi.c
│   │   ├── dbgf_lgt.c
│   │   ├── dbgf_lk.c
│   │   ├── dbgf_log.c
│   │   ├── dbgf_lv.c
│   │   ├── dbgf_mfi.c
│   │   ├── dbgf_mi.c
│   │   ├── dbgf_mki.c
│   │   ├── dbgf_ml.c
│   │   ├── dbgf_pop.c
│   │   ├── dbgf_prt.c
│   │   ├── dbgf_psh.c
│   │   ├── dbgf_var.c
│   │   ├── dbgm_chk.c
│   │   ├── dbgv_s0.c
│   │   ├── dbgv_s10.c
│   │   ├── dbgv_s13.c
│   │   ├── dbgv_s14.c
│   │   ├── dbgv_s15.c
│   │   ├── dbgv_s17.c
│   │   ├── dbgv_s19.c
│   │   ├── dbgv_s2.c
│   │   ├── dbgv_s20.c
│   │   ├── dbgv_s22.c
│   │   ├── dbgv_s23.c
│   │   ├── dbgv_s24.c
│   │   ├── dbgv_s25.c
│   │   ├── dbgv_s3.c
│   │   ├── dbgv_s4.c
│   │   ├── dbgv_s5.c
│   │   ├── dbgv_s6.c
│   │   ├── dbgv_s7.c
│   │   ├── dbgv_s8.c
│   │   ├── dfn.loc
│   │   ├── dfndeli2.c
│   │   ├── dfndelim.c
│   │   ├── dfnexpan.c
│   │   ├── dfnfnam.c
│   │   ├── dfnfullp.c
│   │   ├── dfnmerge.c
│   │   ├── dfnpath.c
│   │   ├── dfnsplit.c
│   │   ├── dfnsquee.c
│   │   ├── dfnstat.c
│   │   ├── dfntruen.c
│   │   ├── dir.loc
│   │   ├── dmemcmpf.c
│   │   ├── dosalloc.c
│   │   ├── dosfree.c
│   │   ├── dossize.c
│   │   ├── dstrchar.c
│   │   ├── dstrfupr.c
│   │   ├── dstrleft.c
│   │   ├── dstrrepl.c
│   │   ├── dstrtrim.c
│   │   ├── dstrupr.c
│   │   ├── eeopen.c
│   │   ├── eestrcon.c
│   │   ├── elvis.rc
│   │   ├── eno.loc
│   │   ├── enoallc.c
│   │   ├── enoreal.c
│   │   ├── enosdup.c
│   │   ├── enosetos.c
│   │   ├── env_chg.c
│   │   ├── env_del.c
│   │   ├── env_dvar.c
│   │   ├── env_find.c
│   │   ├── env_fora.c
│   │   ├── env_free.c
│   │   ├── env_insv.c
│   │   ├── env_len.c
│   │   ├── env_mtch.c
│   │   ├── env_new.c
│   │   ├── env_nost.c
│   │   ├── env_ovrw.c
│   │   ├── env_repl.c
│   │   ├── env_rlsg.c
│   │   ├── env_scnt.c
│   │   ├── env_sdup.c
│   │   ├── env_size.c
│   │   ├── env_strg.c
│   │   ├── env_sub.c
│   │   ├── env_var1.c
│   │   ├── env_var2.c
│   │   ├── environ.loc
│   │   ├── erfc_00f.c
│   │   ├── erfc_015.c
│   │   ├── ffmaxbuf.c
│   │   ├── fgetpos.c
│   │   ├── file_id.diz
│   │   ├── filefind.c
│   │   ├── fmemchr.c
│   │   ├── fmemcmp.c
│   │   ├── fmemcpy.c
│   │   ├── fmemory.loc
│   │   ├── fmemove.c
│   │   ├── fnorm.c
│   │   ├── fputmc.c
│   │   ├── fstrcpy.c
│   │   ├── fstrdup.c
│   │   ├── fstrlen.c
│   │   ├── gm_chgm.c
│   │   ├── gm_dup.c
│   │   ├── gm_gtmem.c
│   │   ├── gm_res.c
│   │   ├── initsupl.loc
│   │   ├── intr.asm
│   │   ├── invokedo.c
│   │   ├── makefile.mak
│   │   ├── mcb_1st.c
│   │   ├── mcb_is.c
│   │   ├── mcb_leng.c
│   │   ├── mcb_nxt.c
│   │   ├── mcb_walk.c
│   │   ├── msgs.lng
│   │   ├── msgs.loc
│   │   ├── msgs_w.loc
│   │   ├── nls/
│   │   │   ├── english.err
│   │   │   └── english.lng
│   │   ├── nls.loc
│   │   ├── nlstime.c
│   │   ├── s_skipwd.c
│   │   ├── s_skipws.c
│   │   ├── sstr.src
│   │   ├── stpcat.c
│   │   ├── stpcpy.c
│   │   ├── str.loc
│   │   ├── strnum.c
│   │   ├── suppldbg.loc
│   │   ├── supplio.loc
│   │   ├── syslog.loc
│   │   └── toupperx.c
│   ├── sstr.h
│   ├── str.h
│   ├── supl_def.h
│   ├── suppl.h
│   ├── suppldbg.h
│   ├── supplio.h
│   └── syslog.h
├── tests/
│   ├── args.bat
│   ├── bat1.bat
│   ├── bat2.bat
│   ├── bat3.bat
│   ├── benny.bat
│   ├── compat.bat
│   ├── ctty-nul.bat
│   ├── dir-test.txt
│   ├── errlvl.bat
│   ├── errlvl.c
│   ├── fdos.out
│   ├── hbp001a.bat
│   ├── hbp001b.bat
│   ├── hbp002.txt
│   ├── hbp_001.txt
│   ├── label.bat
│   ├── longcmd.bat
│   ├── msdos.out
│   ├── refl.bat
│   ├── t.bat
│   ├── test.bat
│   ├── test1.bat
│   ├── test2.bat
│   ├── test3.bat
│   ├── test4.bat
│   ├── testenv.c
│   ├── tst-if.bat
│   └── tstcmdln.bat
├── tools/
│   ├── 28.asm
│   ├── 50.asm
│   ├── debug.h
│   ├── depend.mk
│   ├── files.txt
│   ├── icmd_1.nas
│   ├── icmd_2.nas
│   ├── icmd_3.nas
│   ├── icmd_inc.inc
│   ├── icmd_tpl.nas
│   ├── kssf.asm
│   ├── load_icd.c
│   ├── makefile
│   ├── makefile.1
│   ├── ptchldrv.c
│   ├── ptchsize.c
│   ├── resource.h
│   ├── tools.m1
│   ├── tools.m2
│   └── vspawn.asm
├── utils/
│   ├── MAKECMD.BAT
│   ├── chunk.c
│   ├── debug.h
│   ├── depend.mk
│   ├── files.txt
│   ├── makefile
│   ├── makefile.mak
│   ├── misc.h
│   ├── mkctxt.c
│   ├── mkinfres.c
│   ├── mktools.c
│   ├── ptchsize.c
│   └── resource.h
├── utilsc/
│   ├── critstrs.c
│   ├── fixstrs.c
│   └── makefile.mak
└── version.h

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
* text eol=crlf
*.sh text eol=lf
*.com -text
*.ico -text
elvis.rc -text
ci_*.sh text eol=lf
.github/workflows/*.yml text eol=lf

# On checkout it is the specified encoding, but git internal
# representation is UTF-8 so that diffs work correctly
strings/DEFAULT.??? working-tree-encoding=CP437 text eol=auto
strings/english.??? working-tree-encoding=CP437 text eol=auto
strings/yu437.???   working-tree-encoding=CP437 text eol=auto
strings/dutch.???   working-tree-encoding=CP850 text eol=auto
strings/finnish.??? working-tree-encoding=CP850 text eol=auto
strings/french.???  working-tree-encoding=CP850 text eol=auto
strings/german.???  working-tree-encoding=CP850 text eol=auto
strings/italian.??? working-tree-encoding=CP850 text eol=auto
strings/pt_br.???   working-tree-encoding=CP850 text eol=auto
strings/spanish.??? working-tree-encoding=CP850 text eol=auto
strings/swedish.??? working-tree-encoding=CP850 text eol=auto
strings/serbian.??? working-tree-encoding=CP852 text eol=auto
strings/slovene.??? working-tree-encoding=CP852 text eol=auto
strings/turkish.??? working-tree-encoding=CP857 text eol=auto
strings/pt.???   working-tree-encoding=CP860 text eol=auto
strings/russian.??? working-tree-encoding=CP866 text eol=auto
strings/ukr.???     working-tree-encoding=CP866 text eol=auto
# Does not exist in iconv, so have to do it manually
# strings/polish.???  working-tree-encoding=CP991 text eol=auto
strings/polish.??? text eol=auto


================================================
FILE: .github/actions/build/action.yml
================================================
name: cross-compile-build
description: Cross-compile
inputs:
  cmd:
    description: 'build cmd'
    default: ''
    required: false
    type: string
#
runs:
  using: composite
  steps:
    - name: build (Windows)
      if: runner.os == 'Windows'
      run: |
        copy config.b config.bat
        copy config.std config.mak
        ${{inputs.cmd}}
      shell: cmd
    - name: build (OSX, Linux)
      if: runner.os != 'Windows'
      run: |
        ${{inputs.cmd}}
      shell: bash



================================================
FILE: .github/actions/upx-inst/action.yml
================================================
name: install-upx
description: Load UPX
#
runs:
  using: composite
  steps:
    - name: UPX install (OSX)
      if: runner.os == 'macOS'
      run: brew install upx
      shell: bash
    - name: UPX install (Linux, Windows)
      if: runner.os != 'macOS'
      uses: crazy-max/ghaction-upx@v3
      with:
        install-only: true


================================================
FILE: .github/workflows/ci-build.yml
================================================
name: Build
on:
  pull_request:
    types:
      - opened
      - edited
      - ready_for_review
      - reopened
      - synchronize
  push:

jobs:
  build:
    if: contains(github.event.head_commit.message, '[skip ci]') == false

    runs-on: ubuntu-24.04

    steps:
    - uses: actions/checkout@v4

    - name: prerequisites
      run: ./ci_prereq.sh
      env:
          TC201_ARCHIVE_PATHNAME: ${{ vars.TC201_ARCHIVE_PATHNAME }}
          TC201_ARCHIVE_FILENAME: ${{ vars.TC201_ARCHIVE_FILENAME }}
          TC201_ARCHIVE_PASSPHRASE: ${{ secrets.TC201_ARCHIVE_PASSPHRASE }}

    - name: build
      run: ./ci_build.sh

    - name: test
      run: ./ci_test.sh

    - name: make snapshot name
      id: snapshotname
      run: |
        (
          today=`date -u +%F | tr '\n' '-'`
          s_sha=`echo -n ${GITHUB_SHA} | cut -c1-8`
          printf "fname=snapshot-%s%s\n" $today $s_sha >> $GITHUB_OUTPUT
        )

    - name: upload
      if: github.repository == 'FDOS/freecom' &&
        (github.event_name == 'push' || github.event.pull_request.merged == true)
      uses: actions/upload-artifact@v4
      with:
        name: ${{ steps.snapshotname.outputs.fname }}
        path: _output

  test-ow-cross-compile:
    if: contains(github.event.head_commit.message, '[skip ci]') == false
    strategy:
      matrix:
        ow:
          - name:   '1.9'
            id:     '1.9'
          - name:   '2.0'
            id:     '2.0-64'
        host:
          - name:   'Windows'
            id:     'nt'
            image:  'windows-latest'
            cmd:    'build.bat watcom upx english'
          - name:   'Mac OSX-ARM'
            id:     'osx'
            image:  'macos-latest'
            cmd:    './build.sh watcom upx english'
          - name:   'Linux'
            id:     'linux'
            image:  'ubuntu-latest'
            cmd:    './build.sh watcom upx english'
        exclude:
          - { ow: { name: '1.9' }, host: { id: 'osx' } }
    runs-on: ${{matrix.host.image}}
    name: Test OW ${{matrix.ow.name}} cross-compile (${{matrix.host.name}})

    steps:
    - uses: actions/checkout@v4

    - name: Nasm install
      uses: ilammy/setup-nasm@v1

    - name: UPX install
      uses: "./.github/actions/upx-inst"

    - name: Open Watcom install
      uses: open-watcom/setup-watcom@v0
      with:
        version: ${{matrix.ow.id}}

    - name: build
      uses: "./.github/actions/build"
      with:
        cmd: ${{matrix.host.cmd}}


================================================
FILE: .gitignore
================================================
*.cfg
*.com
*.exe
*.icd
*.lib
*.lst
*.map
*.o
*.obj
*.rsp
*.tmp

# CI build
/_downloads/**
/_output/**
/_watcom/**

/build/**
/strings/strings/**
!/strings/strings/makefile.mak
/**/echolib.bat
/**/echoto.bat
!/scripts/**
/**/gnumake.mak

/config.bat
/config.mak
/context.h_c
/context.inc
/gnuconf.mak
/infores
/info.txt
/strings.h
/criter/context.def
/criter/context.h_c
/criter/context.inc
/criter/criter
/criter/criter1
/shell/command.err
/strings/strings.dat
/strings/strings.err
/strings/strings.h
/strings/strings.log
/strings/xmsswap.cln
/tools/makefile.mak


================================================
FILE: FILE_ID.DIZ
================================================
This is the FreeDOS Command Shell (command.com).

For the latest version and information, visit

http://wiki.freedos.org/wiki/index.php/FreeCOM

See LICENSE for license information.


================================================
FILE: README.md
================================================
# FreeCom - The DOS Command Line Interface #
********************************************

Source code distribution of FreeCOM - a Command line interface
program, which substitutes COMMAND.COM

<!-- Upstream Master -->
<!-- [![Build](https://github.com/FDOS/freecom/workflows/Build/badge.svg)](https://github.com/FDOS/freecom/actions) -->
<!-- Local Branch -->
[![Build](../../workflows/Build/badge.svg)](../../actions)

## About ##
This software is part of the FreeDOS project. 
Please visit the freedos web page at http://www.freedos.org/ for more information about FreeDOS.

FreeCOM implements the command processor for the DOS kernel.  It is usually the first program started by the kernel and provides a command line interface to interactively run other DOS programs.

Additionally, FreeCOM implements a BATCH file processor allowing scripting of commands as well.  See http://help.fdos.org/en/hhstndrd/batch/index.htm for more help with batch commands.


## More information ##
[Changes since last official release](https://github.com/FDOS/freecom/commits/master)

[How to compile FreeCOM](docs/compile.txt)


## Bugs and Help ##

The COMMAND.COM web site (including source hosting) is at

   https://github.com/FDOS/freecom

Bugs may be filed at https://github.com/FDOS/freecom/issues
or you may send any bug reports, comments or other info to the
one of the FreeDOS mailing lists.  For subscription and archives, see:

   http://www.freedos.org/forums/

This software has been developed by many people.  Older changes are listed along with who provided the change within docs/HISTORY.TXT file and more recent changes can be seen with git log (HISTORY.TXT is only updated periodically).

Please note that this software is separate from the DOS-C kernel and
is intended to be compatible with a variety of kernels that implement the DOS API (i.e. it should run on FreeDOS DOS-C kernel and on other DOS kernels such as Microsoft's DOS).

## Installation ##
To use this shell, just run the COMMAND.COM file.
You can also add this to your CONFIG.SYS file:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SHELL=<shell path><shell filename>

e.g.

SHELL=C:\FREEDOS\COMMAND.COM /P
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

See http://help.fdos.org/en/hhstndrd/command.htm for description of command line options.


## Current Features ##
- environment handling with prompt and path support
- directory utilities
- command-line history with doskey-like features + filename completion (TAB)
- batch file processing
- input/output redirection and piping
- loadhigh support
- alias support
- flow control (IF, FOR, GOTO, labels)
- support for error and other messages in multiple languages


================================================
FILE: VERSION.TXT
================================================
FreeCom version 0.87 - WATCOMC [???]


================================================
FILE: build.bat
================================================
@echo off

set SWAP=YES-DXMS-SWAP____________________
if NOT "%SWAP%"=="YES-DXMS-SWAP____________________" goto err1
: BEGIN Internal stuff for ska -- If one of these three commands
:       fail for you, your distribution is broken! Please report.
for %%a in (lib\makefile.mak cmd\makefile.mak shell\makefile.mak) do if not exist %%a set SWAP=NO
if "%SWAP%"=="NO" set XMS_SWAP=
if "%SWAP%"=="NO" call dmake dist
: END
set SWAP=

set COMPILER=TURBOCPP
if not exist config.bat goto err3
if not exist config.mak goto err2
call config.bat
if exist lastmake.mk call clean.bat
if "%1"=="-r" call clean.bat
if "%1"=="-r" shift
if "%1"=="clean" clean.bat
if "%1"=="clean" goto ende
if "%1"=="-h" goto help
if "%1"=="-?" goto help

set XMS_SWAP=1
:loop_commandline
if "%1"=="no-xms-swap" goto special
if "%1"=="xms-swap" goto special
if "%1"=="xmsswap"  goto special
if "%1"=="debug"    goto special
if "%1"=="plainedt" goto plainedt
if "%1"=="watcom"   goto special
if "%1"=="wc"       goto special
if "%1"=="tc"       goto special
if "%1"=="tcpp"     goto special
if "%1"=="bc"       goto special
if "%1"=="upx"      goto special
goto run

:special
if "%1"=="no-xms-swap" set XMS_SWAP=
if "%1"=="xms-swap" set XMS_SWAP=1
if "%1"=="xmsswap"  set XMS_SWAP=1
if "%1"=="debug"    set DEBUG=1
if "%1"=="watcom"   set COMPILER=WATCOM
if "%1"=="wc"       set COMPILER=WATCOM
if "%1"=="tc"       set COMPILER=TC2
if "%1"=="tcpp"     set COMPILER=TURBOCPP
if "%1"=="bc"       set COMPILER=BC5
if "%1"=="upx"      set WITH_UPX=1
shift
if not "%1" == "" goto loop_commandline

if not "%1"=="-h" goto run

:help
echo Build FreeCOM
echo Usage: %0 [-r] [clean] [no-xms-swap] [debug] [language]
echo -r: Rebuild -- Clean before proceed
echo clean: Remove *.OBJ, *.COM, *.LIB, etc. files, then exit
echo no-xms-swap: Build FreeCOM without XMS-Only Swap support
echo debug: Build FreeCOM with debug settings.
echo plainedt: Build FreeCOM without enhanced line editing/history
echo You can select for which language to built FreeCOM by setting
echo the environment variable LNG before running this script, e.g.:
echo SET LNG=german
echo selects the German language. For available language see STRINGS\*.LNG
goto ende

:plainedt
if exist config.$$$ del config.$$$
ren config.h config.$$$
echo #define IGNORE_ENHANCED_INPUT >config.h
type config.$$$ >>config.h
shift
if not "%1" == "" goto loop_commandline
::goto run

:run
if not x%1==x set LNG=%1
if "%lng%"=="" set LNG=english
echo Building FreeCOM for language %LNG%

if not "%MAKE%" == "" goto skip_make

if "%COMPILER%" == "TC2"      set MAKE=%TC2_BASE%\make -fmakefile.mak
if "%COMPILER%" == "TURBOCPP" set MAKE=%TP1_BASE%\bin\make -f makefile.mak
if "%COMPILER%" == "BC5"      set MAKE=%BC5_BASE%\bin\make -f makefile.mak
if "%COMPILER%" == "WATCOM"   set MAKE=wmake -ms -h -f makefile.mak

echo Make is %MAKE%.

:skip_make

echo.
echo Checking SUPPL library
cd suppl
if exist skip goto endSuppl
echo Building SUPPL library
%MAKE% all
if errorlevel 1 goto ende
cd src
%MAKE% all
if errorlevel 1 goto ende
cd ..
:endSuppl
cd ..

echo.
echo Making basic utilities for build process
echo.
cd utils
%MAKE% all
if errorlevel 1 goto ende
cd ..\utilsc
%MAKE% all
if errorlevel 1 goto ende
cd ..

echo.
echo Making STRINGS resource
echo.
cd strings
%MAKE% all
if errorlevel 1 goto ende
cd strings
%MAKE% all
if errorlevel 1 goto ende
cd ..\..

echo.
echo Making CRITER resource
echo.
cd criter
%MAKE% all
if errorlevel 1 goto ende
cd ..

echo.
echo Making misc library
echo.
cd lib
%MAKE% all
if errorlevel 1 goto ende
cd ..

echo.
echo Making commands library
echo.
cd cmd
%MAKE% all
if errorlevel 1 goto ende
cd ..

echo.
echo Making COMMAND.COM
echo.
cd shell
%MAKE% all
if errorlevel 1 goto ende
cd ..

utils\mkinfres.exe /tinfo.txt infores shell\command.map shell\command.exe
:: save version without lang specific files and version with strings embedded
if NOT "%XMS_SWAP%"=="" SET CMD_NAME=strings\xmsswap.cln
if "%XMS_SWAP%"=="" SET CMD_NAME=strings\command.cln
copy /b shell\command.exe + infores + criter\criter1 + criter\criter %CMD_NAME%
copy /b %CMD_NAME% + strings\strings.dat command.com
if not exist command.com goto ende

echo.
echo Making supplemental tools
echo.
cd tools
type tools.m1 >makefile.mak
..\utils\mktools.exe >>makefile.mak
type tools.m2 >>makefile.mak
%MAKE% all
if errorlevel 1 goto ende
cd ..

echo.
echo Patching heap size to 8KB
echo.
utils\ptchsize.exe command.com +8KB
utils\ptchsize.exe %CMD_NAME% +8KB

if %WITH_UPX%x == x goto alldone
if exist command.upx del command.upx >nul
upx --8086 --best -o command.upx command.com

:alldone
echo.
echo All done. COMMAND.COM is ready for use!
echo.
if NOT "%XMS_SWAP%"=="" goto ende

echo Note: To build FreeCOM without XMS-Only Swap, re-run
echo BUILD.BAT -r no-xms-swap %LNG%
goto ende

:err3
echo Please copy CONFIG.B into CONFIG.BAT and update the
echo settings therein.
goto ende

:err2
echo Please copy CONFIG.STD into CONFIG.MAK and update the
echo settings therein.
goto ende

:err1
echo Environment full (cannot add environment variables)
echo Cannot proceed

:ende
set XMS_SWAP=
set DEBUG=
set MAKE=
set COMPILER=
set TC2_BASE=
set TP1_BASE=
set BC5_BASE=
set XNASM=
set LNG=
set WITH_UPX=
set CMD_NAME=
if exist config.$$$ del config.h
if exist config.$$$ ren config.$$$ config.h


================================================
FILE: build.sh
================================================
#!/bin/bash

set -e

WITH_UPX="no"
SED=sed
#workaround for Windows (set to binary mode)
if [ "$(expr substr $(uname -s) 1 5)" == 'MINGW' ]; then
    SED='sed -b'
fi


export SWAP=YES-DXMS-SWAP____________________
# BEGIN Internal stuff for ska -- If one of these three commands
#       fail for you, your distribution is broken! Please report.
for a in lib/makefile.mak cmd/makefile.mak shell/makefile.mak; do if [ ! -f $a ]; then export SWAP=NO; fi; done
if [ "$SWAP" == "NO" ]; then
    unset XMS_SWAP
    dmake dist
fi
# end
export SWAP=

if [ ! -f config.mak ]; then
  echo File config.mak missing, copying config.std to it
  cp config.std config.mak || exit 1
fi

export XNASM=nasm
export COMPILER=watcom
if [ -z "$WATCOM" ]; then
  export WATCOM=$HOME/watcom
  export PATH=$PATH:$WATCOM/binl
fi
export PATH=$PATH:.

if [ -f lastmake.mk ] || [ "$1" == "-r" ]; then ./clean.sh; fi
if [ "$1" == "-r" ]; then ./clean.sh; shift; fi
if [ "$1" == "clean" ]; then ./clean.sh; exit 0; fi

export XMS_SWAP=1
while (( "$#" )); do
  case "$1" in
    -h)
	echo Build FreeCOM
	echo Usage: %0 [-r] [clean] [no-xms-swap] [debug] [language]
	echo -r: Rebuild -- Clean before proceed
	echo clean: Remove *.OBJ, *.COM, *.LIB, etc. files, then exit
	echo no-xms-swap: Build FreeCOM without XMS-Only Swap support
	echo debug: Build FreeCOM with debug settings.
	echo You can select for which language to built FreeCOM by setting
	echo the environment variable LNG before running this script, e.g.:
	echo EXPORT LNG=german
	echo selects the German language. For available language see STRINGS\*.LNG
	exit 0
	;;
    no-xms-swap)
	unset XMS_SWAP
	;;
    debug)
	export DEBUG=1
	;;
    watcom)
	export COMPILER=watcom
	;;
    wc)
	export COMPILER=watcom
	;;
    gcc)
	export COMPILER=gcc
	;;
    upx)
	WITH_UPX="yes"
	;;
    *)
	break
	;;
  esac
  shift
done


if [ -n "$1" ]; then export LNG=$1; fi
if [ -z "$LNG" ]; then export LNG=english; fi
echo Building FreeCOM for language $LNG

if [ -z "$MAKE" ]; then
    case "$COMPILER" in
	watcom)
	    export MAKE="wmake -ms -h -f makefile.mak"
	    ;;
	gcc)
	    export MAKE="make -f gnumake.mak"
	    ;;
	*)
	    ;;
    esac
    echo Make is $MAKE.
fi

# substitutions for GNU Make

gnumake_subst () {
    $SED -e 's@^!@@' \
	-e 's@^include "\(.*\)"@include \1@' \
	-e 's@^include $(TOP)/config.mak@include $(TOP)/gnuconf.mak@' \
	-e 's@if \(.*\) == \(.*\)[\r$]@ifeq (\1,\2)@' \
	-e 's@^CC =@CC :=@' \
	-e 's@^INCLUDEPATH =@INCLUDEPATH :=@' \
	-e 's/\(-f obj.*$<\)/\1 -o $@/' \
	 < $1/$2 > $1/$3
}

if $MAKE -? 2>&1 | grep -q gnu; then
    gnumake_subst . config.mak gnuconf.mak
    for i in suppl utils utilsc strings criter lib cmd; do
	gnumake_subst $i makefile.mak gnumake.mak
    done
    gnumake_subst suppl/src makefile.mak gnumake.mak
    gnumake_subst strings/strings makefile.mak gnumake.mak
    gnumake_subst shell makefile.mak gnumake.mak
fi

echo
echo Checking SUPPL library
cd suppl
if [ ! -f skip ]; then
    echo Building SUPPL library
    $MAKE all

    cd src
    $MAKE all
    cd ..
fi
cd ..

echo
echo Making basic utilities for build process
echo
cd utils
$MAKE all
cd ../utilsc
$MAKE all
cd ..

echo
echo Making STRINGS resource
echo
cd strings
$MAKE all
cd strings
$MAKE all
cd ../..

echo
echo Making CRITER resource
echo
cd criter
$MAKE all
cd ..

echo
echo Making misc library
echo
cd lib
$MAKE all
cd ..

echo
echo Making commands library
echo
cd cmd
$MAKE all
cd ..

echo
echo Making COMMAND.COM
echo
cd shell
$MAKE all
cd ..

utils/mkinfres.exe -Tinfo.txt infores shell/command.map shell/command.exe
cat shell/command.exe infores criter/criter1 criter/criter strings/strings.dat > command.com
[ -f command.com ] || exit 1

echo
echo Making supplemental tools
echo
cd tools
cat tools.m1 > makefile.mak
../utils/mktools.exe >>makefile.mak
cat tools.m2 >>makefile.mak
if $MAKE -? 2>&1 | grep -q gnu; then
    gnumake_subst . makefile.mak gnumake.mak
fi
$MAKE all
cd ..

echo
echo Patching heap size to 8KB
echo
utils/ptchsize.exe command.com +8KB

if [ $WITH_UPX = "yes" ]; then
  rm -f command.upx
  upx --8086 --best -o command.upx command.com
fi

echo
echo All done. COMMAND.COM is ready for use!
echo
if [ -z "$XMS_SWAP" ]; then
  echo Note: To build FreeCOM without XMS-Only Swap, re-run
  echo ./build.sh -r no-xms-swap $LNG
fi


================================================
FILE: buildall.bat
================================================
@ECHO OFF
REM we use BUILD_COMPILER as build.bat sets and clears COMPILER env var
if "%BUILD_COMPILER%"=="" set BUILD_COMPILER=wc
if NOT "%1"=="" goto %1

rd /s /q build
call clean
mkdir build
mkdir build\localize
copy VERSION.TXT build\localize\
copy command.lsm build\localize\
copy docs\localize.txt build\localize\

REM make FreeDOS package structure
md build\package
SET pkgdir=build\package
md %pkgdir%\APPINFO
md %pkgdir%\BIN
md %pkgdir%\DOC
md %pkgdir%\DOC\COMMAND
md %pkgdir%\HELP
md %pkgdir%\NLS
md %pkgdir%\SOURCE
md %pkgdir%\SOURCE\FREECOM

pushd .
set languages=NL Dutch ES Spanish DE German FI Finnish FR French IT Italian PO Polish PTR PT_BR RU Russian SE Swedish Ser Serbian SI Slovene TR Turkish UKR Ukr YUG YU437 EN English
set buildfile=%0
call %0 buildall padding %languages%
::for %%a in (Dutch Spanish German Finnish French Italian Polish PT_BR Russian Swedish Serbian Slovene Turkish Ukr YU437 English) DO %0 %%a
popd

pushd .
cd build\localize
7z a -mx9 -tzip ..\localize.zip .
popd

REM source with filetimes matching commit
pushd .
cd build
md source
cd source
git clone https://github.com/FDOS/freecom.git
cd freecom
REM this is from git-tools, it is not included with git
git restore-mtime
REM remove git references
rd /s /q .git
rd /s /q .github
del .gitattributes
del .gitignore
cd ..
7z a -mx9 -tzip ..\freecom-source.zip .
popd

REM make FreeDOS package
pushd .
copy command.lsm %pkgdir%\APPINFO\COMMAND.LSM
copy bin\fdcom.ico %pkgdir%\BIN\FDCOM.ICO
copy build\English\xmsswap\command.com %pkgdir%\BIN\COMMAND.COM
copy FILE_ID.DIZ %pkgdir%\DOC\COMMAND\FILE_ID.DIZ
copy README.md %pkgdir%\DOC\COMMAND\README.MD
copy VERSION.TXT %pkgdir%\DOC\COMMAND\VERSION.TXT
copy docs\HELP.EN %pkgdir%\HELP\COMMAND.EN
copy docs\html\commands\cmd.html %pkgdir%\DOC\COMMAND\CMD.HTM
copy docs\html\commands\FreeCOM.html %pkgdir%\DOC\COMMAND\FREECOM.HTM
copy utils\MAKECMD.BAT %pkgdir%\NLS\MAKECMD.BAT
:: language specific versions copied into NLS during build
copy build\freecom-source.zip %pkgdir%\SOURCE\FREECOM\SOURCES.ZIP
cd %pkgdir%
7z a -mx9 -tzip ..\command.zip .
popd


call clean
SET languages=
SET pkgdir=
SET buildfile=
ECHO Done bulding all!
goto end

:buildall
rem skip past buildall dummy on first pass, skip last language on each successive pass
shift
shift
rem %1 and %2 are abbr and language name
if "%1"=="" goto end
pushd .
ECHO building %2 (%1)
call %buildfile% dobuild %2
popd
copy build\%2\xmsswap\command.com %pkgdir%\NLS\CMD-%1.COM
goto buildall

:dobuild
rem skip past dobuild
shift
rem %1 is the language name (should match one of the *.LNG files)
mkdir build\%1
copy VERSION.TXT build\%1\
copy command.lsm build\%1\

mkdir build\%1\xmsswap
call build -r %BUILD_COMPILER% xms-swap %1
copy command.com build\%1\xmsswap\
copy tools\28.com build\%1\
copy tools\50.com build\%1\
copy tools\load_icd.exe build\%1\

copy strings\xmsswap.cln build\localize\
copy strings\fixstrs.exe build\localize\
copy strings\default.lng build\localize\
copy strings\%1.lng build\localize\
copy strings\strings.dat build\localize\%1.dat
copy tools\28.com build\localize\
copy tools\50.com build\localize\
copy tools\load_icd.exe build\localize\


mkdir build\%1\kswap
call build -r %BUILD_COMPILER% no-xms-swap %1
copy command.com build\%1\kswap\
copy docs\k-swap.txt build\%1\kswap\
copy tools\kssf.com build\%1\kswap\
copy tools\vspawn.com build\%1\kswap\

copy strings\command.cln build\localize\
copy tools\kssf.com build\localize\
copy tools\vspawn.com build\localize\


mkdir build\%1\debug
call build -r %BUILD_COMPILER% xms-swap debug %1
copy command.com build\%1\debug\


mkdir build\%1\plainedt
call build -r %BUILD_COMPILER% xms-swap plainedt %1
copy command.com build\%1\plainedt\


pushd .
cd build\%1
7z a -mx9 -tzip ..\%1.zip .
popd

:end


================================================
FILE: ci_build.sh
================================================
#!/bin/sh

set -e

if [ ! -z "${TRAVIS_BUILD_DIR}" ] ; then
  CI_BUILD_DIR=${TRAVIS_BUILD_DIR}
else
  CI_BUILD_DIR=$(pwd)
fi
echo CI_BUILD_DIR is \"${CI_BUILD_DIR}\"

# Open Watcom Environment Setup
export WATCOM=$CI_BUILD_DIR/_watcom
export PATH=$CI_BUILD_DIR/bin:$PATH:$WATCOM/binl64

# Output directory
rm -rf _output
mkdir _output

# Which ones to build
LANGUAGES="english dutch finnish french german italian polish pt pt_br russian serbian slovene spanish swedish turkish ukr yu437"

# GCC
for lng in ${LANGUAGES} ; do
  # Do full clean for rebuild of each language
  echo "Do full clean"
  git clean -q -x -d -f -e _output -e _watcom -e _download
  export LNG=${lng}
  ./build.sh gcc
  TGT="_output/gcc/${LNG}"
  mkdir -p ${TGT}
  mv -i command.com ${TGT}/.
done

# Watcom
for lng in ${LANGUAGES} ; do
  # Do full clean for rebuild of each language
  echo "Do full clean"
  git clean -q -x -d -f -e _output -e _watcom -e _download
  export LNG=${lng}
  ./build.sh wc
  TGT="_output/wc/${LNG}"
  mkdir -p ${TGT}
  mv -i command.com ${TGT}/.
done

# Let's use the just compiled command.com for the DOS builds and get some
# testing of it for free. Note case insensitive target in case the freecom
# package ever has an upper or mixed case file.
echo Copying the GCC Linux built command.com to use for the DOS builds
cp -v _output/gcc/english/command.com ${HOME}/.dosemu/drive_c/[Cc][Oo][Mm][Mm][Aa][Nn][Dd].[Cc][Oo][Mm]

# Watcom (DOS) (slow so just English)
mkdir -p _output/wc_dos/english
git clean -q -x -d -f -e _output -e _watcom -e _download
{
  echo set COMPILER=WATCOM
  echo set WATCOM='C:\\devel\\watcomc'
  echo set MAKE=wmake /ms /h /f makefile.mak
  echo set XNASM='C:\\devel\\nasm\\nasm'
  echo set XUPX=upx --8086 --best
  echo set OLDPATH=%PATH%
  echo set PATH='%WATCOM%\\binw;C:\\bin;%OLDPATH%'
  echo set DOS4G=QUIET
} | unix2dos > config.bat

cp config.std config.mak

dosemu -td -q -K . -E "build.bat wc"
mv -i command.com _output/wc_dos/english/.

# Turbo C 2.01 (DOS) (slow so just Spanish)
if [ -d ${HOME}/.dosemu/drive_c/tc201 ] ; then
  export LNG=spanish

  mkdir -p _output/tc2_dos/${LNG}
  git clean -q -x -d -f -e _output -e _watcom -e _downloads
  {
    echo set LNG=${LNG}

    echo set COMPILER=TC2
    echo set TC2_BASE='C:\\tc201'
    echo set XNASM=nasm
    echo set XUPX=upx --8086 --best
    echo set OLDPATH=%PATH%
    echo set PATH='%TC2_BASE%;C:\\devel\\nasm;C:\\bin;%WATCOM%\\binw;%OLDPATH%'
  } | unix2dos > config.bat

  cp config.std config.mak

  dosemu -td -q -K . -E "build.bat"
  mv -i command.com _output/tc2_dos/${LNG}/.
fi

echo done


================================================
FILE: ci_prereq.sh
================================================
#!/bin/sh

set -e

sudo add-apt-repository -y ppa:dosemu2/ppa
sudo add-apt-repository ppa:tkchia/build-ia16
sudo apt update

# Common tools
sudo apt install nasm upx
sudo apt install dosemu2 dos2unix

# GCC-IA16 for Linux
sudo apt install gcc-ia16-elf libi86-ia16-elf

# Tools for DOS builds
mkdir -p _downloads
mkdir -p _watcom
cd _downloads

HERE=$(pwd)

# download and unpack Open Watcom snapshot
[ -f ow-snapshot.tar.xz ] || wget --no-verbose https://github.com/open-watcom/open-watcom-v2/releases/download/Current-build/ow-snapshot.tar.xz
tar -C ../_watcom -xf ow-snapshot.tar.xz

#IBIBLIO_PATH='http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.2/repos'
IBIBLIO_PATH='https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/repositories/1.3'

BASE=${IBIBLIO_PATH}/base

#    get FreeDOS kernel
[ -f kernel.zip ] || wget --no-verbose ${BASE}/kernel.zip

#    get FreeCOM
[ -f freecom.zip ] || wget --no-verbose ${BASE}/freecom.zip

DEVEL=${IBIBLIO_PATH}/devel

#    get gnumake for DOS
[ -f djgpp_mk.zip ] || wget --no-verbose ${DEVEL}/djgpp_mk.zip

#    get nasm for DOS
[ -f nasm.zip ] || wget --no-verbose ${DEVEL}/nasm.zip

#    get upx for DOS
[ -f upx.zip ] || wget --no-verbose ${DEVEL}/upx.zip

#    get Watcom for DOS
[ -f watcomc.zip ] || wget --no-verbose ${DEVEL}/watcomc.zip

#    get Turbo C 2.01 (maybe encrypted) tar file
if [ -n "${TC201_ARCHIVE_FILENAME}" ] && [ ! -f ${TC201_ARCHIVE_FILENAME} ] ; then
   echo "Downloading Turbo C 2.01"
   wget --no-verbose ${TC201_ARCHIVE_PATHNAME}/${TC201_ARCHIVE_FILENAME}
fi

# Unpack the DOS binaries
mkdir -p ${HOME}/.dosemu/drive_c
cd ${HOME}/.dosemu/drive_c && (

  mkdir -p bin

  # Boot files
  unzip -LL -q ${HERE}/kernel.zip
  cp -p bin/kernl386.sys ./kernel.sys
  unzip -LL -q ${HERE}/freecom.zip
  cp -p bin/command.com ./command.com
  cp -p /usr/share/dosemu/dosemu2-cmds-0.3/c/fdconfig.sys .

  # Development files
  unzip -LL -q ${HERE}/djgpp_mk.zip
  cp -p devel/djgpp/bin/make.exe bin/.
  unzip -LL -q ${HERE}/upx.zip
  cp -p devel/upx/upx.exe bin/.
  echo PATH to make and upx binaries is 'c:/bin'

  unzip -LL -q ${HERE}/nasm.zip
  echo PATH to nasm binary is 'c:/devel/nasm'

  unzip -LL -q ${HERE}/watcomc.zip
  echo PATH to watcom binaries is 'c:/devel/watcomc/binw'

  # Turbo C
  if [ -f ${HERE}/${TC201_ARCHIVE_FILENAME} ] && [ -n "${TC201_ARCHIVE_PASSPHRASE}" ] ; then
    echo Decrypting and unpacking Turbo C 2.01
    echo "${TC201_ARCHIVE_PASSPHRASE}" | gpg --decrypt --batch --passphrase-fd 0 ${HERE}/${TC201_ARCHIVE_FILENAME} | tar -jxf -
  elif [ -f ${HERE}/${TC201_ARCHIVE_FILENAME} ] ; then
    echo Unpacking Turbo C 2.01
    tar -jxf ${HERE}/${TC201_ARCHIVE_FILENAME}
  else
    echo No Turbo C 2.01 archive available
  fi
)


================================================
FILE: ci_test.sh
================================================
#!/bin/sh

echo No tests created yet!
exit 0


================================================
FILE: clean.bat
================================================
@echo off
if "%1"=="" goto main
for %%i in (%2 %3 %4 %5 %6 %7 %8 %9) do if exist %1%%i del %1%%i>nul
goto end

:main
cd suppl
call clnsuppl.bat
cd ..
call %0 .\ command.com command.upx 
call %0 .\ lastmake.mk context.h_c context.inc strings.h infores info.txt gnuconf.mak
call %0 criter\ criter criter1 context.def context.inc context.h_c
call %0 strings\ command.cln xmsswap.cln strings.h strings.err strings.dat strings.log
call %0 strings\strings\ makefile strings.mak
call %0 strings\strings\*. c
call %0 tools\ makefile.mak
call %0 tools\*. icd

for %%i in (cmd lib strings strings\strings) do call %0 %%i\*. lib lst
for %%i in (cmd lib shell strings strings\strings tools utils utilsc) do call %0 %%i\*. obj o cfg map exe com rsp
for %%i in (cmd lib shell strings strings\strings tools utils utilsc) do call %0 %%i\ echoto.bat echolib.bat gnumake.mak
for %%i in (. criter) do call %0 %%i\ gnumake.mak

:end



================================================
FILE: clean.sh
================================================
#!/bin/sh
cd suppl
rm -f all_done untar.exe untar.com untar.obj untar.map gnumake.mak
rm -f compile.me suppl*.lib suppl*.lst echoto.bat vars.bat *.cfg
cd src
rm -f *.obj suppllib.rsp echoto.bat echolib.bat *.cfg gnumake.mak suppl*.lib suppl*.lst
cd ../..
rm -f command.com command.upx
rm -f lastmake.mk context.h_c context.inc strings.h infores info.txt
cd strings    && rm -f strings.h strings.err strings.dat strings.log
cd ../criter  && rm -f criter criter1 context.def context.inc context.h_c
cd ../strings/strings && rm -f *.c makefile strings.mak
cd ../../tools && rm -f makefile.mak *.icd
cd ..
for i in cmd lib strings strings/strings; do rm -f $i/*.lib $i/*.lst; done
for i in cmd lib shell strings strings/strings tools utils utilsc; do
  rm -f $i/gnumake.mak $i/*.obj $i/*.o $i/*.cfg $i/*.map $i/*.exe
  rm -f $i/*.com $i/*.rsp $i/echoto.bat $i/echolib.bat
done
for i in . criter; do rm -f $i/gnumake.mak; done


================================================
FILE: cmd/alias.c
================================================
/* $Id$
 *  ALIAS.C - alias administration module
 *
 */

#include "../config.h"

#include <nls_f.h>

#include "../err_fcts.h"
#include "../include/cmdline.h"
#include "../include/command.h"
#include "../include/context.h"
#include "../include/misc.h"
#include "../strings.h"

int cmd_alias(char *param)
{	char *value;

		/* Bail on every option */
	if(leadOptions(&param, 0, 0) != E_None)
		return 1;

	/* *param != whitespace */
	switch(breakVarAssign(ctxtAlias, param, &value)) {
	case 1:			/* no equal sign */
		error_syntax(0);
		return 1;
	case 0:			/* displayed */
		return 0;
#ifdef DEBUG
	case 2: break;
	default:
		dprintf(("[ALIAS: Invalid response from breakVarAssign()]\n"));
		return 1;
#endif
	}

	/* param[] == alias name -> check its validity */
	rtrimsp(param);		/* spaces are ignored at its end */
	if(!*param) {
		error_syntax(0);
		return 1;
	}
	if(!is_fnstr(param)) {
		error_no_alias_name(param);
		return 1;
	}
	StrFUpr(param);				/* Aliases are case-insensitive */
	value = trimsp(value);

	return chgCtxt(CTXT_TAG_ALIAS, param, *value? value: 0);
}


================================================
FILE: cmd/beep.c
================================================
/* $Id$
 *  BEEP.C - beep command.
 *
 *  Comments:
 *
 * 16 Jul 1998 (Hans B Pufal)
 *   started.
 *
 * 16 Jul 1998 (John P Price)
 *   Seperated commands into individual files.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 *
 */

#include "../config.h"

#include "../include/command.h"
#include "../include/misc.h"

int cmd_beep (char * param) { (void)param; beep (); return 0; }


================================================
FILE: cmd/break.c
================================================
/* $Id$
 *  BREAK.C - break command.
 *
 *  Comments:
 *
 * 14-Aug-1998 (John P Price)
 *   started.
 *
 */

#include "../config.h"

#include "../err_fcts.h"
#include "../include/command.h"
#include "../include/misc.h"
#include "../strings.h"

int cmd_break(char *param)
{
	switch(onoffStr(param)) {
  	default:
		error_on_off();
		return 1;
	case OO_Null:	case OO_Empty:
		displayString(TEXT_MSG_BREAK_STATE, getbreak() ? D_ON : D_OFF);
		break;
  	case OO_Off:	setbreak(0);	break;
  	case OO_On:		setbreak(1);	break;
	}

	return 0;
}


================================================
FILE: cmd/call.c
================================================
/* $Id$
 *  CALL.C - batch file call command.
 *
 *  Comments:
 *
 * 16 Jul 1998 (Hans B Pufal)
 *   started.
 *
 * 16 Jul 1998 (John P Price)
 *   Seperated commands into individual files.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 04-Aug-1998 (Hans B Pufal)
 * - added lines to initialize for pointers (HBP004)  This fixed the
 *   lock-up that happened sometimes when calling a batch file from
 *   another batch file.
 *
 * 10-Aug-1998 ska
 * - changed: initialize bcontext with function
 *
 */

#include "../config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "../include/batch.h"
#include "../include/cmdline.h"
#include "../include/command.h"
#include "../err_fcts.h"
#include "../include/kswap.h"

static int optS = 0;		/* force to swap out FreeCOM during call */
static int optN = 0;		/* force to NOT swap (superceeds optS) */

optScanFct(opt_call)
{
  (void)arg;
  switch(ch) {
  case 'S': return optScanBool(optS);
  case 'N': return optScanBool(optN);
  case 'Y': return optScanBool(tracemode);
  }
  optErr();
  return E_Useage;
}

/*
 * Perform CALL command.
 *
 * Allocate a new batch context and add it to the current chain.
 * Call parsecommandline passing in our param string
 * If No batch file was opened then remove our newly allocted
 * context block.
 */
int cmd_call (char * param) {
	struct bcontext *n = newBatchContext();
	int ec;

        (void)param;
	if (n == 0) {
		/* Not in a batch file */
		return 1;
	}

	optS = optN = 0;

	if((ec = leadOptions(&param, opt_call, 0)) != E_None)
		return ec;

	if(swapOnExec != ERROR) {
		if(optS)
			swapOnExec = TRUE;
		if(optN)
			swapOnExec = FALSE;
	}

	parsecommandline(param, FALSE);
	if(swapOnExec != ERROR)
		swapOnExec = FALSE;

	if (bc->bfile == 0
	 && bc->bfnam == 0) {    /* Wasn't a batch file so remove context */
		bc = bc->prev;
		free(n);
	}

	return 0;
}


================================================
FILE: cmd/cdd.c
================================================
/* $Id$
 * CDD - changes drive and directory
 */

#include "../config.h"

#include "../include/command.h"

int cmd_cdd(char *param)
{
	return cd_dir(param, 1, "CDD");
}


================================================
FILE: cmd/chcp.c
================================================
/* $Id$
 *  CHCP.C - CHCP command.

 	CHCP [codepage]

 	via DOS-66-01/02

	$Log$
	Revision 1.3  2004/07/19 18:13:39  skaus
	bugfix: CHCP: use n to set new codepage [Eduardo Casino]

	Revision 1.2  2003/03/05 17:43:51  skaus
	bugfix: cached NLS data not flushed
	
	Revision 1.1  2002/11/12 21:47:16  skaus
	add: CHCP (disabled by default)
	
 */

#include "../config.h"

#include <assert.h>
#include <dos.h>
#include <ctype.h>

#include <portable.h>

#include "../err_fcts.h"
#include "../include/command.h"
#include "../include/cmdline.h"
#include "../include/nls.h"
#include "../strings.h"

int cmd_chcp(char *param)
{	USEREGS
	unsigned curCP, sysCP;

	_AX = 0x6601;
	_BX = 0xffffU;
	geninterrupt(0x21);
	curCP = _BX;
	sysCP = _DX;
	if(_CFLAG || curCP == 0xffffU) {
		error_get_codepage();
		return 1;
	}

	if(!param || !*param) {
		/* display current codepage */
		displayString(TEXT_DISPLAY_CODEPAGE, curCP, sysCP);
	} else {
		char *p;
		unsigned n = 0;

		/* set code page */
		if(!isdigit(*param)) {
			error_syntax(param);
			return 1;
		}

		p = param;
		do  n = n * 10 + (*p - '0');
		while (isdigit(*++p));

		if(*ltrimcl(p)) {
			error_syntax(param);
			return 1;
		}

		invalidateNLSbuf();

		_DX = sysCP;
		_BX = n;
		_AX = 0x6602;
		geninterrupt(0x21);
		if(_CFLAG) {
			error_set_codepage();
			return 1;
		}
	}
	return 0;
}


================================================
FILE: cmd/chdir.c
================================================
/* $Id$
 * CD / CHDIR - changes the current working directory of a drive
 */

#include "../config.h"

#include "../include/command.h"

int cmd_chdir(char *param)
{
  return cd_dir(param, 0, "CHDIR");
}


================================================
FILE: cmd/cls.c
================================================
/* $Id$
 *  CLS.C - clear screen internal command
 *
 *  Comments:
 *
 *	Issues ^L (Form Feed), then:
 *	if file descriptor #1 (aka stdout) is connected to a device _and_
 *	is not the NUL: device, uses the BIOS to clear the screen
 *	and home the cursor to the upper left.
 *
 *  07/27/1998 (John P. Price)
 *    started.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 30-Nov-1998 (John P Price <linux-guru@gcfl.net>)
 * - CLS now sets the text colors to lightgray on black before clearing the
 *   screen.
 *
 * $Log$
 * Revision 1.9  2006/09/05 01:44:32  blairdude
 * Massive patches from Arkady that I'm way too lazy to sort through.  If anything happens, Arkady can answer for it.
 *
 * Revision 1.8  2006/06/12 04:55:42  blairdude
 * All putchar's now use outc which first flushes stdout and then uses write to write the character to the console.  Some potential bugs have been fixed ( Special thanks to Arkady for noticing them :-) ).  All CONIO dependencies have now been removed and replaced with size-optimized functions (for example, mycprintf, simply opens "CON" and directly writes to the console that way, and mywherex and mywherey use MK_FP to access memory and find the cursor position).  FreeCOM is now
 * significantly smaller.
 *
 * Revision 1.7  2006/06/11 02:06:11  blairdude
 *
 *
 * All of FreeCOM now uses write instead of putchar and intr instead of int86[x] or intdos[x]
 *
 * Revision 1.6  2004/08/19 19:10:49  skaus
 * fix: CLS: cut debug message
 *
 * Revision 1.5  2004/06/29 14:14:54  skaus
 * fix: help screen of internal commands causes "Unknown command error" {Bernd Blaauw}
 *
 * Revision 1.4  2004/06/15 19:27:43  skaus
 * bugfix: CLS: use BIOS, unless fd1 is file or NUL {Eric Auer}
 *
 */

#include "../config.h"

#include <dos.h>
#include <stdio.h>

#include "../include/command.h"
#include "../include/openf.h"
#include "../include/misc.h"

int cmd_cls (char * param) {
    int attr = fdattr(1);
    (void)param;
    outc( '\xc' ); /* ^L Form feed */

	/* Output stream is standard CON device */
	if((attr & 0x9f) == 0x93) {
		unsigned attr = 0x0700;
		int mode;
		IREGS r;
		
		/* Get the current video mode */
		
		r.r_ax = 0x0f00;	/* Scroll window up // entire window */
		intrpt(0x10, &r);
		mode = r.r_ax & 0x7f;
		
		switch (mode)
		{
		case 0x04: /* CGA 320x200 */
		case 0x05: /* CGA 320x200, grayscale */
		case 0x09: /* PCjr 320x200 */
		case 0x0a: /* PCjr 640x200 */
		case 0x0b: /* Tandy 1000 SL/TL */
		case 0x0d: /* EGA/VGA 320x200, 16 colors */
		case 0x0e: /* EGA/VGA 640x200, 16 colors */
		case 0x0f: /* EGA/VGA 640x350, mono */
		case 0x10: /* EGA/VGA 640x350, 4 or 16 colors */
		case 0x11: /* VGA 640x480, mono */
		case 0x12: /* VGA 640x480, 16 colors */
		case 0x13: /* VGA 320x200, 256 colors */
		case 0x59: /* SVGA 800x600, 16 colors */
			attr = 0;
			break;
		default:
			;
		}
		
		/* Now roll the screen */
		r.r_ax = 0x0600;	/* Scroll window up // entire window */
		r.r_bx = attr;		/* Attribute to write */
		r.r_cx = 0x0000;	/* Upper left */
		r.r_dx = ((SCREEN_ROWS - 1) << 8) | (SCREEN_COLS - 1); /* Lower right */
		intrpt(0x10, &r);
		goxy(1, 1);			/* home the cursor */
	}
	else if((attr & 0x9c) == 0x80) {
		/* character device neither NUL nor CLOCK$ nor standard CON
		  (guess AUX or COMn, which is connected commmon serial terminal) */
		outs( "\x1b[2J" );
	}

	return 0;
}


================================================
FILE: cmd/cmd.m1
================================================
.AUTODEPEND

CFG_DEPENDENCIES = makefile.mak

!include "..\config.mak"

all: $(CFG) cmds.lib



================================================
FILE: cmd/cmd.m2
================================================



================================================
FILE: cmd/copy.c
================================================
/* $Id$
 * COPY.C -- Internal Copy Command
 *
 * 1999/05/10 ska
 * rewritten, based upon previous COPY.C of FreeCom v0.76b
 *
 * Known bugs:
 *  + Multiple '+' plus signs are scanned as a single one.
 *
 * 1999/07/08 ska
 * bugfix: destination is a drive letter only
 *
 * 2000/07/17 Ron Cemer
 * bugfix: destination ending in "\\" must be a directory, but fails
 *	within dfnstat()
 *
 * 2000/07/24 Ron Cemer
 * bugfix: Suppress "Overwrite..." prompt if destination is device
 *
 * 2001/02/17 ska
 * add: interactive command flag
 
 * bugfix: copy 1 + 2 + 3 <-> only first and last file is stored
 */

#include "../config.h"

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <limits.h>

#include <portable.h>

/*#define DEBUG*/

#include "dfn.h"
#include "suppl.h"
#include "supplio.h"

#include "../include/lfnfuncs.h"
#include "../include/command.h"
#include "../include/cmdline.h"
#include "../err_fcts.h"
#include "../include/misc.h"
#include "../strings.h"
#include "../include/openf.h"

#define ASCII 1
#define BINARY 2
#define IS_DIRECTORY 5

static struct CopySource {
  struct CopySource *nxt;   /* next source */
  struct CopySource *app;   /* list of files to append */
  int flags;          /* ASCII / Binary */
  char *fnam;         /* filename */
} *head, *last, *lastApp;


static int appendToFile; /* Append the next file rather than new source */
static char *destFile;     /* destination file/directory/pattern */
static int destFlags;

static int optY, optV, optA, optB;

optScanFct(opt_copy)
{
  (void)arg;
  switch(ch) {
  case 'Y': return optScanBool(optY);
  case 'V': return optScanBool(optV);
  case 'A': case 'B': return E_Ignore;
  }
  optErr();
  return E_Useage;
}

optScanFct(opt_copy1)
{
  int ec, *opt = NULL, *optReset = NULL;

  (void)arg;
  switch(ch) {
#ifndef NDEBUG
  default:
    fprintf(stderr, "Invalid option: file '%s' in line %d\n"
      , __FILE__, __LINE__);
    abort();
#endif
  case 'A': opt = &optA; optReset = &optB; break;
  case 'B': opt = &optB; optReset = &optA; break;
  }
  if((ec = optScanBool(*opt)) == E_None
   && *opt)
    *optReset = 0;

  return ec;
}


static void initContext(void)
{
  appendToFile = 0;
  last = lastApp = 0;
}

static void killContext(void)
{
  if(last) {
    assert(head);
    do {
      if((lastApp = head->app) != 0) do {
        lastApp = (last = lastApp)->app;
        free(last);
      } while(lastApp);
      head = (last = head)->nxt;
      free(last);
    } while(head);
  }
}

/*
	faster copy, using large (far) buffers
*/

/*
	a) this copies data, using a 60K buffer
	b) if transfer is slow (or on a huge file),
	   indicate some progress
*/

static int BIGcopy(int fdout, int fdin, int asc)
{
	char far *buffer;
	unsigned size;
	unsigned rd;
	int retval = 0;
								/* stat stuff */
	unsigned startTime, lastTime=0, now, doStat = 0, deviceIn;
	unsigned long copied = 0, toCopy = filelength(fdin);
	char *statString;
	char far *ctrlz;
	
	
	/* Fetch the largest available buffer */
	for(size = 60*1024u; size != 0; size -= 4*1024) {
#ifdef FARDATA
		/* use last-fit allocation to work well with large model */
		buffer = MK_SEG_PTR(void, DOSalloc(size/16,2));
#else
		buffer = MK_SEG_PTR(void, DOSalloc(size/16,0));
#endif
		if(buffer != NULL)
			goto ok;
	}
	return 3;	/* out of memory error */

ok:
	dprintf( ("[MEM: BIGcopy() allocate %u bytes @ 0x%04x]\n"
	 , size, FP_SEG(buffer)) );
	deviceIn = isadev(fdin);
	statString = getString(deviceIn
		? TEXT_COPY_COPIED_NO_END
		: TEXT_COPY_COPIED);
	startTime = *(unsigned far *)MK_FP(0x40,0x6c);

	ctrlz = 0;
	while((rd = farread(fdin, buffer, size)) != 0) {
		if(rd == 0xffff) {
			retval = 1;
			goto _exit;
		}

		if(asc) {
			ctrlz = _fmemchr(buffer, 0x1a, rd);
			if(ctrlz != 0)
				rd = (unsigned)(ctrlz - buffer);
		}
		
		if(farwrite(fdout, buffer, rd) != rd) {
			if(!isadev(fdout)) retval = 2;
			goto _exit;
		}
			
						/* statistics */
		copied += rd;	
			
		now = *(unsigned far *)MK_FP(0x40,0x6c);
		
		if(!doStat
		 && now - startTime > 15 * 18
		 && isatty(fileno(stdout)))
			doStat = TRUE;
		
		if(now - lastTime > 18) {
			if(doStat)
				printf(statString, copied/1024, toCopy/1024);
				
			if(cbreak) {
				retval = 3;
				goto _exit;
			}	
				
			lastTime = now;
		}
		if(ctrlz || (rd < size && !(deviceIn && asc))) break;
	}	
		
_exit:		
	if(doStat)
		printf("%30s\r","");
		
	dprintf( ("[MEM: BIGcopy() release memory @ 0x%04x]\n"
	 , FP_SEG(buffer)) );
	DOSfree(FP_SEG(buffer));
	free(statString);
	return retval;
}

static int is_valid_disk(int tstdsk)
{
  int savdsk = getdisk();
  int newdsk;

  /* Change to new disk */
  setdisk(tstdsk);
  newdsk = getdisk();

  /* Restore */
  setdisk(savdsk);

  return (newdsk == tstdsk);
}

static int copy(char *dst, char *pattern, struct CopySource *src
  , int openMode)
{ struct dos_ffblk ff;
  struct CopySource *h;
  char rDest[MAXPATH], rSrc[MAXPATH];
  int fdin, fdout;
  int rc;
  FLAG keepFTime;
#if defined(__WATCOMC__) && __WATCOMC__ < 1280
  unsigned short date, time;
#elif defined(__TURBOC__)
  struct ftime fileTime;
#else
  unsigned date, time;
#endif
  char *srcFile;
  FLAG wildcarded;
  /*FLAG isfirst = 1;*/
  FLAG singleFileCopy = src->app == NULL;

  assert(dst);
  assert(pattern);
  assert(src);

  if(strpbrk(pattern, "*?") == 0) {
  	srcFile = dfnfilename(pattern);
  	wildcarded = 0;
  } else if(dos_findfirst(pattern, &ff, FA_RDONLY | FA_ARCH) != 0) {
    error_sfile_not_found(pattern);
    return 0;
  } else {
  	srcFile = ff.ff_name;
  	wildcarded = 1;
  }

  do {
/*    if( wildcarded && !strpbrk( dst, "*?" ) && !isfirst ) openMode = O_APPEND; */
    fillFnam(rDest, dst, srcFile);
    if(rDest[0] == 0)
      return 0;
    h = src;
    do {  /* to prevent to open a source file for writing, e.g.
          for COPY *.c *.?    */
      fillFnam(rSrc, h->fnam, srcFile);
      if(rSrc[0] == 0) {
        return 0;
      }
      rc = samefile(rDest, rSrc);
      if(rc < 0) {
        error_out_of_memory();
        return 0;
      } else if(rc) {
        error_selfcopy(rDest);
        return 0;
      }
    } while((h = h->app) != 0);

    /* Concenation of files uses ASCII by default */
    if(src->app) {
      for(h = src; h && !h->flags; h = h->app)
        h->flags = ASCII;
      if(!destFlags) destFlags = ASCII;
    }

    if(interactive_command		/* Suppress prompt if in batch file */
       && openMode != O_APPEND && !optY
       && (fdout = dos_open(rDest, O_RDONLY)) >= 0) {
    	int destIsDevice = isadev(fdout);

      dos_close(fdout);
      if(!destIsDevice) {	/* Devices do always exist */
        if((fdin = devopen(rSrc, O_RDONLY)) < 0) { /* Source doesn't exist */
            error_open_file( rSrc );
            return 0;
        } else {
	        dos_close(fdin);
          	switch(userprompt(PROMPT_OVERWRITE_FILE, rDest)) {
	    	default:	/* Error */
		    case 4:	/* Quit */
	    		  return 0;
		    case 3:	/* All */
			    optY = 1;
    		case 1: /* Yes */
	    		break;
		    case 2:	/* No */
    			continue;
    		}
        }
	  }
    }
    if(cbreak) {
      return 0;
    }
    if((fdout = devopen(rDest, openMode)) < 0) {
      error_open_file(rDest);
      return 0;
    }
    keepFTime = 1;
    if(isadev(fdout)) {
      if(destFlags & BINARY)  {
        /* in forced binary mode character devices are set to raw */
        fdsetattr(fdout, (fdattr(fdout) & 0xff) | 0x20);
      }
      keepFTime = 0;
    }
    h = src;
    keepFTime = (keepFTime && h->app == 0);
    do {
      fillFnam(rSrc, h->fnam, srcFile);
      if(rSrc[0] == 0) {
        dos_close(fdout);
        unlink(rDest);		/* if device -> no removal, ignore error */
        return 0;
      }
      if((fdin = devopen(rSrc, O_RDONLY)) < 0) {
        error_open_file(rSrc);
        dos_close(fdout);
        unlink(rDest);		/* if device -> no removal, ignore error */
        return 0;
      }
      if(isadev(fdin)) {
		keepFTime = 0;		/* Cannot keep file time of devices */
      	if(h->flags & BINARY)
		  /* in forced binary mode character devices are set to raw */
		  fdsetattr(fdin, (fdattr(fdin) & 0xff) | 0x20);
      	else
		  /* make sure to stop at Ctrl-Z */
		  h->flags |= ASCII;
      }
      if(keepFTime)
#ifdef __TURBOC__
        if(getftime(fdin , &fileTime))
#else
        if(_dos_getftime(fdin , &date , &time))
#endif
          keepFTime = 0; /* if error: turn it off */

      displayString(TEXT_MSG_COPYING, rSrc
	   , (openMode == 'a' || h != src)? "=>>": "=>", rDest);
      if(cbreak) {
        dos_close(fdin);
        dos_close(fdout);
        unlink(rDest);		/* if device -> no removal, ignore error */
        return 0;
      }

      /* Now copy the file */
      rc = 1;
      {
      	FLAG sizeChanged = !(h->flags & ASCII) && singleFileCopy &&
			!isadev(fdin) && !isadev(fdout);
        if(sizeChanged) {	/* faster copy, *MUCH* faster on floppies
								 change destination filesize to wanted size.
								 this a) writes all required entries to the
								 FAT (faster) determines, if there is enough
								 space on the destination device
								 no need to copy file, if it won't fit */
        					/* No test if chsize() fails for MS DOS 5/6 bug
        						see RBIL DOS-40 */
        					/* Don't use chsize() as Turbo RTL fills with
        						'\0' bytes, which is not useful here */
        	lseek(fdout, filelength(fdin), SEEK_SET);
        	if(truncate(fdout) != 0
        	 || lseek(fdout, 0, SEEK_SET) == -1) {
				error_write_file_disc_full(rDest, filelength(fdin));
        		rc = 0;
			} else {
				dprintf( ("[COPY chsize(%s, %lu)]\n", rDest,
				 filelength(fdin)) );
			}
		}
      
        if(rc != 0)
			switch(BIGcopy(fdout, fdin, h->flags & ASCII)) {
			case 0: 
				if(sizeChanged)
					/* probably the source file got truncated */
					/* we silently ignore any failure here, because it is
						assumed that we never extend, but truncate the file
						only (or do not change the length at all) */
					truncate(fdout);
				break;
			case 1:  error_read_file(rSrc);   rc = 0; break;
			case 2:  error_write_file(rDest); rc = 0; break;
			default: error_copy();            rc = 0; break;
			}
      }
      if(cbreak)
        rc = 0;
      dos_close(fdin);
      if(!rc) {
        dos_close(fdout);
        unlink(rDest);		/* if device -> no removal, ignore error */
        return 0;
      }
    } while((h = h->app) != 0);
    rc = 0;
    if((destFlags & ASCII) && !isadev(fdout)) {   /* append the ^Z as we copied in ASCII mode */
      if (dos_write(fdout, "\x1a", 1) != 1)
		rc = 1;
    }
    if(keepFTime)
#ifdef __TURBOC__
      setftime(fdout, &fileTime);
#else
      _dos_setftime(fdout, date, time);
#endif
    if(dos_close(fdout) != 0)
      rc = 1;
    if(rc) {
      error_write_file(rDest);
      unlink(rDest);		/* if device -> no removal, ignore error */
      return 0;
    }
  } while (wildcarded && dos_findnext(&ff) == 0);
  /*} while(wildcarded && FINDNEXT(&ff) == 0 && !(isfirst = 0)); */

  dos_findclose(&ff);

  return 1;
}

static int copyFiles(struct CopySource *h)
{ int differ, rc;

  rc = 0;

#define dst destFile
  if((differ = samefile(h->fnam, dst)) < 0)
    error_out_of_memory();
  else if(!differ)
    rc = copy(dst, h->fnam, h, O_WRONLY|O_TRUNC|O_CREAT);
  else if(h->app)
    rc = copy(dst, h->fnam, h->app, O_WRONLY|O_APPEND);
  else
    error_selfcopy(dst);
#undef dst

  return rc;
}

static int cpyFlags(void)
{
  return (optA? ASCII: 0) | (optB? BINARY: 0);
}

static struct CopySource *srcItem(char *fnam)
{	struct CopySource *h;

    if((h = malloc(sizeof(struct CopySource))) == 0) {
      error_out_of_memory();
      return 0;
    }

    h->fnam = fnam;
    h->nxt = h->app = 0;
    h->flags = cpyFlags();

    return h;
}

static int addSource(char *p)
{ struct CopySource *h;
  char *q;

  assert(p);
  q = strtok(p, "+");
  assert(q && *q);

  if(appendToFile) {
    appendToFile = 0;
    if(!lastApp) {
      error_leading_plus();
      return 0;
    }
  } else {      /* New entry */
    if(0 == (h = srcItem(q)))
      return 0;
    if(!last)
      last = lastApp = head = h;
    else
      last = lastApp = last->nxt = h;

    if((q = strtok(0, "+")) == 0)   /* no to-append file */
      return 1;
  }

  /* all the next files are to be appended to the source in "last" */
  assert(q);
  assert(lastApp);
  do {
    if(0 == (h = srcItem(q)))
      return 0;
    lastApp = lastApp->app = h;
  } while((q = strtok(0, "+")) != 0);

  return 1;
}


int cmd_copy(char *rest)
{ char **argv, *p;
  int argc, opts, argi;
  struct CopySource *h;
  char **argBuffer = 0;

  /* Initialize options */
  optA = optB = optV = optY = 0;

  /* read the parameters from env */
  if ((argv = scanCmdline(p = getEnv("COPYCMD"), opt_copy, 0, &argc, &opts))
   == 0) {
    free(p);
    return 1;
  }
  free(p);
  freep(argv);    /* ignore any parameter from env var */

  if((argv = scanCmdline(rest, opt_copy, 0, &argc, &opts)) == 0)
    return 1;

  initContext();

  /* Now parse the remaining arguments into the copy file
    structure */
  for(argi = 0; argi < argc; ++argi)
    if(isoption(p = argv[argi])) {    /* infix /a or /b */
      if(leadOptions(&p, opt_copy1, 0) != E_None) {
        killContext();
        freep(argv);
        return 1;
      }
      /* Change the flags of the previous argument */
      if(lastApp)
        lastApp->flags = cpyFlags();
    } else {            /* real argument */
      if(*p == '+') {       /* to previous argument */
        appendToFile = 1;
        while(*++p == '+');
        if(!*p)
          continue;
      }

      if(!addSource(p)) {
        killContext();
        freep(argv);
        return 1;
      }

    }

  if(appendToFile) {
    error_trailing_plus();
    killContext();
    freep(argv);
    return 1;
  }

  if(!last) {   /* Nothing to do */
    error_nothing_to_do();
    killContext();
    freep(argv);
    return 1;
  }

  assert(head);

  /* Check whether the source items are files or directories */
  h = head;
  argc = 0;		/* argBuffer entries */
  do {
	struct CopySource *p = h;
  	do {
  		char *s = strchr(p->fnam, '\0') - 1;
  		if(*s == '/' || *s == '\\'		/* forcedly be directory */
  		 || 0 != (dfnstat(p->fnam) & DFN_DIRECTORY)) {
			char **buf;
			char *q;
			if(*s == ':') 
				q = dfnmerge(0, p->fnam, 0, "*", "*");
			else
				q = dfnmerge(0, 0, p->fnam, "*", "*");
			if(0 == (buf = realloc(argBuffer, (argc + 2) * sizeof(char*)))
			 || !q) {
				free(q);
				error_out_of_memory();
				goto errRet;
			}
			argBuffer = buf;
			buf[argc] = p->fnam = q;
			buf[++argc] = 0;
		} else if(*s == ':' && (s - p->fnam) > 1) {		/* Device name LPT1:, but not X: */
  			if(!isDeviceName(p->fnam)) {
				error_invalid_parameter(p->fnam);
				goto errRet;
			}
  		}
  	} while(0 != (p = p->app));
  } while(0 != (h = h->nxt));

  destFlags = last->flags;
	if(last != head) {
		/* The last argument is to be the destination */
		if(last->app) {	/* last argument is a + b syntax -> no dst! */
			error_copy_plus_destination();
			goto errRet;
		}
		destFile = last->fnam;
		h = head;         /* remove it from argument list */
		while(h->nxt != last) {
		  assert(h->nxt);
		  h = h->nxt;
		}
		free(last);
		(last = h)->nxt = 0;
  } else {              /* Nay */
    destFile = ".\\*.*";
  }

#define dst destFile
  /* If the destination specifies a drive, check that it is valid */
  if (dst[0] && dst[1] == ':' && !is_valid_disk(toupper(dst[0]) - 'A')) {
    error_invalid_drive(toupper(dst[0]) - 'A');
    return 0;
  }
#undef dst

  /* Now copy the files */
  h = head;
  while(copyFiles(h) && (h = h->nxt) != 0);

errRet:
  killContext();
  freep(argv);
  freep(argBuffer);
  return 0;
}


================================================
FILE: cmd/ctty.c
================================================
/* $Id$
 *  CTTY.C - ctty command.
 *
 *  Comments:
 *
 *  Current possible problems: -- 2000/01/14 ska
 *
 *  Problem: Only the first three handles are changed to the passed device.
 *  -->
 *  As far as I know to CTTY (Change TTY) it is not sufficient just to
 *  change the handles 0-2 (stdin, stdout, stderr), but one must inform
 *  the system that another driver is the default STDIN/OUT device,
 *  what would include to:
 *  + return ienabled STDIN/STDOUT bits when the device attributes are
 *    retreived via IOCTL,
 *  + change the pointer at LoL+0C.
 *  My original implication that INT-29 is effected, too, is wrong in
 *  the Win98 DOSbox.
 *
 *  FreeDOS kernel 2017f passes the DOS1-compatible IO functions to
 *  the handle based ones, so maybe most simply programs will work?!
 *
 * 14 Aug 1998 (John P Price)
 * - Created dummy command.
 *
 * 2000/01/14 ska
 * + Added to change the first three handles to the given device name
 * + Supports only redirection of stdin and stdout, e.g.:
 *    C:\> CTTY COM1 >file
 *  -or-
 *    C:\> echo Hallo | CTTY COM1 | echo du
 *  The CTTY command effects the commands on the _next_ line.
 */

#include "../config.h"

#include <fcntl.h>
#ifdef DEBUG
#include <dos.h>
#endif
#include <io.h>
#include <stdio.h>

#include "../include/command.h"
#include "../err_fcts.h"
#include "../include/openf.h"
#include "../strings.h"
#include "../include/lfnfuncs.h"

#ifdef DEBUG
static void devAttr(int fd)
{ int attr;

  if((attr = fdattr(fd)) == 0)
	{
    dprintf(("[Failed to read attributes of fd #%d]\n", fd));
	}
  else {
    dbg_print("[fd #%d is", fd);
    if(attr & 0x80) {
      if(attr & 7) {
        if(attr & 1) dbg_outs(" STDIN");
        if(attr & 2) dbg_outs(" STDOUT");
        if(attr & 4) dbg_outs(" NUL");
      } else dbg_outs(" a device");
    } else dbg_outs(" a file");
    dbg_outsn("]");
  }
}
#endif

int cmd_ctty(char *param)
{ int f, attr, failed;

  if(!param || !*param) {
    displayString(TEXT_CMDHELP_CTTY);
    return 1;
  }

#ifdef DEBUG
  devAttr(0);
  devAttr(1);
  devAttr(2);
#endif

  if((f = devopen(param, O_RDWR)) < 0) {
    error_no_rw_device(param);
    return 1;
  }

  if(((attr = fdattr(f)) & 0x80) == 0
   || dos_write(f, "\r\n", 2) != 2) {		/* need \r as in bin mode */
    dos_close(f);
    error_no_rw_device(param);
    return 1;
  }

	/* Now inform the system that this device is the new console
		now; STDIN and STDOUT flag are the most lowest two bits  */
	fdsetattr(f, (attr & 0xFF) | 0x03);

  /* Now change the file descriptors:
    0 := rdonly
    1,2 := wronly

    if CTTY is called within a pipe or its I/O is redirected,
    oldinfd or oldoutfd is not equal to -1. In such case the
    old*fd is modified in order to effect the file descriptor
    after the redirections are restored. Otherwise a pipe or
    redirection would left CTTY in a half-made status.
  */
  failed = dup2(f, 2);   /* no redirection support */
  if(oldinfd != -1)
  	dos_close(oldinfd);
  oldinfd = f;
  if(oldoutfd != -1)
  	dos_close(oldoutfd);
  if((oldoutfd = dup(f)) == -1)
  	failed = 1;

  if(failed)
    error_ctty_dup(param);
  else {
    setCurrentConDev(param);
    /* workaround: do not use enhanced input if switched device is
                   not standard 'CON' */
    set_readcommandType( (attr & 0x9f) == 0x93 );
  }

  return failed;
}


================================================
FILE: cmd/date.c
================================================
/* $Id$
 *  DATE.C - date internal command
 *
 *  Comments:
 *
 *  08 Jul 1998 (John P. Price)
 *    started.
 *
 *  20 Jul 1998 (John P. Price)
 *  - corrected number of days for December from 30 to 31.
 *    (Thanx to Steffen Kaiser for bug report)
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 29-Jul-1998 (Rob Lake)
 * - fixed stand-alone mode.  Added Pacific C compatible dos_getdate functions
 *
 * 1999/03/17 ska
 * bugfix: detection for invalid date strings.
 *  Now the whole string must match: ^\s*\d+(.(\d+(.\d*)?)?)?\s*$
 *  The numbers can be delimited by any character from the 7-bit ASCII set,
 *  which is printable, but not alphanumerical.
 *  One need not specify all three parts (in which case the delimiter
 *  may be omitted, too). If one specify;
 *    1 number --> only the day changes
 *    2 numbers --> month/day; year remains unchanged
 *    3 numbers --> month/day/year
 *
 * 2001/02/08 ska
 * chg: two-digit year -> 2000 if less than 80
 * add: DATE /D and TIME /T
 *
 * 2001/02/14 ska
 * fix: years in range 80..199 are promoted to century 1900
 *		allows to parse dates created with year100 bug (by Arkady)
 */

#include "../config.h"

#include <dos.h>
#include <io.h>
#include <stdlib.h>

#include "../include/cmdline.h"
#include "../include/command.h"
#include "../err_fcts.h"
#include "../include/misc.h"
#include "../include/nls.h"
#include "../strings.h"


static int noPrompt = 0;

optScanFct(opt_date)
{
  (void)arg;
  switch(ch) {
  case 'D':
  case 'T': return optScanBool(noPrompt);
  }
  optErr();
  return E_Useage;
}


static int my_setdate(const char *s)
{	struct dosdate_t d;

	switch(parsedate(s, &d)) {
	case E_None:		/* success -> set the date */
		_dos_setdate(&d);
		_dos_setdate(&d);		/* In WinNT the date is often one day +/- */
		/* fall through */
	case E_Empty:		/* empty line */
		return 1;		/* success */
	}

	return 0;			/* failure */
}

int cmd_date(char *param)
{
	char s[40];
	int ec;

	noPrompt = 0;

#ifdef FEATURE_NLS
	refreshNLS();
#endif

	if((ec = leadOptions(&param, opt_date, 0)) != E_None)
		return ec;

	if (!*param) {
		char *date;

		if((date = curDateLong()) == 0)
			return 1;		/* out of mem */

		displayString(TEXT_MSG_CURRENT_DATE, date);
		free(date);

		param = 0;
	}

	while(1)  {                    /*forever loop */
		if (!param) {
			int len;
			if(noPrompt) return 0;

			displayString(TEXT_MSG_ENTER_DATE_AMERICAN
#ifdef FEATURE_NLS
			 + nlsBuf->datefmt, nlsBuf->dateSep, nlsBuf->dateSep
#else
			 , "-", "-"
#endif
			);
			len = dos_read(0, s, sizeof(s) - 1);
			if(cbreak || len < 0)
				return 1;
			s[len] = '\0';
			param = s;
		}

		if(my_setdate(param))
			break;
		
		error_invalid_date();
		/* force input the next time around. */
		param = 0;
	}

	return 0;
}


================================================
FILE: cmd/del.c
================================================
/* $Id$
 *  DEL.C - del command.
 *
 *  Comments:
 *
 *  06/29/98 (Rob Lake rlake@cs.mun.ca)
 *      rewrote del to support wildcards
 *      added my name to the contributors
 *
 * 07/13/98 (Rob Lake)
 *  - fixed bug that caused del not to delete file with out attribute.
 *  - moved set, del, ren, and ver to there own files
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 09-Aug-1998 (Rob Lake <rlake@cs.mun.ca>)
 * - changed check for ^C
 * - alloced mem for char **arg
 *
 * 10-Aug-1998 ska
 * - fixed allocation of char **arg incl. out-of-memory check
 *
 * 1998/12/04 ska
 * - chg: vcgetchar() displays a space rather beep()s for no-printable
 *  characters. the caller can beep()
 * - chg: moved vcgetchar() to misc.c as it is multiply used now
 * - chg: use vcgetcstr() instead of vcgetchar() loop
 *
 * 1999/04/27 ska
 * chg: uniform command line parser
 * add: allow multiple patterns on command line
 * add: delete count
 *
 * 1999/07/02 ska
 * chg: replaced stat() by dfnstat() [reduces size of image]
 */

#include "../config.h"

#include <assert.h>
#include <dos.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "suppl.h"
#include "dfn.h"

#include "../include/lfnfuncs.h"
#include "../include/cmdline.h"
#include "../include/command.h"
#include "../err_fcts.h"
#include "../strings.h"

#ifdef FEATURE_LONG_FILENAMES
#define abspath( x, y ) abspath( getshortfilename( x ), y )
#endif

static int optP, verbose;

optScanFct(opt_del)
{
  (void)arg;
  switch(ch) {
  case 'P': return optScanBool(optP);
  case 'V': return optScanBool(verbose);
  }
  optErr();
  return E_Useage;
}

int cmd_del(char *param)
{
	int ec = E_None;    /* exit code */
	int i;
	unsigned count = 0;

	struct dos_ffblk f;

	/* Make fullname somewhat larger to ensure that appending
		a matched name, one backslash and one hope. */
	char fullname[MAXPATH + sizeof(f.ff_name) + 2],
	*p, *q;
	int len;

	char **arg;
	int argc, optc;

	/* initialize options */
	verbose = optP = 0;

	if((arg = scanCmdline(param, opt_del, 0, &argc, &optc)) == 0)
		return E_Other;

	if(!argc) {
		error_req_param_missing();
		ec = E_Useage;
	} else {
		i = 0;
		do {
			assert(arg[i]);

		/* Get the pattern fully-qualified */
			/* Note: An absolute path always contains:
				A:\\
				--> It's always three bytes long at minimum
				and always contains a backslash */
			p = abspath(arg[i], 1);
			if(!p)
				return E_Other;
			assert(strlen(p) >= 3);

			if((len = strlen(p)) >= MAXPATH) {
				error_filename_too_long(p);
				free(p);
				ec = E_Other;
				goto errRet;
			}
			strcpy(fullname, p);  /* Operating over a local buffer simplifies
					 the process; rather than keep the pattern
					 within dynamic memory */
			free(p);
			p = fullname + len;

			/* check if it is a directory */
			if(dfnstat(fullname) & DFN_DIRECTORY) {
				if (p[-1] != '\\')
					*p++ = '\\';
			}

			if(p[-1] == '\\')    /* delete a whole directory */
				p = stpcpy(p, "*.*");

			/* p := address to copy the filename to to form the fully-qualified
				filename */
			/* There is at least one backslash within fullname,
				because of dfnexpand() */
			while(*--p != '\\') ;
			++p;

			/* make sure user is sure if all files are to be
			 * deleted */
            /*
             * Also make sure to find the LAST '.', as long filenames
             * are allowed to contain several
             */
			if(!optP && *p == '*'
			 && ((q = strrchr(p, '.')) == 0 || q[1] == '*')) {
				int r;
				
				p[-1] = 0;
				r = userprompt(PROMPT_DELETE_ALL, fullname);
				p[-1] = '\\';
				
				if (r != 1) {
					ec = E_Other;
					goto errRet;
				}
			}

			if (dos_findfirst(fullname, &f, FA_ARCH)) {
				error_sfile_not_found(fullname);
			} else do {
				strcpy(p, f.ff_name);       /* Make the full path */

				if(optP) {
					switch(userprompt(PROMPT_DELETE_FILE, fullname)) {
					case 4:             /* Quit/^Break pressed */
						ec = E_CBreak;
						goto errRet;
					case 3:				/* all */
						optP = 0;
					case 1:
						break;                /* yes, delete */
					default:
					case 2:
						continue;             /* no, don't delete */
					}
				}
				else if(cbreak) {  /* is also probed for in vcgetstr() */
					ec = E_CBreak;
					goto errRet;
				}

#ifdef NODEL
				/* define NODEL if you want to debug */
				puts(fullname);
#else
				if(verbose && !optP)
					displayString(TEXT_DELETE_FILE, fullname);
				if(unlink(fullname) != 0) {
					myperror(fullname);   /* notify the user */
				} else
					++count;
#endif

			} while (dos_findnext(&f) == 0);
		} while(++i < argc && *arg[i]);/* arg[i] can be NULL with LFNS?? */
	}

errRet:
    dos_findclose(&f);

	if(echo)
		dispCount(count, TEXT_MSG_DEL_CNT_FILES);

	freep(arg);
	return ec;
}


================================================
FILE: cmd/depend.mk
================================================
cmd .SEQUENTIAL : utils err_fcts.h strings context lib cmd_dir

cmd_dir .SETDIR=cmd :
	@echo Entering $(PWD)
	$(RUNMAKE) all
	@echo Leaving $(PWD)

CLEAN_DEPENDENCIES += cmd_clean
cmd_clean .SETDIR=cmd :
	@echo Entering  $(PWD)
	$(RUNMAKE) clean
	@echo Leaving  $(PWD)

CLOBBER_DEPENDENCIES += cmd_clobber
cmd_clobber .SETDIR=cmd :
	@echo Entering  $(PWD)
	$(RUNMAKE) clobber
	@echo Leaving  $(PWD)

DIST_DEPENDENCIES += cmd_dist
cmd_dist .SETDIR=cmd :
	@echo Entering  $(PWD)
	$(RUNMAKE) dist
	@echo Leaving  $(PWD)


================================================
FILE: cmd/dir.c
================================================
/* $Id$
 *  DIR.C - dir internal command
 *
 *  Comments:
 *
 *  01/29/97 (Tim Norman)
 *    started.
 *
 *  06/13/97 (Tim Norman)
 *    Fixed code.
 *
 *  07/12/97 (Tim Norman)
 *    Fixed bug that caused the root directory to be unlistable
 *
 *  07/12/97 (Marc Desrochers)
 *    Changed to use maxx, maxy instead of findxy()
 *
 *  06/08/98 (Rob Lake)
 *    Added compatibility for /w in dir
 *
 * Compatibility for dir/s started 06/09/98 -- Rob Lake
 * 06/09/98 (Rob Lake)
 * -Tested that program finds directories off root fine
 *
 *
 * 06/10/98 (Rob Lake)
 *      -do_recurse saves the cwd and also stores it in Root
 *      -build_tree adds the cwd to the beginning of
 *   its' entries
 *      -Program runs fine, added print_tree -- works fine.. as EXE,
 *   program won't work properly as COM.
 *
 * 06/11/98 (Rob Lake)
 * -Found problem that caused COM not to work
 *
 * 06/12/98 (Rob Lake)
 *      -debugged...
 *      -added free mem routine
 *
 * 06/13/98 (Rob Lake)
 *      -debugged the free mem routine
 *      -debugged whole thing some more
 *      Notes:
 *      -ReadDir stores Root name and _Read_Dir does the hard work
 *      -PrintDir prints Root and _Print_Dir does the hard work
 *      -KillDir kills Root _after_ _Kill_Dir does the hard work
 *      -Integrated program into DIR.C(this file) and made some same
 *       changes throughout
 *
 * 06/14/98 (Rob Lake)
 *      -Cleaned up code a bit, added comments
 *
 * 06/16/98 (Rob Lake)
 * - Added error checking to my previously added routines
 *
 * 06/17/98 (Rob Lake)
 *      - Rewrote recursive functions, again! Most other recursive
 *      functions are now obsolete -- ReadDir, PrintDir, _Print_Dir,
 *      KillDir and _Kill_Dir.  do_recurse does what PrintDir did
 *      and _Read_Dir did what it did before along with what _Print_Dir
 *      did.  Makes /s a lot faster!
 *  - Reports 2 more files/dirs that DOS actually reports
 *      when used in root directory(is this because dir defaults
 *      to look for read only files?)
 *      - Added support for /b, /a and /l
 *      - Made error message similar to DOS error messages
 * - Added help screen
 *
 * 06/20/98 (Rob Lake)
 * - Added check for /-(switch) to turn off previously defined
 * switches
 * - Added ability to check for DIRCMD in environment and
 * process it
 *
 * 06/21/98 (Rob Lake)
 * - Fixed up /B
 * - Now can dir *.ext/X, no spaces!
 *
 * 06/29/98 (Rob Lake)
 *      - error message now found in command.h
 *
 * 07/08/1998 (John P. Price)
 * - removed extra returns; closer to MSDOS
 * - fixed wide display so that an extra return is not displayed when
 *   there is five filenames in the last line.
 *
 * 07/12/98 (Rob Lake)
 * - Changed error messages
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 09-Aug-1998 (Rob Lake <rlake@cs.mun.ca>)
 * - fixed bug that caused blank lines to be printed
 * - renamed _Read_Dir to Read_Dir
 *
 * 10-Aug-1998 ska
 * - added checks for ^break
 *
 * 03-Dec-1998 John P Price
 * - Rewrote DIR command.  fixed problem with "DIR .COM" and other bugs
 *   Recursive switch does not work now, but it will be added soon.
 *
 * 31-Jan-1999 (John P. Price)
 * - Changed dir_print_header to use function INT21,AH=69 instead of the
 *   function it was using.  I'm not sure if this will fix anything or not.
 *   Also fixed bug with changing and restoring the current drive.
 *
 * 1999/04/23 ska
 * bugfix: cmd_dir(): dircmd can be NULL
 *
 * 25-Apr-1999 (John P. Price)
 * - changed dir so it always shows the bytes free.
 *
 * 29-Apr-1999 (John P. Price)
 * - Changed so that "dir command" with no extension will do as
 *   "dir command.*" (as it should).  Also made the display of the directory
 *   not include the whole filespec, but only the directory
 *
 * 2000/01/05 ska (Reported by Jeremy Greiner 2000/01/03)
 * bugfix: Last modification time displays year 2000 as 100
 *    --> Should be revised to allow 4-digit year
 *    Note: This fix differs from Jeremy Greiner's by that it does
 *    still display a 2-digit year rather than a 4-digit one.
 *    A four-digit year would break all batch files scanning the
 *    output of DIR.
 *
 * 2000/07/07 Ron Cemer
 * Added code to detect a pattern of "." or "" and convert to ".\*.*",
 * to prevent "file not found" errors from command.com when executed
 * from the root of drive C: and "DIR" is typed without any arguments,
 * or if you type "DIR C:" and the current directory on drive C: is \.
 * Also added code to convert \.\ in paths to \ (eliminate the .\ when
 * not needed).  Hopefully this will help to bypass any findfirst/findnext
 * bugs which may exist in the kernel.
 *
 * 2000/07/16 Ron Cemer
 * Fixed "DIR .." or "DIR C:\FREEDOS\COM079\..".
 * Fixed "DIR /S".
 * No longer reallocate the "path" variable in dir_list().  This would break
 * "DIR /S" because dir_list() is recursive and simply tacks on additional
 * subdirectories to the end of the "path" variable.  So the "path" variable
 * must NOT be moving around in memory, so I pre-allocate it to 270 characters
 * to allow plenty of room to tack on subdirectories while recursing.
 * Changed formatting to exactly match DOS's formatting as much as possible,
 * except that the "bytes free" count is still printed in bytes instead of
 * KB or MB.
 *
 * 2001/02/16 ska
 * chg: using STRINGS resource
 */

#include "../config.h"

#include <assert.h>
#include <conio.h>
#include <ctype.h>
#include <dos.h>
#ifndef FA_DEVICE
#define FA_DEVICE 0x0040u
#endif
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <portable.h>

/* Not available with TURBOC++ 1.0 or earlier: */
#if defined __GNUC__
#define pause cmdpause
#elif ( (!defined(__WATCOMC__) && !defined(__TURBOC__)) || (__TURBOC__ > 0x297) )
#include <dirent.h>
#endif

#include "dfn.h"

#define __LFNFUNCS_C
#include "../include/lfnfuncs.h"
#include "../include/cmdline.h"
#include "../include/command.h"
#include "../err_fcts.h"
#include "../include/nls.h"
#include "../strings.h"

/* useful macros */
#define MEM_ERR error_out_of_memory(); return 1;

#define WIDE_COLUMNS 5
	/* FINDFIRST() file mask used if no /A has been given */
#define ATTR_DEFAULT FA_RDONLY | FA_ARCH | FA_DIREC
	/* FINDFIRST() file mask used if /A (no args) has been given */
#define ATTR_ALL FA_RDONLY | FA_ARCH | FA_DIREC | FA_HIDDEN | FA_SYSTEM;

/* Definitions for optO */
#define ORDER_BY_SIZE 2
#define ORDER_BY_DATE 4
#define ORDER_BY_NAME 8
#define ORDER_BY_EXT  0x10
#define ORDER_INVERSE 0x01
#define ORDER_DIRS_FIRST 0x20
#define ORDER_DIRS_LAST 0x40
#define ORDER_BY_MASK 0x1e    
#define DEFAULT_SORT_ORDER "NG"

static unsigned char optOdir = 0;
static char optOorderby[5]; /* Array: One byte longer than order methods,
							the last unused orderby[] byte is zero
							by design always
							--> eases implementation, e.g. memcpy()
							in scanOrder() and for() loop in
							orderFuntion() */


struct currDir {
	unsigned linecount; /* for /B */
	};          
	
static int optS, optP, optW, optB, optL, longyear, optO;


#ifdef FEATURE_LONG_FILENAMES
static int dispLFN;
#endif

#ifdef FEATURE_DESCRIPT_ION
static int descriptionExists;
static int fDescription;
static void showDescription(const char *shortName, char *ext);
#endif

static struct ffblk _seg *orderArray;

static unsigned attrMay, attrMask, attrMatch;
/* within/right after the parsing of the options:
		what attributes "may" be on (but need not), which "must" be set
		and which "must not" be set.
	attrMay is just passed into FINDFIRST(),
	attrMask and attrMatch are aggregated so that
		<current attributes> & mask == match
	selects all valid files
*/


static char *path;
static unsigned line;
static int need_nl;

/* FAT32: file sizes are less then unsigned long, but accumulated
          directory sizes may be up to 2 TB

   so here comes simple 'large integer' arithmetic with billions separate
*/

typedef struct _bignum
{
  unsigned long low;
  unsigned billions;
} bignum;

static void bignum_add(bignum *big, bignum *to_add)
{
  big->billions += to_add->billions;
  big->low  += to_add->low;

  if (big->low >= 1000000000ul) {	/* carry propagation, school style */
    big->low -= 1000000000ul;
    big->billions++;
  }
}

#ifdef FEATURE_LONG_FILENAMES
static void printLFNname(char *shortName, char *ext)
{
    IREGS r;
    char pathbuffer[128];
	char longname[270];
	int pathlen;

	/* reconstruct the path+filename */
	pathlen = strrchr(path,'\\') - path;

	sprintf(pathbuffer,"%*.*s\\%s%c%s"
	 , pathlen
	 , pathlen
	 , path
	 , shortName
	 , *ext ? '.' : 0x0
	 , *ext ? ext : 0x0);

    dprintf(("[LFN: path %s\n",pathbuffer)); 
	
      /* LFN get canonical LFN */
	r.r_flags = 1;	/* CY before 21.71 calls! */
	r.r_ax = 0x7160;
	r.r_cx = 0x8002;
	r.r_si = FP_OFF( pathbuffer );
    r.r_ds = FP_SEG( pathbuffer );
	r.r_di = FP_OFF( longname );
    r.r_es = FP_SEG( longname );
	intrpt(0x21, &r);
	
    if( r.r_flags & 1 || r.r_ax == 0x7100 || !__supportlfns ) {
        dprintf(("[LFN: not supported %x]\n",r.r_ax)); 
		return;
	}

    if(samefile(longname, ".")) strcpy(longname, "\\.");

    if(dfnstat("..") != 0 && samefile(longname, "..")) strcpy(longname, "\\..");
	
	printf(" %.30s ", &strrchr(longname, '\\')[1]);
}
#endif


#ifdef FEATURE_DESCRIPT_ION
static int incline(void); /* forward reference */

/* this will read in next non-blank line from fDescription,
   and stores next token (ie filename or description).
   returns 0 on any error or no more entries in file
   *buf will equal '\0' or successfully read in filename
*/
static int descGetNextToken(char *buf, int fn, int maxlen)
{
  /* skip blank lines and any initial spaces, also exit early on any read error */
  do {
    if (dos_read(fDescription, buf, 1) != 1)
    {
      /*printf("[read error]\n");*/
      *buf = '\0';
      return 0;
    }
  } while ( (*buf == ' ') || (fn && isspace(*buf)) );

  /* read in characters until end of line/file (or space) is found */
  do {
    if (maxlen > 1) /* reuse last char in buffer, but don't exceed maxlen */
    {
      maxlen--;
      buf++;
    }
    if (dos_read(fDescription, buf, 1) != 1)
      break;
  } while ( (*buf!='\r') && (*buf!='\n') && 
            (*buf!=0x4/*Ctrl-D*/) && (*buf!=26/*Ctrl-Z*/) &&
            (!fn || (fn && !isspace(*buf))) );

  /* if read in description, then skip to end of line */
  /* note: because we stop at \r, next read may seem like blank line (\n) */
  if (!fn) 
    while ( (*buf!='\r') && (*buf!='\n') )
    {
      if (dos_read(fDescription, buf, 1) != 1)
        break;
    }

  /* terminate filename read in */
  *buf = '\0';
  return 1;
}

/* if a DESCRIPT.ION file was found (and opened) in current
   directory, then sequentially (as it's unsorted) read through it
   and print matching descriptions if found. Basic format are lines of
   filename <whitespace> description text [Ctrl-D ...] <EOL (\r,\n,\r\n)>|<EOF>
 */
static void showDescription(const char *shortName, char *ext)
{
  char fn[14], dummy[1], buf[128]; /* 4096 is max line size officially supported */
  assert(fDescription != 0);

  if (*shortName == '.') return; /* ignore . and .. entries */

  sprintf(fn, "%s%c%s", shortName, (*ext)?'.':0x0, ext); /* fn is 8.3 filename[.extension] */
  fn[13]='\0';
  lseek(fDescription, 0, SEEK_SET);  /* start at beginning of unsorted description file */
  while (descGetNextToken(buf,1,sizeof(buf)) && (strcmpi(fn,buf) != 0)) 
    { descGetNextToken(dummy,0,sizeof(dummy)); /* skip rest of this line & try again */ }

  if (*buf) /* found line in DESCRIPT.ION file matching this file */
  {
    descGetNextToken(buf,0,sizeof(buf));
    /* loop displaying upto 34 characters of description at a time. */
    #define DESCLEN 34
    {
      char *p = buf;
      while (strlen(p) > DESCLEN) /* display in chunks */
      {
        char t;

        /* start at end of chunk, try to split word at whitespace [or
           any punctuation]; don't split if word too big.
           i set to where '\0' will be stored.
         */
        int i = DESCLEN+1;
        while ((i>(DESCLEN/2)) && !isspace(*(p+i)) /*&& !ispunct(*(p+i))*/) i--;
        if (i<=(DESCLEN/2)) i = DESCLEN+1;
        else if (i<=DESCLEN) i++;

        t = *(p+i);                   /* store character          */
        *(p+i) = '\0';                /* temp force end of string */
        printf("\n");  incline();     /* handle dir /p            */
        printf("%44c%s", ' ', p);     /* display the substring    */
        p += i;                       /* skip past portion shown  */
        *p = t;                       /* restore saved character  */

        while(isspace(*p)) p++;       /* skip past whitespace splitting words at line edge */
      }
      /* and print the final (or only) chunk of description */
      printf("\n");  incline();       /* handle dir /p            */
      printf("%44c%s", ' ', p);
      /* printf("\n%44c%s", ' ', (*buf)? buf : "<empty description>"); */
    }
  }
  /* else printf("\n%44c%s", ' ', "NO MATCH FOUND"); */
}
#endif


/* The DIR command accepts more than one /A options, the later ones
	replaces former ones */
static int scanAttr(const char *p)
{	unsigned attr;

	attrMask = attrMatch = 0;	/* purge previous /A*** */
	attrMay = ATTR_ALL;

	if(p && *p) {
		for(--p;;) {
			switch(toupper(*++p)) {
			case 'R': attr = FA_RDONLY; break;
			case 'A': attr = FA_ARCH; break;
			case 'D': attr = FA_DIREC; break;
			case 'H': attr = FA_HIDDEN; break;
			case 'S': attr = FA_SYSTEM; break;
			/* case 'L': WinXP has this one too? */
			/* case '+': */ case '-': continue;
			case '\0': goto done;
			default:	/* error */
				error_illformed_option(p);
				return E_Useage;
			}
			switch(p[-1]) {
			case '-': /* disable */	attrMatch &= ~attr; break;
			default: /* enable */	attrMatch |= attr; break;
			/* case '+': / * anyway * / break; */
			}
			attrMask |= attr;	/* "mustNot" is dropped later, must need to
									be ORed later anyway */
		}
done:
		/* no need to fetch entries with disabled attributes */
		attrMay &= ~attrMask | attrMatch;
	}
	/* else  no specifying arguments --> display all */

	return E_None;
}
    

    
    
static int scanOrder(const char *p)
{
	if(!p || !*p)
		p = DEFAULT_SORT_ORDER;

restart:	
	memset(optOorderby, 0, sizeof(optOorderby));
	optOdir = 0;

	if(p && *p) {
		for(;;p++) {
			int inverse = p[-1] == '-';
			int option;
			int i;
			
			switch(toupper(*p)) {
			case '-': continue;
			case 'S': option = ORDER_BY_SIZE; break;
			case 'D': option = ORDER_BY_DATE; break;
			case 'N': option = ORDER_BY_NAME; break;
			case 'E': option = ORDER_BY_EXT; break;
			case 'G': optOdir = inverse? ORDER_DIRS_LAST: ORDER_DIRS_FIRST;
						continue;
			case 'U': ++p; goto restart;
			case '\0': goto done;
			default:	/* error */
				error_illformed_option(p);
				return E_Useage;
			}

			for(i = 0; i < sizeof(optOorderby); ++i) {
				if(optOorderby[i] == 0)
					break;
				if((optOorderby[i] & ORDER_BY_MASK) == option) {
					memcpy(optOorderby+i, optOorderby+i+1
					 , (sizeof(optOorderby)-1-i)*sizeof(optOorderby[0]));
				}
			}
			optOorderby[i] = option | inverse;
#ifdef DEBUG
			while(++i < sizeof(sizeof(optOorderby))) {
				assert(!optOorderby[i]);
			}
#endif
		}
done:;
	}

	optO = optOorderby[0] | optOdir;
	return E_None;
}

optScanFct(opt_dir)
{
  (void)arg;
  switch(ch) {
  case 'S': return optScanBool(optS);
  case 'P': return optScanBool2(optP);  /* multiple uses, /P /P, do not cancel, only /-P */
  case 'W': return optScanBool(optW);
  case 'B': return optScanBool(optB);
  case 'O': if(!bool) return scanOrder(strarg);
  			break;
  case 'A': if(!bool) return scanAttr(strarg);
  			break;
  case 'L': return optScanBool(optL);
  case '4':
  case 'Y': return optScanBool(longyear);
  case 0:	/* Longname option, e.g. /A without argument sign */
  	switch(*optstr) {
  	case 'A': case 'a':		/* /A*** */
  		if(!bool && !optHasArg())
			return scanAttr(optstr + 1);
		break;
  	case 'O': case 'o':		/* /O*** */
  		if(!bool && !optHasArg())
			return scanOrder(optstr + 1);
		break;
#ifdef FEATURE_LONG_FILENAMES
    case 'L': case 'l':		/* enable to display LFNs? */
      if(optLong("LFN"))
        return optScanBool(dispLFN);
      break;
#endif
	}
  }
  optErr();
  return E_Useage;
}

/*
 * pause
 *
 * pause until a key is pressed
 */
static int pause(void)
{
  cmd_pause(0);

  return 0;
}

/*
 * incline
 *
 * increment our line if paginating, display message at end of screen
 */
static int incline(void)
{

  if (!optP)
    return E_None;

  if (++line >= MAX_Y)
  {
    line = 0;
    return pause();
  }

  return 0;
}

static int flush_nl(void)
{ if(need_nl) {
    outc('\n');
    return incline();
  }

  return E_None;
}

/*
 * dir_print_header
 *
 * print the header for the dir command
 */
static int dir_print_header(int drive)
{

# include "algnbyte.h"

  struct media_id
  {
    int info_level;
    int serial1;
    int serial2;
    char vol_id[11];
    char file_sys[8];
  }
  media;

# include "algndflt.h"

  struct ffblk f;
  IREGS r;
  int currDisk;
  int rv;

  if (cbreak)
    return E_CBreak;

  if (optB)
    return 0;

  currDisk = getdisk();
  if(changeDrive(drive+1) != 0) {
    setdisk(currDisk);
    return 1;
  }

  /* get the media ID of the drive */
/*
   Format of disk info:
   Offset  Size    Description     (Table 01766)
   00h    WORD    0000h (info level)
   02h    DWORD   disk serial number (binary)
   06h 11 BYTEs   volume label or "NO NAME    " if none present
   11h  8 BYTEs   (AL=00h only) filesystem type (see #01767)

 */

  r.r_ax = 0x6900;
  r.r_bx = drive + 1;
  r.r_ds = FP_SEG(&media);
  r.r_dx = FP_OFF(&media);
  intrpt( 0x21, &r );

  /* print drive info */
 	displayString(TEXT_DIR_HDR_VOLUME, drive + 'A');


  if (sfnfindfirst("\\*.*", &f, FA_LABEL) == 0)
  {
        /* Added to remove "." from labels which are longer than
           8 characters (as DOS does), but must pad name with spaces. */
    char *dotptr = strchr(f.ff_name, '.');
    if (dotptr != 0)
    {
      char *mptr = f.ff_name+8;
      /* shift extension either back over dot or to end of space padding */
      memmove(mptr, dotptr+1, 4);  /* 4=max 3 char ext + \0 */
      /* add spaces for padding / overwrite with spaces shifted extension */
      while (dotptr < mptr)
        *dotptr++ = ' ';  /* pad with space and increment */
    }
    displayString(TEXT_DIR_HDR_VOLUME_STRING, f.ff_name);
  }
  else
  {
    displayString(TEXT_DIR_HDR_VOLUME_NONE);
  }

  setdisk(currDisk);

  if ((rv = incline()) == 0) {
  /* print the volume serial number if the return was successful */
      if (!( r.r_flags & 1 )) {
		displayString(TEXT_DIR_HDR_SERIAL_NUMBER
		 , media.serial2, media.serial1);
		rv = incline();
	  }
  }

        /* Added to exactly match DOS's formatting. */
  if ( (optS) && (rv == 0) ) {
      outc('\n');
      rv = incline();
  }

  return rv;
}


#ifdef INCLUDE_CMD_DIR
/*
 * print_summary: prints dir summary
 */
static int print_summary(unsigned long files
  , bignum *bytes)
{
  char buffer[32];

  if (optB)
    return 0;

  convert(files, 0, buffer);
  displayString(TEXT_DIR_FTR_FILES, buffer);
  convert(bytes->low, bytes->billions, buffer);
  displayString(TEXT_DIR_FTR_BYTES, buffer);
  need_nl = 1;
  return incline();
}

static int print_total
    (unsigned long files,
     bignum *bytes)
{ int rv;

  if(optB)
    return 0;

  rv = flush_nl();
  if(rv == E_None) {
    displayString(TEXT_DIR_FTR_TOTAL_NUMBER);
    if((rv = incline()) == E_None)
      return print_summary(files, bytes);
  }

  return rv;
}

static int dir_print_free(unsigned long dirs)
{
  char buffer[32];
  IREGS r;
  struct {
  	unsigned short whatever;
  	unsigned short version;
  	unsigned long  sectors_per_cluster; 
  	unsigned long  bytes_per_sector;
  	unsigned long  free_clusters;
  	unsigned long  total_clusters;
  	unsigned long  available_physical_sectors;
  	unsigned long  total_physical_sectors;
  	unsigned long  free_allocation_units; 
  	unsigned long  total_allocation_units; 
  	unsigned char  reserved[8];
  	} FAT32_Free_Space;
  static char rootname[] = "C:\\";	
  unsigned long clustersize;

  if(optB)
    return 0;

  /* print number of dirs and bytes free */

  convert(dirs, 0, buffer);
  displayString(TEXT_DIR_FTR_DIRS, buffer);

  rootname[0] = toupper(*path);
  r.r_flags = 1;	/* CY before 21.73 calls! */
  r.r_ax = 0x7303;
  r.r_ds = FP_SEG(rootname);
  r.r_dx = FP_OFF(rootname);
  r.r_es = FP_SEG(&FAT32_Free_Space);
  r.r_di = FP_OFF(&FAT32_Free_Space);
  r.r_cx = sizeof(FAT32_Free_Space);
  intrpt( 0x21, &r);

  /* Note: RBIL carry clear and al==0 also means unimplemented 
     alternately carry set and ax==undefined (usually unchanged) for unimplemented
     ecm: RBIL is wrong, CF unchanged al=0 is the typical error return.
     EDR-DOS returns NC ax=0 so checking for al!=0 here was wrong.
  */
  if(!( r.r_flags & 1 ) && ( r.r_ax != 0x7300 ) ) {
	dprintf(("[DIR: Using FAT32 info]\n"));
	clustersize = FAT32_Free_Space.sectors_per_cluster
	 * FAT32_Free_Space.bytes_per_sector;

       /* The following loop is intended to handle large free space amounts
          and huge [fake] cluster sizes, such as NTFS4DOS driver on large HDs.
       */
       if (clustersize)
          if (FAT32_Free_Space.free_clusters >= 0x80000000ul / clustersize)
                {
                int shift;
                
                for (shift = 21; --shift;)
                        {
                        if ((clustersize & 1) == 0) clustersize >>= 1;
                        else                        FAT32_Free_Space.free_clusters >>= 1;
                        }
                
                convert(FAT32_Free_Space.free_clusters * clustersize, 0, buffer);

                strcat(buffer, " Mega");
                goto output;
                }
  }  
  r.r_ax = 0x3600;
  r.r_dx = toupper(*path) - 'A' + 1;
  intrpt(0x21, &r);
  convert((unsigned long)r.r_ax * r.r_bx * r.r_cx, 0, buffer);
output:
  displayString(TEXT_DIR_FTR_BYTES_FREE, buffer);

  return incline();
}

static int DisplaySingleDirEntry(struct ffblk *file, struct currDir *cDir)
{
   int rv = E_None;

    if (cbreak)
      return E_CBreak;

    if (optL)
      strlwr(file->ff_name);

    if (optW)
    {
      char buffer[sizeof(file->ff_name) + 3];

      if (file->ff_attrib & FA_DIREC)
      {
        sprintf(buffer, "[%s]", file->ff_name);
      }
      else
      {
        strcpy(buffer, file->ff_name);
      }
      displayString(TEXT_DIR_LINE_FILENAME_WIDE, buffer);
      if (++cDir->linecount == WIDE_COLUMNS)
      {
        /* outputted 5 columns */
        outc('\n');
        rv = incline();
        cDir->linecount = 0;
      }
    }
    else if (optB)
    {
      if (strcmp(file->ff_name, ".") == 0 || strcmp(file->ff_name, "..") == 0)
        return E_None;
      if (optS)
        outs(path);
      displayString(TEXT_DIR_LINE_FILENAME_BARE, file->ff_name);
      rv = incline();
    }
    else
    {
      char buffer[sizeof(long) * 4 + 2], *ext = "";

      if (file->ff_name[0] == '.')
        displayString(TEXT_DIR_LINE_FILENAME_SINGLE, file->ff_name);
      else
      {
        ext = strrchr(file->ff_name, '.');
        if (!ext)
          ext = "";
        else
          *ext++ = '\0';

        displayString(TEXT_DIR_LINE_FILENAME, file->ff_name, ext);
      }

      if (file->ff_attrib & FA_DIREC)
      {
        displayString(TEXT_DIR_LINE_SIZE_DIR);
      }
      else
      {
        convert(file->ff_fsize, 0, buffer);
        displayString(TEXT_DIR_LINE_SIZE, buffer);
      }

	{ char *p;
		int year, month, day;
		int hour, minute;

		year = (file->ff_fdate >> 9) + 80;
		if(longyear)
			year += 1900;
		else	year %= 100;
		day = file->ff_fdate & 0x001f;
		month = (file->ff_fdate >> 5) & 0x000f;
		hour = file->ff_ftime >> 5 >> 6;
		minute = (file->ff_ftime >> 5) & 0x003f;

		p = nls_makedate(0, year, month, day);
		if(!p) {
			error_out_of_memory();
			return E_NoMem;
		}
        outc(' ');
		outs(p);
		free(p);
		p = nls_maketime(NLS_MAKE_SHORT_AMPM, hour, minute, -1, 0);
		if(!p) {
			error_out_of_memory();
			return E_NoMem;
		}
        outc(' ');
		outs(p);
		free(p);
		#ifdef FEATURE_LONG_FILENAMES
            if( dispLFN )
				printLFNname(file->ff_name, ext);
		#endif
		#ifdef FEATURE_DESCRIPT_ION
			if (descriptionExists)
				showDescription(file->ff_name, ext);
		#endif
        outc('\n');
	 }

      rv = incline();
   }
   return cbreak? E_CBreak: rv;
}

/* return -1,0,1 where -1 if p1 is before p2, 0 if same, 1 if p2 is before p1 */
static int orderFunction(const void *p1, const void *p2)
{
  int i1 = *(int*)p1;
  int i2 = *(int*)p2;
  int rv = 0;
  int i;

  struct ffblk f1, f2;

  _fmemcpy(&f1, orderArray + i1 , sizeof(f1));
  _fmemcpy(&f2, orderArray + i2 , sizeof(f2));
  
  if(optOdir && (f1.ff_attrib & FA_DIREC) != (f2.ff_attrib & FA_DIREC))
  	return (optOdir & ORDER_DIRS_FIRST ? f1.ff_attrib: f2.ff_attrib)
  	         & FA_DIREC ? -1 : 1;  
  	         
  
  for (i = 0; rv == 0; i++) {
  	int opt = optOorderby[i];
  	assert(i < sizeof(optOorderby));
  	
	switch(opt & ORDER_BY_MASK) {
	
	  case 0:
	  	return rv;			/* is 0 actually */
	
	  case ORDER_BY_SIZE:
		if(f1.ff_fsize > f2.ff_fsize) rv = 1;
		else if(f1.ff_fsize < f2.ff_fsize) rv = -1;
		break;
	
	  case ORDER_BY_DATE:
	    rv = f1.ff_fdate - f2.ff_fdate;
	    if(!rv)
	    	 rv = f1.ff_ftime - f2.ff_ftime;
		break;
	
	  case ORDER_BY_EXT:
		{ char *x1 = strchr(f1.ff_name, '.');
		char *x2 = strchr(f2.ff_name, '.');
		
		
		if(!x1 && !x2)	/* both are equal */
			continue;
		
		if (x1 && x2) rv = strcmp(x1, x2);
		else if (!x1 && x2) rv = -1;
		else rv = 1;			/* x1 && !x2 */
	    }
	    break;
		
	  case ORDER_BY_NAME:
		rv = strcmp(f1.ff_name,f2.ff_name);
		break;
	}
	if (opt & ORDER_INVERSE) rv = - rv;
  }  
  
  /* if criteria (size, date, etc) compare equal then return results lexically by filename */
  if (rv == 0)
	rv = strcmp(f1.ff_name,f2.ff_name);

  return rv;
}    	


static int flushOrder(struct ffblk _seg *orderArray,
  		int *orderIndex,
  		int  orderCount,
		struct currDir *cDir)
{
  int i;
  struct ffblk file;
  
  for (i = 0; i < orderCount; i++)
  	orderIndex[i] = i;
  	
  qsort(orderIndex, orderCount, sizeof(orderIndex[0]), orderFunction);

  for (i = 0; i < orderCount; i++) {
  	int rv;
    _fmemcpy(&file, &orderArray[orderIndex[i]], sizeof(file));
    if((rv = DisplaySingleDirEntry(&file, cDir)) != E_None)
    	return rv;
  }
  return E_None;  
}  		

/*
 * dir_list
 *
 * list the files in the directory
 */
static int dir_list(int pathlen
  , char *pattern
  , unsigned long *dcnt
  , unsigned long *fcnt
  , bignum *bcnt
  )
{
  struct ffblk file;
  bignum bytecount = {0};
  unsigned long filecount = 0;
  unsigned long dircount = 0;
  int rv = E_None;
  struct currDir cDir = {0};
  
#define MAX_ORDER (0xffff / sizeof(struct ffblk))
  int *orderIndex = NULL;
  int  orderCount;

  assert(path);
  assert(pattern);
  assert(pathlen >= 2);   /* at least root */

  if(optO)  {
    orderIndex = malloc(MAX_ORDER * sizeof(unsigned));
    if(!orderIndex) {
    	error_out_of_memory();
    	optO = 0;
	} else {
#ifdef FARDATA
		/* use last-fit allocation to work well with large model */
		orderArray = MK_SEG_PTR(void, DOSalloc(0x1000,2));
#else
		orderArray = MK_SEG_PTR(void, DOSalloc(0x1000,0));
#endif
		if(!orderArray) {
			free(orderIndex);
			error_out_of_dos_memory();
			optO = 0;
		}    	
		orderCount = 0;
  	}
  }
    
  /* Search for matching entries */
  path[pathlen - 1] = '\\';
#ifdef FEATURE_DESCRIPT_ION
  strcpy(&path[pathlen], "DESCRIPT.ION");
  descriptionExists = ((fDescription = dos_open(path, O_RDONLY)) >= 0);
#endif
  strcpy(&path[pathlen], pattern);

  if (sfnfindfirst(path, &file, attrMay) == 0) {
  	int printDirectoryEntry = !optB;
/* For counting columns of output */
  cDir.linecount = 0;
  /* if optB && optS the path with trailing backslash is needed,
  	also for optS below do {} while */
  strcpy(&path[pathlen - 1], "\\");

  if(rv == E_None) do
  if((file.ff_attrib & attrMask) == attrMatch) {
    assert(strlen(file.ff_name) < 13);

  /* moved down here because if we are recursively searching and
   * don't find any files, we don't want just to print
   * Directory of C:\SOMEDIR
   * with nothing else
   * 2003-02-03 moved down even further to handle attribute selection.
   */

  if(printDirectoryEntry) {
    printDirectoryEntry = 0;
    rv = flush_nl();
    if(rv == E_None) {
	   	/* path without superflous '\' at its end */
	   if(pathlen == 3)     /* root directory */
		 path[pathlen] = '\0';    /* path := path w/o filename */
	   else path[pathlen - 1] = '\0';
        displayString(optS ? TEXT_DIR_DIRECTORY: TEXT_DIR_DIRECTORY_WITH_SPACE
         , path);
	    path[pathlen - 1] = '\\';	/* need this below */
        if((rv = incline()) == E_None) {
        outc('\n');
        rv = incline();
    }
   }
  }

    if (cbreak)
      rv = E_CBreak;
    else if (rv == E_None && file.ff_attrib != FA_DEVICE) {
		if(file.ff_attrib & FA_DIREC) {
			dircount++;
		} else {
			bignum tmp;
			filecount++;
			tmp.low = (unsigned long)file.ff_fsize % 1000000000ul;
			tmp.billions = (unsigned long)file.ff_fsize / 1000000000ul;
			bignum_add(&bytecount, &tmp);
		}
		if(optO) {  
			_fmemcpy(&orderArray[orderCount], &file, sizeof(file));
			orderCount++;
			if(orderCount >= MAX_ORDER) {
				rv = flushOrder(orderArray,orderIndex,orderCount,&cDir);
				orderCount = 0;
			}
		} else
			rv = DisplaySingleDirEntry(&file, &cDir);
    }
  }
  while (rv == E_None && sfnfindnext(&file) == 0);
  }

  #ifdef FEATURE_DESCRIPT_ION
    if (descriptionExists) dos_close(fDescription);
  #endif


  if(optO) {
    if(rv == E_None)
		rv = flushOrder(orderArray,orderIndex,orderCount,&cDir);
    free(orderIndex);
    DOSfree(FP_SEG(orderArray));
  }

  if (rv == E_None && optW && (cDir.linecount != 0)) {
    outc('\n');
    rv = incline();
  }

	if(rv == E_None) {
		if(filecount || dircount)
			rv = print_summary(filecount, &bytecount);
		else if(!optS) {
			error_file_not_found();
			rv = E_Other;
		}
	}

  if(rv == E_None       /* no error */
   && optS) {            /* do recursively */
      /* already set for optB && optS before do {} while above 
		  path[pathlen - 1] = '\\';		*/
      strcpy(&path[pathlen], "*.*");
      	/* Import attributes S & H from "maybe" */
      if (sfnfindfirst(path, &file, attrMay | FA_DIREC) == 0) do {
        if((file.ff_attrib & FA_DIREC) != 0 /* is directory */
         && strcmp(file.ff_name, ".") != 0  /* not cur dir */
         && strcmp(file.ff_name, "..") != 0) {  /* not parent dir */
          if (optL)
            strlwr(file.ff_name);
          strcpy(&path[pathlen], file.ff_name);
          rv = dir_list(pathlen + strlen(file.ff_name) + 1, pattern
           , &dircount, &filecount, &bytecount
           );
        }
      } while (rv == E_None && sfnfindnext(&file) == 0);
  }

    *dcnt += dircount;
    *fcnt += filecount;
    bignum_add(bcnt, &bytecount);

  return rv;
}


static int dir_print_body(char *arg, unsigned long *dircount)
{	int rv;
	unsigned long filecount;
	bignum bytecount = {0};
	char *pattern, *cachedPattern;
	char *p;
#if 0
    char altarg[ MAXPATH ];

    if( ( p = strrchr( arg, '\\' ) ) == NULL && arg[ 1 ] ) {
        if( *arg = '.' ) {
            sprintf( altarg, "*%s", arg );
        } else if( strchr( arg, '.' ) == NULL ) {
            sprintf( altarg, "%s.*", arg );
        }
    } else if( p[ 1 ] ) {
        if( *arg = '.' ) {
        }
    }
#endif

		/* Modified to pre-allocate path to 270 bytes so that
		   we don't have to realloc() it later.  That was causing
		   "DIR /S" not to work properly.  The path variable cannot
		   be reallocated once dir_list() is called, because dir_list()
		   is recursive.  This will also help to reduce memory
		   fragmentation. */
	if((p = abspath(arg, 1)) == 0) {
		return E_NoMem;
	}
	if((path = realloc(p, 270*sizeof(char))) == 0) {
		free(p);
		error_out_of_memory();
		return E_NoMem;
	}

	filecount = 0;

	/* print the header */
	if((rv = dir_print_header(toupper(path[0]) - 'A')) == 0) {
		/* There are some directory specs that are not detected by
			dfnstat() as they are no part of the filesystem in DOS */
		pattern = dfnfilename(path);
		assert(p);
		if(!*pattern || (dfnstat(path) & DFN_DIRECTORY) != 0) {
			pattern = strchr(pattern, '\0');
			if(pattern[-1] != '\\')
				++pattern;
			rv = dir_list(pattern - path, "*.*", dircount, &filecount
			 , &bytecount
			 );
		} else {
			if((cachedPattern = strdup(pattern)) == 0) {
				error_out_of_memory();
				rv = E_NoMem;
			} else {
				rv = dir_list(pattern - path, cachedPattern, dircount
				 , &filecount, &bytecount
				 );
				free(cachedPattern);
			}
		}
	}

  if(optS) {
    if(filecount)
		rv = print_total(filecount, &bytecount);
    else {
		error_file_not_found();
		rv = E_Other;
    }
  }
  if(!rv)
    rv = dir_print_free(*dircount);

	free(path);
	return rv;
}


/*
 * dir
 *
 * internal dir command
 */
int cmd_dir (char * rest) {
  char **argv;
  char *p;
  int argc, opts;
  int rv;                       /* return value */
  unsigned long dircount;
  int appState;					/* DOS/APPEND state */

  /* initialize options */
  attrMask = attrMatch = optO = longyear = optS = optP = optW = optB = optL = 0;
#ifdef FEATURE_LONG_FILENAMES
  dispLFN = 0;
#endif
  attrMay = ATTR_DEFAULT;

  /* read the parameters from env */
  if ((argv = scanCmdline(p = getEnv("DIRCMD"), opt_dir, 0, &argc, &opts))
   == 0) {
    free(p);
    return 1;
  }
  free(p);
  freep(argv);    /* ignore any parameter from env var */

  line = 0;
  /* read the parameters */
  if ((argv = scanCmdline(rest, opt_dir, 0, &argc, &opts)) == 0)
    return 1;

  /* critEnableRepeatCheck(); */
  appState = appendDisable();
  dircount = 0;
  if(argc)
    for(opts = 0
     ; opts < argc && (rv = dir_print_body(argv[opts], &dircount)) == 0
     ; ++opts)
      ;
  else
    rv = dir_print_body(".", &dircount);
  /* critEndRepCheck(); */

  appendRestore(appState);
  freep(argv);
  return rv;
}

#endif

#ifdef INCLUDE_CMD_VOL

/*
 * vol
 *
 * internal vol command
 */
int cmd_vol (char * rest) {
  int drive;

  assert(rest);

  /* save the current directory info */
      line = 0;
      optB = 0;

  if (rest && *rest)
  {
    /* trim whitespace after drive indicator, else extra spaces cause syntax error */
    rtrimcl(rest);

    if ((strlen(rest) != 2) || (rest[1] != ':'))
    {
      error_syntax(rest);
      return E_Useage;
    }
    drive = toupper(rest[0]) - 'A';
  }
  else
    drive = getdisk();

  return dir_print_header(drive);
}

#endif


================================================
FILE: cmd/dirs.c
================================================
/* $Id$
 *  DSTACK.C - Directory stack PUSHD/POPD support, compatible with 4/NDOS
 *
 * Outputs directory stack contents
 */

#include "../config.h"

#include "../include/context.h"
#include "../include/command.h"
#include "../strings.h"

int cmd_dirs (char * param) {
    (void)param;
    return ctxtView (CTXT_TAG_DIRSTACK, TEXT_DIRSTACK_EMPTY);
}


================================================
FILE: cmd/doskey.c
================================================
/* $Id$
 *  DOSKEY -- command line editor extender <-> incorporated, but
 *		not loadable
 */

#include "../config.h"

#include "../include/command.h"
#include "../strings.h"

int cmd_doskey (char * param) {
    (void)param;
    displayString (TEXT_MSG_DOSKEY);
    return 0;
}


================================================
FILE: cmd/echo.c
================================================
/* $Id$
 *  ECHO.C - echo command.
 *
 *  Comments:
 *
 * 16 Jul 1998 (Hans B Pufal)
 *   started.
 *
 * 16 Jul 1998 (John P Price)
 *   Seperated commands into individual files.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 1999/04/27 ska
 * add: "ECHO." displays empty line
 */

#include "../config.h"

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../include/batch.h"
#include "../include/cmdline.h"
#include "../include/command.h"
#include "../strings.h"

int cmd_echo(char *param)
{	int nostatus;

	dprintf( ("[ECHO: %s]\n", param) );

	if(param && *param) {
		nostatus = !isspace(*param);
			/* Unlike other internal commands, puncation characters
				are not removed by ECHO */
		++param;
	} else nostatus = 0;

	switch(onoffStr(param)) {
	case OO_Null:	case OO_Empty:
	default:
	  if(nostatus)
		outc('\n');
	  else
		displayString(TEXT_MSG_ECHO_STATE, echo ? D_ON : D_OFF);
	  break;

	case OO_Off:	echo = 0; break;
	case OO_On:		echo = 1; break;
    case OO_Other:
		puts(param);
	}

	return 0;
}


================================================
FILE: cmd/exit.c
================================================
/* $Id$
 *  EXIT -- exits current instance of FreeCOM or leave all batch files
 *
 * set the exitflag to true
 */

#include "../config.h"

#include "../include/command.h"

int internal_exit (char * rest) { (void)rest; exitflag = 1; return 0; }


================================================
FILE: cmd/exit2.c
================================================
/* $Id$
 *  EXIT -- exits current instance of FreeCOM or leave all batch files
 *
 * set the exitflag to true
 * and _force_ exit
 */

#include "../config.h"

#include "../include/command.h"

int force_exit (char * rest) { (void)rest; canexit = exitflag = 1; return 0; }


================================================
FILE: cmd/fddebug.c
================================================
/* $Id$
 *  FDDEBUG.C - verify command.
 *
 *  Comments: Turn on/off the debug flag
 *
 * 30-Mar-2000 (John P Price <linux-guru@gcfl.net>)
 *   started.
 *
 * 2001/02/16 ska
 * add: redirect output into file
 */

#include "../config.h"

#include <assert.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../include/cmdline.h"
#include "../include/command.h"
#include "../err_fcts.h"
#include "../strings.h"

#ifdef DEBUG
extern FILE *dbg_logfile;
extern char *dbg_logname;

int cmd_fddebug(char *param)
{
	switch(onoffStr(param)) {
  	default: {
  		FILE *f;
  		char *p;

  		if((p = strdup(trimcl(param))) == 0) {
  			error_out_of_memory();
  			return 1;
  		}

  		if(stricmp(param, "stderr") == 0) f = stderr;
  		else if(stricmp(param, "stdout") == 0) f = stdout;
  		else if((f = fopen(param, "at")) == 0) {
  			error_open_file(param);
  			return 2;
  		}
		if(dbg_logfile != stderr && dbg_logfile != stdout)
			fclose(dbg_logfile);
		dbg_logfile = f;
		free(dbg_logname);
		dbg_logname = p;
		/* FALL THROUGH */
	}
  	case OO_On:		fddebug = 1;	break;
	case OO_Null:	case OO_Empty:
		displayString(TEXT_MSG_FDDEBUG_STATE, fddebug ? D_ON : D_OFF);
		displayString(TEXT_MSG_FDDEBUG_TARGET
		 , dbg_logname? dbg_logname: "stdout");
		break;
  	case OO_Off:	fddebug = 0;	break;
	}
  return 0;
}
#endif


================================================
FILE: cmd/for.c
================================================
/* $Id$
 *  FOR.C - for command.
 *
 *	Synopsises:
 *		a) FOR { '%' } v  IN (...) DO ...
 *		b) FOR [{ '%' }] name [ '%' ] IN (...) DO ...
 *	v ::= a single alphabetic character
 *	name ::= a name; at least two characters that may be used in
 *		filenames as well; name != "IN"
 */

#include "../config.h"

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../include/batch.h"
#include "../include/cmdline.h"
#include "../include/command.h"
#include "../include/context.h"
#include "../err_fcts.h"
#include "../strings.h"

	/* If set --> toupper(varE[-1]) */
#define FLAG_HACKERY_FOR 1

typedef enum {
	OK, badVar, noIN, noParens, noDO, noCMD
} forErrors;

static forErrors checkFOR(char * param	/* in: command line */
	, char ** varS, char ** varE		/* out: start/end variable name */
	, char ** paramS, char ** paramE	/* out: start/end paramter list */
	, char ** cmd, int *flags)			/* out */
{
	assert(param);

	assert(varS);
	assert(varE);
	assert(paramS);
	assert(paramE);
	assert(cmd);
	assert(flags);

	*flags = 0;

    /* skip past and process any option flags
	   /D filespec is for directories instead of files
	   /F ??? - not currently supported, parse file instead of perform findfirst/next
	   /R [basepath] - not currently supported, repeat for each subdir of basepath
	 */
	if (*param == '/' || *param == '-') {
		param++;
		switch(toupper(*param++)) {
			case 'D':
				*flags |= FLAG_OPT_DIRECTORY;
				break;
#if 0
			case 'F':
				*flags |= FLAG_OPT_FILEPARSE;
				break;
			case 'R':
				*flags |= FLAG_OPT_RECURSE;
				break;
#endif
			default:
				return badVar;
		}
		param = ltrimcl(param + 1);   /* skip whitespaces */
	}

	/* Check that it starts with a % then an alpha char followed by space */
	*varS = param;
	if(*param == '%') { 	/* Check for FOR %%%%v IN syntax */
		while(*++param == '%');
		if(isalpha(*param) && isargdelim(param[1])) {
			/* hackery FOR variable */
			*flags |= FLAG_HACKERY_FOR;
			*varE = ++param;
			goto varfound;
		}
	}

#if 0
	/* the standard release does not support normal variables as
		FOR variables */
	return badVar;
#else
	/* Use a normal variable; strip leading %'s */
	*varE = param = skipfnam(*varS = param);
	if(*param == '%')		/* ignore _one_ trailing percent sign */
		++param;
	if(!*param || !isargdelim(*param)
	 || *varE - *varS < 2
/*	 || (*varE - *varS == 2 && memicmp(*varS, "IN", 2) == 0) */ ) {
		return badVar;
	}
#endif

varfound:
	param = ltrimcl(param + 1);   /* skip whitespaces */

	/* Check next element is 'IN' */
	if(!matchtok(param, "in")) {
		return noIN;
	}

	/* Followed by a '(', find also matching ')' */
	if(*param != '(')
		return noParens;

	*paramS = param + 1;

	{ 	/* Search for right ) */
		int inQuote = 0;

		while(*++param)
			if(is_quote(*param)) {
				if(inQuote)
					inQuote = 0;
				else
					inQuote = *param;
			} else if(*param == ')' && !inQuote
				&& isargdelim(param[1])	/* COMMAND bug: sees right parens
											only if followed by whitespace */
					)
				goto rightParansFound;
		return noParens;
	}
	rightParansFound:
		*paramE = param;

	param = ltrimcl(param + 1);

	/* Check if DO follows */
	if(!matchtok(param, "do"))
		return noDO;

	/* Check that command tail is not empty */
	if(!*param)
		return noCMD;

	*cmd = param;
	return OK;
}

static int doFOR (char * varname, char * varE, char * param, char * paramE,
                  char *cmd, int flags) {
#if 0
        char *oldContents;
	char **argv;			/* pattern list */
	int argc;
	int rv;
#endif

	assert(varname);
	assert(varE);
	assert(param);
	assert(paramE);
	assert(cmd);

	*varE = 0;
	*paramE = 0;

/* OK all is correct, build the exec contexts */
#if 1
	assert(*varname == '%');
	{
		char parsedParam[MAX_INTERNAL_COMMAND_SIZE + sizeof(errorlevel) * 8];

		if(!expandEnvVars(param, parsedParam)) {
			error_line_too_long();
			return 1;
		}

		if(!newBatchContext())
			return 1;


		if((bc->forproto = strdup(cmd)) == 0
		 || (bc->forvar = strdup(varname)) == 0) {
			error_out_of_memory();
			exit_batch();   /* remove the newly created batch context */
			return 1;
		}

		if(!setBatchParams(parsedParam)) { /* Split out list */
			exit_batch();
			return 1;
		}

		bc->shiftlevel = 1;     /* skip %0 <=> filename */
		bc->forFlags = flags;
	}
	return 0;

#else
	rv = E_None;

	/* 1st: C/FORVAR|SET hidden context */
	if(*varname == '%') {	/* special FOR variable */
		switch(ctxtGetS(1, CTXT_TAG_IVAR, varname, &oldContents)) {
#ifdef DEBUG
		default:
			dprintf(("[FOR: Invalid return value from ctxtGetS]\n"));
			rv = E_None;
			break;
		case 1:		/* no such item */
#else
		default:
#endif
			rv = ecMkc("IVAR %@VERBATIM()", varname, (char*)0);
			break;
		case 0:		/* Got it */
			rv = ecMkc("IVAR %@VERBATIM()", varname, "="
			 , oldContents, (char*)0);
			myfree(oldContents);
			break;
		case 2:	/* Out of memory */
			error_out_of_memory();
			return 1;
		}
	} else {			/* normal variable */
		oldContents = getEnv(varname);
			/* getEnv() will also update the varname array with the current
				case of the particular characters */
		rv = ecMkc("SET /C %@VERBATIM()", varname, "=", oldContents, (char*)0);
		free(oldContents);
	}

	if(rv == E_None) {
		if((argv = split(param, &argc)) == 0) {
			error_out_of_memory();
			return E_NoMem;
		}

		/* Make the F context */
		if(argc)
			rv = ecMkF(argv, argc, varname, cmd);
		/* else silently ignore an empty argument line */
		freep(argv);
	}

	return rv;
#endif
}


int cmd_for(char *param)
{
	/*
	 * First check syntax is correct : FOR %v IN ( <list> ) DO <command>
	 *   v must be alphabetic, <command> must not be empty.
	 *
	 * If all is correct build a new F exec context.
	 * If also preserves the old contents of the FOR variable
	 *
	 *	varname := name of FOR variable
	 *	param := parameters within '(...)'
	 *	cmd := command
	 */

	char *varname, *varE, *cmd, *paramE;
	int flags;

	switch(checkFOR(param, &varname, &varE, &param, &paramE, &cmd, &flags)) {
	case badVar:
		error_for_bad_var();
		return 1;
	case noIN:
		error_for_in();
		return 1;
	case noParens:
		error_for_parens();
		return 1;
	case noDO:
		error_for_do();
		return 1;
	case noCMD:
		error_for_no_command();
		return 1;
	case OK:
		break;
	default:
#ifdef DEBUG
		dprintf(("[FOR: Invalid return value from checkFOR()]\n"));
#endif
		return 1;
	}

	return doFOR(varname, varE, param, paramE, cmd, flags);
}

int cmd_for_hackery(char *Xparam)
{	char *param;
	char *varname, *varE, *cmd, *paramE;
	int flags;

	if(!matchtok(Xparam, "for")
	 || checkFOR(Xparam, &varname, &varE, &param, &paramE, &cmd, &flags)
	 != OK)
		return 0;

		/* Ignore the return value as this is a FOR cmd now, but if it
			fails here, some other error caused it */
	doFOR(varname, varE, param, paramE, cmd, flags);

	return 1;
}


================================================
FILE: cmd/goto.c
================================================
/* $Id$
 *  GOTO.C - goto command.
 *
 *  Comments:
 *
 * 16 Jul 1998 (Hans B Pufal)
 *   started.
 *
 * 16 Jul 1998 (John P Price)
 *   Seperated commands into individual files.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 28 Jul 1998 (Hans B Pufal) [HBP_003]
 *   Terminate label on first space character, use only first 8 chars of
 *   label string
 *
 * 10-Aug-1998 ska
 * - moved code into readbatchline() that automatically supports
 *   modifyable scripts & ^Break checks
 *
 * 1999/11/02 ska
 * bugfix: some DOS shells except a colon before the label
 *
 * 2000/07/05 Ron Cemer
 *	bugfix: renamed skipwd() -> skip_word() to prevent duplicate symbol
 */

#include "../config.h"

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../include/batch.h"
#include "../include/cmdline.h"
#include "../include/command.h"
#include "../err_fcts.h"
#include "../strings.h"

int cmd_goto(char *param)
{
	/*
	 * Perform GOTO command.
	 *
	 * Only valid if batch file current.
	 */

	char *tmp;

	while(bc && bc->forvar)   /* is FOR context */
		exit_batch();       /* remove it */

	if(bc == 0) {
	/*!! not in batch error */

		return 1;
	}
	assert(param);

	if(*param == ':')    /* some old DOS shell excepts a colon */
		param = skipdm(param + 1);

	if(*param == '\0') {
		error_goto_label();
		exit_batch();
		return 1;
	}

	tmp = skip_word(param);
	*tmp = '\0';

	tmp = strdup(param);
	if(!tmp) {
		error_out_of_memory();
		return 1;
	}

	/* Restart the batch file from the beginning */
	bc->brewind = 1;
	bc->blabel = tmp;

	return 0;
}


================================================
FILE: cmd/history.c
================================================
/*	$Id$

	command line history

	This file bases on HISTORY.C of FreeCOM v0.81 beta 1.

	$Log$
	Revision 1.2  2004/02/01 13:52:17  skaus
	add/upd: CVS $id$ keywords to/of files

	Revision 1.1  2001/04/12 00:09:06  skaus
	chg: New structure
	chg: If DEBUG enabled, no available commands are displayed on startup
	fix: PTCHSIZE also patches min extra size to force to have this amount
	   of memory available on start
	bugfix: CALL doesn't reset options
	add: PTCHSIZE to patch heap size
	add: VSPAWN, /SWAP switch, .SWP resource handling
	bugfix: COMMAND.COM A:\
	bugfix: CALL: if swapOnExec == ERROR, no change of swapOnExec allowed
	add: command MEMORY
	bugfix: runExtension(): destroys command[-2]
	add: clean.bat
	add: localized CRITER strings
	chg: use LNG files for hard-coded strings (hangForEver(), init.c)
		via STRINGS.LIB
	add: DEL.C, COPY.C, CBREAK.C: STRINGS-based prompts
	add: fixstrs.c: prompts & symbolic keys
	add: fixstrs.c: backslash escape sequences
	add: version IDs to DEFAULT.LNG and validation to FIXSTRS.C
	chg: splitted code apart into LIB\*.c and CMD\*.c
	bugfix: IF is now using error system & STRINGS to report errors
	add: CALL: /N
	
 */

#include "../config.h"

#include <stdlib.h>

#include "../include/command.h"
#include "../include/context.h"
#include "../strings.h"
#include "../err_fcts.h"

int cmd_history(char *param)
{
	if(param && *param) {
		unsigned long x;

		x = atol(param);
		if(x < 256 || x > 32768U) {
			error_history_size(param);
			return 1;
		}
		puts("HISTORY: To change to size of the history is not implemented, yet");
		return 0;
	}

	return ctxtView(CTXT_TAG_HISTORY, TEXT_HISTORY_EMPTY);
}


================================================
FILE: cmd/if.c
================================================
/* $Id$
 *  IF.C - if command.
 *
 *  Comments:
 *
 * 16 Jul 1998 (Hans B Pufal)
 *   started.
 *
 * 16 Jul 1998 (John P Price)
 *   Seperated commands into individual files.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 1999/11/04 ska
 * + bugfix: if: case-insensitive compare  in "==" format
 * + bugfix: if: added support for quoted operands of "==" format
 * + add: if: detailed error messages
 * + bugfix: if: keyword "EXIST" misspelled
 *
 * 2000/07/05 Ron Cemer
 *	bugfix: renamed skipwd() -> skip_word() to prevent duplicate symbol
 */

#include "../config.h"

#include <assert.h>
#include <ctype.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <suppl.h>

#include "../include/lfnfuncs.h"
#include "../include/batch.h"
#include "../include/cmdline.h"
#include "../include/command.h"
#include "../err_fcts.h"

#ifdef XMS_SWAP
#include "../include/cswap.h"
#endif

int cmd_if(char *param)
{

#define X_EXEC 1

	char *pp;

	int x_flag = 0;       /* when set cause 'then' clause to be exec'ed */
	int negate = 0;       /* NOT keyword present */
	int ignore_case = 0;  /* /I option, case insensitive compare */


	/* First check if param exists */
	assert(param);

	/* check for options, note non-options must be treated as part of comparision */
	/* also check if param string begins with word 'not' */
    /* users will expect /I NOT and NOT /I to both work */
	if (matchtok(param, "NOT")) negate = X_EXEC;            /* Remember 'NOT' */
	if (matchtok(param, "/I"))  ignore_case++;
	if (matchtok(param, "NOT")) negate = X_EXEC;            /* Remember 'NOT' */


	/* Check for 'exist' form */

	if(matchtok(param, "exist")) {
		struct dos_ffblk f;
		isr olderrhandler;

		if(!*param) {
			/* syntax error */
			error_if_exist();
			return 0;
		}

		pp = skip_word(param);
		*pp = '\0';
		pp++;

		/* don't show abort/retry/fail if no disk in drive */
		get_isr(0x24, olderrhandler);
#ifdef XMS_SWAP
		set_isrfct(0x24, autofail_err_handler);  /* always fails */
#else
		set_isrfct(0x24, dummy_criter_handler);  /* always fails */
#endif

		if(dos_findfirst(param, &f, FA_NORMAL|FA_ARCH|FA_SYSTEM|FA_RDONLY|FA_HIDDEN) == 0)
			x_flag = X_EXEC;
		dos_findclose(&f);
        
		/* restore critical error handler */
		set_isrfct(0x24, olderrhandler);
	}

	/* Check for 'errorlevel' form */

	else if(matchtok(param, "errorlevel")) {
		int n = 0;

#if 0
		if(!isdigit(*param)) {
			error_if_errorlevel();
			return 0;
		}

		pp = param;
		do  n = n * 10 + (*pp - '0');
		while (isdigit(*++pp));

		if(*pp && !isargdelim(*pp)) {
			error_if_errorlevel_number();
			return 0;
		}
#else
		/* Add this COMMAND bug as someone tries to use:
			IF ERRORLEVEL H<upper-case_letter>
			-or-
			IF ERRORLEVEL x<lower-case_letter>

			to match the errorlevel against drive letters.
			NOT supported by 4dos or WinNT.

			HA --> maps to errorlevel 1
			xa --> same

			HB & xb --> to 2
			a.s.o.
		*/

		if(!*param) {
			error_if_errorlevel();
			return 0;
		}
		pp = param;
		do  n = n * 10 + (*pp - '0');
		while(*++pp && !isargdelim(*pp));
		n &= 255;
		dprintf( ("IF: checking for ERRORLEVEL >= %u\n", n) );
#endif

		if(errorlevel >= n)
			x_flag = X_EXEC;
	}

	/* Check that '==' is present, syntax error if not */
	else {
		size_t len_l, len_r;
		char *r;      /* right operand */

		pp = skipqword(param, "==");

        /* skip past any garbage characters before the == */
        while (*pp && (*pp != '=') && !isargdelim(*pp)) pp++;

		if(*pp != '=' || pp[1] != '=') {
			error_syntax(0);
			return 0;
		}

		*pp = '\0';     /* param[] points to the left operand */

		/* skip over the '==' and subsquent spaces */
        r = ltrimcl(pp + 2);
        /* and assign the end of the right operator to pp */
		pp = skipqword(r, 0);

		/*	now: param := beginning of the left operand
			r := beginning of the right operand
			pp := end of right operand
		*/

		rtrimcl(param);      /* ensure that spurious whitespaces are ignored */
		len_l = strlen(param);
		len_r = strlen(r);
		dprintf(("left side=[%s] %i\n", param, len_l));
		dprintf(("rigt side=[%s] %i\n", r, len_r));

		/* check if strings differ */
		if ( (len_l == len_r) &&
		     ((ignore_case && strnicmp(param, r, len_l) == 0) ||
		      (memcmp(param, r, len_l) == 0)) )
			x_flag = X_EXEC;
	}

	if(x_flag ^ negate) {		/* perform the command */
		if(!*(pp = ltrimcl(pp)))
			error_if_command();
		else
			parsecommandline(pp, FALSE);
	}

	return 0;
}


================================================
FILE: cmd/lfnfor.c
================================================
/* $Id$
 *  LFNFOR.C - lfnfor command (MS-DOS 7.0).
 *
 *  Comments:
 *
 * 22-June-2006 (Blair Campbell)
 *   started.
 *
 */

#include "../config.h"

#include <string.h>

#include "../err_fcts.h"
#include "../include/command.h"
#include "../include/misc.h"
#include "../strings.h"

unsigned char lfnfor = 0;
unsigned char lfncomplete = 0;

int cmd_lfnfor(char *param)
{
    if(strnicmp(param, "COMPLETE", 8) == 0) {
        switch(onoffStr(&param[8])) {
        default:
            error_on_off();
            return 1;
        case OO_Null:   case OO_Empty:
            displayString(TEXT_MSG_LFNFOR_COMPLETE_STATE, lfncomplete ?
                                                          D_ON : D_OFF );
            break;
        case OO_Off:    lfncomplete = 0; break;
        case OO_On:     lfncomplete = 1; break;
        }
    }
    else switch(onoffStr(param)) {
  	default:
		error_on_off();
		return 1;
	case OO_Null:	case OO_Empty:
		displayString(TEXT_MSG_LFNFOR_STATE, lfnfor ? D_ON : D_OFF);
		break;
  	case OO_Off:	lfnfor = 0;	break;
  	case OO_On:		lfnfor = 1;	break;
	}

	return 0;
}


================================================
FILE: cmd/makefile
================================================
# $Id$
#
# Makefile for the FreeCOM library
#
# $Log$
# Revision 1.5  2002/11/12 21:56:14  skaus
# v0.83 Beta 52:
#
# Revision 1.4  2002/04/02 23:36:37  skaus
# add: XMS-Only Swap feature (FEATURE_XMS_SWAP) (Tom Ehlert)
#
# Revision 1.3  2001/12/03 20:15:54  skaus
# v0.83 Beta 32:
# bugfix: if FREECOM.COM /P without AUTOEXEC.BAT --> assert() failure.
# add: if DEBUG enabled: internal command EXIT!! that ignores /P
# chg: FEATURE_BOOT_KEYS: mandory boot keys (F5/F8) turned into
# 	optional compile-time option; disabled by default now as the
# 	kernel provides F5/F8 checking
# chg: some document updates
#
# Revision 1.2  2001/06/10 17:17:23  skaus
# bugfix: Single point of configuration CONFIG.MAK/.H
#
# Revision 1.1  2001/04/12 00:09:06  skaus
# chg: New structure
# chg: If DEBUG enabled, no available commands are displayed on startup
# fix: PTCHSIZE also patches min extra size to force to have this amount
#    of memory available on start
# bugfix: CALL doesn't reset options
# add: PTCHSIZE to patch heap size
# add: VSPAWN, /SWAP switch, .SWP resource handling
# bugfix: COMMAND.COM A:\
# bugfix: CALL: if swapOnExec == ERROR, no change of swapOnExec allowed
# add: command MEMORY
# bugfix: runExtension(): destroys command[-2]
# add: clean.bat
# add: localized CRITER strings
# chg: use LNG files for hard-coded strings (hangForEver(), init.c)
# 	via STRINGS.LIB
# add: DEL.C, COPY.C, CBREAK.C: STRINGS-based prompts
# add: fixstrs.c: prompts & symbolic keys
# add: fixstrs.c: backslash escape sequences
# add: version IDs to DEFAULT.LNG and validation to FIXSTRS.C
# chg: splitted code apart into LIB\*.c and CMD\*.c
# bugfix: IF is now using error system & STRINGS to report errors
# add: CALL: /N
#
#

.INCLUDE : ../_config.mk

# Sources of this make target
SRC = alias.c beep.c break.c call.c cdd.c chcp.c chdir.c cls.c copy.c \
	ctty.c date.c del.c dir.c dirs.c doskey.c echo.c exit.c exit2.c \
	fddebug.c for.c goto.c history.c if.c memory.c mkdir.c path.c pause.c \
	popd.c prompt.c pushd.c rem.c ren.c rmdir.c set.c shift.c time.c \
	truename.c type.c verify.c which.c
OBJ = alias.obj beep.obj break.obj call.obj cdd.obj chcp.obj chdir.obj \
	cls.obj copy.obj ctty.obj date.obj del.obj dir.obj dirs.obj doskey.obj \
	echo.obj exit.obj exit2.obj fddebug.obj for.obj goto.obj history.obj \
	if.obj memory.obj mkdir.obj path.obj pause.obj popd.obj prompt.obj \
	pushd.obj rem.obj ren.obj rmdir.obj set.obj shift.obj time.obj \
	truename.obj type.obj verify.obj which.obj
HDR = ..\config.h ..\err_fcts.h ..\include/batch.h ..\include/cmdline.h \
	..\include/command.h ..\include/context.h ..\include/datefunc.h \
	..\include/debug.h ..\include/kswap.h ..\include/misc.h ..\include/nls.h \
	..\include/openf.h ..\include/timefunc.h


#	Default target
all: cmds.lib

dist: makefile.mak

%.obj : %.asm ; $(NASM) $(NASMFLAGS) -f obj -F borland -o $@ $< >>errlist

### Utils are required by build process
.INIT .PHONY .SEQUENTIAL : verscheck $(CFG) __errl


.IF $(THISMAKE) == $(LASTMAKE)
verscheck :;
.ELSE
verscheck : 
	@+-echo Changed Make parameters, already made files invalid!
	+-echo LASTMAKE = $(THISMAKE) >lastmake.mk
	$(RUNMAKE) clobber
.IF $(CFG)
	$(RUNMAKE) $(CFG)
.ENDIF
.ENDIF

__errl:
	@+-if exist errlist del errlist >nul
	-ctags *.c ..\lib\*.c ..\shell\*.c $(FREEDOS)\SRC\LIB\SUPPL\*.c

cmds.lib .LIBRARY : $(OBJ)

#MAKEDEP START
mkdir.obj : mkdir.c \
	 ../config.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h
memory.obj : memory.c \
	 ../config.h ../include/command.h ../include/context.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/timefunc.h ../strings.h
goto.obj : goto.c \
	 ../config.h ../err_fcts.h ../include/batch.h ../include/cmdline.h \
	../include/command.h ../include/datefunc.h ../include/debug.h \
	../include/misc.h ../include/timefunc.h ../strings.h
copy.obj : copy.c \
	 ../config.h ../err_fcts.h ../include/cmdline.h ../include/command.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/openf.h ../include/timefunc.h ../strings.h
shift.obj : shift.c \
	 ../config.h ../include/batch.h ../include/command.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/timefunc.h
rmdir.obj : rmdir.c \
	 ../config.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h
pause.obj : pause.c \
	 ../config.h ../include/batch.h ../include/command.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/timefunc.h ../strings.h
date.obj : date.c \
	 ../config.h ../err_fcts.h ../include/cmdline.h ../include/command.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/nls.h ../include/timefunc.h ../strings.h
chcp.obj : chcp.c \
	 ../config.h ../err_fcts.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h ../strings.h
dir.obj : dir.c \
	 ../config.h ../err_fcts.h ../include/cmdline.h ../include/command.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/nls.h ../include/timefunc.h ../strings.h
truename.obj : truename.c \
	 ../config.h ../err_fcts.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h
rem.obj : rem.c \
	 ../config.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h
ctty.obj : ctty.c \
	 ../config.h ../err_fcts.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/openf.h \
	../include/timefunc.h ../strings.h
ren.obj : ren.c \
	 ../config.h ../err_fcts.h ../include/cmdline.h ../include/command.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/timefunc.h
break.obj : break.c \
	 ../config.h ../err_fcts.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h ../strings.h
for.obj : for.c \
	 ../config.h ../err_fcts.h ../include/batch.h ../include/cmdline.h \
	../include/command.h ../include/context.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h ../strings.h
chdir.obj : chdir.c \
	 ../config.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h
alias.obj : alias.c \
	 ../config.h ../err_fcts.h ../include/cmdline.h ../include/command.h \
	../include/context.h ../include/datefunc.h ../include/debug.h \
	../include/misc.h ../include/timefunc.h ../strings.h
cdd.obj : cdd.c \
	 ../config.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h
set.obj : set.c \
	 ../config.h ../err_fcts.h ../include/cmdline.h ../include/command.h \
	../include/context.h ../include/datefunc.h ../include/debug.h \
	../include/misc.h ../include/timefunc.h ../strings.h
exit2.obj : exit2.c \
	 ../config.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h
path.obj : path.c \
	 ../config.h ../include/cmdline.h ../include/command.h \
	../include/context.h ../include/datefunc.h ../include/debug.h \
	../include/misc.h ../include/timefunc.h ../strings.h
if.obj : if.c \
	 ../config.h ../err_fcts.h ../include/batch.h ../include/cmdline.h \
	../include/command.h ../include/datefunc.h ../include/debug.h \
	../include/misc.h ../include/timefunc.h
history.obj : history.c \
	 ../config.h ../err_fcts.h ../include/command.h ../include/context.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/timefunc.h ../strings.h
dirs.obj : dirs.c \
	 ../config.h ../include/command.h ../include/context.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/timefunc.h ../strings.h
which.obj : which.c \
	 ../config.h ../include/cmdline.h ../include/command.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/timefunc.h
popd.obj : popd.c \
	 ../config.h ../include/command.h ../include/context.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/timefunc.h ../strings.h
exit.obj : exit.c \
	 ../config.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h
call.obj : call.c \
	 ../config.h ../context.h_c ../err_fcts.h ../include/batch.h \
	../include/cmdline.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/kswap.h ../include/misc.h \
	../include/timefunc.h
beep.obj : beep.c \
	 ../config.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h
echo.obj : echo.c \
	 ../config.h ../include/batch.h ../include/cmdline.h \
	../include/command.h ../include/datefunc.h ../include/debug.h \
	../include/misc.h ../include/timefunc.h ../strings.h
type.obj : type.c \
	 ../config.h ../err_fcts.h ../include/cmdline.h ../include/command.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/openf.h ../include/timefunc.h ../strings.h
prompt.obj : prompt.c \
	 ../config.h ../include/cmdline.h ../include/command.h \
	../include/context.h ../include/datefunc.h ../include/debug.h \
	../include/misc.h ../include/timefunc.h
cls.obj : cls.c \
	 ../config.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h
pushd.obj : pushd.c \
	 ../config.h ../include/command.h ../include/context.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/timefunc.h
time.obj : time.c \
	 ../config.h ../err_fcts.h ../include/cmdline.h ../include/command.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/nls.h ../include/timefunc.h ../strings.h
doskey.obj : doskey.c \
	 ../config.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h ../strings.h
fddebug.obj : fddebug.c \
	 ../config.h ../err_fcts.h ../include/cmdline.h ../include/command.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/timefunc.h ../strings.h
verify.obj : verify.c \
	 ../config.h ../err_fcts.h ../include/command.h ../include/datefunc.h \
	../include/debug.h ../include/misc.h ../include/timefunc.h ../strings.h
del.obj : del.c \
	 ../config.h ../err_fcts.h ../include/cmdline.h ../include/command.h \
	../include/datefunc.h ../include/debug.h ../include/misc.h \
	../include/timefunc.h ../strings.h
DYNSOURCES =
#MAKEDEP STOP

clobber : clean
	$(RM) $(RMFLAGS) *.com *.cln *.lib *.lst *.cfg makefile.mak

clean : 
	$(RM) $(RMFLAGS) *.lst *.map *.bin *.bak *.las *.obj *.exe $(CFG) *.dmp com.com tags errlist


makefile.mak : makefile cmd.m1 cmd.m2
	+copy cmd.m1 + $(mktmp cmds.lib : \44(CFG) $(OBJ:t" \\\\\\n\\t") \n\tif exist cmds.lib \44(AR) cmds.lib /c @&&|\n+-$(OBJ:t" &\\n+-")\n| , cmds.lst \n\tif not exist cmds.lib \44(AR) cmds.lib /c @&&|\n+$(OBJ:t" &\\n+")\n| , cmds.lst \n) + cmd.m2 $@



================================================
FILE: cmd/makefile.mak
================================================
CFG_DEPENDENCIES = makefile.mak

TOP = ..
!include "$(TOP)/config.mak"

all: $(CFG) cmds.lib

OBJS1 = alias.obj beep.obj break.obj call.obj cdd.obj chcp.obj chdir.obj
OBJS2 = cls.obj copy.obj ctty.obj date.obj del.obj dir.obj dirs.obj
OBJS3 = doskey.obj echo.obj exit.obj exit2.obj fddebug.obj for.obj goto.obj
OBJS4 = history.obj if.obj lfnfor.obj memory.obj mkdir.obj path.obj pause.obj
OBJS5 = popd.obj prompt.obj pushd.obj rem.obj ren.obj rmdir.obj set.obj
OBJS6 = shift.obj time.obj truename.obj type.obj verify.obj which.obj

cmds.rsp : $(ECHOLIBDEP) makefile.mak
	$(RMFILES) cmds.rsp
	$(ECHOLIB) cmds.rsp $(OBJS1)
	$(ECHOLIB) cmds.rsp $(OBJS2)
	$(ECHOLIB) cmds.rsp $(OBJS3)
	$(ECHOLIB) cmds.rsp $(OBJS4)
	$(ECHOLIB) cmds.rsp $(OBJS5)
	$(ECHOLIB) cmds.rsp $(OBJS6)

cmds.lib : $(CFG) $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) cmds.rsp
	$(RMFILES) cmds.lib
	$(AR) cmds.lib @cmds.rsp $(LIBLIST) cmds.lst 


================================================
FILE: cmd/memory.c
================================================
/* $Id$

	Internal command MEMORY to display the amount of memory used by
	the various internal data structures.

*/

#include "../config.h"

#ifdef __TURBOC__
#include <alloc.h>
#endif

#include <environ.h>
#include <mcb.h>

#include "../include/context.h"
#include "../include/command.h"
#include "../strings.h"

static void displayTag(int string, Context_Tag tag)
{	ctxt_info_t *info;

	info = &CTXT_INFO_STRUCT(tag);

	displayString(string, info->c_sizemax, info->c_sizecur
	 , info->c_nummin < info->c_nummax
	 	? info->c_nummax - info->c_nummin : 0);
}
static void displayTag1(int string, Context_Tag tag)
{	ctxt_info_t *info;

	info = &CTXT_INFO_STRUCT(tag);

	displayString(string, info->c_sizecur
	 , info->c_nummin < info->c_nummax
	 	? info->c_nummax - info->c_nummin : 0);
}

int cmd_memory (char * param) {
        (void)param;
	displayString(TEXT_MEMORY_ENVIRONMENT
		, mcb_length(env_glbSeg), env_freeCount(env_glbSeg));
	displayString(TEXT_MEMORY_CONTEXT
		, mcb_length(ctxt), env_freeCount(ctxt));
	displayTag(TEXT_MEMORY_CTXT_ALIAS, CTXT_TAG_ALIAS);
	displayTag(TEXT_MEMORY_CTXT_HISTORY, CTXT_TAG_HISTORY);
	displayTag(TEXT_MEMORY_CTXT_DIRSTACK, CTXT_TAG_DIRSTACK);
	displayTag1(TEXT_MEMORY_CTXT_LASTDIR, CTXT_TAG_LASTDIR);
/*	displayTag1(TEXT_MEMORY_CTXT_BATCH, CTXT_TAG_BATCH);
	not used, yet -- 2001/06/11 ska*/
	displayTag1(TEXT_MEMORY_CTXT_SWAPINFO, CTXT_TAG_SWAPINFO);
#ifdef __TURBOC__
	displayString(TEXT_MEMORY_HEAP, (unsigned long)coreleft());
#endif

	return 0;
}


================================================
FILE: cmd/mkdir.c
================================================
/* $Id$
 * MD / MKDIR - makes a call to directory_handler to do its work
 */

#include "../config.h"

#include <sys/stat.h>
#include <string.h>

#include "suppl.h"
#include "dfn.h"
#ifdef DBCS
# include "mbcs.h"
#endif

#include "../include/command.h"
#include "../include/misc.h"
#include "../include/lfnfuncs.h"

int recursive_mkdir(const char * path, int recursiveMode, int quiet)
{
	if (recursiveMode) {
		char fullname[MAXPATH];
		char *p = fullname;
		int flag_not_done = 0;
		int ret;
		strcpy(fullname, path); /* so we can modify in place */
		dprintf(("fullpath = %s\n", fullname));
		do {
			while (*p && ((*p != '\\') && (*p != '/'))) {
#ifdef DBCS
				p += MbLen(p);
#else
				p++;
#endif
			}
			flag_not_done = *p; /* == 0 when end of path found, nonzero if \ or / */
			*p = '\0';
			dprintf(("mkdir(%s)\n", fullname));
			/* validate if path exists and is a directory */
			ret = dfnstat(fullname);
			if (ret) { /* found, verify it is a directory */
				if (!(ret & DFN_DIRECTORY)) {
					/* path component exists but not a directory */
					ret = E_Other;
				} else {
					ret = 0;  /* no error */
				}
			} else { /* not found (or other error) so attempt to make directory */
				ret = mkdir(fullname);
			}
			if (ret) {
				if (!quiet) {
					/* TODO show error message */
				}
				return ret;
			}
			if (flag_not_done)
				*p++ = '\\';
		} while(flag_not_done);		
		return ret;
	} else {
		return mkdir(path);
	}
}

int cmd_mkdir(char *param)
{
	return mk_rd_dir(param, recursive_mkdir, "MKDIR");
}




================================================
FILE: cmd/path.c
================================================
/* $Id$
 *  PATH.C - path command.
 *
 *  Comments:
 *
 * 17 Jul 1998 (John P Price)
 *   Seperated commands into individual files.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 12-Aug-1998 ska
 * - added: SUPPL environment handling
 *   currently "PATH=" will delete the environment variable PATH;
 *   if an empty one shall be created, replace chgEnv1() by chgEnv()
 */

#include "../config.h"

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../include/cmdline.h"
#include "../include/command.h"
#include "../include/context.h"
#include "../strings.h"

#define PATHVAR    "PATH"

int cmd_path(char *param)
{	char *p;

	/* >>PATH ;<< must remove the string entirely */
	if(!param || (!*(p = ltrimcl(param)) && !strchr(param, ';'))) {
		p = getEnv(PATHVAR);
		displayString(p? TEXT_MSG_PATH: TEXT_MSG_PATH_NONE, p);
		free(p);
		return 0;
	}

	rtrimcl(p);			/* remove trailing spaces */
	return chgEnvRemove(PATHVAR, p);
}


================================================
FILE: cmd/pause.c
================================================
/* $Id$
 *  PAUSE.C - pause command.
 *
 * FREEDOS extension : If resteter is specified use that as the pause
 *   message.
 *
 *  Comments:
 *
 * 16 Jul 1998 (Hans B Pufal)
 *   started.
 *
 * 16 Jul 1998 (John P Price)
 *   Seperated commands into individual files.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 1999/05/03 ska
 * bugfix: '\n' issued after waiting for keypress
 */

#include "../config.h"

#include <string.h>
#include <io.h>

#include "../include/batch.h"
#include "../include/command.h"
#include "../strings.h"

int cmd_pause (char * param) {
	if(param && *param)
        dos_write( 1, param, strlen(param) );
	else
		displayString(TEXT_MSG_PAUSE);

	cgetchar();
	outc('\n');

	return 0;
}


================================================
FILE: cmd/popd.c
================================================
/* $Id$
 *  DSTACK.C - Directory stack PUSHD/POPD support, compatible with 4/NDOS
 *
 *	POPD [*]
 *
 * Pops a directory off the stack, and sets it as cwd.
 * Accepts the parameter '*', causing it to wipe the stack.
 */

#include "../config.h"

#include <stdlib.h>

#include "../include/context.h"
#include "../include/command.h"
#include "../include/misc.h"
#include "../strings.h"

int cmd_popd(char *param)
{
	if(!param || *param != '*') {
		char *todir;

		if(ctxtPop(CTXT_TAG_DIRSTACK, &todir)) {
			int rc;

			rc = cmd_cdd(todir);
			free(todir);
			return rc;
		}

		displayString(TEXT_DIRSTACK_EMPTY);
	}

		/* Wipe the dirstack */
	ctxtClear(CTXT_TAG_DIRSTACK);

	return 0;
}


================================================
FILE: cmd/prompt.c
================================================
/* $Id$
 *  PROMPT.C - prompt handling.
 *
 */

#include "../config.h"


#include "../include/cmdline.h"
#include "../include/command.h"
#include "../include/context.h"
#include "../include/misc.h"

int cmd_prompt(char *param)
{
  if(param && *param == '=')    /* skip '=' & spaces */
    param = ltrimcl(param + 1);

  /* NO rtrim()! */
  return chgEnvRemove(PROMPTVAR, param);
}


================================================
FILE: cmd/pushd.c
================================================
/* $Id$
 *  DSTACK.C - Directory stack PUSHD/POPD support, compatible with 4/NDOS
 *
 *	PUSHD <dir>
 *
 * Pushes the current directory onto the stack.  If the length of
 * the directory string exceeds the remainer of the stack, it pops the first
 * entry, adjusts, and proceeds with the push.
 * Also: changes to the directory specified on the command line.
 */

#include "../config.h"

#include <stdlib.h>

#include "../include/context.h"
#include "../include/command.h"
#include "../include/misc.h"

int cmd_pushd(char *param)
{	char *curdir;

	if((curdir = cwd(0)) != 0) {
		int rc;

		rc = ctxtPush(CTXT_TAG_DIRSTACK, curdir);
		free(curdir);

		if(rc == E_None) {
			/* Change to directory specified on command line */
			if(param && *param)
				return cmd_cdd(param);
			return 0;
		}
	}
	return 1;
}


================================================
FILE: cmd/rem.c
================================================
/* $Id$
 *  REM -- includes comments "remarks" into batch scripts
 */

#include "../config.h"

#include "../include/command.h"

int cmd_rem (char * param) { (void)param; return 0; }


================================================
FILE: cmd/ren.c
================================================
/* $Id$
 * REN.C - rename command
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 * 15-Mar-2003 (Wolf Bergenheim <dog@users.sf.net>)
 * - added support for * and ?
 *
 */

#include "../config.h"

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

/*#define DEBUG*/

#include <dfn.h>
#include <suppl.h>
#include <supplio.h>

#include "../include/lfnfuncs.h"
#include "../include/cmdline.h"
#include "../include/command.h"
#include "../include/misc.h"
#include "../err_fcts.h"

void myfnsplit( const char *path,
                      char *buf,
                      char *drv,
                      char **dir,
                      char **name,
                      char **ext )
{
    const char* end;
    const char* p;
    const char* s;

    if( path[ 0 ] && path[ 1 ] == ':' ) {
        if( drv ) {
            *drv++ = *path++;
            *drv++ = *path++;
            *drv = '\0';
        }
    } else if( drv ) *drv = '\0';

    for( end = path; *end && *end != ':'; ) end++;

    for( p = end; p > path && *--p != '\\'/* && *p != '/'*/; )
        if( *p == '.' ) {
            end = p;
            break;
        }
    if ( ext ) {
        *ext = buf;
        for( s = end; ( *buf++ = *s++ ) != '\0'; );
    }

    for( p = end; p > path; )
        if( *--p == '\\'/* || *p == '/'*/) {
        /* 
         * '/' can't happen as a path seperator in FreeCOM because it's treated
         * as a switch character no matter where it's found
         */
            p++;
            break;
        }

    if( name ) {
        *name = buf;
        for( s = p; s < end; ) *buf++ = *s++;
        *buf++ = '\0';
    }

    if ( dir ) {
        *dir = buf;
        for( s = path; s < p; ) *buf++ = *s++;
        *buf = '\0';
    }
}

void myfnmerge( char *path, const char *drive, const char *dir,
                            const char *fname, const char *ext )
{
    if( *drive ) {
        strcpy( path, drive );
#if 0 /* Unused */
        if( !drive[ 1 ] )strcat( path, ":" );
#endif
    } else ( *path ) = 0;

    if( *dir ) {
        strcat( path, dir );
        if( *( dir + strlen( dir ) - 1 ) != '\\' )
            strcat( path, "\\" );
    }

    if( *fname ) {
        strcat( path, fname );
        if( ext && *ext ) {
#if 0 /* Unused */
            if( *ext != '.' ) strcat( path, "." );
#endif
            strcat( path, ext );
        }
    }
}

int cmd_rename(char *param)
{	
	char **argv;
	int argc, opts, ec = E_None;
	struct dos_ffblk ff;
	int appState;

	if((argv = scanCmdline(param, 0, 0, &argc, &opts)) == 0)
		return 1;

	appState = appendDisable();
	if(argc < 2) {
		error_req_param_missing();
		ec = E_Useage;
	}
	else if(argc > 2) {
		error_too_many_parameters(param);
		ec = E_Useage;
	} else if(dos_findfirst(argv[0], &ff
		 , FA_NORMAL|FA_DIREC|FA_ARCH|FA_SYSTEM|FA_RDONLY|FA_HIDDEN) != 0) {
			error_sfile_not_found(argv[0]);
		/* ec == E_None */
	} else {
#if 0   /*
         * There is some dynamic memory bug in relation to dfnmerge
         * Let's spare ourselves the whole mucking about in dynamic memory
         * thing, and we can use myfnmerge/myfnsplit to make everything work.
         * Unless of course someone wants to fix the bug in dfnmerge/split
         * So... the old code is still here if anyone wants to give it a shot
         * AND, if anyone tries to blame the _REGISTER usage in lfnfuncs.c as
         * the culprit, it already uses intr instead :-)
         */
		char *s_drv = NULL, *s_dir = NULL, *s_fil = NULL, *s_ext = NULL;
		char *d_drv = NULL, *d_dir = NULL, *d_fil = NULL, *d_ext = NULL;
		char *newname = 0, *sn = 0, *dn = 0;
		char *oldFname;

#define p oldFname
		if(!dfnsplit(argv[0], &s_drv, &s_dir, &s_fil, &s_ext)
		 || !dfnsplit(argv[1], &d_drv, &d_dir, &d_fil, &d_ext)
		 || (sn = dfnmerge(0, s_drv, s_dir, "", NULL)) == 0
		 || (p = realloc(sn, strlen(sn) + sizeof(ff.ff_name) + 1)) == 0) {
		/* build dir to use */
			error_out_of_memory();
			ec = E_NoMem;
			goto errRet;
		}
		sn = p;
		p = strchr(sn, '\0');
#undef p
#else
        char s_drv[ MAXDRIVE ], d_drv[ MAXDRIVE ];
        char *s_dir, *d_dir, *d_fil, *d_ext;
        char s_buf[ MAXPATH ], d_buf[ MAXPATH ],
             *sn, dn[ MAXPATH ], newname[MAXPATH];

        myfnsplit( argv[ 0 ], s_buf, s_drv, &s_dir, NULL, NULL );
        myfnsplit( argv[ 1 ], d_buf, d_drv, &d_dir, &d_fil, &d_ext );
#endif

		/* if drive or path in second arg, return with syntax error */
		if((d_drv[ 0 ]) || (d_dir[ 0 ])) {
			error_syntax(argv[1]);
			ec = E_Useage;
			goto errRet;
		}

#if 0
		if((dn = dfnmerge(0, s_drv, s_dir, d_fil, d_ext)) == 0) {
		/* build dir to use */
			error_out_of_memory();
			ec = E_NoMem;
			goto errRet;
		}
#else
        myfnmerge( dn, s_drv, s_dir, d_fil, d_ext );
	/* d_buf no longer used after this */
	sn = d_buf;
#endif

		do {
            fillFnam(newname, dn, ff.ff_name);
#if 0
			if(newname[0] == 0) {
				error_out_of_memory();
				ec = E_NoMem;
				break;
			}
#endif
			myfnmerge( sn, s_drv, s_dir, ff.ff_name, NULL );
			dprintf(("rename(%s, %s)\n", sn, newname) );
			if(rename(sn, newname) != 0) {
				myperror("rename");
				ec = E_Other;
				break;
			}
			/*free(newname);*/
            newname[0] = 0;
		} while(dos_findnext(&ff) == 0);

	errRet:
        dos_findclose(&ff);
#if 0 /* free(newname) isn't even necessary because it is free'd above */
		free(s_drv); free(s_dir); free(s_fil); free(s_ext);
		free(d_drv); free(d_dir); free(d_fil); free(d_ext);
		free(newname); free(sn); free(dn);
#endif
	}
	
	appendRestore(appState);
	freep(argv);
	return ec;
}


================================================
FILE: cmd/rmdir.c
================================================
/* $Id$
 * RD / RMDIR - makes a call to directory_handler to do its work
 */

#include "../config.h"

#include <assert.h>
#include <dos.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "suppl.h"
#include "dfn.h"
#ifdef DBCS
# include "mbcs.h"
#endif

#include "../include/command.h"
#include "../include/misc.h"
#include "../include/lfnfuncs.h"
#include "../err_fcts.h"
#include "../strings.h"

#ifdef FEATURE_LONG_FILENAMES
#define abspath( x, y ) abspath( getshortfilename( x ), y )
#endif

/* recursively delete subdirs and files */
#ifdef DBCS
int rmdir_withfiles(const char * fullname, char * path, int maxlen)
#else
int rmdir_withfiles(char * path, int maxlen)
#endif
{
	struct dos_ffblk *f;
	int ret;
	int len = strlen(path);  /* Warning: we assume path is a buffer is large enough for longest file path */
	char *p = path+len;

	/* ensure ends with \ */
#ifdef DBCS
	if (*fullname && *(CharPrev(fullname, p)) != '\\')
#else
	if (p[-1] != '\\')
#endif
		*p++ = '\\';
	*p = '\0';
	
	dprintf(("rmdir(%s)\n", path));	

	/* cycle through removing directories first */
	stpcpy(p, "*.*");
	/* allocate our findfirst/next structure on heap to avoid exhausting stack */
	f = (struct dos_ffblk *)malloc(sizeof(struct dos_ffblk));
	if (f == NULL) {
		error_out_of_memory();
		return E_NoMem;
	}
	if (!dos_findfirst(path, f, FA_DIREC)) {
		ret = 0;
		do {
			/* skip . and .. directory entries */
			if ((strcmp(f->ff_name, ".")==0) ||
			    (strcmp(f->ff_name, "..")==0))
				continue;

			if (f->ff_attrib & FA_DIREC) {
				dprintf(("name=%s\n", f->ff_name));
				/* avoid overflowing our buffer */
				if((len + strlen(f->ff_name)) > maxlen) {
					error_filename_too_long(p);
					ret = E_Other;
					continue;
				}

				strcpy(p, f->ff_name);       /* Make the full path */
				/* recursively delete subdirectory */
#ifdef DBCS
				ret = rmdir_withfiles(fullname, path, maxlen);
#else
				ret = rmdir_withfiles(path, maxlen);
#endif
			}
		} while (!ret && (dos_findnext(f) == 0));
		dos_findclose(f);
		/* return early on error */
		if (ret) {
			free(f);
			return ret;
		}
	}

	/* remove any files in current directory */
	stpcpy(p, "*.*");
	if (!dos_findfirst(path, f, FA_NORMAL)) {
		ret = 0;
		do {
			/* avoid overflowing our buffer */
			if((len + strlen(f->ff_name)) > maxlen) {
				error_filename_too_long(p);
				ret = E_Other;
				continue;
			}

			strcpy(p, f->ff_name);       /* Make the full path */
			dprintf(("deleting [%s]\n", path));
			/* try to delete the file */
			if(unlink(path) != 0) {
				myperror(path);  /* notify the user */
				/* could exit here, but we just let rmdir fail */
			}
		} while (!ret && (dos_findnext(f) == 0));
		dos_findclose(f);
	}
	free(f);

	/* finally actually remove the directory */
	p[-1] = '\0';
	return rmdir(path);
}

int recursive_rmdir(const char * path, int recursiveMode, int quiet)
{
	if (recursiveMode) {
		struct dos_ffblk f;
		char *p;
		static char fullname[MAXPATH + sizeof(f.ff_name) + 2];
		int len;
		/* Get the pattern fully-qualified */
			/* Note: An absolute path always contains:
				A:\\
				--> It's always three bytes long at minimum
				and always contains a backslash */
		p = abspath(path, 1);
		if(!p)
			return E_Other;
		assert(strlen(p) >= 3);

		if((len = strlen(p)) >= MAXPATH) {
			error_filename_too_long(p);
			free(p);
			return E_Other;
		}
		strcpy(fullname, p);
		free(p);
		p = fullname + len;

		/* validate path exists and is a directory */
		if(!(dfnstat(fullname) & DFN_DIRECTORY)) {
			/* not a directory */
			return E_Other;
		}
		
		/* ensure ends with \ */
#ifdef DBCS
		if (len > 0 && *(CharPrev(fullname, p)) != '\\')
#else
		if (p[-1] != '\\')
#endif
			*p++ = '\\';
		*p = 0;
		
		/* prompt user if they are sure, regardless if files or not */
		if (!quiet) {
			int r;
			r = userprompt(PROMPT_DELETE_ALL, fullname);  /* Are you sure? TODO fix me */
				
			if (r != 1) {
				return E_Other;
			}
		}
#ifdef DBCS
		return rmdir_withfiles(fullname, fullname, sizeof(fullname));
#else
		return rmdir_withfiles(fullname, sizeof(fullname));
#endif
	} else {
		return rmdir(path);
	}
}

int cmd_rmdir(char *param)
{
	return mk_rd_dir(param, recursive_rmdir, "RMDIR");
}


================================================
FILE: cmd/set.c
================================================
/* $Id$
 *	Set environment variables
 *
 */

#include "../config.h"

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>

#include "environ.h"
#include "nls_c.h"

#include "../include/cmdline.h"
#include "../include/command.h"
#include "../include/context.h"
#include "../include/misc.h"
#include "../err_fcts.h"
#include "../strings.h"

#define promptBuffer 256

/* optC determines if env variable's name (param) is set using
   passed in case or uppercased, whereas upCaseValue determines
   if the value the user passes in (with the /P option) is
   stored as typed or uppercased. */
static int optC, promptUser, upCaseValue, optExecute;

optScanFct(opt_set)
{
  (void)arg;
  switch(ch) {
  /* case 'A': return optScanBool(optA); arithmetic expression */
  case 'C': return optScanBool(optC);
  case 'U': return optScanBool(upCaseValue);
#if 1
  case 'I': /* Display Information about current memory */
		printf("Size of environment segment: %u bytes; unused: %u\n"
		 , env_resize(0, 0), env_freeCount(env_glbSeg));
		return E_Other;
#endif
  case 'P': return optScanBool(promptUser);
  case 'E': return optScanBool(optExecute);
  }
  optErr();
  return E_Useage;
}

int cmd_set(char *param)
{	char *value;
	char *promptBuf = 0, tempcmd[255];
	int ret;

	optC = promptUser = upCaseValue = optExecute = 0;

	if(leadOptions(&param, opt_set, 0) != E_None)
		return 1;

	switch(breakVarAssign(ctxtEnvironment, param, &value)) {
	case 1:			/* no equal sign */
#ifdef FEATURE_CMD_SET_PRINT
        if( ( value = getEnv( param ) ) != NULL ) printf( "%s\n", value );
        else {
            error_env_var_not_found( param );
            return( 1 );
        }
        free(value);
        return( 0 );
#else
		error_syntax(0);
		return 1;
#endif
	case 0:			/* displayed */
		return 0;
#ifdef DEBUG
	case 2: break;
	default:
		dprintf(("[SET: Invalid response from breakVarAssign()]\n"));
		return 1;
#endif
	}

	if(promptUser) {	/* -> Display the value, then read and assign */
		int len;
		assert(value);
		outs(value);
		promptBuf = malloc(promptBuffer);
		if(!promptBuf) {
			error_out_of_memory();
			return E_NoMem;
		}
		len = dos_read(0, promptBuf, promptBuffer-1);
		if(cbreak || len < 0) {
			free(promptBuf);
			return E_CBreak;
		}
		value = &promptBuf[len];
		while(--value >= promptBuf && (*value == '\n' || *value == '\r'));
		value[1] = '\0';	/* strip trailing newlines */
		value = promptBuf;
	}
    if (optExecute) {
        char *tempfile = tmpfn();
        int fd, len;

        if (!tempfile) return (1);
        sprintf (tempcmd, "%s>%s", value, tempfile);
        parsecommandline (tempcmd, TRUE);
        fd = dos_open (tempfile, O_RDONLY);
        if (fd < 0) {
            unlink (tempfile);
            free (tempfile);
            return (1);
        }
        len = dos_read(fd, tempcmd, 254);
        if (len >= 0) {
            value = memchr(tempcmd, '\n', len);
            if (value) len = value - tempcmd;
	    if (len > 0 && tempcmd[len-1] == '\r') len--;
            tempcmd[len] = '\0';
        }
        value = tempcmd;
        dos_close (fd);
        unlink (tempfile);
        free (tempfile);
    }

	/* If the value is just blanks, it means to delete the value;
		but otherwise even leading and trailing spaces must be kept */
	if(is_empty(value))
		value = 0;

	if (upCaseValue) StrUpr(value); /* set value as upper case, eg for if testing */

	ret = chgEnvCase(optC, param, value);
	free(promptBuf);
	return ret;
}


================================================
FILE: cmd/shift.c
================================================
/* $Id$
 *  SHIFT.C - shift command.
 *
 * Only valid inside batch files.
 *
 * FREEDOS extension : optional parameter DOWN to allow shifting
 *   parameters backwards.
 *
 * 16 Jul 1998 (Hans B Pufal)
 *   started.
 *
 * 16 Jul 1998 (John P Price)
 *   Seperated commands into individual files.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 */

#include "../config.h"

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../include/batch.h"
#include "../include/command.h"

int cmd_shift(char *param)
{
	struct bcontext *b = activeBatchContext();

	if(!b)
		/* not in batch - error */
		return 1;

	assert(param);
	if(stricmp(param, "down") == 0) {
		if(b->shiftlevel)
			b->shiftlevel--;
	} else                          /* shift up */
		b->shiftlevel++;

	return 0;
}


================================================
FILE: cmd/time.c
================================================
/* $Id$
 *  TIME.C - time internal command
 *
 *  Comments:
 *
 *  07/08/1998 (John P. Price)
 *    started.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 1999/03/17 ska
 * bugfix: Detection of invalid time strings
 *  One can specify:
 *    ^\s*\d+.\d+(.(\d+(.\d*)?)?)?\s*([aApP]([mM]|\.[mM]\.)?\s*$
 *  If one specifies:
 *    1 number --> error
 *    2 numbers --> hour:minute, seconds & hundreds default to zero
 *    3 numbers --> hour:minute:seconds, hundreds defaults to zero
 *    4 numbers --> hour:minute:seconds.hundreds
 *  The numbers may be delimited by any character from the 7-bit ASCII set,
 *  which is printable, but not alphanumerical.
 *
 * 2001/02/08 ska
 * add: DATE /D and TIME /T
 */

#include "../config.h"

#include <dos.h>
#include <io.h>
#include <stdlib.h>

#include "../include/cmdline.h"
#include "../include/command.h"
#include "../err_fcts.h"
#include "../include/misc.h"
#include "../include/nls.h"
#include "../strings.h"

static int noPrompt = 0;

optScanFct(opt_date)
{
  (void)arg;
  switch(ch) {
  case 'D':
  case 'T': return optScanBool(noPrompt);
  }
  optErr();
  return E_Useage;
}


static int my_settime(const char *s)
{	struct dostime_t t;

	switch(parsetime(s, &t)) {
	case E_None:		/* success -> set the date */
		_dos_settime(&t);
		/* fall through */
	case E_Empty:		/* empty line */
		return 1;		/* success */
	}

	return 0;			/* failure */
}

int cmd_time(char *param)
{
	char s[40];
	int ec;

	noPrompt = 0;

	if((ec = leadOptions(&param, opt_date, 0)) != E_None)
		return ec;

	if(!*param) {
		char *time;

		if((time = curTime()) == 0)
			return 1;

		displayString(TEXT_MSG_CURRENT_TIME, time);
		free(time);
		param = 0;
	}

	while(1) {
		if(!param) {
			int len;
			if(noPrompt) return 0;

			displayString(TEXT_MSG_ENTER_TIME);
			len = dos_read(0, s, sizeof(s) - 1);
			if (cbreak || len < 0)
				return 1;
			s[len] = '\0';
			param = s;
		}
		if(my_settime(param))
			break;
		error_invalid_time();
		/* force user interaction the next time around. */
		param = 0;
	}

	return 0;
}


================================================
FILE: cmd/truename.c
================================================
/* $Id$
 * TRUENAME.C -- Truename Command (undocumented DOS?)
 *
 * 07/14/98 (Rob Lake)
 *  - started and tested fine
 *  - added stand alone debugging
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 28-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - changed _truename function so it does not return a pointer to a local
 *   variable.
 *
 * 09-Aug-1998 (Rob Lake <rlake@cs.mun.ca>)
 * - _truename now sets errno
 *
 */

#include "../config.h"

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include <dfn.h>

#include "../include/command.h"
#include "../err_fcts.h"

int cmd_truename(char *param)
{
	char *p;

	if(0 != (p = truepath((param && *param)? param: "."))) {
		puts(p);
		free(p);
		return 1;
	}
	return 0;
}


================================================
FILE: cmd/type.c
================================================
/* $Id$
 *  TYPE.C - type internal command
 *
 *  Comments:
 *
 *  07/08/1998 (John P. Price)
 *    started.
 *
 * 07/12/98 (Rob Lake)
 *    - Changed error messages
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 10-Aug-1998 ska
 * - added ^Break checking
 *
 * 1999/01/24 ska
 * add: support for CP/M style device names (openf.h)
 */

#include "../config.h"

#include <assert.h>
#include <io.h>
#include <fcntl.h>
#include <string.h>

#include "../include/cmdline.h"
#include "../include/command.h"
#include "../err_fcts.h"
#include "../include/openf.h"
#include "../strings.h"

int cmd_type(char *param)
{
	char buf[256];
	char **argv;
	int argc, opts, ec = E_None;
	int fd, len;

	if((argv = scanCmdline(param, 0, 0, &argc, &opts)) == 0)
		return 1;

	/* Because no option was passed into scanCmdline() no
		option can have been processed */
	assert(opts == 0);

	if(!argc) {
		error_req_param_missing();
		ec = E_Useage;
		goto errRet;
	}

	for(argc = 0; argv[argc]; ++argc) {
		if((fd = devopen(argv[argc], O_RDONLY)) < 0) {
			error_sfile_not_found(argv[argc]);
			ec = E_Other;
			break;
		}

		while((len = dos_read(fd, buf, sizeof(buf))) >= 0) {
			char *bufp, *p;
			if(cbreak) {
				dos_close(fd);
				ec = E_CBreak;
				goto errRet;
			}
			bufp = buf;
			for(p = buf; p < buf+len; p++) {
				if(*p == 26) break; /* CTRL-Z */
				if(*p == '\r' || *p == '\n') {
					if(p > bufp) dos_write(1, bufp, p - bufp);
					if(*p == '\n') dos_write(1, "\r\n", 2);
					bufp = p + 1;
				}
			}
			dos_write(1, bufp, p - bufp);
			if (len == 0 || *p == 26) break;
		}
		dos_close(fd);
		if(cbreak) {
			ec = E_CBreak;
			break;
		}
	}

errRet:
	freep(argv);

	return ec;
}


================================================
FILE: cmd/verify.c
================================================
/* $Id$
 *  VERIFY.C - verify command.
 *
 *  Comments:
 *
 * 31 Jul 1998 (John P Price)
 *   started.
 *
 *
 */

#include "../config.h"

#include <assert.h>
#include <dos.h>

#include "../err_fcts.h"
#include "../include/command.h"
#include "../strings.h"

#ifdef __WATCOMC__
void setverify(char a);
#pragma aux setverify = \
	"mov ah,0x2e" \
	"mov dl,0" \
	"int 0x21" \
	__parm [__al] __modify __exact [__ah __dl]
char getverify(void);
#pragma aux getverify = \
	"mov ah,0x54" \
	"int 0x21" \
	__value [__al] __modify __exact [__ah]
#endif

#ifdef __GNUC__
static inline void setverify(char a)
{
	asm volatile("int $0x21":: "Rah"((char)0x2e), "Rdl"((char)0), "Ral"(a));
}

static inline char getverify(void)
{
	char ret;
	asm volatile("int $0x21": "=Ral"(ret): "Rah"((char)0x54));
	return ret;
}
#endif

int cmd_verify(char *param)
{
  switch(onoffStr(param)) {
  	default:
		error_on_off();
		return 1;
	case OO_Null:	case OO_Empty:
		displayString(TEXT_MSG_VERIFY_STATE, getverify() ? D_ON : D_OFF);
		break;
  	case OO_Off:	setverify(0);	break;
  	case OO_On:		setverify(1);	break;
	}
  return 0;
}


================================================
FILE: cmd/which.c
================================================
/* $Id$
 *  WHERE.C - path functions.
 *
 *
 *
 *  Comments:
 *
 *  07/15/95 (Tim Norman)
 *    started.
 *
 *  08/08/95 (Matt Rains)
 *    i have cleaned up the source code. changes now bring this source into
 *    guidelines for recommended programming practice.
 *
 *  12/12/95 (Steffan Kaiser & Tim Norman)
 *    added some patches to fix some things and make more efficient
 *
 *  1/6/96 (Tim Norman)
 *    fixed a stupid pointer mistake...  Thanks to everyone who noticed it!
 *
 *  8/1/96 (Tim Norman)
 *    fixed a bug when getenv returns NULL
 *
 *  8/7/96 (Steffan Kaiser and Tim Norman)
 *    speed improvements and bug fixes
 *
 *  8/27/96 (Tim Norman)
 *    changed code to use pointers directly into PATH environment variable
 *    rather than making our own copy.  This saves some memory, but requires
 *    we write our own function to copy pathnames out of the variable.
 *
 *  12/23/96 (Aaron Kaufman)
 *    Fixed a bug in get_paths() that did not point to the first PATH in the
 *    environment variable.
 *
 *  7/12/97 (Tim Norman)
 *    Apparently, Aaron's bugfix got lost, so I fixed it again.
 *
 *  16 July 1998 (John P. Price)
 *    Added stand alone code.
 *
 *  17 July 1998 (John P. Price)
 *    Rewrote find_which to use searchpath function
 *
 * 24-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - fixed bug where didn't check all extensions when path was specified
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 30-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - fixed so that it find_which returns NULL if filename is not executable
 *   (does not have .bat, .com, or .exe extention). Before command would
 *   to execute any file with any extension (opps!)
 *
 * 2001/02/16 ska
 * add: command WHICH
 */

#include "../config.h"

#include <assert.h>
#include <stdio.h>

#include "../include/cmdline.h"
#include "../include/command.h"


int cmd_which(char *param)
{
	char **arg, *p;
	int argc, optc, i;

	if((arg = scanCmdline(param, 0, 0, &argc, &optc)) == 0)
		return E_Other;

	for(i = 0; i < argc; ++i) {
		assert(arg[i]);
		outs(arg[i]);
		if((p = find_which(arg[i])) != 0) {
			outc('\t');
			puts(p);
		} else {
			outc('\n');
		}
	}

	freep(arg);
	return E_None;
}


================================================
FILE: command.lsm
================================================
Begin3
Title:          FreeCom
Version:        0.87
Entered-date:   Mon DD 202Y
Description:    The FreeDOS Command Shell
Keywords:       freecom freedos command shell
Author:         freedos-devel@lists.sourceforge.net (developers)
Maintained-by:  freedos-devel@lists.sourceforge.net (maintainers)
Primary-site:   https://github.com/FDOS/freecom
Alternate-site: http://freedos.sourceforge.net/
Alternate-site: http://www.freedos.org/
Platforms:      dos dosemu
Copying-policy: GNU General Public License, Version 2 (GPL)
Wiki-site:      http://wiki.freedos.org/wiki/index.php/Command
End


================================================
FILE: config.b
================================================
@echo off
:-****************************************************************
:-  NOTICE!  You can edit but then copy this file to CONFIG.BAT! *
:-****************************************************************

:-**********************************************************************
:-- define NASM executable
:-**********************************************************************

set XNASM=nasm

:**********************************************************************
:- define your COMPILER type here, pick one of them
:**********************************************************************

:- Open Watcom C
:- set COMPILER=WATCOM
:- Turbo C 2.01
:- set COMPILER=TC2
:- Turbo C++ 1.01
set COMPILER=TURBOCPP
:- Borland C
:- set COMPILER=BC5

:-**********************************************************************
:-- where is the BASE dir of your compiler(s) ??
:-**********************************************************************
                                                
:- set TC2_BASE=c:\tc201
set TP1_BASE=c:\tcpp
:- set BC5_BASE=c:\bc5

:- if WATCOM maybe you need to set your WATCOM environment variables 
:- and path
:- if not \%WATCOM% == \ goto watcom_defined
:- set WATCOM=c:\watcom
:- set PATH=%PATH%;%WATCOM%\binw
:watcom_defined


================================================
FILE: config.h
================================================
/*
 * config.h - Used to configure what will be compiled into the shell.
 *
 */

/* define DEBUG to add debugging code */
#ifndef DEBUG           /* possibly already defined via command line */
/*#define DEBUG*/
#endif

/* Define to enable the alias command, and aliases. */
#define FEATURE_ALIASES
#define ALIAS_DEFAULT_SIZE 1024

/* Define to disable context error messages that may scare a user */
/* #define NO_CONTEXT_ERROR */

/* Define to enable enhanced input (prerequisite of History and Filename
    completion */
#define FEATURE_ENHANCED_INPUT

/* Define to enable history (aka DOSKEY); requires: Enhanced Input */
#define FEATURE_HISTORY
#define HISTORY_DEFAULT_SIZE 256

/* Define to enable filename completion; requires: Enhanced Input */
#define FEATURE_FILENAME_COMPLETION

/* Define to enable to load messages into memory */
#define FEATURE_LOAD_MESSAGES

/* Define to enable /Z support, display exit code on program exit */
#define DISP_EXITCODE

/* Define to enable usage of LFNs */
#define FEATURE_LONG_FILENAMES

/* Define to enable usage or the DOS switch character in option processing */
#define FEATURE_SWITCHAR

/* Define to enable printing of environment variables for "SET VAR" syntax */
/* (Like Win2k's cmd.exe does) */
#define FEATURE_CMD_SET_PRINT

/* Define for limited support of 4DOS DESCRIPT.ION files */
#define FEATURE_DESCRIPT_ION

/* Define to enable DOS NLS */
#define FEATURE_NLS

/* Define to enable F5/F8 key test on startup if /P is present on
    command line */
/* #define FEATURE_BOOT_KEYS */

/* Command line logging feature */
/* #define FEATURE_CALL_LOGGING */

/* Preserves last directory (CD, CHDIR, CDD, PUSHD, POPD);
    "CD -" chdir's there */
#define FEATURE_LAST_DIR

/* Enables CDD to a filepath (ignores filename portion) */
#define FEATURE_CDD_FNAME

/* Enable to support installable COMMAND extensions (MUX-AE)
 */
#define FEATURE_INSTALLABLE_COMMANDS
/* How often gets the MUX-AE called, when an installable command
    extension rewrote the command. */
#define MUX_AE_MAX_REPEAT_CALL  32

/* Name of the executable */
#define COM_NAME "COMMAND.COM"
/* standard name of AUTOEXEC.BAT */
#define AUTO_EXEC "\\autoexec.bat"
/* Logfile for some logging features; MUST be fully-qualified! */
#define LOG_FILE "C:\\FreeCom.log"

/* Define to number of loops when to redirect to CON if the
    shells hangs in the "hangForEver()" loop
   Undefine to remove this feature */
#define FEATURE_AUTO_REDIRECT_TO_CON 5

/* How many batch files should be nestable minimally */
#define BATCH_NESTLEVEL_MIN 5

/* Define to support kernel-supported swapout of FreeCOM
    see DOCS\K-SWAP.TXT
*/
#define FEATURE_KERNEL_SWAP_SHELL

/* Define to support XMS-only swap support of FreeCOM
    This setting is incompatible with the above one!
*/
/* #define FEATURE_XMS_SWAP */

/* Define the size of the buffer used to store old paths for PUSHD/POPD */
#define DIRSTACK_DEFAULT_SIZE 256

/* Use this errorlevel if an external program was terminated by
    ^C or ^Break --> DOS error code interrupted system call */
#define CBREAK_ERRORLEVEL 0x5F

/* Use these filemode while searching for file completion */
#define FILE_SEARCH_MODE FA_RDONLY | FA_ARCH | FA_DIREC

/* If no /E: is specified, always keep this amount of bytes
    free within the environment */
#define ENVIRONMENT_KEEP_FREE 256


/* Default message settings:
  PATTERN: how the string is constructed for the ID (with \n)
  OUTOFMEMORY: string to issue on out-of-memory condition (no \n)
  ID_: the error ID when no default pattern is to be created, but
    the out-of-memory string is to be displayed
*/
#define MSG_DFL_PATTERN "String #%u\n"
#define MSG_DFL_OUTOFMEMORY "Out of memory!"
#define MSG_ERR_ID_OUTOFMEMORY TEXT_ERROR_OUT_OF_MEMORY


/* Default prompt */
#define DEFAULT_PROMPT "$P$G"

/* Provides the uppermost size the context may have */
#define CONTEXT_MAX_SIZE (65535U - 12)

/* Define this value to select the initialization value of fddebug */
#define FDDEBUG_INIT_VALUE 1

#define INCLUDE_CMD_BEEP
#define INCLUDE_CMD_BREAK
#define INCLUDE_CMD_CHDIR
#define INCLUDE_CMD_CHCP
#define INCLUDE_CMD_CDD
#define INCLUDE_CMD_CLS
#define INCLUDE_CMD_COPY
#define INCLUDE_CMD_CTTY
#define INCLUDE_CMD_DATE
#define INCLUDE_CMD_DEL
#define INCLUDE_CMD_DIR
#define INCLUDE_CMD_DIRS
#ifdef FEATURE_LONG_FILENAMES
#define INCLUDE_CMD_LFNFOR
#endif
#define INCLUDE_CMD_LOADFIX
#define INCLUDE_CMD_LOADHIGH
/*#define INCLUDE_CMD_FAKELOADHIGH */ /* DO NOT include this and CMD_LOADHIGH nor CMD_LOADFIX */
#define INCLUDE_CMD_MEMORY
#define INCLUDE_CMD_MKDIR
#define INCLUDE_CMD_PATH
#define INCLUDE_CMD_PAUSE
#define INCLUDE_CMD_PROMPT
#define INCLUDE_CMD_PUSHD
#define INCLUDE_CMD_POPD
#define INCLUDE_CMD_REM
#define INCLUDE_CMD_RENAME
#define INCLUDE_CMD_RMDIR
#define INCLUDE_CMD_SET
#define INCLUDE_CMD_TIME
#define INCLUDE_CMD_TRUENAME
#define INCLUDE_CMD_TYPE
#define INCLUDE_CMD_VER
#define INCLUDE_CMD_VERIFY
#define INCLUDE_CMD_VOL
#define INCLUDE_CMD_QUESTION
#define INCLUDE_CMD_WHICH
#ifdef DEBUG
#define INCLUDE_CMD_FDDEBUG
#endif
/*
   command that do not have a define:

   exit
   call
   echo
   goto
   for
   if
   shift

 */

/********
    ***** Resolve dependencies
    ***** Don't change without change the appropriate sources!
    ************/
#if defined(INCLUDE_CMD_PUSHD) || defined(INCLUDE_CMD_POPD)
#define INCLUDE_CMD_CDD
#endif

/* Not available with TURBOC++ 1.0 or earlier: */
#ifdef __TURBOC__

#if __TURBOC__ > 0x297
#define _TC_LATER_
#else
#define _TC_EARLY_
#endif

#endif

/* Define if your compiler does not have 'dosdate_t' or 'dostime_t' */
#if defined(_TC_EARLY_) || defined(__GNUC__)
    /* TC++1 */
#define _NO__DOS_DATE
#define _NO__DOS_TIME
#define _NO_FMEMCHR
#define _NO_FMEMCMP
#endif


    /* set by MKDIST.BAT */
#ifdef IGNORE_ENHANCED_INPUT
#undef FEATURE_ENHANCED_INPUT
#endif

#ifndef FEATURE_ENHANCED_INPUT
#undef FEATURE_HISTORY
#undef FEATURE_FILENAME_COMPLETION
#endif

#ifdef INCLUDE_CMD_PUSHD
#define FEATURE_DIRSTACK
#endif

#if CONTEXT_MAX_SIZE > 65535U - 12
#error "The maximal context size may not exceed 65535 - 12 bytes"
#endif

#if defined(FEATURE_KERNEL_SWAP_SHELL) && defined(FEATURE_XMS_SWAP)
#error "FreeCOM cannot support both Kernel- and XMS-based swapping simultaneously"
#endif

/* Externally defined to compile with XMS-Swap support */
#if defined(XMS_SWAP)
#undef FEATURE_KERNEL_SWAP_SHELL
#define FEATURE_XMS_SWAP
#endif

#ifdef __TURBOC__
#if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__)
/* Compiling in Large memory model --> turn of Warning:
    "Conversation may lose significant digits"  */
#pragma warn -sig
#endif
#endif

#include "../include/debug.h"


================================================
FILE: config.std
================================================
# defaults for DOS; can be overridden in compiler makefiles
DIRSEP = \ #a backslash
ECHOTO = echoto
ECHOTODEP = echoto.bat
LIBLIST = ,
ECHOLIB = echolib
ECHOLIBDEP = echolib.bat
CP = copy
CLO =
SCRIPTS_PATH = ..\scripts
!if $(TOP2LVL)0 == 10
SCRIPTS_PATH = ..\..\scripts
!endif
RMFILES = $(SCRIPTS_PATH)\rmfiles

FIXSTRSOPT = --lib

## Where the pre-compiled SUPPL files are located
## See DOCS\SUPPL.TXT for more information about this library
SUPPL_INC_PATH = ..$(DIRSEP)suppl
SUPPL_LIB_PATH = $(SUPPL_INC_PATH)

## Memory model of FreeCOM
!if $(DEBUG)0 == 10
SHELL_MMODEL=m
DEBUG=-DDEBUG
!else
SHELL_MMODEL=s
DEBUG=-UDEBUG -DNDEBUG
!endif
SHELL_MMODEL_COMP=$(SHELL_MMODEL)

## Compact Memory model used if it requires far data pointers, so uses compact memory model by default
COMPACT_MMODEL=-mc

## Add -DDEBUG=1 below to enable debug support for assembly files
NASMFLAGS = -I$(TOP)/include

!include "$(TOP)/mkfiles/$(COMPILER).mak"

## Which programs to use
NASM = $(XNASM)

## Add -DDEBUG=1 below to enable FreeCOM-debug support for C files
## Add -DNDEBUG=1 below to disable any debug (even assert)

!if $(XMS_SWAP)0 == 10
__XMS_SWAP = -DXMS_SWAP
!endif

!if $(COMPACT_MODEL)0 == 10
MMODEL = $(COMPACT_MMODEL)
!endif

# Default configuration
# added strings.h here because $(CFG) is included everywhere already
## Add -D_NO__DOS_DATE if your compiler does not have no dosdate_t (*)
## Add -D_NO__DOS_TIME if your compiler does not have no dostime_t (*)
## Add -D_NO_FMEMCHR if your compiler does not have no _fmemchr() (*)
## Add -D_NO_FMEMCMP if your compiler does not have no _fmemcmp() (*)
##
## (*) Note: Should be detected by CONFIG.H automatically for Turbo C
##     and Borland C compilers.
$(CFG): $(ECHOTODEP) $(CFG_DEPENDENCIES) $(TOP)/config.mak
	$(RMFILES) $(CFG)
	$(ECHOTO) $(CFG) $(CFLAGS1)
	$(ECHOTO) $(CFG) $(CFLAGS2)
	$(ECHOTO) $(CFG) $(INCLUDEPATH) -I$(SUPPL_INC_PATH)
	$(ECHOTO) $(CFG) -m$(SHELL_MMODEL_COMP) $(MMODEL)
	$(ECHOTO) $(CFG) $(DEBUG) $(__XMS_SWAP)

echoto.bat: $(SCRIPTS_PATH)\echoto.bat
	$(CP) $(SCRIPTS_PATH)\echoto.bat .

echolib.bat: $(SCRIPTS_PATH)\echolib.bat
	$(CP) $(SCRIPTS_PATH)\echolib.bat .

#		*Implicit Rules*
.asm.obj:
	$(NASM) -f obj $(NASMFLAGS) -DMODEL=$(SHELL_MMODEL) -DCOMPILER=$(COMPILER) $(__XMS_SWAP) $<


================================================
FILE: criter/context.x
================================================
# Context description file
#
#	Contains persistent information to be preserved during the
#	execution of an external program
#
# separated to allow to use one file for both assembly and C
# TOOLS\MKCTXT.EXE creates the following files:
#	context.h_c: contains the structure in C syntax
#	context.h_a: contains the definition of the structure in assembly
#	context.inc: contains the EQUs of the offsets of a value into the structure
#		two definitions per offset:
#		<value> - offset from the very beginning of the context
#		<package>_<value> - offset of the value relative to the beginning
#			of the specific package

# "typedef" opens a new "typedef struct {".
# "package" groups different values together, if the package
# is a shared module, too, a pointer to this position is passed
# to the module. Within C, they are represented by struct's
# "structure" is more or less the same, but it is ensured that all
# structures defined for one package are physically located in above the
# pointer to the package
# An empty line (no comment lines!) end a structure.

# Type:
# byte - one single byte (unsigned char)
# word - two bytes (unsigned short int)
# pointer - far pointer (void far*)
# constant - #define of _numerical_ constant
# reference - label at exactly this position (unsigned char [])


typedef kswap_t	# Type currently defined

word envSegm 0		# segment to be passed forth as environment 
pointer prg 0		# program to be executed 
pointer cmdline 0	# command line arguments of program 
word execErr 0		# exit code of DOS-4B of external program
pointer shell 0		# absolute path to shell to be executed 
word canexit 0		# true unless FreeCOM was invoked with /P 
word dfltSwap 0		# default value of swapOnExec
word debug 0		# Debug status
word envSize 0		# size of environment segment 
word dyn_ctxt 0		# dynamically changed portions of context 
word ofs_criter _lowlevel_err_handler		# offset of criter module within this context 
reference cbreak_hdlr	# start of dummy ^Break handler active if FreeCOM
					# is NOT running itself


================================================
FILE: criter/criter.asm
================================================
; $Id$
;
;		Critical Error handler -- module
;
; Three macros to customize the assembler process:
;		COMPILE_COM in order to generate a .COM file (Debugging ONLY)
;			automatically defines COMPILE_STRINGS
;			includes this:	write(open("A:\AUX", O_RDWR), 0, 65535)
;			it is assumed that A: is empty first, then a floppy is
;			inserted and no AUX: device is present
;			--> produces 1st a block device Criter, then a char device
;				Criter
;		COMPILE_STRINGS to include English response strings right into
;			this image
;		NO_RESOURCE_BLOCK omit resource block at the end of the file
;		XMS_SWAP_CRITER disables interfering stuff when assembling for
;			XMS Swap variant
;
;	Doing a ECHO >A:\FILE results in:
;		WinNT 4 DOSbox:
;			no floppy in drive --> AX := 0x1800 ; [BP:SI+4] == 0x0000
;			write protected floppy & file already exists
;				--> AX := 0x98FF; [attr] == 0x8000
;			write protected floppy, but files does NOT exist
;				--> AX := 0x1800; [attr] == 0x0000
;		Win98 plain:
;			no floppy in drive --> AX := 0x1A00; [attr] == 0x08C2
;			write protected floppy -> AX := 0x1B00; [attr] == 0x08C2
;		FreeDOS build 2021:
;			no floppy in drive --> AX := 0x3800; [attr] == 0x08C2
;			write protected floppy -> same as above
;		FreeDOS build 2022:
;			no floppy in drive --> AX := 0x3800; [attr] == 0x08C2
;			write protected floppy -> stalled quite some time, but NO CRITER!
;		FreeDOS build 2023b [Mar 27 2001 21:51:20]:
;			no floppy in drive --> AX := 0x3800; [attr] == 0x08C2
;			write protected floppy -> stalled quite some time, but NO CRITER!
;
;	This handler does:
;	0) The current context is passed into this function within ES:BX
;		The original ES & BX are restored by CRITER.
;	1) Probe for Autofail <-> return FAIL for all criterrs
;	2) Display error message:
;	block devices:
;		Error "reading from"|"writing to" drive ?: XXX area: error
;	character devices:
;		Error "reading from"|"writing to" device XXXXXXX: error
;	3) Display user action possebilities:
;		(A)bort (I)gnore (R)etry (F)ail? _
;	4) Get user input & return to DOS (via IRET)
;
;	Fields of context used:
;		offset 0, byte (boolean), autofail
;
;	== What to do if neither I,R,nor F are allowed??
;	== Simply return??
;
;	Organization of the strings:
;	+ There may be upto 256 strings, numbered from 0 through N
;	+ The actual "error strings" must be the last ones and their
;	  order must be the same as the code in DI
;	+ All strings are packed together as follows:
;	  (N+1) words	near pointer to character sequence of string #X
;	  character sequences of strings, no obvious order among them required
;	  This block is created by an external tool, like the messages for
;	  FreeCom itself and simply attached to the criterr handler code.
;	+ Within the code procedure ?oString maps BL -> near pointer (BX)
;	  and displays the associated character sequence with ?oBuffer
;	+ Special sequences:
;		%%	--> a single percent sign
;		%#	--> where '#' is a decimal digit --> insert string
;				with number BYTE [?strarg#]
;		%A	--> where 'A' is a capital Latin letter --> insert
;				the buffer at ?strargA
;
;	Possible NLS hazards:
;	+ drive letter is created via "+ 'A'"
;	+ for robustness when displaying the driver's name, characters less
;	  than ' ' are ignored (usually control characters)
;
; $Log$
; Revision 1.5  2004/09/13 18:59:39  skaus
; add: CRITER: Repeat check autofail magic {Tom Ehlert/Eric Auer}
;
; Revision 1.4  2003/10/18 10:55:24  skaus
; bugfix: CRITERR: to use DOS API {Tom Ehlert/Bart Oldeman}
;
; Revision 1.3  2003/08/03 16:00:57  skaus
; bugfix: /F (AutoFail) for the XMS_Swap variant
;
; Revision 1.2  2002/04/02 18:09:31  skaus
; add: XMS-Only Swap feature (FEATURE_XMS_SWAP) (Tom Ehlert)
;
; Revision 1.1  2001/04/23 21:35:41  skaus
; Beta 7 changes (code split)
;
; Revision 1.1.2.3  2001/02/27 18:27:06  skaus
; fix: criter.asm: DEBUG does no longer compile to .COM (for consistency)
; chg: removed all NULLs to prevent NULL problematic, functions must be
; 	used fully prototyped now
;
; Revision 1.1.2.2  2001/02/18 17:59:36  skaus
; bugfix: KSSF: restore parentPSP on exit
; chg: Using STRINGS resource for all non-interactive messages
; chg: moving all assembly files to NASM
;
; Revision 1.1.2.1  2001/01/28 21:23:55  skaus
; add: Kernel Swap Support
;
; Revision 1.1.2.1.2.1  2000/12/17 21:57:36  skaus
; intermediate update 1
;

;;; Settings for stand-alone variant
%define COMPILE_STRINGS		;; always keep this enabled in this release!!
%define INCLUDE_STRINGS		;; use STRINGS.INC instead of hard-coded strings
;; %define AUTO_FAIL		;; make the autofail variant of Criter
%define HIDE_CRITER_DRIVES 26	;; For how many drives hide-multiple is active

;; Version of this module
MODULE_VERSION EQU 2

%include "../include/stuff.inc"
%ifndef XMS_SWAP_CRITER
%include "resource.inc"
%endif

???start:

%ifdef COMPILE_COM
ORG 100h

mov ax, cs
mov ds, ax
mov ax, 2524h
mov dx, _lowlevel_err_handler
int 21h

;; Trying to open a file on drive A:
mov ax, 3d02h
mov dx, dummy_file
int 21h

;; Trying to copy stuff on PRN:
mov bx, ax
mov ah, 40h
mov cx, 0ffffh
mov dx, 0
int 21h

mov ax, 4c00h
int 21h
int 20h

dummy_file DB "a:\ux", 0

%ifndef COMPILE_STRINGS
%define COMPILE_STRINGS
%endif
%endif

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Real start
;; Join both modules into the same memory image in order to handle
;; them easier

%ifndef XMS_SWAP_CRITER
	;; Static context of KSwap support
%include "context.def" 

%include "dmy_cbrk.asm"
%endif

;; Low level Critical Error handler
;; Note: Both I/O functions should use the channel to read/write
;;	the characters. In this case: the BIOS.
;; Sidenote: RBIL states that some BIOSes destroy the BP register.
%macro printALtoConsole 0
	call ?oChar
%endmacro
%macro readALfromConsole 0
	mov ax, 0c07h	; clear buffer, read from STDIN one key without echo
	int 21h
%endmacro


LOCAL_BELL	EQU 7

;; Return values
IGNORE		EQU 0
RETRY		EQU 1
ABORT		EQU 2
FAIL		EQU 3

; bitmask of the "allowed action" flags
CodeIgnore	EQU 32
CodeRetry	EQU 16
CodeFail	EQU 8

;; String numbers -- fixed order section
; 0 -> %1: write to
; 1 -> %1: read from 

StrBlockDevice	EQU 2
StrCharDevice	EQU 3

StrArea EQU 4
; StrArea (area of failure)
; + 0 -> DOS
; + 1 -> FAT
; + 2 -> root
; + 3 -> data

; StrActionStrings 8
; + 0 -> Ignore
; + 1 -> Retry
; + 2 -> Abort
; + 3 -> Fail
StrIgnore	EQU 8
StrRetry	EQU 9
StrAbort	EQU 10
StrFail		EQU 11

StrQuestionMark	EQU 12
StrDelimiter	EQU 13
StrKeys			EQU 14		; enumerated valid input keys
		; format:	LK..KA..A
		;	L: BYTE number of K's (== number of A's)
		;	K: BYTE one keystroke
		;	A: BYTE one action code 0..3 (IRAF)
		;	a K's action code is located at the byte pointed to
		;	by the address of K plus L

StrErrCodes		EQU 15

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;; Entry point

; arguments:
;		ES:BX == pointer to context, package int24
;		else: as normal INT-24 handler

%ifdef XMS_SWAP_CRITER
	cglobal autofail_err_handler
autofail_err_handler:
	mov al, FAIL
	iret
%endif

	cglobal lowlevel_err_handler
lowlevel_err_handler:
%ifdef AUTO_FAIL
	;; most simple <-> return AL := 3
	mov al, FAIL
	iret
%else
	push dx
	pushm es, ds, bp, si, di, cx, bx, ax

	mov cx, cs
	mov ds, cx		; DS := local code/data segment

%ifdef DEBUG
	call ??dispAX
%endif

	push ax			; save AH bit 7  and AL for later

			;; free AL
	add al, 'A'		; AL may contain the drive number
	mov BYTE [??strargA], al	;; will be overwritten, if char device
	xor al, al
	mov BYTE [??strargA + 1], al	; end of string

	mov es, cx		; still shared local code/data segm

	shr ah, 1		; Carry := 0-> read; 1->write
	adc al, al		; AL := 0-> read; 1->write
	mov BYTE [??strarg1], al

	mov al, ah
	and al, 3		; AL := 0/1/2/3 -> DOS/FAT/root/data area
	add al, StrArea	;  make it a string#
	mov BYTE [??strarg2], al	;; will be ignored if char device

;;
;; and al, (CodeIgnore or CodeRetry or CodeFail) / 2
;; jz ONLY_ABORT_ALLOWED_AND_NOW??
;;
	mov al, ah
	and al, CodeFail / 2
	mov [??allowFail], al
	mov al, ah
	and al, CodeRetry / 2
	mov [??allowRetry], al
	and ah, CodeIgnore / 2
	mov [??allowIgnore], ah

;; AX is empty now
%ifdef DEBUG
	push ds
	mov ax, bp
	mov ds, bp
	push si
	push di
	push cx
	mov cx, 8
	mov di, ??_c
	add si, byte 10
??__e:
	lodsb
	cmp al, 32
	jnc ??__d
	mov al, 32
??__d:
	stosb
	loop ??__e
	pop cx
	pop di
	pop si
	mov ax, [si+4]
	pop ds
	call ??dispAX
	mov bx, ??_d
	call ?oBuffer
%endif

%if 0		;; No need when doing I/O through DOS
	mov ah, 0fh		; Get current video mode
	int 10h
	mov BYTE [??actPage], bh
	mov BYTE [??actColour], 255
%endif

	mov ax, di		; AL := lobyte(DI) -> error number
	add al, StrErrCodes
	mov BYTE [??strarg3], al

	mov bl, StrBlockDevice		; by default issue block device error
	pop ax						; AL := drive letter again
	shl ah, 1					; get bit 7 --> carry flag
	jnc ?noCharDevice

	mov ds, bp					; is still segment of device driver
	test BYTE [si+5], 128		; bit 7 == 1 if block device
	jz ?noCharDevice
			; fetch the name of the character device
		mov cx, 8		; max eight characters to display
		add si, byte 10		; located at offset 10
		mov di, ??strargA
		mov ah, ' '
		cld
?drvNameGetLoop:
		lodsb
		cmp al, ah
		jnc ?charOK
		mov al, ah
?charOK:
		stosb
		loop ?drvNameGetLoop

			;; Remove trailing whitespaces
		mov cx, 8		; max eight characters to display
		mov al, ah
		std
		dec di			; stosb leaves DI behind the last written byte
		repe scasb
		mov BYTE [ES:di+2], ch	; place termination character
		mov cx, cs
		mov bl, StrCharDevice		; issue device driver message
		mov al, 0ffh		; AL := invalidate

?noCharDevice:

	cld				; forward direction
	mov ds, cx		; CX is still or again == CS

	push bx
	;; Now many registers are available to use
	;; Perform the repeat check; AL == -1 (char device), 0..31 if block
	mov bx, ?repCheck
	mov di, dummyByte	; Tha byte at [DI} will be decremented eventually
	inc WORD [BX]	; check if enabled
	jz ?noRepCheck
	;; paranoid check to avoid memory overflow
	;; also skips if char device
	cmp al, HIDE_CRITER_DRIVES	; 0..26 == A..Z
	jnc ?noRepCheck
	cbw				; AH := 0
	add al, 2		; correction as BX is two bytes below
	add ax, bx		; repCheckByte area 
	mov di, ax
	inc BYTE [DI]	; will display the 1st and every 256th Criter
	jnz	?fail		; displayed already --> AutoFail && keep incremented [BX]
					; NOTE: There is no output generated til now!!
					;	The output channels have not been touched
?noRepCheck:
	dec WORD [BX]	; keep the word at value -1
	mov WORD [repCheckDecAddr], di

;; Try to find a suitable I/O channel
	mov ah, 62h		; Get PSP
	int 21h
	mov es, bx
;;	mov cx, [ES:32h]	; number of entries in JFT
	les bx, [ES:34h]	; Pointer to JFT
	mov al, [es:bx+2]	; stderr
	; patch STDIN & STDOUT to point to the found channel
	mov ah, al
	xchg WORD [ES:bx], ax
	mov WORD [?orgIOchannels], ax
	mov WORD [??repatchAddr], bx
	mov WORD [??repatchAddr+2], es
	pop bx
	mov es, cx			;; reset ES to the shared code/data segement


	call ?oString	; Display the Critical Error message string
	call ?newline
	mov bl, StrAbort
	call ?oString
	mov bl, 0		; try Ignore
	call ?oAction
	mov bl, 1		; try Retry
	call ?oAction
	mov bl, 3		; try Fail
	call ?oAction
	mov bl, StrQuestionMark
	call ?oString
	jmp short ?inputLoop

?fail:
	pop bx		; correct the stack from repeat check
	mov bl, FAIL
	jmp short ?iret	; actually return

?inputError:
	mov al, LOCAL_BELL
	printALtoConsole

?inputLoop:
	; Prepare to decode the character
	mov di, [StrKeys * 2 + 1 + ??strings]	; address of enumerated valid keys
	xor ax, ax
	mov al, [di]
	inc di
	mov cx, ax			; number of enumerated keys
	mov bx, ax

	readALfromConsole
	;; special keys (AL == 0) are ignored

;; Decode user input
	repne scasb
	jne ?inputError		; key not found

	mov bl, [bx+di-1]	; action code (DI is one byte too far by SCASB)
	mov al, [bx+??allow]
	or al, al
	jz ?inputError		; not allowed

?errRet:
	;; allowed action code in BL
	call ?newline

	;; Restore the JFT
	les di, [??repatchAddr]
	mov ax, 1234h
?orgIOchannels EQU $-2
	mov WORD [ES:di], ax

?iret:
	pop ax			; preserve AH
	mov al, bl		; action code
	cmp al, ABORT
	je ?iretNow
	cmp al, FAIL
	je ?iretNow
	;; AutoFail is activated for ABORT an
Download .txt
gitextract_1pnn224c/

├── .gitattributes
├── .github/
│   ├── actions/
│   │   ├── build/
│   │   │   └── action.yml
│   │   └── upx-inst/
│   │       └── action.yml
│   └── workflows/
│       └── ci-build.yml
├── .gitignore
├── FILE_ID.DIZ
├── README.md
├── VERSION.TXT
├── build.bat
├── build.sh
├── buildall.bat
├── ci_build.sh
├── ci_prereq.sh
├── ci_test.sh
├── clean.bat
├── clean.sh
├── cmd/
│   ├── alias.c
│   ├── beep.c
│   ├── break.c
│   ├── call.c
│   ├── cdd.c
│   ├── chcp.c
│   ├── chdir.c
│   ├── cls.c
│   ├── cmd.m1
│   ├── cmd.m2
│   ├── copy.c
│   ├── ctty.c
│   ├── date.c
│   ├── del.c
│   ├── depend.mk
│   ├── dir.c
│   ├── dirs.c
│   ├── doskey.c
│   ├── echo.c
│   ├── exit.c
│   ├── exit2.c
│   ├── fddebug.c
│   ├── for.c
│   ├── goto.c
│   ├── history.c
│   ├── if.c
│   ├── lfnfor.c
│   ├── makefile
│   ├── makefile.mak
│   ├── memory.c
│   ├── mkdir.c
│   ├── path.c
│   ├── pause.c
│   ├── popd.c
│   ├── prompt.c
│   ├── pushd.c
│   ├── rem.c
│   ├── ren.c
│   ├── rmdir.c
│   ├── set.c
│   ├── shift.c
│   ├── time.c
│   ├── truename.c
│   ├── type.c
│   ├── verify.c
│   └── which.c
├── command.lsm
├── config.b
├── config.h
├── config.std
├── criter/
│   ├── context.x
│   ├── criter.asm
│   ├── criter.txt
│   ├── dmy_cbrk.asm
│   ├── files.txt
│   ├── makefile
│   ├── makefile.mak
│   ├── resource.id
│   └── resource.inc
├── docs/
│   ├── HELP.EN
│   ├── _config.yml
│   ├── c0.txt
│   ├── cmt1.txt
│   ├── cmt10.txt
│   ├── cmt2.txt
│   ├── cmt3.txt
│   ├── cmt4.txt
│   ├── cmt5.txt
│   ├── cmt6.txt
│   ├── cmt7.txt
│   ├── cmt8.txt
│   ├── comments.txt
│   ├── compile.txt
│   ├── contrib.txt
│   ├── download.txt
│   ├── faq.txt
│   ├── files.txt
│   ├── history.txt
│   ├── html/
│   │   ├── build48.html
│   │   └── commands/
│   │       ├── FreeCOM.html
│   │       ├── appendix.html
│   │       ├── cmd.html
│   │       ├── db2html
│   │       ├── info
│   │       ├── parse.pl
│   │       └── parseHTML
│   ├── index.md
│   ├── k-swap.txt
│   ├── language.txt
│   ├── loadhigh.txt
│   ├── localize.txt
│   ├── module.txt
│   ├── notes.txt
│   ├── piping.txt
│   ├── pt_br/
│   │   ├── config.h
│   │   ├── config.mak
│   │   ├── download.txt
│   │   ├── file_id.diz
│   │   └── readme
│   ├── ptchldrv.txt
│   ├── resource.txt
│   ├── todo.txt
│   ├── upload.txt
│   └── vspawn.txt
├── err_fcts.h
├── include/
│   ├── batch.h
│   ├── cmdline.h
│   ├── command.h
│   ├── context.h
│   ├── crossjmp.h
│   ├── cswap.h
│   ├── datefunc.h
│   ├── debug.h
│   ├── infores.h
│   ├── keys.h
│   ├── kswap.h
│   ├── large.inc
│   ├── lfnfuncs.h
│   ├── medium.inc
│   ├── misc.h
│   ├── model.inc
│   ├── module.h
│   ├── mux_ae.h
│   ├── nls.h
│   ├── openf.h
│   ├── res.h
│   ├── resource.h
│   ├── small.inc
│   ├── strings.typ
│   ├── stuff.inc
│   └── timefunc.h
├── lib/
│   ├── absfile.c
│   ├── almemblk.c
│   ├── alprmblk.c
│   ├── alsysblk.c
│   ├── app_get.c
│   ├── app_set.c
│   ├── beep_l.c
│   ├── beep_n.c
│   ├── brk_get.c
│   ├── brk_set.c
│   ├── c16.mac
│   ├── cbreak.c
│   ├── cbs.c
│   ├── cd_dir.c
│   ├── cgetch.c
│   ├── cgettime.c
│   ├── chgctxt.c
│   ├── chgdrv.c
│   ├── chgenv.c
│   ├── chgenvc.c
│   ├── chgenvr.c
│   ├── cmdinput.c
│   ├── comfile.c
│   ├── compfile.c
│   ├── critend.c
│   ├── critrchk.c
│   ├── ctxt.c
│   ├── ctxt_adr.c
│   ├── ctxt_as.c
│   ├── ctxt_chg.c
│   ├── ctxt_clr.c
│   ├── ctxt_get.c
│   ├── ctxt_inf.c
│   ├── ctxt_mk.c
│   ├── ctxt_mkb.c
│   ├── ctxt_mkn.c
│   ├── ctxt_pop.c
│   ├── ctxt_psh.c
│   ├── ctxt_rnu.c
│   ├── ctxt_set.c
│   ├── ctxt_ss.c
│   ├── ctxt_vw.c
│   ├── curdatel.c
│   ├── curtime.c
│   ├── cwd.c
│   ├── dateget.c
│   ├── dateset.c
│   ├── dbg_c.c
│   ├── dbg_mem.c
│   ├── dbg_prnt.c
│   ├── dbg_s.c
│   ├── dbg_sn.c
│   ├── delay.c
│   ├── depend.mk
│   ├── devopen.c
│   ├── dfn_err.c
│   ├── dispcnt.c
│   ├── dispexit.c
│   ├── drvnum.c
│   ├── efct_001.c
│   ├── err1.c
│   ├── err10.c
│   ├── err11.c
│   ├── err12.c
│   ├── err13.c
│   ├── err14.c
│   ├── err15.c
│   ├── err16.c
│   ├── err17.c
│   ├── err18.c
│   ├── err19.c
│   ├── err2.c
│   ├── err20.c
│   ├── err21.c
│   ├── err22.c
│   ├── err23.c
│   ├── err24.c
│   ├── err25.c
│   ├── err26.c
│   ├── err27.c
│   ├── err28.c
│   ├── err29.c
│   ├── err3.c
│   ├── err30.c
│   ├── err31.c
│   ├── err32.c
│   ├── err33.c
│   ├── err34.c
│   ├── err35.c
│   ├── err36.c
│   ├── err37.c
│   ├── err38.c
│   ├── err39.c
│   ├── err4.c
│   ├── err40.c
│   ├── err41.c
│   ├── err42.c
│   ├── err43.c
│   ├── err44.c
│   ├── err45.c
│   ├── err46.c
│   ├── err47.c
│   ├── err48.c
│   ├── err49.c
│   ├── err5.c
│   ├── err50.c
│   ├── err51.c
│   ├── err52.c
│   ├── err53.c
│   ├── err54.c
│   ├── err55.c
│   ├── err56.c
│   ├── err57.c
│   ├── err58.c
│   ├── err59.c
│   ├── err6.c
│   ├── err60.c
│   ├── err61.c
│   ├── err62.c
│   ├── err63.c
│   ├── err64.c
│   ├── err65.c
│   ├── err66.c
│   ├── err67.c
│   ├── err68.c
│   ├── err69.c
│   ├── err7.c
│   ├── err70.c
│   ├── err71.c
│   ├── err72.c
│   ├── err73.c
│   ├── err74.c
│   ├── err75.c
│   ├── err76.c
│   ├── err77.c
│   ├── err78.c
│   ├── err79.c
│   ├── err8.c
│   ├── err80.c
│   ├── err81.c
│   ├── err82.c
│   ├── err83.c
│   ├── err84.c
│   ├── err85.c
│   ├── err86.c
│   ├── err87.c
│   ├── err9.c
│   ├── err_fcts.mk
│   ├── err_fcts.src
│   ├── exec.c
│   ├── exec1.c
│   ├── farread.c
│   ├── fdattr.c
│   ├── fdevopen.c
│   ├── fdsattr.c
│   ├── filecomp.c
│   ├── files.txt
│   ├── fillcomp.c
│   ├── find.c
│   ├── freep.c
│   ├── frsysblk.c
│   ├── fstpcpy.c
│   ├── gallstr.c
│   ├── get1mcb.c
│   ├── getenv.c
│   ├── goxy.c
│   ├── grabfcom.c
│   ├── gumblink.c
│   ├── hdlrctxt.c
│   ├── hist_get.c
│   ├── hist_set.c
│   ├── inputdos.c
│   ├── is_empty.c
│   ├── is_fnamc.c
│   ├── is_fnstr.c
│   ├── is_pchr.c
│   ├── isadev.c
│   ├── keyprsd.c
│   ├── kswap_c.c
│   ├── lastdget.c
│   ├── lastdset.c
│   ├── leadopt.c
│   ├── lfnfuncs.c
│   ├── lib.m1
│   ├── lib.m2
│   ├── lowexec.asm
│   ├── ltrimcl.c
│   ├── ltrimsp.c
│   ├── lwr1wd.c
│   ├── makefile
│   ├── makefile.mak
│   ├── match.c
│   ├── messages.c
│   ├── mk_rddir.c
│   ├── mktmpfil.c
│   ├── msg_dflt.c
│   ├── msg_dps.c
│   ├── msg_fstr.c
│   ├── msg_get.c
│   ├── msg_gpt.c
│   ├── msg_mkey.c
│   ├── msg_prmp.c
│   ├── mux_ae.c
│   ├── myperror.c
│   ├── nls.c
│   ├── nls_date.c
│   ├── nls_time.c
│   ├── num_fmt.c
│   ├── onoff.c
│   ├── openf.c
│   ├── optsb.c
│   ├── optsi.c
│   ├── optss.c
│   ├── parsenum.c
│   ├── pr_date.c
│   ├── pr_prmpt.c
│   ├── pr_time.c
│   ├── prf.c
│   ├── prprompt.c
│   ├── readcmd.c
│   ├── realnum.c
│   ├── res.c
│   ├── res_r.c
│   ├── res_vald.c
│   ├── res_w.c
│   ├── resfile.c
│   ├── rmtmpfil.c
│   ├── rtrimcl.c
│   ├── rtrimsp.c
│   ├── salloc.c
│   ├── samefile.c
│   ├── scancmd.c
│   ├── scanerr.pl
│   ├── scanopt.c
│   ├── session.c
│   ├── showcmds.c
│   ├── skqwd.c
│   ├── spfnam.c
│   ├── split.c
│   ├── sumblink.c
│   ├── timeget.c
│   ├── timeset.c
│   ├── tmpnam.c
│   ├── trimcl.c
│   ├── trimsp.c
│   ├── truepath.c
│   ├── truncate.c
│   ├── txtlend.c
│   ├── unquote.c
│   ├── vcgetch.c
│   ├── vcgetstr.c
│   └── where.c
├── license
├── makefile
├── mkdist.bat
├── mkfiles/
│   ├── bc5.mak
│   ├── gcc.mak
│   ├── tc2.mak
│   ├── turbocpp.mak
│   └── watcom.mak
├── scripts/
│   ├── complng.pl
│   ├── compsyms.pl
│   ├── director.bat
│   ├── disp_cmd.asm
│   ├── echolib.bat
│   ├── echoto.bat
│   ├── fetchseg.pl
│   ├── findstrg.pl
│   ├── makecmd.bat
│   ├── mkxref.pl
│   ├── rmfiles.bat
│   └── sav.btm
├── shell/
│   ├── batch.c
│   ├── cb_catch.asm
│   ├── cmdtable.c
│   ├── command.c
│   ├── command.ld
│   ├── command.m1
│   ├── command.m2
│   ├── cswap.asm
│   ├── cswapc.c
│   ├── depend.mk
│   ├── dummies.asm
│   ├── expalias.c
│   ├── init.c
│   ├── kswap.c
│   ├── loadhigh.c
│   ├── makefile
│   ├── makefile.mak
│   ├── module.c
│   ├── redir.c
│   ├── termhook.asm
│   ├── ver.c
│   ├── wlinker.bat
│   ├── xms_2e.asm
│   ├── xms_brk.asm
│   └── xms_crit.asm
├── strings/
│   ├── CHANGED
│   ├── DEFAULT.err
│   ├── DEFAULT.lng
│   ├── depend.mk
│   ├── dutch.err
│   ├── dutch.lng
│   ├── english.err
│   ├── english.lng
│   ├── finnish.err
│   ├── finnish.lng
│   ├── fixstrs.c
│   ├── french.err
│   ├── french.lng
│   ├── german.err
│   ├── german.lng
│   ├── indent.pro
│   ├── italian.err
│   ├── italian.lng
│   ├── makefile
│   ├── makefile.mak
│   ├── polish.err
│   ├── polish.lng
│   ├── pt.err
│   ├── pt.lng
│   ├── pt_br.err
│   ├── pt_br.lng
│   ├── russian.err
│   ├── russian.lng
│   ├── serbian.err
│   ├── serbian.lng
│   ├── slovene.err
│   ├── slovene.lng
│   ├── spanish.err
│   ├── spanish.lng
│   ├── strings/
│   │   └── makefile.mak
│   ├── swedish.err
│   ├── swedish.lng
│   ├── turkish.err
│   ├── turkish.lng
│   ├── ukr.err
│   ├── ukr.lng
│   ├── yu437.err
│   └── yu437.lng
├── suppl/
│   ├── algnbyte.h
│   ├── algndflt.h
│   ├── appname.h
│   ├── clnsuppl.bat
│   ├── cntry.h
│   ├── compat/
│   │   ├── conio.h
│   │   ├── dos.h
│   │   ├── io.h
│   │   └── process.h
│   ├── dfn.h
│   ├── dynstr.h
│   ├── environ.h
│   ├── errcodes.h
│   ├── external.h
│   ├── fmemory.h
│   ├── getopt.h
│   ├── makefile.mak
│   ├── mcb.h
│   ├── msglib.h
│   ├── msgs.h
│   ├── nls.h
│   ├── nls_c.h
│   ├── nls_f.h
│   ├── p-bc.h
│   ├── p-gcc.h
│   ├── p-mc.h
│   ├── p-pac.h
│   ├── p-watcom.h
│   ├── portable.h
│   ├── psp.h
│   ├── readme.txt
│   ├── regproto.h
│   ├── src/
│   │   ├── _getdcwd.c
│   │   ├── addu.c
│   │   ├── app_ievx.c
│   │   ├── app_ini_.c
│   │   ├── app_init.c
│   │   ├── app_name.c
│   │   ├── app_namx.c
│   │   ├── app_vars.c
│   │   ├── appname.loc
│   │   ├── bugs
│   │   ├── byte2par.c
│   │   ├── cntry.c
│   │   ├── copying
│   │   ├── copying.lb
│   │   ├── dbgf_chg.c
│   │   ├── dbgf_cl.c
│   │   ├── dbgf_cle.c
│   │   ├── dbgf_clg.c
│   │   ├── dbgf_dl.c
│   │   ├── dbgf_dpl.c
│   │   ├── dbgf_et.c
│   │   ├── dbgf_ext.c
│   │   ├── dbgf_fl.c
│   │   ├── dbgf_flg.c
│   │   ├── dbgf_ien.c
│   │   ├── dbgf_lgh.c
│   │   ├── dbgf_lgi.c
│   │   ├── dbgf_lgt.c
│   │   ├── dbgf_lk.c
│   │   ├── dbgf_log.c
│   │   ├── dbgf_lv.c
│   │   ├── dbgf_mfi.c
│   │   ├── dbgf_mi.c
│   │   ├── dbgf_mki.c
│   │   ├── dbgf_ml.c
│   │   ├── dbgf_pop.c
│   │   ├── dbgf_prt.c
│   │   ├── dbgf_psh.c
│   │   ├── dbgf_var.c
│   │   ├── dbgm_chk.c
│   │   ├── dbgv_s0.c
│   │   ├── dbgv_s10.c
│   │   ├── dbgv_s13.c
│   │   ├── dbgv_s14.c
│   │   ├── dbgv_s15.c
│   │   ├── dbgv_s17.c
│   │   ├── dbgv_s19.c
│   │   ├── dbgv_s2.c
│   │   ├── dbgv_s20.c
│   │   ├── dbgv_s22.c
│   │   ├── dbgv_s23.c
│   │   ├── dbgv_s24.c
│   │   ├── dbgv_s25.c
│   │   ├── dbgv_s3.c
│   │   ├── dbgv_s4.c
│   │   ├── dbgv_s5.c
│   │   ├── dbgv_s6.c
│   │   ├── dbgv_s7.c
│   │   ├── dbgv_s8.c
│   │   ├── dfn.loc
│   │   ├── dfndeli2.c
│   │   ├── dfndelim.c
│   │   ├── dfnexpan.c
│   │   ├── dfnfnam.c
│   │   ├── dfnfullp.c
│   │   ├── dfnmerge.c
│   │   ├── dfnpath.c
│   │   ├── dfnsplit.c
│   │   ├── dfnsquee.c
│   │   ├── dfnstat.c
│   │   ├── dfntruen.c
│   │   ├── dir.loc
│   │   ├── dmemcmpf.c
│   │   ├── dosalloc.c
│   │   ├── dosfree.c
│   │   ├── dossize.c
│   │   ├── dstrchar.c
│   │   ├── dstrfupr.c
│   │   ├── dstrleft.c
│   │   ├── dstrrepl.c
│   │   ├── dstrtrim.c
│   │   ├── dstrupr.c
│   │   ├── eeopen.c
│   │   ├── eestrcon.c
│   │   ├── elvis.rc
│   │   ├── eno.loc
│   │   ├── enoallc.c
│   │   ├── enoreal.c
│   │   ├── enosdup.c
│   │   ├── enosetos.c
│   │   ├── env_chg.c
│   │   ├── env_del.c
│   │   ├── env_dvar.c
│   │   ├── env_find.c
│   │   ├── env_fora.c
│   │   ├── env_free.c
│   │   ├── env_insv.c
│   │   ├── env_len.c
│   │   ├── env_mtch.c
│   │   ├── env_new.c
│   │   ├── env_nost.c
│   │   ├── env_ovrw.c
│   │   ├── env_repl.c
│   │   ├── env_rlsg.c
│   │   ├── env_scnt.c
│   │   ├── env_sdup.c
│   │   ├── env_size.c
│   │   ├── env_strg.c
│   │   ├── env_sub.c
│   │   ├── env_var1.c
│   │   ├── env_var2.c
│   │   ├── environ.loc
│   │   ├── erfc_00f.c
│   │   ├── erfc_015.c
│   │   ├── ffmaxbuf.c
│   │   ├── fgetpos.c
│   │   ├── file_id.diz
│   │   ├── filefind.c
│   │   ├── fmemchr.c
│   │   ├── fmemcmp.c
│   │   ├── fmemcpy.c
│   │   ├── fmemory.loc
│   │   ├── fmemove.c
│   │   ├── fnorm.c
│   │   ├── fputmc.c
│   │   ├── fstrcpy.c
│   │   ├── fstrdup.c
│   │   ├── fstrlen.c
│   │   ├── gm_chgm.c
│   │   ├── gm_dup.c
│   │   ├── gm_gtmem.c
│   │   ├── gm_res.c
│   │   ├── initsupl.loc
│   │   ├── intr.asm
│   │   ├── invokedo.c
│   │   ├── makefile.mak
│   │   ├── mcb_1st.c
│   │   ├── mcb_is.c
│   │   ├── mcb_leng.c
│   │   ├── mcb_nxt.c
│   │   ├── mcb_walk.c
│   │   ├── msgs.lng
│   │   ├── msgs.loc
│   │   ├── msgs_w.loc
│   │   ├── nls/
│   │   │   ├── english.err
│   │   │   └── english.lng
│   │   ├── nls.loc
│   │   ├── nlstime.c
│   │   ├── s_skipwd.c
│   │   ├── s_skipws.c
│   │   ├── sstr.src
│   │   ├── stpcat.c
│   │   ├── stpcpy.c
│   │   ├── str.loc
│   │   ├── strnum.c
│   │   ├── suppldbg.loc
│   │   ├── supplio.loc
│   │   ├── syslog.loc
│   │   └── toupperx.c
│   ├── sstr.h
│   ├── str.h
│   ├── supl_def.h
│   ├── suppl.h
│   ├── suppldbg.h
│   ├── supplio.h
│   └── syslog.h
├── tests/
│   ├── args.bat
│   ├── bat1.bat
│   ├── bat2.bat
│   ├── bat3.bat
│   ├── benny.bat
│   ├── compat.bat
│   ├── ctty-nul.bat
│   ├── dir-test.txt
│   ├── errlvl.bat
│   ├── errlvl.c
│   ├── fdos.out
│   ├── hbp001a.bat
│   ├── hbp001b.bat
│   ├── hbp002.txt
│   ├── hbp_001.txt
│   ├── label.bat
│   ├── longcmd.bat
│   ├── msdos.out
│   ├── refl.bat
│   ├── t.bat
│   ├── test.bat
│   ├── test1.bat
│   ├── test2.bat
│   ├── test3.bat
│   ├── test4.bat
│   ├── testenv.c
│   ├── tst-if.bat
│   └── tstcmdln.bat
├── tools/
│   ├── 28.asm
│   ├── 50.asm
│   ├── debug.h
│   ├── depend.mk
│   ├── files.txt
│   ├── icmd_1.nas
│   ├── icmd_2.nas
│   ├── icmd_3.nas
│   ├── icmd_inc.inc
│   ├── icmd_tpl.nas
│   ├── kssf.asm
│   ├── load_icd.c
│   ├── makefile
│   ├── makefile.1
│   ├── ptchldrv.c
│   ├── ptchsize.c
│   ├── resource.h
│   ├── tools.m1
│   ├── tools.m2
│   └── vspawn.asm
├── utils/
│   ├── MAKECMD.BAT
│   ├── chunk.c
│   ├── debug.h
│   ├── depend.mk
│   ├── files.txt
│   ├── makefile
│   ├── makefile.mak
│   ├── misc.h
│   ├── mkctxt.c
│   ├── mkinfres.c
│   ├── mktools.c
│   ├── ptchsize.c
│   └── resource.h
├── utilsc/
│   ├── critstrs.c
│   ├── fixstrs.c
│   └── makefile.mak
└── version.h
Download .txt
SYMBOL INDEX (724 symbols across 383 files)

FILE: cmd/alias.c
  function cmd_alias (line 17) | int cmd_alias(char *param)

FILE: cmd/beep.c
  function cmd_beep (line 23) | int cmd_beep (char * param) { (void)param; beep (); return 0; }

FILE: cmd/break.c
  function cmd_break (line 18) | int cmd_break(char *param)

FILE: cmd/call.c
  function optScanFct (line 40) | optScanFct(opt_call)
  function cmd_call (line 60) | int cmd_call (char * param) {

FILE: cmd/cdd.c
  function cmd_cdd (line 9) | int cmd_cdd(char *param)

FILE: cmd/chcp.c
  function cmd_chcp (line 34) | int cmd_chcp(char *param)

FILE: cmd/chdir.c
  function cmd_chdir (line 9) | int cmd_chdir(char *param)

FILE: cmd/cls.c
  function cmd_cls (line 54) | int cmd_cls (char * param) {

FILE: cmd/copy.c
  type CopySource (line 58) | struct CopySource {
  function optScanFct (line 72) | optScanFct(opt_copy)
  function optScanFct (line 84) | optScanFct(opt_copy1)
  function initContext (line 107) | static void initContext(void)
  function killContext (line 113) | static void killContext(void)
  function BIGcopy (line 138) | static int BIGcopy(int fdout, int fdin, int asc)
  function is_valid_disk (line 226) | static int is_valid_disk(int tstdsk)
  function copy (line 241) | static int copy(char *dst, char *pattern, struct CopySource *src
  function copyFiles (line 463) | static int copyFiles(struct CopySource *h)
  function cpyFlags (line 482) | static int cpyFlags(void)
  type CopySource (line 487) | struct CopySource
  type CopySource (line 488) | struct CopySource
  type CopySource (line 490) | struct CopySource
  function addSource (line 502) | static int addSource(char *p)
  function cmd_copy (line 541) | int cmd_copy(char *rest)

FILE: cmd/ctty.c
  function devAttr (line 51) | static void devAttr(int fd)
  function cmd_ctty (line 72) | int cmd_ctty(char *param)

FILE: cmd/date.c
  function optScanFct (line 55) | optScanFct(opt_date)
  function my_setdate (line 67) | static int my_setdate(const char *s)
  function cmd_date (line 82) | int cmd_date(char *param)

FILE: cmd/del.c
  function optScanFct (line 63) | optScanFct(opt_del)
  function cmd_del (line 74) | int cmd_del(char *param)

FILE: cmd/dir.c
  type currDir (line 218) | struct currDir {
  type ffblk (line 235) | struct ffblk
  type bignum (line 258) | typedef struct _bignum
  function bignum_add (line 264) | static void bignum_add(bignum *big, bignum *to_add)
  function printLFNname (line 276) | static void printLFNname(char *shortName, char *ext)
  function descGetNextToken (line 328) | static int descGetNextToken(char *buf, int fn, int maxlen)
  function showDescription (line 372) | static void showDescription(const char *shortName, char *ext)
  function scanAttr (line 427) | static int scanAttr(const char *p)
  function scanOrder (line 468) | static int scanOrder(const char *p)
  function optScanFct (line 520) | optScanFct(opt_dir)
  function pause (line 562) | static int pause(void)
  function incline (line 574) | static int incline(void)
  function flush_nl (line 589) | static int flush_nl(void)
  function dir_print_header (line 603) | static int dir_print_header(int drive)
  function print_summary (line 704) | static int print_summary(unsigned long files
  function print_total (line 720) | static int print_total
  function dir_print_free (line 738) | static int dir_print_free(unsigned long dirs)
  function DisplaySingleDirEntry (line 816) | static int DisplaySingleDirEntry(struct ffblk *file, struct currDir *cDir)
  function orderFunction (line 929) | static int orderFunction(const void *p1, const void *p2)
  function flushOrder (line 995) | static int flushOrder(struct ffblk _seg *orderArray,
  function dir_list (line 1022) | static int dir_list(int pathlen
  function dir_print_body (line 1190) | static int dir_print_body(char *arg, unsigned long *dircount)
  function cmd_dir (line 1275) | int cmd_dir (char * rest) {
  function cmd_vol (line 1330) | int cmd_vol (char * rest) {

FILE: cmd/dirs.c
  function cmd_dirs (line 13) | int cmd_dirs (char * param) {

FILE: cmd/doskey.c
  function cmd_doskey (line 11) | int cmd_doskey (char * param) {

FILE: cmd/echo.c
  function cmd_echo (line 32) | int cmd_echo(char *param)

FILE: cmd/exit.c
  function internal_exit (line 11) | int internal_exit (char * rest) { (void)rest; exitflag = 1; return 0; }

FILE: cmd/exit2.c
  function force_exit (line 12) | int force_exit (char * rest) { (void)rest; canexit = exitflag = 1; retur...

FILE: cmd/fddebug.c
  function cmd_fddebug (line 30) | int cmd_fddebug(char *param)

FILE: cmd/for.c
  type forErrors (line 30) | typedef enum {
  function forErrors (line 34) | static forErrors checkFOR(char * param	/* in: command line */
  function doFOR (line 150) | static int doFOR (char * varname, char * varE, char * param, char * paramE,
  function cmd_for (line 252) | int cmd_for(char *param)
  function cmd_for_hackery (line 297) | int cmd_for_hackery(char *Xparam)

FILE: cmd/goto.c
  function cmd_goto (line 44) | int cmd_goto(char *param)

FILE: cmd/history.c
  function cmd_history (line 46) | int cmd_history(char *param)

FILE: cmd/if.c
  function cmd_if (line 46) | int cmd_if(char *param)

FILE: cmd/lfnfor.c
  function cmd_lfnfor (line 23) | int cmd_lfnfor(char *param)

FILE: cmd/memory.c
  function displayTag (line 21) | static void displayTag(int string, Context_Tag tag)
  function displayTag1 (line 30) | static void displayTag1(int string, Context_Tag tag)
  function cmd_memory (line 40) | int cmd_memory (char * param) {

FILE: cmd/mkdir.c
  function recursive_mkdir (line 20) | int recursive_mkdir(const char * path, int recursiveMode, int quiet)
  function cmd_mkdir (line 67) | int cmd_mkdir(char *param)

FILE: cmd/path.c
  function cmd_path (line 33) | int cmd_path(char *param)

FILE: cmd/pause.c
  function cmd_pause (line 31) | int cmd_pause (char * param) {

FILE: cmd/popd.c
  function cmd_popd (line 19) | int cmd_popd(char *param)

FILE: cmd/prompt.c
  function cmd_prompt (line 14) | int cmd_prompt(char *param)

FILE: cmd/pushd.c
  function cmd_pushd (line 20) | int cmd_pushd(char *param)

FILE: cmd/rem.c
  function cmd_rem (line 9) | int cmd_rem (char * param) { (void)param; return 0; }

FILE: cmd/ren.c
  function myfnsplit (line 31) | void myfnsplit( const char *path,
  function myfnmerge (line 85) | void myfnmerge( char *path, const char *drive, const char *dir,
  function cmd_rename (line 112) | int cmd_rename(char *param)

FILE: cmd/rmdir.c
  type dos_ffblk (line 37) | struct dos_ffblk
  type dos_ffblk (line 56) | struct dos_ffblk
  type dos_ffblk (line 56) | struct dos_ffblk
  function recursive_rmdir (line 124) | int recursive_rmdir(const char * path, int recursiveMode, int quiet)
  function cmd_rmdir (line 184) | int cmd_rmdir(char *param)

FILE: cmd/set.c
  function optScanFct (line 32) | optScanFct(opt_set)
  function cmd_set (line 52) | int cmd_set(char *param)

FILE: cmd/shift.c
  function cmd_shift (line 30) | int cmd_shift(char *param)

FILE: cmd/time.c
  function optScanFct (line 43) | optScanFct(opt_date)
  function my_settime (line 55) | static int my_settime(const char *s)
  function cmd_time (line 69) | int cmd_time(char *param)

FILE: cmd/truename.c
  function cmd_truename (line 31) | int cmd_truename(char *param)

FILE: cmd/type.c
  function cmd_type (line 35) | int cmd_type(char *param)

FILE: cmd/verify.c
  function setverify (line 36) | static inline void setverify(char a)
  function getverify (line 41) | static inline char getverify(void)
  function cmd_verify (line 49) | int cmd_verify(char *param)

FILE: cmd/which.c
  function cmd_which (line 69) | int cmd_which(char *param)

FILE: include/batch.h
  type bcontext (line 18) | struct bcontext
  type bcontext (line 46) | struct bcontext
  type bcontext (line 53) | struct bcontext
  type bcontext (line 55) | struct bcontext
  type bcontext (line 56) | struct bcontext

FILE: include/command.h
  type InternalErrorCodes (line 28) | enum InternalErrorCodes {
  type CMD (line 179) | struct CMD
  type CMD (line 186) | struct CMD

FILE: include/context.h
  type word (line 14) | typedef word ctxt_t;
  type Context_Tag (line 21) | typedef enum {
  type ctxt_info_t (line 51) | typedef struct {

FILE: include/cswap.h
  type ParamDosExec (line 13) | struct ParamDosExec {
  type ParamDosExec (line 26) | struct ParamDosExec
  function XMSrequest (line 40) | static inline unsigned long XMSrequest(unsigned request, unsigned dx, vo...
  type XMScopy (line 62) | struct XMScopy{
  type XMScopy (line 70) | struct XMScopy
  type XMScopy (line 71) | struct XMScopy

FILE: include/datefunc.h
  type dosdate_t (line 30) | struct dosdate_t
  type dosdate_t (line 38) | struct dosdate_t
  type dosdate_t (line 39) | struct dosdate_t

FILE: include/infores.h
  type infotags (line 48) | typedef enum {
  type infotag (line 58) | typedef struct {
  type EXE_header (line 64) | struct EXE_header {

FILE: include/kswap.h
  type kswap_t (line 14) | typedef  kswap_t _seg *kswap_p;

FILE: include/lfnfuncs.h
  type lfnffblk (line 16) | struct lfnffblk {
  type locffblk (line 35) | struct locffblk {
  type lfnffblk (line 59) | struct lfnffblk
  type lfnffblk (line 61) | struct lfnffblk
  type lfnffblk (line 62) | struct lfnffblk

FILE: include/misc.h
  type OnOff (line 26) | enum OnOff {		/* ON/OFF tester */
  type loadStatus (line 34) | typedef enum {
  type OnOff (line 97) | enum OnOff
  type dosdate_t (line 182) | struct dosdate_t
  type dostime_t (line 183) | struct dostime_t

FILE: include/resource.h
  type res_minorid_t (line 21) | typedef unsigned short res_minorid_t;
  type res_length_t (line 23) | typedef unsigned int res_length_t;
  type res_length_t (line 25) | typedef unsigned long res_length_t;
  type res_majorid_t (line 35) | typedef short res_majorid_t;
  type resource_t (line 37) | typedef struct {		/* type of a control area */

FILE: include/timefunc.h
  type dostime_t (line 31) | struct dostime_t
  type dostime_t (line 39) | struct dostime_t
  type dostime_t (line 40) | struct dostime_t

FILE: lib/almemblk.c
  function allocMemBlk (line 21) | unsigned allocMemBlk(const unsigned size, const unsigned Xmode)

FILE: lib/alprmblk.c
  function allocPermBlk (line 50) | unsigned allocPermBlk(const unsigned size, const unsigned mode)

FILE: lib/alsysblk.c
  function allocSysBlk (line 51) | unsigned allocSysBlk(const unsigned size, const unsigned mode)

FILE: lib/app_get.c
  function appendDisable (line 29) | int appendDisable(void)

FILE: lib/app_set.c
  function appendRestore (line 25) | void appendRestore(const int state)

FILE: lib/beep_l.c
  function beep_low (line 47) | void beep_low(void)

FILE: lib/beep_n.c
  function beep (line 49) | void beep(void)

FILE: lib/brk_get.c
  function getbreak (line 43) | int getbreak(void)

FILE: lib/brk_set.c
  function setbreak (line 43) | void setbreak(const int OnOff)        /* Off = 0, On = 1 */

FILE: lib/cbreak.c
  function setCurrentConDev (line 71) | int setCurrentConDev(const char * dnam)
  function mycprintf (line 83) | static void mycprintf( char *fmt, ... )
  function chkCBreak (line 100) | int chkCBreak(int mode)

FILE: lib/cbs.c
  function cutBackslash (line 15) | void cutBackslash(char * const s)

FILE: lib/cd_dir.c
  function cd_dir (line 20) | int cd_dir(char *param, int cdd, const char * const fctname)

FILE: lib/cgetch.c
  function mygetch (line 53) | static int mygetch( void )
  function cgetchar (line 64) | int cgetchar(void)

FILE: lib/cgettime.c
  function cgetchar_timed (line 48) | int cgetchar_timed(int secs)

FILE: lib/chgctxt.c
  function weight (line 61) | static unsigned long weight(ctxt_info_t *info)
  function chgCtxt (line 74) | int chgCtxt(const Context_Tag tag, const char * const name, const char *...

FILE: lib/chgdrv.c
  function changeDrive (line 60) | int changeDrive(int drive)

FILE: lib/chgenv.c
  function chgEnv (line 71) | int chgEnv(const char name[], const char value[])

FILE: lib/chgenvc.c
  function chgEnvCase (line 57) | int chgEnvCase(const int keepCase, char var[], const char value[])

FILE: lib/chgenvr.c
  function chgEnvRemove (line 52) | int chgEnvRemove(const char name[], const char value[])

FILE: lib/cmdinput.c
  type SCRPOS (line 22) | typedef struct { unsigned char col, row; } SCRPOS;
  function mywherex (line 25) | unsigned mywherex (void) {
  function mywherey (line 29) | unsigned mywherey (void) {
  function my_setcursortype (line 42) | static void my_setcursortype( unsigned short state )
  function isworddelimiter (line 80) | static int isworddelimiter(unsigned c)
  function outc (line 88) | void outc(char c)
  function outblank (line 95) | static void outblank(void)
  function outs (line 102) | void outs(const char * const s)
  function outsblank (line 109) | static void outsblank(const char * const s)
  function clrcmdline (line 114) | static void clrcmdline(char * const str, const unsigned pos, const int m...
  function numLinesToScroll (line 142) | static unsigned numLinesToScroll(const unsigned curx, unsigned cury, con...
  function readcommandEnhanced (line 149) | void readcommandEnhanced(char * const str, const int maxlen)

FILE: lib/critend.c
  function critEndRepCheck (line 18) | void critEndRepCheck(void)

FILE: lib/critrchk.c
  function registerCriterRepeatCheckAddr (line 40) | void registerCriterRepeatCheckAddr(word far *p)
  function critEnableRepeatCheck (line 60) | void critEnableRepeatCheck(void)
  function critDisableRepeatCheck (line 69) | unsigned critDisableRepeatCheck(void)

FILE: lib/ctxt_as.c
  function ctxtAddStatus (line 27) | int ctxtAddStatus(const Context_Tag tag)

FILE: lib/ctxt_chg.c
  function ctxtChgSize (line 18) | int ctxtChgSize(unsigned tosize)

FILE: lib/ctxt_clr.c
  function clear (line 15) | static int clear(void *arg, word segm, word ofs)
  function ctxtClear (line 26) | int ctxtClear(const Context_Tag tag)

FILE: lib/ctxt_get.c
  function ctxtGet (line 21) | int ctxtGet (const int remove, const Context_Tag tag,

FILE: lib/ctxt_mk.c
  function ctxtCreate (line 19) | void ctxtCreate(void)

FILE: lib/ctxt_mkb.c
  function ctxtCreateMemBlock (line 26) | void ctxtCreateMemBlock(unsigned length)

FILE: lib/ctxt_mkn.c
  function ctxtMkItemName (line 13) | void ctxtMkItemName(char * const name

FILE: lib/ctxt_pop.c
  function ctxtPop (line 20) | int ctxtPop(const Context_Tag tag, char ** const Xbuf)

FILE: lib/ctxt_psh.c
  function ctxtPush (line 15) | int ctxtPush(const Context_Tag tag, const char * const buf)

FILE: lib/ctxt_rnu.c
  function renumber (line 17) | static int renumber(void *arg, word segm, word ofs)
  function ctxtRenumberItems (line 35) | void ctxtRenumberItems(const Context_Tag tag)

FILE: lib/ctxt_set.c
  function ctxtSet (line 12) | int ctxtSet(const Context_Tag tag

FILE: lib/ctxt_ss.c
  function scan (line 16) | static int scan (void * arg, word segm, word ofs) {
  function ctxtScanStatus (line 62) | void ctxtScanStatus(void)

FILE: lib/ctxt_vw.c
  type view_t (line 18) | typedef struct {
  function view (line 26) | static int view (void * arg, word segm, word ofs) {
  function ctxtView (line 36) | int ctxtView(const Context_Tag tag, const unsigned empty)

FILE: lib/curdatel.c
  type dosdate_t (line 53) | struct dosdate_t

FILE: lib/curtime.c
  type dostime_t (line 49) | struct dostime_t

FILE: lib/dateget.c
  function _dos_getdate (line 50) | void _dos_getdate(struct dosdate_t *d)

FILE: lib/dateset.c
  function _dos_setdate (line 50) | unsigned _dos_setdate(struct dosdate_t *d)

FILE: lib/dbg_c.c
  function dbg_outc (line 44) | void dbg_outc (int ch) { putc (ch, dbg_logfile); }

FILE: lib/dbg_mem.c
  function dbg_printmem (line 63) | void dbg_printmem (void) {

FILE: lib/dbg_prnt.c
  function dbg_print (line 50) | void dbg_print(const char fmt[], ...)

FILE: lib/dbg_s.c
  function dbg_outs (line 44) | void dbg_outs (const char *const s) {

FILE: lib/dbg_sn.c
  function dbg_outsn (line 44) | void dbg_outsn (const char *const s) {

FILE: lib/delay.c
  function delay (line 14) | void delay(unsigned ms)

FILE: lib/devopen.c
  function devopen (line 52) | int devopen(char *const fnam, int mode)

FILE: lib/dfn_err.c
  function display_errno_fnam_error (line 23) | void display_errno_fnam_error(const char * const fnam)

FILE: lib/dispcnt.c
  function dispCount (line 45) | void dispCount(int cnt, unsigned base_id)

FILE: lib/dispexit.c
  function displayExitcode (line 18) | void displayExitcode(void)

FILE: lib/drvnum.c
  function drvNum (line 47) | int drvNum(int drive)

FILE: lib/efct_001.c
  function error_env (line 55) | void error_env(int base, int err_no, const char * const var)

FILE: lib/err1.c
  function error_invalid_switch (line 15) | void error_invalid_switch(char c)

FILE: lib/err10.c
  function error_out_of_memory (line 15) | void error_out_of_memory(void)

FILE: lib/err11.c
  function error_syntax (line 15) | void error_syntax(const char * const s)

FILE: lib/err12.c
  function error_nothin_to_do (line 15) | void error_nothin_to_do(void)

FILE: lib/err13.c
  function error_selfcopy (line 15) | void error_selfcopy(const char * const s)

FILE: lib/err14.c
  function error_long_batchline (line 15) | void error_long_batchline(const char * const fnam, long linenr)

FILE: lib/err15.c
  function error_bfile_vanished (line 15) | void error_bfile_vanished(const char * const fnam)

FILE: lib/err16.c
  function error_bfile_no_such_label (line 15) | void error_bfile_no_such_label(const char * const fnam, const char * con...

FILE: lib/err17.c
  function error_invalid_time (line 15) | void error_invalid_time(void)

FILE: lib/err18.c
  function error_env_var (line 15) | void error_env_var(const char * const var)

FILE: lib/err19.c
  function error_env_var_not_found (line 15) | void error_env_var_not_found(const char * const var)

FILE: lib/err2.c
  function error_invalid_lswitch (line 15) | void error_invalid_lswitch(const char * const str)

FILE: lib/err20.c
  function error_filename_too_long (line 15) | void error_filename_too_long(const char * const fname)

FILE: lib/err21.c
  function error_command_too_long (line 15) | void error_command_too_long(void)

FILE: lib/err22.c
  function error_line_too_long (line 15) | void error_line_too_long(void)

FILE: lib/err23.c
  function error_tempfile (line 15) | void error_tempfile(void)

FILE: lib/err24.c
  function error_close_quote (line 15) | void error_close_quote(int quote)

FILE: lib/err25.c
  function error_illformed_option (line 15) | void error_illformed_option(const char * const s)

FILE: lib/err26.c
  function error_opt_arg (line 15) | void error_opt_arg(const char * const  str)

FILE: lib/err27.c
  function error_opt_noarg (line 15) | void error_opt_noarg(const char * const  str)

FILE: lib/err28.c
  function error_leading_plus (line 15) | void error_leading_plus(void)

FILE: lib/err29.c
  function error_trailing_plus (line 15) | void error_trailing_plus(void)

FILE: lib/err3.c
  function error_too_many_parameters (line 15) | void error_too_many_parameters(const char * const s)

FILE: lib/err30.c
  function error_open_file (line 15) | void error_open_file(const char * const fnam)

FILE: lib/err31.c
  function error_read_file (line 15) | void error_read_file(const char * const fnam)

FILE: lib/err32.c
  function error_write_file (line 15) | void error_write_file(const char * const fnam)

FILE: lib/err33.c
  function error_write_file_disc_full (line 15) | void error_write_file_disc_full(const char * const fnam, const unsigned ...

FILE: lib/err34.c
  function error_copy (line 15) | void error_copy(void)

FILE: lib/err35.c
  function error_nothing_to_do (line 15) | void error_nothing_to_do(void)

FILE: lib/err36.c
  function error_invalid_number (line 15) | void error_invalid_number(const char * const s)

FILE: lib/err37.c
  function error_init_fully_qualified (line 15) | void error_init_fully_qualified(const char * const s)

FILE: lib/err38.c
  function error_corrupt_command_line (line 15) | void error_corrupt_command_line(void)

FILE: lib/err39.c
  function error_quoted_c_k (line 15) | void error_quoted_c_k(void)

FILE: lib/err4.c
  function error_path_not_found (line 15) | void error_path_not_found(void)

FILE: lib/err40.c
  function error_ctty_excluded (line 15) | void error_ctty_excluded(void)

FILE: lib/err41.c
  function error_l_notimplemented (line 15) | void error_l_notimplemented(void)

FILE: lib/err42.c
  function error_u_notimplemented (line 15) | void error_u_notimplemented(void)

FILE: lib/err43.c
  function error_restore_session (line 15) | void error_restore_session(void)

FILE: lib/err44.c
  function error_save_session (line 15) | void error_save_session(void)

FILE: lib/err45.c
  function error_no_rw_device (line 15) | void error_no_rw_device(const char * const devname)

FILE: lib/err46.c
  function error_ctty_dup (line 15) | void error_ctty_dup(const char * const devname)

FILE: lib/err47.c
  function error_no_cwd (line 15) | void error_no_cwd(int drive)

FILE: lib/err48.c
  function error_kswap_alias_size (line 15) | void error_kswap_alias_size(void)

FILE: lib/err49.c
  function error_kswap_allocmem (line 15) | void error_kswap_allocmem(void)

FILE: lib/err5.c
  function error_file_not_found (line 15) | void error_file_not_found(void)

FILE: lib/err50.c
  function error_if_exist (line 15) | void error_if_exist(void)

FILE: lib/err51.c
  function error_if_errorlevel (line 15) | void error_if_errorlevel(void)

FILE: lib/err52.c
  function error_if_errorlevel_number (line 15) | void error_if_errorlevel_number(void)

FILE: lib/err53.c
  function error_if_command (line 15) | void error_if_command(void)

FILE: lib/err54.c
  function error_alias_out_of_memory (line 15) | void error_alias_out_of_memory(void)

FILE: lib/err55.c
  function error_alias_insert (line 15) | void error_alias_insert(void)

FILE: lib/err56.c
  function error_alias_no_such (line 15) | void error_alias_no_such(const char * const name)

FILE: lib/err57.c
  function error_loading_context (line 15) | void error_loading_context(void)

FILE: lib/err58.c
  function error_dirfct_failed (line 15) | void error_dirfct_failed(const char * const fctname, const char * const ...

FILE: lib/err59.c
  function error_no_alias_name (line 15) | void error_no_alias_name(const char name[])

FILE: lib/err6.c
  function error_sfile_not_found (line 15) | void error_sfile_not_found(const char * const f)

FILE: lib/err60.c
  function error_history_size (line 15) | void error_history_size(const char s[])

FILE: lib/err61.c
  function error_context_out_of_memory (line 15) | void error_context_out_of_memory(void)

FILE: lib/err62.c
  function error_no_context_after_swap (line 15) | void error_no_context_after_swap(void)

FILE: lib/err63.c
  function error_out_of_dos_memory (line 15) | void error_out_of_dos_memory(void)

FILE: lib/err64.c
  function error_context_length (line 15) | void error_context_length(unsigned long islen, unsigned maxlen)

FILE: lib/err65.c
  function error_context_add_status (line 15) | void error_context_add_status(void)

FILE: lib/err66.c
  function error_empty_redirection (line 15) | void error_empty_redirection(void)

FILE: lib/err67.c
  function error_redirect_from_file (line 15) | void error_redirect_from_file(const char * const fnam)

FILE: lib/err68.c
  function error_redirect_to_file (line 15) | void error_redirect_to_file(const char * const fnam)

FILE: lib/err69.c
  function error_bad_mcb_chain (line 15) | void error_bad_mcb_chain(void)

FILE: lib/err7.c
  function error_req_param_missing (line 15) | void error_req_param_missing(void)

FILE: lib/err70.c
  function error_unknown (line 15) | void error_unknown(int err)

FILE: lib/err71.c
  function error_invalid_drive (line 15) | void error_invalid_drive(int drive)

FILE: lib/err72.c
  function error_no_env (line 15) | void error_no_env(void)

FILE: lib/err73.c
  function error_on_off (line 15) | void error_on_off(void)

FILE: lib/err74.c
  function error_invalid_date (line 15) | void error_invalid_date(void)

FILE: lib/err75.c
  function error_for_bad_var (line 15) | void error_for_bad_var(void)

FILE: lib/err76.c
  function error_for_in (line 15) | void error_for_in(void)

FILE: lib/err77.c
  function error_for_parens (line 15) | void error_for_parens(void)

FILE: lib/err78.c
  function error_for_do (line 15) | void error_for_do(void)

FILE: lib/err79.c
  function error_for_no_command (line 15) | void error_for_no_command(void)

FILE: lib/err8.c
  function error_bad_command (line 15) | void error_bad_command(const char * const f)

FILE: lib/err80.c
  function error_goto_label (line 15) | void error_goto_label(void)

FILE: lib/err81.c
  function error_get_codepage (line 15) | void error_get_codepage(void)

FILE: lib/err82.c
  function error_set_codepage (line 15) | void error_set_codepage(void)

FILE: lib/err83.c
  function error_copy_plus_destination (line 15) | void error_copy_plus_destination(void)

FILE: lib/err84.c
  function error_invalid_parameter (line 15) | void error_invalid_parameter(const char * const str)

FILE: lib/err85.c
  function error_fcom_is_device (line 15) | void error_fcom_is_device(const char * const fnam)

FILE: lib/err86.c
  function error_fcom_invalid (line 15) | void error_fcom_invalid(const char * const fnam)

FILE: lib/err87.c
  function error_exe_corrupt (line 15) | void error_exe_corrupt(void)

FILE: lib/err9.c
  function error_no_pipe (line 15) | void error_no_pipe(void)

FILE: lib/exec.c
  type fcb (line 68) | struct fcb     {
  type fcb (line 73) | struct fcb
  type fcb (line 94) | struct fcb
  type ExecBlock (line 108) | struct ExecBlock
  type ExecBlock (line 118) | struct ExecBlock
  function exec (line 120) | int exec(const char *cmd, char *cmdLine, const unsigned segOfEnv)

FILE: lib/exec1.c
  function setErrorLevel (line 62) | void setErrorLevel(int rc)

FILE: lib/farread.c
  function DOSreadwrite (line 52) | static unsigned DOSreadwrite(int fd, void far *buffer, unsigned size,
  function farread (line 67) | size_t farread(int fd, void far*buf, size_t length)
  function farwrite (line 74) | size_t farwrite(int fd, void far*buf, size_t length)
  function farread (line 79) | size_t farread(int fd, void far*buf, size_t length)
  function farwrite (line 89) | size_t farwrite(int fd, void far*buf, size_t length)
  function sfn_open (line 99) | int sfn_open(const char *pathname, int flags)
  function dos_close (line 117) | int dos_close(int fd)
  function dos_read (line 127) | int dos_read(int fd, void *buf, unsigned int len)
  function dos_write (line 132) | int dos_write(int fd, const void *buf, unsigned int len)
  function sfn_creat_common (line 137) | static int sfn_creat_common(const char *pathname, int attr, int new)
  function sfn_creat (line 159) | int sfn_creat(const char *pathname, int attr)
  function sfn_creatnew (line 164) | int sfn_creatnew(const char *pathname, int attr)

FILE: lib/fdattr.c
  function fdattr (line 48) | int fdattr(const int fd)

FILE: lib/fdevopen.c
  function FILE (line 47) | FILE *fdevopen(char *const fnam, const char *const mode)

FILE: lib/fdsattr.c
  function fdsetattr (line 28) | int fdsetattr(const int fd, const int attr)

FILE: lib/filecomp.c
  function do_complete (line 59) | static int do_complete(char *str, unsigned charcount, int show)
  function complete_filename (line 213) | void complete_filename(char *str, unsigned charcount)
  function show_completion_matches (line 218) | int show_completion_matches(char *str, unsigned charcount)

FILE: lib/fillcomp.c
  function fillComp (line 71) | static void fillComp(char * const dst
  function fillFnam (line 118) | void fillFnam(char *dest, const char * const pattern

FILE: lib/freep.c
  function freep (line 45) | void freep(char **p)

FILE: lib/frsysblk.c
  function freeSysBlk (line 48) | void freeSysBlk (const unsigned segm) {

FILE: lib/gallstr.c
  function dosGetAllocStrategy (line 46) | int dosGetAllocStrategy(void)

FILE: lib/get1mcb.c
  function word (line 47) | word GetFirstMCB(void)

FILE: lib/goxy.c
  function goxy (line 55) | void goxy(const unsigned char x, const unsigned char y)

FILE: lib/grabfcom.c
  function grabComFilename (line 72) | int grabComFilename(const int warn, const char far * const fnam)

FILE: lib/gumblink.c
  function dosGetUMBLinkState (line 46) | int dosGetUMBLinkState(void)

FILE: lib/hdlrctxt.c
  function view (line 20) | static int view (void *arg, word segm, word ofs) {
  function breakVarAssign (line 28) | int breakVarAssign(ctxt_t context, char * const s, char ** const value)

FILE: lib/hist_get.c
  function histGet (line 23) | int histGet(const int num, char * const str, const unsigned len)

FILE: lib/hist_set.c
  function histSet (line 19) | void histSet(const int num, const char * const str)

FILE: lib/inputdos.c
  function readcommandDOS (line 66) | void readcommandDOS(char * const str, int maxlen)

FILE: lib/is_empty.c
  function is_empty (line 14) | int is_empty(const char *s)

FILE: lib/is_fnamc.c
  function is_fnchar (line 51) | int is_fnchar(const int c)

FILE: lib/is_fnstr.c
  function is_fnstr (line 14) | int is_fnstr(const char * const s)

FILE: lib/is_pchr.c
  function is_pathdelim (line 39) | int is_pathdelim(const int c)

FILE: lib/isadev.c
  function isadev (line 44) | int isadev(const int fd)

FILE: lib/keyprsd.c
  function keypressed (line 47) | int keypressed(void)

FILE: lib/lastdget.c
  function lastDirGet (line 15) | void lastDirGet(char ** const buf)

FILE: lib/lastdset.c
  function lastDirSet (line 15) | void lastDirSet(void)

FILE: lib/leadopt.c
  function leadOptions (line 52) | int leadOptions (char **Xline, optScanner fct, void *const arg){

FILE: lib/lfnfuncs.c
  function __creat_or_truncate (line 72) | static int __creat_or_truncate( const char * filename, int mode, int code )
  function FILE (line 105) | FILE * lfnfopen( const char *filename, const char *mode )
  function lfn_creat (line 114) | int lfn_creat( const char *filename, int attr )
  function lfnrename (line 121) | int lfnrename( const char *oldfilename, const char *newfilename )
  function convert_to_ffblk (line 153) | static void convert_to_ffblk( struct lfnffblk *dosblock,
  function lfnfindfirst (line 171) | int lfnfindfirst( const char *path, struct lfnffblk *buf, unsigned attr )
  function lfnfindnext (line 215) | int lfnfindnext( struct lfnffblk *buf )
  function lfnfindclose (line 247) | int lfnfindclose( struct lfnffblk *buf )
  function lfnmkdir (line 271) | int lfnmkdir( const char *path )
  function lfn_rc_dir (line 289) | static int lfn_rc_dir( const char *path, int func )
  function lfnrmdir (line 301) | int lfnrmdir( const char *path )
  function lfnchdir (line 306) | int lfnchdir( const char *path )

FILE: lib/lwr1wd.c
  function partstrlower (line 44) | void partstrlower(char *str)

FILE: lib/match.c
  function match_ (line 62) | int match_(char ** const Xp, const char * const word, int len)

FILE: lib/messages.c
  function unloadMsgs (line 80) | void unloadMsgs(void)
  function loadStrings (line 103) | static int loadStrings (res_majorid_t major,
  function msgSegment (line 175) | unsigned msgSegment(void)              /* load messages into memory */

FILE: lib/mk_rddir.c
  function optScanFct (line 21) | optScanFct(opt_md_rd)
  function mk_rd_dir (line 38) | int mk_rd_dir(char *param, int (*func) (const char *, int recursiveMode,...

FILE: lib/msg_dps.c
  function displayXString (line 67) | static void displayXString(FILE *stream, unsigned id, va_list args)
  function displayString (line 75) | void displayString(unsigned id,...)
  function displayError (line 82) | void displayError(unsigned id,...)

FILE: lib/msg_gpt.c
  function getPromptString (line 43) | int getPromptString(unsigned id

FILE: lib/msg_mkey.c
  function mapMetakey (line 46) | int mapMetakey(const char * const str, int ch)

FILE: lib/msg_prmp.c
  function userprompt (line 57) | int userprompt(unsigned id,...)

FILE: lib/mux_ae.c
  function runExtension (line 74) | int runExtension(char * const command, char * const line)

FILE: lib/myperror.c
  function myperror (line 12) | void myperror( const char *msg )

FILE: lib/nls.c
  function refreshNLS (line 46) | void refreshNLS(void)

FILE: lib/num_fmt.c
  function convert (line 50) | void convert(unsigned long num, unsigned int billions, char * const des)

FILE: lib/onoff.c
  function onoffStr (line 59) | enum OnOff onoffStr(char *line)

FILE: lib/openf.c
  function isDeviceName (line 77) | int isDeviceName(char *const fnam)

FILE: lib/optsb.c
  function optScanBool_ (line 55) | int optScanBool_(const char * const optstr, int bool, const char *arg, i...

FILE: lib/optsi.c
  function optScanInteger_ (line 49) | int optScanInteger_ (const char *const optstr, int bool_v,

FILE: lib/optss.c
  function optScanString_ (line 50) | int optScanString_ (const char *const optstr, int bool_v,

FILE: lib/pr_date.c
  type dosdate_t (line 72) | struct dosdate_t
  type dosdate_t (line 73) | struct dosdate_t

FILE: lib/pr_prmpt.c
  function printprompt (line 13) | void printprompt(void)

FILE: lib/pr_time.c
  function parsetime (line 71) | int parsetime(const char *s, struct dostime_t * const timep)

FILE: lib/prf.c
  function flushbuf (line 50) | static void flushbuf(FILE *f)
  function puts (line 56) | int puts(const char *s)
  function handle_char (line 62) | static void handle_char(int c, FILE *f)
  function vprintf (line 112) | int vprintf(const char * fmt, va_list arg)
  function vfprintf (line 117) | int vfprintf(FILE *f, const char * fmt, va_list arg)
  function printf (line 127) | int printf(const char * fmt, ...)
  function fprintf (line 135) | int fprintf(FILE *f, const char * fmt, ...)
  function sprintf (line 143) | int sprintf(char * buff, const char * fmt, ...)
  function vsprintf (line 151) | int vsprintf(char *buff, const char * fmt, va_list arg)
  function do_printf (line 159) | int do_printf(FILE *f, const char * fmt, va_list arg)
  function cso (line 330) | void cso(char c)

FILE: lib/prprompt.c
  function displayPrompt (line 79) | void displayPrompt(const char *pr)

FILE: lib/readcmd.c
  function set_readcommandType (line 14) | int set_readcommandType(int enhanced)
  function set_readcommandType (line 21) | int set_readcommandType(int enhanced)
  function readcommand (line 28) | void readcommand(char * const str, int maxlen)

FILE: lib/realnum.c
  function realNum (line 14) | unsigned realNum(const Context_Tag tag, const int num)

FILE: lib/res.c
  function enumResources (line 73) | int enumResources(res_majorid_t id

FILE: lib/res_r.c
  function filelength (line 98) | static long int filelength(int fd)
  function enumFileResources (line 113) | int enumFileResources(const char *const fnam

FILE: lib/res_vald.c
  function test_fct (line 28) | static int test_fct (res_majorid_t major,
  function validResFile (line 38) | int validResFile(const char * const fnam)

FILE: lib/res_w.c
  function startResource (line 65) | void startResource(FILE *f, res_majorid_t major, res_minorid_t minor)
  function endResource (line 80) | void endResource(FILE *f)

FILE: lib/rmtmpfil.c
  function killtmpfn (line 61) | void killtmpfn(char * const fn)

FILE: lib/rtrimcl.c
  function rtrimcl (line 34) | void rtrimcl(char * const str)

FILE: lib/rtrimsp.c
  function rtrimsp (line 60) | void rtrimsp(char * const str)

FILE: lib/salloc.c
  function dosSetAllocStrategy (line 47) | void dosSetAllocStrategy(int newState)

FILE: lib/samefile.c
  function samefile (line 53) | int samefile(const char * const f1, const char * const f2)

FILE: lib/scancmd.c
  function parseOptions (line 63) | static int parseOptions(optScanner fct, void * const arg, char **argv, i...

FILE: lib/scanopt.c
  function scanOption (line 53) | int scanOption(optScanner fct, void * const ag, char *rest)

FILE: lib/session.c
  function saveSession (line 45) | void saveSession(void)
  function restoreSession (line 61) | void restoreSession(void)

FILE: lib/showcmds.c
  function showcmds (line 64) | int showcmds (char * rest) {

FILE: lib/split.c
  function addArg (line 54) | static int addArg(char ***Xarg, int *argc, char *sBeg, char **sEnd, int ...

FILE: lib/sumblink.c
  function dosSetUMBLinkState (line 46) | void dosSetUMBLinkState(int newState)

FILE: lib/timeget.c
  function _dos_gettime (line 48) | void _dos_gettime(struct dostime_t *t)

FILE: lib/timeset.c
  function _dos_settime (line 54) | unsigned _dos_settime(struct dostime_t *t)

FILE: lib/truncate.c
  function truncate (line 28) | int truncate(int fd)

FILE: lib/vcgetch.c
  function vcgetchar (line 56) | int vcgetchar(void)

FILE: lib/vcgetstr.c
  function vcgetcstr (line 58) | int vcgetcstr(const char *const legalCh)

FILE: shell/batch.c
  type bcontext (line 101) | struct bcontext
  type bcontext (line 113) | struct bcontext
  type bcontext (line 128) | struct bcontext
  type bcontext (line 129) | struct bcontext
  function setBatchParams (line 148) | int setBatchParams(char *s)
  function clearBatchContext (line 161) | static void clearBatchContext(struct bcontext *b)
  function initBatchContext (line 184) | static void initBatchContext(struct bcontext *b)
  function exit_batch (line 192) | void exit_batch(void)
  function exit_all_batch (line 228) | void exit_all_batch(void)
  type bcontext (line 236) | struct bcontext
  type bcontext (line 238) | struct bcontext
  function batch (line 263) | int batch (char * fullname, char * firstword, char * param) {
  function getbline (line 328) | static int getbline(int fd, char *textline, int len, int bufsize)
  type ffblk (line 420) | struct ffblk
  type ffblk (line 448) | struct ffblk

FILE: shell/cmdtable.c
  type CMD (line 50) | struct CMD

FILE: shell/command.c
  function suppl_testMemChain (line 47) | void suppl_testMemChain() {}
  function stack_check_init (line 96) | void stack_check_init(void)
  function stack_check (line 109) | int stack_check(const char *commandline)
  function dup (line 134) | int dup(int fd)
  function dup2 (line 141) | int dup2(int oldfd, int newfd)
  function switchar (line 151) | char switchar(void)
  function isdrive (line 162) | unsigned isdrive(unsigned char cc) {
  function execute (line 170) | void execute(char *first, char *rest, int lh_lf)
  function docommand (line 298) | static void docommand(char *line)
  function parsecommandline (line 468) | void parsecommandline(char *s, int redirect)
  function expandEnvVars (line 630) | int expandEnvVars(char *ip, char * const line)
  function process_input (line 761) | int process_input(int xflag, char *commandline)
  function hangForever (line 903) | static void hangForever(void)
  function my2e_parsecommandline (line 938) | int cdecl my2e_parsecommandline( char *s )
  function main (line 946) | int main(void)

FILE: shell/cswapc.c
  function XMSisactive (line 83) | int XMSisactive(void)
  function fmemcpy (line 88) | void fmemcpy(void far *d1, void far *s1, unsigned len)
  function XMScopy (line 98) | __attribute__((noinline))
  function XMSinit (line 131) | void XMSinit(void)
  function XMSexit (line 283) | void XMSexit(void)
  function InitSwapping (line 309) | void InitSwapping(void)
  function XMSswapmessagesOut (line 340) | void XMSswapmessagesOut(void)
  function word (line 365) | word XMSswapmessagesIn(loadStatus *status)
  function exit (line 445) | void exit(int status)

FILE: shell/expalias.c
  function aliasexpand (line 22) | void aliasexpand(char * const cmd, const int maxlen)

FILE: shell/init.c
  function exitfct (line 67) | void exitfct(void)
  function optScanFct (line 84) | optScanFct(opt_init)
  function initialize (line 158) | int initialize(void)

FILE: shell/kswap.c
  function kswapInit (line 31) | int kswapInit(void)
  function kswapSetISR (line 61) | static void kswapSetISR(void)
  function kswapRegister (line 72) | void kswapRegister(kswap_p ctxt)
  function kswapDeRegister (line 106) | void kswapDeRegister(kswap_p ctxt)
  function kswapMkStruc (line 119) | unsigned kswapMkStruc(const char * const prg, const char * const cmdline)
  function kswapLoadStruc (line 194) | int kswapLoadStruc(void)

FILE: shell/loadhigh.c
  type error_codes (line 60) | enum error_codes
  function cmd_loadhigh (line 91) | int cmd_loadhigh(char *rest)
  function cmd_loadfix (line 117) | int cmd_loadfix(char *rest)
  type UMBREGION (line 137) | struct UMBREGION
  function initialise (line 152) | static int initialise(void)
  function lh_lf (line 196) | static int lh_lf(char *args)
  function lh_error (line 258) | static void lh_error(int errcode)
  function findUMBRegions (line 295) | static int findUMBRegions(void)
  function loadhigh_prepare (line 433) | static int loadhigh_prepare(void)
  function loadfix_prepare (line 560) | static int loadfix_prepare(void)
  function loadfix_prepare (line 596) | static int loadfix_prepare(void)
  function optScanFct (line 621) | optScanFct(opt_lh)
  function parseArgs (line 642) | static int parseArgs(char *cmdline, char **fnam, char **rest)

FILE: shell/module.c
  function loadModule (line 22) | static int loadModule (res_majorid_t major,
  function kswap_p (line 77) | kswap_p modContext(void)

FILE: shell/redir.c
  function is_redir (line 36) | static int is_redir(char c)
  function get_redirection (line 41) | int get_redirection(char *s, char **ifn, char **ofn, int *ofatt)

FILE: shell/ver.c
  function short_version (line 63) | void short_version(void)
  function optScanFct (line 73) | optScanFct(opt_ver)
  function cmd_ver (line 92) | int cmd_ver (char * rest) {

FILE: strings/fixstrs.c
  type read_state (line 106) | typedef enum STATE {
  type dynstring (line 140) | typedef struct {
  type symKey (line 144) | typedef struct {
  function appMem_ (line 264) | int appMem_(dynstring *vs, char *s, int length)
  function fromxdigit (line 280) | unsigned fromxdigit(int ch)
  function pxerror (line 291) | void pxerror(const char * const msg1, const char * const msg2)
  function dumpCh (line 296) | void dumpCh(FILE * const f, const unsigned char ch)
  function dumpString (line 308) | void dumpString(const int stringId)
  function mapBSEscape (line 342) | int mapBSEscape(char ** const s)
  function mapSymKey (line 367) | int mapSymKey(char * const p)
  function loadFile (line 379) | int loadFile(const char * const fnam)
  function create_make_dependency (line 648) | static int create_make_dependency(void)
  function main (line 690) | int main(int argc, char **argv)

FILE: suppl/cntry.h
  type Country_ (line 40) | struct Country_ {		/* local copy of country information */
  type Country (line 88) | typedef struct Country_ Country;

FILE: suppl/compat/conio.h
  function getch (line 9) | static inline int getch(void)

FILE: suppl/compat/dos.h
  function inportb (line 6) | static inline unsigned char inportb (unsigned short int port)
  function outportb (line 14) | static inline void outportb (unsigned short int port, unsigned char value)
  function sound (line 20) | static inline void sound(int freq)
  function nosound (line 28) | static inline void nosound(void)
  function getpsp (line 43) | static inline unsigned getpsp(void)
  function getosmajor (line 54) | static inline unsigned char getosmajor(void)

FILE: suppl/compat/io.h
  function filelength (line 19) | static inline long int filelength(int fd)

FILE: suppl/dfn.h
  type DFN_GLOB_t (line 70) | struct DFN_GLOB_t {
  type DFN_GLOB (line 83) | typedef struct DFN_GLOB_t DFN_GLOB;

FILE: suppl/dynstr.h
  type STR_SAVED_TOKENS_ (line 101) | struct STR_SAVED_TOKENS_ {
  type STR_SAVED_TOKENS (line 109) | typedef struct STR_SAVED_TOKENS_ STR_SAVED_TOKENS;
  type STR_QUOTES_ (line 115) | struct STR_QUOTES_ {
  type STR_QUOTES (line 143) | typedef struct STR_QUOTES_ STR_QUOTES;

FILE: suppl/getopt.h
  type option (line 35) | struct option {
  type getopt_save_t (line 44) | struct getopt_save_t {
  type option (line 60) | struct option
  type option (line 63) | struct option
  type option (line 66) | struct option
  type option (line 69) | struct option
  type getopt_save_t (line 77) | struct getopt_save_t
  type getopt_save_t (line 79) | struct getopt_save_t

FILE: suppl/mcb.h
  type MCB (line 43) | struct MCB {
  type SUPPL_verify_alignment_MCB (line 51) | struct SUPPL_verify_alignment_MCB {

FILE: suppl/nls.h
  type SupplTime (line 31) | struct SupplTime {			/* Universial time/date structure */
  type nlstime (line 40) | typedef struct SupplTime nlstime;

FILE: suppl/p-bc.h
  type byte (line 33) | typedef unsigned char byte;
  type word (line 34) | typedef unsigned short word;
  type FLAG (line 35) | typedef int FLAG;
  type FLAG8 (line 36) | typedef unsigned FLAG8;
  type dword (line 37) | typedef unsigned long dword;
  type IREGS (line 53) | typedef struct REGPACK IREGS;

FILE: suppl/p-gcc.h
  type byte (line 49) | typedef unsigned char byte;
  type word (line 50) | typedef unsigned short word;
  type FLAG (line 51) | typedef unsigned FLAG;
  type FLAG8 (line 52) | typedef unsigned FLAG8;
  type dword (line 54) | typedef unsigned dword;
  type dword (line 56) | typedef unsigned long dword;
  type IREGS (line 77) | typedef struct {
  function CS_ (line 91) | static inline unsigned short CS_(void)
  function getdisk (line 100) | static inline int getdisk(void)
  function setdisk (line 107) | static inline int setdisk(int drive)
  function _dos_getftime (line 115) | static inline int _dos_getftime(int fd, unsigned *date, unsigned *time)
  function _dos_setftime (line 125) | static inline int _dos_setftime(int fd, unsigned date, unsigned time)
  function _dos_setvect (line 144) | static inline void _dos_setvect(int intno, void far *vect)
  function setdta (line 158) | static inline void setdta(void far *dta)

FILE: suppl/p-mc.h
  type DWORD (line 70) | struct DWORD {

FILE: suppl/p-pac.h
  type byte (line 62) | typedef unsigned char byte;
  type word (line 63) | typedef unsigned word;
  type byte (line 64) | typedef byte FLAG;
  type byte (line 65) | typedef byte FLAG8;
  type dword (line 66) | typedef unsigned long dword;
  type IREGS (line 91) | typedef struct {

FILE: suppl/p-watcom.h
  type byte (line 37) | typedef unsigned char byte;
  type word (line 38) | typedef unsigned word;
  type FLAG (line 39) | typedef unsigned FLAG;
  type FLAG8 (line 40) | typedef unsigned FLAG8;
  type dword (line 41) | typedef unsigned long dword;
  type IREGS (line 62) | typedef struct {

FILE: suppl/psp.h
  type PSP (line 33) | struct PSP {
  type SUPPL_verify_alignment_PSP (line 79) | struct SUPPL_verify_alignment_PSP {

FILE: suppl/src/app_ievx.c
  function appInitEnvEx (line 51) | int appInitEnvEx(void)

FILE: suppl/src/app_ini_.c
  function appInit_ (line 55) | int appInit_(char * const fnam)

FILE: suppl/src/app_init.c
  function appInit (line 54) | int appInit(const char * const fnam)

FILE: suppl/src/cntry.c
  function savePtr_ (line 136) | static void savePtr_(int *len, dword *tbl, word *ptr)
  function savePtr_ (line 156) | static void savePtr_(int *len, char far * *tbl, byte far * *ptr)
  function Country (line 170) | Country *nlsInfo(void)
  function nlsWriteFallback (line 175) | void nlsWriteFallback(Country *nls)
  function Country (line 218) | Country *nlsNewInfo(void)
  function main (line 341) | main(void)

FILE: suppl/src/dbgf_chg.c
  function suppl_log_change (line 56) | void suppl_log_change(suppl_log_csptr_t state)

FILE: suppl/src/dbgf_cl.c
  function suppl_log_chg_list_ (line 73) | void suppl_log_chg_list_(FLAG *flag

FILE: suppl/src/dbgf_cle.c
  function suppl_log_class_enabled (line 58) | int suppl_log_class_enabled(suppl_log_csptr_t str)

FILE: suppl/src/dbgf_clg.c
  function suppl_log_close (line 56) | void suppl_log_close(void)

FILE: suppl/src/dbgf_dl.c
  function suppl_log_del_list_ (line 56) | void suppl_log_del_list_(suppl_log_list_t *list)

FILE: suppl/src/dbgf_dpl.c
  function suppl_log_dup_list (line 56) | void suppl_log_dup_list(suppl_log_list_t *list)

FILE: suppl/src/dbgf_et.c
  function suppl_log_enter (line 79) | void suppl_log_enter(suppl_log_sptr_t library_name

FILE: suppl/src/dbgf_ext.c
  function suppl_log_terminate (line 55) | void suppl_log_terminate(suppl_log_csptr_t loginfo)

FILE: suppl/src/dbgf_fl.c
  function suppl_log_find_list (line 57) | int suppl_log_find_list(suppl_log_list_t *list

FILE: suppl/src/dbgf_flg.c
  function suppl_log_flag_ (line 64) | void suppl_log_flag_(FLAG *flag, suppl_log_sptr_t *str)

FILE: suppl/src/dbgf_ien.c
  function suppl_log_item_enabled (line 60) | int suppl_log_item_enabled(suppl_log_list_t *list

FILE: suppl/src/dbgf_lgh.c
  function suppl_log_log_header (line 69) | void suppl_log_log_header(void)

FILE: suppl/src/dbgf_lgi.c
  function suppl_log_log_item (line 68) | void suppl_log_log_item(suppl_log_csptr_t fmt, ...)
  function suppl_log_log_vitem (line 76) | void suppl_log_log_vitem(suppl_log_csptr_t fmt, va_list ap)

FILE: suppl/src/dbgf_lgt.c
  function suppl_log_log_trailer (line 59) | void suppl_log_log_trailer(void)

FILE: suppl/src/dbgf_lk.c
  function suppl_log_lock (line 79) | int suppl_log_lock(void)
  function suppl_log_unlock (line 88) | void suppl_log_unlock(void)

FILE: suppl/src/dbgf_log.c
  function suppl_log_log (line 60) | void suppl_log_log(suppl_log_csptr_t fmt, ...)

FILE: suppl/src/dbgf_lv.c
  function suppl_log_leave (line 58) | void suppl_log_leave(suppl_log_local_data_t *local_data)

FILE: suppl/src/dbgf_mfi.c
  function suppl_log_list_t (line 59) | suppl_log_list_t *suppl_log_mkf_item(int flag, const char * const s

FILE: suppl/src/dbgf_mi.c
  function suppl_log_match_item (line 57) | int suppl_log_match_item(suppl_log_list_t *item

FILE: suppl/src/dbgf_mki.c
  function suppl_log_list_t (line 59) | suppl_log_list_t *suppl_log_mk_item(const char * const s)

FILE: suppl/src/dbgf_ml.c
  function suppl_log_match_list (line 59) | int suppl_log_match_list(suppl_log_list_t *list

FILE: suppl/src/dbgf_pop.c
  function suppl_log_pop (line 56) | void suppl_log_pop(void)

FILE: suppl/src/dbgf_prt.c
  function suppl_log_print_1 (line 87) | int suppl_log_print_1(suppl_log_csptr_t inf_class)
  function suppl_log_print_2 (line 96) | void suppl_log_print_2(suppl_log_csptr_t fmt, ...)

FILE: suppl/src/dbgf_psh.c
  function suppl_log_push (line 56) | void suppl_log_push(void)

FILE: suppl/src/dbgm_chk.c
  function checkItem (line 66) | static int checkItem(void *arg, word segm)
  function suppl_testMemChain (line 83) | void suppl_testMemChain(void)

FILE: suppl/src/dfndeli2.c
  function dfndelim2 (line 59) | int dfndelim2(const int ch)

FILE: suppl/src/dfndelim.c
  function dfndelim (line 60) | int dfndelim(const int ch)

FILE: suppl/src/dfnexpan.c
  function chkHeap (line 144) | chkHeap

FILE: suppl/src/dfnsplit.c
  function dfnsplit (line 120) | int dfnsplit(const char * const fnam, char ** const dr, char ** const path

FILE: suppl/src/dfnsquee.c
  function chkHeap (line 92) | chkHeap

FILE: suppl/src/dfnstat.c
  function dfnstat (line 68) | int dfnstat(const char * const fnam)

FILE: suppl/src/dmemcmpf.c
  function _fMemiCmp (line 50) | int _fMemiCmp(unsigned const dseg, unsigned dofs
  function _fMemiCmp (line 72) | int _fMemiCmp(const byte far * dest, const byte far * src, unsigned length)

FILE: suppl/src/dosalloc.c
  function word (line 80) | word DOSalloc(word length, int mode)

FILE: suppl/src/dossize.c
  function word (line 86) | word resizeBlk(const word segm, const unsigned length)

FILE: suppl/src/eeopen.c
  function FILE (line 58) | FILE *Eopen(const char * const fnam, const char * const mode)

FILE: suppl/src/eestrcon.c
  function chkHeap (line 91) | chkHeap

FILE: suppl/src/enosetos.c
  function eno_setOSerror (line 69) | int eno_setOSerror(int errnr)

FILE: suppl/src/env_chg.c
  function env_change (line 63) | int env_change(word segm, const char * const var, const char * const value)

FILE: suppl/src/env_del.c
  function env_delete (line 58) | void env_delete(word segm)

FILE: suppl/src/env_dvar.c
  function chkMem (line 85) | chkMem

FILE: suppl/src/env_find.c
  function word (line 58) | word env_findVar(const word segm, const char * const var)

FILE: suppl/src/env_fora.c
  function env_forAll (line 70) | int env_forAll(word segm, ENV_WALKFUNC fct, void *arg)

FILE: suppl/src/env_free.c
  function word (line 87) | word env_endOfVars(const word segm)
  function word (line 105) | word env_firstFree(const word segm)
  function word (line 116) | word env_freeCount(const word segm)

FILE: suppl/src/env_insv.c
  function env_appVar (line 78) | int env_appVar(word segm, const char * const var, const char * const value)

FILE: suppl/src/env_len.c
  function env_varlen (line 56) | unsigned env_varlen(const word segm, const word offset)

FILE: suppl/src/env_mtch.c
  function env_matchVar (line 74) | int env_matchVar(word segm, char * const var)

FILE: suppl/src/env_new.c
  function word (line 53) | word env_create(const unsigned length)

FILE: suppl/src/env_nost.c
  function env_nullStrings (line 60) | int env_nullStrings(word segm)

FILE: suppl/src/env_ovrw.c
  function env_ovrVarOffset (line 64) | int env_ovrVarOffset(word segm, word ofs, const char *var

FILE: suppl/src/env_repl.c
  function word (line 104) | word env_replace(word Oenv, int mode, ...)

FILE: suppl/src/env_rlsg.c
  function env_relocateSegment (line 55) | void env_relocateSegment(const word segm, const word tosegm)

FILE: suppl/src/env_scnt.c
  function env_strcounter (line 58) | int env_strcounter(word segm, int diff)

FILE: suppl/src/env_sdup.c
  function chkMem (line 74) | chkMem

FILE: suppl/src/env_size.c
  function word (line 100) | word env_setsize(word Osegm, unsigned newLength)

FILE: suppl/src/env_strg.c
  function word (line 62) | word env_string(word segm, int index)

FILE: suppl/src/env_sub.c
  function env_subVarOffset (line 64) | void env_subVarOffset(word segm, word offset)

FILE: suppl/src/erfc_00f.c
  function Esuppl_noMem (line 31) | void Esuppl_noMem(void)

FILE: suppl/src/erfc_015.c
  function Esuppl_openFile (line 31) | void Esuppl_openFile(const char * const fnam)

FILE: suppl/src/ffmaxbuf.c
  function Fmaxbuf (line 54) | int Fmaxbuf(byte ** const Xbuf, size_t * const Xlen)

FILE: suppl/src/fgetpos.c
  function fgetpos (line 52) | int fgetpos(FILE * const stream, fpos_t * const pos)

FILE: suppl/src/filefind.c
  function findfirst (line 80) | int findfirst(const char * const pattern, struct ffblk *ff, int attrib)
  function findnext (line 103) | int findnext(struct ffblk *ff)

FILE: suppl/src/fmemchr.c
  function _fmemchr (line 48) | unsigned _fmemchr(unsigned const seg, unsigned ofs, const unsigned value...

FILE: suppl/src/fmemcmp.c
  function _fmemcmp (line 50) | int _fmemcmp(unsigned const dseg, unsigned dofs
  function _fmemcmp (line 68) | int _fmemcmp(const void far * const s1, const void far * const s2

FILE: suppl/src/fmemcpy.c
  function _fmemcpy (line 50) | void _fmemcpy(unsigned const dseg, unsigned const dofs

FILE: suppl/src/fmemove.c
  function _fmemmove (line 51) | void _fmemmove(unsigned dseg, unsigned dofs

FILE: suppl/src/fnorm.c
  function _fnormalize_ (line 46) | void _fnormalize_(unsigned *seg, unsigned *ofs)

FILE: suppl/src/fputmc.c
  function fputmc (line 57) | int fputmc(int ch, int cnt, FILE *f)

FILE: suppl/src/fstrcpy.c
  function _fstrcpy (line 43) | void _fstrcpy(fargDecl(char, dst), fargDecl(const char, src))

FILE: suppl/src/fstrlen.c
  function _fstrlen (line 42) | unsigned _fstrlen(unsigned const seg, unsigned const ofs)
  function _fstrlen (line 57) | unsigned _fstrlen(const char far * const s)

FILE: suppl/src/invokedo.c
  function invokeDOS (line 61) | int invokeDOS(IREGS *prp)

FILE: suppl/src/mcb_1st.c
  function word (line 51) | word mcb_first(void)

FILE: suppl/src/mcb_is.c
  function isMCBcomp (line 49) | static int isMCBcomp(void *arg, word mcb)
  function isMCB (line 53) | int isMCB(const word mcb)

FILE: suppl/src/mcb_leng.c
  function mcb_length (line 59) | unsigned mcb_length(const word segm)

FILE: suppl/src/mcb_nxt.c
  function word (line 54) | word nxtMCB(word mcb)

FILE: suppl/src/mcb_walk.c
  function mcb_walk (line 69) | int mcb_walk(word mcb, const MCB_WALKFUNC fct, void * const arg)

FILE: suppl/src/nlstime.c
  type dostime_t (line 67) | struct dostime_t

FILE: suppl/src/strnum.c
  function strnum (line 74) | int strnum(const char * const s, int * const num, char ** const endp)

FILE: suppl/src/toupperx.c
  function toMTrans (line 86) | static int toMTrans(int ch, int len, fartbl iM(*)tbl, int (*fct)(int))
  function toFUpper (line 97) | int toFUpper(int ch)
  function toUpper (line 102) | int toUpper(int ch)
  function toLower (line 109) | int toLower(int ch)

FILE: suppl/suppl.h
  type ffblk (line 218) | struct ffblk {
  type ffblk (line 243) | struct ffblk
  type ffblk (line 244) | struct ffblk
  type ffblk (line 290) | struct ffblk {
  type ffblk (line 299) | struct ffblk
  type ffblk (line 304) | struct ffblk

FILE: suppl/suppldbg.h
  type suppl_log_lvl_t (line 541) | typedef unsigned suppl_log_lvl_t;
  type suppl_log_linenr_t (line 542) | typedef unsigned long suppl_log_linenr_t;
  type suppl_log_local_data_t (line 545) | typedef struct {

FILE: suppl/supplio.h
  type fpos_t (line 64) | typedef long fpos_t;
  type Suppl_ExtAttr_ (line 426) | struct Suppl_ExtAttr_ {	/* extended attributes */
  type Suppl_ExtAttr (line 436) | typedef struct Suppl_ExtAttr_ Suppl_ExtAttr;

FILE: tests/testenv.c
  function main (line 7) | int

FILE: tools/load_icd.c
  function main (line 22) | int main(int argc, char **argv)

FILE: tools/ptchsize.c
  function getInfo (line 42) | int getInfo (res_majorid_t major,
  function err_ (line 67) | void err_(int i, int num)
  function getInfoValues (line 71) | void getInfoValues(void)
  function prUns (line 115) | void prUns(unsigned val, char *name)
  function addUns_ (line 124) | void addUns_(unsigned long *minVal, unsigned val)
  function addSize (line 130) | void addSize(unsigned short *size, char * const Xp)
  function main (line 175) | int main(int argc, char **argv)

FILE: utils/chunk.c
  function main (line 14) | int main(int argc, char **argv)

FILE: utils/mkctxt.c
  function incOffs (line 80) | static void incOffs(int size)
  function dumpDefine (line 84) | static void dumpDefine(char *name, char *value)
  function dumpEQU (line 91) | static void dumpEQU(char *symbol)
  function indent (line 98) | static void indent(void)
  function endStru (line 103) | static void endStru(void)
  function endPkg (line 110) | static void endPkg(void)
  function endType (line 117) | static void endType(void)
  function dumpItem (line 125) | static void dumpItem(char *name, char *value, char *Ctype, char asmType)
  function match_ (line 149) | static int match_(char **Xp, char *w)
  function main (line 167) | int main(int argc, char **argv)

FILE: utils/mkinfres.c
  function scanMapFile (line 29) | int scanMapFile(const char * const fnam
  function addImageDisplacement (line 99) | int addImageDisplacement(const char * const fnam
  function dumpTag (line 143) | void dumpTag(int ttype, int tlength, void *tvalue)
  function dumpTagU (line 198) | void dumpTagU(int ttype, unsigned tvalue)
  function main (line 202) | int main(int argc, char **argv)

FILE: utils/mktools.c
  function main (line 29) | int main(void)

FILE: utilsc/critstrs.c
  type strings (line 48) | typedef struct {
  type word (line 53) | typedef unsigned short word;
  type byte (line 54) | typedef unsigned char byte;
  function strupr (line 104) | static void strupr(char *s)
  function pxerror (line 116) | void pxerror(char *msg1, char *msg2)
  function tonum (line 121) | int tonum(int ch)
  function savetext (line 126) | void savetext(strings s[], int i, const char * const line)
  function search (line 166) | int search(strings s[], const char * const k, const char * const line)
  function loadFile (line 177) | int loadFile(char *fnam)
  function main (line 251) | int main(int argc, char **argv)
Condensed preview — 750 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,961K chars).
[
  {
    "path": ".gitattributes",
    "chars": 1476,
    "preview": "* text eol=crlf\r\n*.sh text eol=lf\r\n*.com -text\r\n*.ico -text\r\nelvis.rc -text\r\nci_*.sh text eol=lf\r\n.github/workflows/*.ym"
  },
  {
    "path": ".github/actions/build/action.yml",
    "chars": 514,
    "preview": "name: cross-compile-build\r\ndescription: Cross-compile\r\ninputs:\r\n  cmd:\r\n    description: 'build cmd'\r\n    default: ''\r\n "
  },
  {
    "path": ".github/actions/upx-inst/action.yml",
    "chars": 347,
    "preview": "name: install-upx\r\ndescription: Load UPX\r\n#\r\nruns:\r\n  using: composite\r\n  steps:\r\n    - name: UPX install (OSX)\r\n      i"
  },
  {
    "path": ".github/workflows/ci-build.yml",
    "chars": 2474,
    "preview": "name: Build\non:\n  pull_request:\n    types:\n      - opened\n      - edited\n      - ready_for_review\n      - reopened\n     "
  },
  {
    "path": ".gitignore",
    "chars": 609,
    "preview": "*.cfg\r\n*.com\r\n*.exe\r\n*.icd\r\n*.lib\r\n*.lst\r\n*.map\r\n*.o\r\n*.obj\r\n*.rsp\r\n*.tmp\r\n\r\n# CI build\r\n/_downloads/**\r\n/_output/**\r\n/_"
  },
  {
    "path": "FILE_ID.DIZ",
    "chars": 189,
    "preview": "This is the FreeDOS Command Shell (command.com).\r\n\r\nFor the latest version and information, visit\r\n\r\nhttp://wiki.freedos"
  },
  {
    "path": "README.md",
    "chars": 2735,
    "preview": "# FreeCom - The DOS Command Line Interface #\r\n********************************************\r\n\r\nSource code distribution o"
  },
  {
    "path": "VERSION.TXT",
    "chars": 38,
    "preview": "FreeCom version 0.87 - WATCOMC [???]\r\n"
  },
  {
    "path": "build.bat",
    "chars": 5523,
    "preview": "@echo off\r\n\r\nset SWAP=YES-DXMS-SWAP____________________\r\nif NOT \"%SWAP%\"==\"YES-DXMS-SWAP____________________\" goto err1\r"
  },
  {
    "path": "build.sh",
    "chars": 4290,
    "preview": "#!/bin/bash\n\nset -e\n\nWITH_UPX=\"no\"\nSED=sed\n#workaround for Windows (set to binary mode)\nif [ \"$(expr substr $(uname -s) "
  },
  {
    "path": "buildall.bat",
    "chars": 3920,
    "preview": "@ECHO OFF\r\nREM we use BUILD_COMPILER as build.bat sets and clears COMPILER env var\r\nif \"%BUILD_COMPILER%\"==\"\" set BUILD_"
  },
  {
    "path": "ci_build.sh",
    "chars": 2590,
    "preview": "#!/bin/sh\n\nset -e\n\nif [ ! -z \"${TRAVIS_BUILD_DIR}\" ] ; then\n  CI_BUILD_DIR=${TRAVIS_BUILD_DIR}\nelse\n  CI_BUILD_DIR=$(pwd"
  },
  {
    "path": "ci_prereq.sh",
    "chars": 2744,
    "preview": "#!/bin/sh\n\nset -e\n\nsudo add-apt-repository -y ppa:dosemu2/ppa\nsudo add-apt-repository ppa:tkchia/build-ia16\nsudo apt upd"
  },
  {
    "path": "ci_test.sh",
    "chars": 45,
    "preview": "#!/bin/sh\n\necho No tests created yet!\nexit 0\n"
  },
  {
    "path": "clean.bat",
    "chars": 939,
    "preview": "@echo off\r\nif \"%1\"==\"\" goto main\r\nfor %%i in (%2 %3 %4 %5 %6 %7 %8 %9) do if exist %1%%i del %1%%i>nul\r\ngoto end\r\n\r\n:mai"
  },
  {
    "path": "clean.sh",
    "chars": 922,
    "preview": "#!/bin/sh\ncd suppl\nrm -f all_done untar.exe untar.com untar.obj untar.map gnumake.mak\nrm -f compile.me suppl*.lib suppl*"
  },
  {
    "path": "cmd/alias.c",
    "chars": 1128,
    "preview": "/* $Id$\r\n *  ALIAS.C - alias administration module\r\n *\r\n */\r\n\r\n#include \"../config.h\"\r\n\r\n#include <nls_f.h>\r\n\r\n#include "
  },
  {
    "path": "cmd/beep.c",
    "chars": 446,
    "preview": "/* $Id$\r\n *  BEEP.C - beep command.\r\n *\r\n *  Comments:\r\n *\r\n * 16 Jul 1998 (Hans B Pufal)\r\n *   started.\r\n *\r\n * 16 Jul "
  },
  {
    "path": "cmd/break.c",
    "chars": 568,
    "preview": "/* $Id$\r\n *  BREAK.C - break command.\r\n *\r\n *  Comments:\r\n *\r\n * 14-Aug-1998 (John P Price)\r\n *   started.\r\n *\r\n */\r\n\r\n#"
  },
  {
    "path": "cmd/call.c",
    "chars": 2008,
    "preview": "/* $Id$\r\n *  CALL.C - batch file call command.\r\n *\r\n *  Comments:\r\n *\r\n * 16 Jul 1998 (Hans B Pufal)\r\n *   started.\r\n *\r"
  },
  {
    "path": "cmd/cdd.c",
    "chars": 181,
    "preview": "/* $Id$\r\n * CDD - changes drive and directory\r\n */\r\n\r\n#include \"../config.h\"\r\n\r\n#include \"../include/command.h\"\r\n\r\nint c"
  },
  {
    "path": "cmd/chcp.c",
    "chars": 1422,
    "preview": "/* $Id$\r\n *  CHCP.C - CHCP command.\r\n\r\n \tCHCP [codepage]\r\n\r\n \tvia DOS-66-01/02\r\n\r\n\t$Log$\r\n\tRevision 1.3  2004/07/19 18:1"
  },
  {
    "path": "cmd/chdir.c",
    "chars": 214,
    "preview": "/* $Id$\r\n * CD / CHDIR - changes the current working directory of a drive\r\n */\r\n\r\n#include \"../config.h\"\r\n\r\n#include \".."
  },
  {
    "path": "cmd/cls.c",
    "chars": 3505,
    "preview": "/* $Id$\r\n *  CLS.C - clear screen internal command\r\n *\r\n *  Comments:\r\n *\r\n *\tIssues ^L (Form Feed), then:\r\n *\tif file d"
  },
  {
    "path": "cmd/cmd.m1",
    "chars": 102,
    "preview": ".AUTODEPEND\r\n\r\nCFG_DEPENDENCIES = makefile.mak\r\n\r\n!include \"..\\config.mak\"\r\n\r\nall: $(CFG) cmds.lib\r\n\r\n"
  },
  {
    "path": "cmd/cmd.m2",
    "chars": 2,
    "preview": "\r\n"
  },
  {
    "path": "cmd/copy.c",
    "chars": 16428,
    "preview": "/* $Id$\r\n * COPY.C -- Internal Copy Command\r\n *\r\n * 1999/05/10 ska\r\n * rewritten, based upon previous COPY.C of FreeCom "
  },
  {
    "path": "cmd/ctty.c",
    "chars": 3473,
    "preview": "/* $Id$\r\n *  CTTY.C - ctty command.\r\n *\r\n *  Comments:\r\n *\r\n *  Current possible problems: -- 2000/01/14 ska\r\n *\r\n *  Pr"
  },
  {
    "path": "cmd/date.c",
    "chars": 2938,
    "preview": "/* $Id$\r\n *  DATE.C - date internal command\r\n *\r\n *  Comments:\r\n *\r\n *  08 Jul 1998 (John P. Price)\r\n *    started.\r\n *\r"
  },
  {
    "path": "cmd/del.c",
    "chars": 5009,
    "preview": "/* $Id$\r\n *  DEL.C - del command.\r\n *\r\n *  Comments:\r\n *\r\n *  06/29/98 (Rob Lake rlake@cs.mun.ca)\r\n *      rewrote del t"
  },
  {
    "path": "cmd/depend.mk",
    "chars": 541,
    "preview": "cmd .SEQUENTIAL : utils err_fcts.h strings context lib cmd_dir\r\n\r\ncmd_dir .SETDIR=cmd :\r\n\t@echo Entering $(PWD)\r\n\t$(RUNM"
  },
  {
    "path": "cmd/dir.c",
    "chars": 36073,
    "preview": "/* $Id$\r\n *  DIR.C - dir internal command\r\n *\r\n *  Comments:\r\n *\r\n *  01/29/97 (Tim Norman)\r\n *    started.\r\n *\r\n *  06/"
  },
  {
    "path": "cmd/dirs.c",
    "chars": 366,
    "preview": "/* $Id$\r\n *  DSTACK.C - Directory stack PUSHD/POPD support, compatible with 4/NDOS\r\n *\r\n * Outputs directory stack conte"
  },
  {
    "path": "cmd/doskey.c",
    "chars": 293,
    "preview": "/* $Id$\r\n *  DOSKEY -- command line editor extender <-> incorporated, but\r\n *\t\tnot loadable\r\n */\r\n\r\n#include \"../config."
  },
  {
    "path": "cmd/echo.c",
    "chars": 1173,
    "preview": "/* $Id$\r\n *  ECHO.C - echo command.\r\n *\r\n *  Comments:\r\n *\r\n * 16 Jul 1998 (Hans B Pufal)\r\n *   started.\r\n *\r\n * 16 Jul "
  },
  {
    "path": "cmd/exit.c",
    "chars": 255,
    "preview": "/* $Id$\r\n *  EXIT -- exits current instance of FreeCOM or leave all batch files\r\n *\r\n * set the exitflag to true\r\n */\r\n\r"
  },
  {
    "path": "cmd/exit2.c",
    "chars": 283,
    "preview": "/* $Id$\r\n *  EXIT -- exits current instance of FreeCOM or leave all batch files\r\n *\r\n * set the exitflag to true\r\n * and"
  },
  {
    "path": "cmd/fddebug.c",
    "chars": 1413,
    "preview": "/* $Id$\r\n *  FDDEBUG.C - verify command.\r\n *\r\n *  Comments: Turn on/off the debug flag\r\n *\r\n * 30-Mar-2000 (John P Price"
  },
  {
    "path": "cmd/for.c",
    "chars": 7106,
    "preview": "/* $Id$\r\n *  FOR.C - for command.\r\n *\r\n *\tSynopsises:\r\n *\t\ta) FOR { '%' } v  IN (...) DO ...\r\n *\t\tb) FOR [{ '%' }] name "
  },
  {
    "path": "cmd/goto.c",
    "chars": 1726,
    "preview": "/* $Id$\r\n *  GOTO.C - goto command.\r\n *\r\n *  Comments:\r\n *\r\n * 16 Jul 1998 (Hans B Pufal)\r\n *   started.\r\n *\r\n * 16 Jul "
  },
  {
    "path": "cmd/history.c",
    "chars": 1710,
    "preview": "/*\t$Id$\r\n\r\n\tcommand line history\r\n\r\n\tThis file bases on HISTORY.C of FreeCOM v0.81 beta 1.\r\n\r\n\t$Log$\r\n\tRevision 1.2  200"
  },
  {
    "path": "cmd/if.c",
    "chars": 4691,
    "preview": "/* $Id$\r\n *  IF.C - if command.\r\n *\r\n *  Comments:\r\n *\r\n * 16 Jul 1998 (Hans B Pufal)\r\n *   started.\r\n *\r\n * 16 Jul 1998"
  },
  {
    "path": "cmd/lfnfor.c",
    "chars": 1154,
    "preview": "/* $Id$\r\n *  LFNFOR.C - lfnfor command (MS-DOS 7.0).\r\n *\r\n *  Comments:\r\n *\r\n * 22-June-2006 (Blair Campbell)\r\n *   star"
  },
  {
    "path": "cmd/makefile",
    "chars": 11239,
    "preview": "# $Id$\r\n#\r\n# Makefile for the FreeCOM library\r\n#\r\n# $Log$\r\n# Revision 1.5  2002/11/12 21:56:14  skaus\r\n# v0.83 Beta 52:\r"
  },
  {
    "path": "cmd/makefile.mak",
    "chars": 947,
    "preview": "CFG_DEPENDENCIES = makefile.mak\r\n\r\nTOP = ..\r\n!include \"$(TOP)/config.mak\"\r\n\r\nall: $(CFG) cmds.lib\r\n\r\nOBJS1 = alias.obj b"
  },
  {
    "path": "cmd/memory.c",
    "chars": 1551,
    "preview": "/* $Id$\r\n\r\n\tInternal command MEMORY to display the amount of memory used by\r\n\tthe various internal data structures.\r\n\r\n*"
  },
  {
    "path": "cmd/mkdir.c",
    "chars": 1599,
    "preview": "/* $Id$\r\n * MD / MKDIR - makes a call to directory_handler to do its work\r\n */\r\n\r\n#include \"../config.h\"\r\n\r\n#include <sy"
  },
  {
    "path": "cmd/path.c",
    "chars": 1074,
    "preview": "/* $Id$\r\n *  PATH.C - path command.\r\n *\r\n *  Comments:\r\n *\r\n * 17 Jul 1998 (John P Price)\r\n *   Seperated commands into "
  },
  {
    "path": "cmd/pause.c",
    "chars": 794,
    "preview": "/* $Id$\r\n *  PAUSE.C - pause command.\r\n *\r\n * FREEDOS extension : If resteter is specified use that as the pause\r\n *   m"
  },
  {
    "path": "cmd/popd.c",
    "chars": 724,
    "preview": "/* $Id$\r\n *  DSTACK.C - Directory stack PUSHD/POPD support, compatible with 4/NDOS\r\n *\r\n *\tPOPD [*]\r\n *\r\n * Pops a direc"
  },
  {
    "path": "cmd/prompt.c",
    "chars": 402,
    "preview": "/* $Id$\r\n *  PROMPT.C - prompt handling.\r\n *\r\n */\r\n\r\n#include \"../config.h\"\r\n\r\n\r\n#include \"../include/cmdline.h\"\r\n#inclu"
  },
  {
    "path": "cmd/pushd.c",
    "chars": 844,
    "preview": "/* $Id$\r\n *  DSTACK.C - Directory stack PUSHD/POPD support, compatible with 4/NDOS\r\n *\r\n *\tPUSHD <dir>\r\n *\r\n * Pushes th"
  },
  {
    "path": "cmd/rem.c",
    "chars": 191,
    "preview": "/* $Id$\r\n *  REM -- includes comments \"remarks\" into batch scripts\r\n */\r\n\r\n#include \"../config.h\"\r\n\r\n#include \"../includ"
  },
  {
    "path": "cmd/ren.c",
    "chars": 5845,
    "preview": "/* $Id$\r\n * REN.C - rename command\r\n *\r\n * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)\r\n * - added config.h include"
  },
  {
    "path": "cmd/rmdir.c",
    "chars": 4406,
    "preview": "/* $Id$\r\n * RD / RMDIR - makes a call to directory_handler to do its work\r\n */\r\n\r\n#include \"../config.h\"\r\n\r\n#include <as"
  },
  {
    "path": "cmd/set.c",
    "chars": 3643,
    "preview": "/* $Id$\r\n *\tSet environment variables\r\n *\r\n */\r\n\r\n#include \"../config.h\"\r\n\r\n#include <assert.h>\r\n#include <stdlib.h>\r\n#i"
  },
  {
    "path": "cmd/shift.c",
    "chars": 896,
    "preview": "/* $Id$\r\n *  SHIFT.C - shift command.\r\n *\r\n * Only valid inside batch files.\r\n *\r\n * FREEDOS extension : optional parame"
  },
  {
    "path": "cmd/time.c",
    "chars": 2199,
    "preview": "/* $Id$\r\n *  TIME.C - time internal command\r\n *\r\n *  Comments:\r\n *\r\n *  07/08/1998 (John P. Price)\r\n *    started.\r\n *\r\n"
  },
  {
    "path": "cmd/truename.c",
    "chars": 817,
    "preview": "/* $Id$\r\n * TRUENAME.C -- Truename Command (undocumented DOS?)\r\n *\r\n * 07/14/98 (Rob Lake)\r\n *  - started and tested fin"
  },
  {
    "path": "cmd/type.c",
    "chars": 1808,
    "preview": "/* $Id$\r\n *  TYPE.C - type internal command\r\n *\r\n *  Comments:\r\n *\r\n *  07/08/1998 (John P. Price)\r\n *    started.\r\n *\r\n"
  },
  {
    "path": "cmd/verify.c",
    "chars": 1166,
    "preview": "/* $Id$\r\n *  VERIFY.C - verify command.\r\n *\r\n *  Comments:\r\n *\r\n * 31 Jul 1998 (John P Price)\r\n *   started.\r\n *\r\n *\r\n *"
  },
  {
    "path": "cmd/which.c",
    "chars": 2342,
    "preview": "/* $Id$\r\n *  WHERE.C - path functions.\r\n *\r\n *\r\n *\r\n *  Comments:\r\n *\r\n *  07/15/95 (Tim Norman)\r\n *    started.\r\n *\r\n *"
  },
  {
    "path": "command.lsm",
    "chars": 604,
    "preview": "Begin3\r\nTitle:          FreeCom\r\nVersion:        0.87\r\nEntered-date:   Mon DD 202Y\r\nDescription:    The FreeDOS Command "
  },
  {
    "path": "config.b",
    "chars": 1301,
    "preview": "@echo off\r\n:-****************************************************************\r\n:-  NOTICE!  You can edit but then copy t"
  },
  {
    "path": "config.h",
    "chars": 6917,
    "preview": "/*\r\n * config.h - Used to configure what will be compiled into the shell.\r\n *\r\n */\r\n\r\n/* define DEBUG to add debugging c"
  },
  {
    "path": "config.std",
    "chars": 2346,
    "preview": "# defaults for DOS; can be overridden in compiler makefiles\r\nDIRSEP = \\ #a backslash\r\nECHOTO = echoto\r\nECHOTODEP = echot"
  },
  {
    "path": "criter/context.x",
    "chars": 2095,
    "preview": "# Context description file\r\n#\r\n#\tContains persistent information to be preserved during the\r\n#\texecution of an external "
  },
  {
    "path": "criter/criter.asm",
    "chars": 22093,
    "preview": "; $Id$\r\n;\r\n;\t\tCritical Error handler -- module\r\n;\r\n; Three macros to customize the assembler process:\r\n;\t\tCOMPILE_COM in"
  },
  {
    "path": "criter/criter.txt",
    "chars": 1191,
    "preview": "Critical Error & Dummy ^Break handler & Kernel Swap Context\r\n\r\nCompile:\r\n\tnasm -f bin criter.asm\r\n\r\nResult is CRITER, th"
  },
  {
    "path": "criter/dmy_cbrk.asm",
    "chars": 650,
    "preview": ";   $Id$\r\n;\r\n;\tDummy ^Break signal catcher -- module\r\n;\tAborts any program\t\t<-> Activated only if FreeCOM is not active\r"
  },
  {
    "path": "criter/files.txt",
    "chars": 537,
    "preview": "Implementation of the Criter, Dummy CBreak and Context module\r\n\r\nThis implementation is a spin-off of two other on-going"
  },
  {
    "path": "criter/makefile",
    "chars": 1969,
    "preview": "# $Id$\r\n#\r\n# Makefile for the FreeCOM CRITER module\r\n#\r\n# $Log$\r\n# Revision 1.2  2002/04/02 23:36:37  skaus\r\n# add: XMS-"
  },
  {
    "path": "criter/makefile.mak",
    "chars": 486,
    "preview": "CFG_DEPENDENCIES = makefile.mak\r\n\r\nTOP = ..\r\n!include \"$(TOP)/config.mak\"\r\n\r\nall:  context.def criter criter1\r\n\r\ncontext"
  },
  {
    "path": "criter/resource.id",
    "chars": 135,
    "preview": "RES_ID_NONE EQU -32766\r\nRES_ID_ANY EQU -32767\r\nRES_ID_STRINGS EQU 0\r\nRES_ID_CRITER EQU 1\r\nRES_ID_CBREAK EQU 2\r\nRES_ID_RE"
  },
  {
    "path": "criter/resource.inc",
    "chars": 210,
    "preview": "%include \"resource.id\"\r\n%macro resIdBlock 1-2 -1\r\n\tdd\t???ende - ???start\t\t;; Length of this resource\r\n\tdw %1\t\t\t\t\t\t;; maj"
  },
  {
    "path": "docs/HELP.EN",
    "chars": 102339,
    "preview": "FreeCom 0.85\r\n(Note: some features and commands are optional)\r\n\r\nList of commands and features of FreeCOM:\r\n\r\n    * ALIA"
  },
  {
    "path": "docs/_config.yml",
    "chars": 197,
    "preview": "theme: jekyll-theme-architect\r\ntitle: \"FreeCom : FreeDOS command.com\"\r\ndescription: \"FreeCom is an implementation of the"
  },
  {
    "path": "docs/c0.txt",
    "chars": 1819,
    "preview": "1999/06/17 - exclusion of argc/argv and C-style environment\r\n\r\nNOTE: Currently no changes have been made to the C0 code "
  },
  {
    "path": "docs/cmt1.txt",
    "chars": 4962,
    "preview": "1999/04/27 ska - Redesign of command line parser for internal commands\r\n\r\nEvery internal command parses the command line"
  },
  {
    "path": "docs/cmt10.txt",
    "chars": 2683,
    "preview": "$Id$\r\nCritical Error Handler Repeat Check Autofailer\r\n\t-- 2004-09-13 ska\r\n\r\nDue to some heavy and annoying invocations o"
  },
  {
    "path": "docs/cmt2.txt",
    "chars": 3777,
    "preview": "$Id$\r\nBatch file processing\r\n\r\nThis document discusses the features and functionality of the\r\nbatch file processing. It "
  },
  {
    "path": "docs/cmt3.txt",
    "chars": 2964,
    "preview": "$Id$\r\nCommand line parser\r\n\r\nChanges: single quotes and backticks are valid filename characters,\r\n\ttheir meta function a"
  },
  {
    "path": "docs/cmt4.txt",
    "chars": 2347,
    "preview": "How the COPY command works -- 1999/05/10 ska\r\n\r\nThere are several curiosities about the COPY command:\r\n\r\n===\r\nExample: C"
  },
  {
    "path": "docs/cmt5.txt",
    "chars": 13027,
    "preview": "option parser -- 1999/07/09 ska\r\n\r\nAll internal commands and the arguments of COMMAND.COM itself are\r\nscanned and parsed"
  },
  {
    "path": "docs/cmt6.txt",
    "chars": 13669,
    "preview": "MUX-AE handler\r\n\t-- 2000/12/10 ska\r\n\r\nI. Overview\r\n\r\nThe MUX-AE handler allows TSRs and alike programs to install extens"
  },
  {
    "path": "docs/cmt7.txt",
    "chars": 5221,
    "preview": "Permanent data storage within external memory block\r\n\t-- 20001/03/30 ska\r\n\r\nFreeCOM utilizes several information that ne"
  },
  {
    "path": "docs/cmt8.txt",
    "chars": 3802,
    "preview": "$Id$\r\nBatch file processing\r\n\t-- 2001/04/26 ska\r\n\r\nThis document discusses the features and functionality of the\r\nbatch "
  },
  {
    "path": "docs/comments.txt",
    "chars": 450,
    "preview": "cmt1.txt - Redesign of command line parser for internal commands\r\ncmt2.txt - Batchfile processing\r\ncmt3.txt - Command li"
  },
  {
    "path": "docs/compile.txt",
    "chars": 4385,
    "preview": "Compile notes:\r\n\r\nNOTE: Use NASM version 0.98.35 or later!\r\nWhen building on Windows a native (win32 or win64) version i"
  },
  {
    "path": "docs/contrib.txt",
    "chars": 619,
    "preview": "Contributions are welcome!\r\n\r\nCurrently the best way to submit a patch is via a pull request (PR) on GitHub - see https:"
  },
  {
    "path": "docs/download.txt",
    "chars": 832,
    "preview": "You can download pre-compiled variants of FreeCOM from:\r\n\r\nhttps://github.com/FDOS/freecom\r\n\r\nFor each language supporte"
  },
  {
    "path": "docs/faq.txt",
    "chars": 2404,
    "preview": "$Id$\r\n\r\nFrequently Asked Questions about FreeCOM\r\n\tCopyright (C) 2000 Steffen Kaiser <ska-src@gmx.net>\r\n\r\ncurrent versio"
  },
  {
    "path": "docs/files.txt",
    "chars": 3121,
    "preview": "Archive Contents\r\n~~~~~~~~~~~~~~~~\r\nbugs.txt        Bug List\r\nfiles.txt       This file list\r\nhistory.txt     History of"
  },
  {
    "path": "docs/history.txt",
    "chars": 73592,
    "preview": "FreeDOS Command Line Interface Development History\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\r\nv0.86\r\n~~~~~\r\n"
  },
  {
    "path": "docs/html/build48.html",
    "chars": 29607,
    "preview": "<!-- $Id$ -->\r\n<HTML>\r\n<HEAD>\r\n<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=iso-8859-15\">\r\n<META NAME=\"GE"
  },
  {
    "path": "docs/html/commands/FreeCOM.html",
    "chars": 31210,
    "preview": "<!-- $Id$ -->\r\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\r\n<HTML>\r\n<HEAD>\r\n<META HTTP-EQUIV=\"Content-Type\" "
  },
  {
    "path": "docs/html/commands/appendix.html",
    "chars": 20540,
    "preview": "<!-- $Id$ -->\r\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\r\n<HTML>\r\n<HEAD>\r\n<META HTTP-EQUIV=\"Content-Type\" "
  },
  {
    "path": "docs/html/commands/cmd.html",
    "chars": 94771,
    "preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\r\n<HTML>\r\n<HEAD>\r\n<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/h"
  },
  {
    "path": "docs/html/commands/db2html",
    "chars": 6374,
    "preview": "#!perl\r\n\r\n## Formats the command DB files into HTML.\r\n## See INFO\r\n\r\n## if the TOC exists, it is inserted right at the s"
  },
  {
    "path": "docs/html/commands/info",
    "chars": 4165,
    "preview": "File format of .DB files:\r\n\r\nHeader:\r\nna)me: of object described herein; should match the filename\r\nde)scription: one li"
  },
  {
    "path": "docs/html/commands/parse.pl",
    "chars": 3449,
    "preview": "#!perl\r\n\r\n# Parses <IN> as EBNF HTML into HTML\r\n\r\n$file_cmd = \"CMDLIST\";\t# List of commands to be automatically linked\r\n"
  },
  {
    "path": "docs/html/commands/parseHTML",
    "chars": 1570,
    "preview": "#!perl\r\n\r\n# Parse additional *.html files useing parse.pl\r\n\r\nrequire 'parse.pl';\r\n\r\ndie \"Cannot open TOC: $!\\n\"\r\n\tunless"
  },
  {
    "path": "docs/index.md",
    "chars": 53,
    "preview": "FreeCOM - FreeDOS Command Interpreter - COMMAND.COM\r\n"
  },
  {
    "path": "docs/k-swap.txt",
    "chars": 6331,
    "preview": "Description of kernel-supoorted swapping of FreeCOM\r\n\t-- 2001/01/21 ska\r\n\r\n===> Please also read VSPAWN.TXT.\r\n\r\nThis sor"
  },
  {
    "path": "docs/language.txt",
    "chars": 1848,
    "preview": "How to change the language of FreeCOM?\r\n\t-- 2000/07/10 ska\r\n\r\n\r\nAt this time not all strings can be customized, but it w"
  },
  {
    "path": "docs/loadhigh.txt",
    "chars": 15274,
    "preview": "$Id$\r\nImplementation of the LOADHIGH (aka LH) command\r\n\t-- 2002/04/12 ska\r\n\r\nSee below test results (tools reside in TOO"
  },
  {
    "path": "docs/localize.txt",
    "chars": 6404,
    "preview": "How to localize FreeCOM -- 2000/08/16 ska\r\n\r\nCurrently FreeCOM contains only one point, where it can be \"localized\"\r\naka"
  },
  {
    "path": "docs/module.txt",
    "chars": 3987,
    "preview": "Description of Modules Used Within FreeCOM\r\n\t-- 2000/07/15 ska\r\n\r\nThe information of this document is obsolte!\r\n\r\nFreeCO"
  },
  {
    "path": "docs/notes.txt",
    "chars": 6643,
    "preview": "Notes from contributors....\r\n\r\nNotes from Hans B Pufal <hansp@digiweb.com>:\r\n\r\nHere is my package of changes to COMMAND,"
  },
  {
    "path": "docs/piping.txt",
    "chars": 1274,
    "preview": "Piping -- 2000/08/16 ska\r\n\r\n\r\nPiping, e.g. \"cmd1 | cmd2\", is actually spawned as:\r\n\r\n1\tSET some_internal_variable=%TEMP%"
  },
  {
    "path": "docs/pt_br/config.h",
    "chars": 5862,
    "preview": "/*\r\n * config.h - Usado para configurar o que ser compilado para interpretador.\r\n *\r\n */\r\n\r\n/* Defina DEBUG para adicion"
  },
  {
    "path": "docs/pt_br/config.mak",
    "chars": 1689,
    "preview": "## Diretrio base do Turbo C++ v1.01\r\nCC_BASE_PATH = D:\\TC101\r\n\r\n## Onde os arquivo SUPPL(suplementares) pre-compilados e"
  },
  {
    "path": "docs/pt_br/download.txt",
    "chars": 526,
    "preview": "Voc pode fazer o download de variantes pre-compiladas do FreeCOM de:\r\n\r\nhttps://github.com/FDOS/freecom\r\n\r\noutros lugare"
  },
  {
    "path": "docs/pt_br/file_id.diz",
    "chars": 202,
    "preview": "Este  interpretados de comandos do FreeDOS(command.com).\r\n\r\nPara saber informaes sobre a ltima verso visite:\r\nhttp://wik"
  },
  {
    "path": "docs/pt_br/readme",
    "chars": 278,
    "preview": "Cdigo fonte para distribuio do FreeCOM - um programa de interface de linha\r\nde comando, que substitue o COMMAND.COM\r\n\r\nO"
  },
  {
    "path": "docs/ptchldrv.txt",
    "chars": 1007,
    "preview": "Start logging feature 2000/01/05 ska\r\n\r\nThis feature logs, if compiled in, the command line into a file,\r\nwhenever FreeC"
  },
  {
    "path": "docs/resource.txt",
    "chars": 4678,
    "preview": "Description of layout of COMMAND.COM image\r\n\t-- 2000/07/11 ska\r\n\r\n\r\nGeneral layout:\r\n+ start of file at file offset 0\r\n+"
  },
  {
    "path": "docs/todo.txt",
    "chars": 1110,
    "preview": "Things to do\r\n~~~~~~~~~~~~\r\n\r\n(#) is the suggested priority, the lower the more urgent.\r\n\r\n\r\n\r\n(0) Fix bugs :)\r\n\r\n(2) En"
  },
  {
    "path": "docs/upload.txt",
    "chars": 2941,
    "preview": "(this file is now obsolete, please submit changes as patches to FreeDOS mailing list or as Pull Request via GitHub)\r\n\r\nH"
  },
  {
    "path": "docs/vspawn.txt",
    "chars": 1300,
    "preview": "Swap Support #2\r\n\t-- 2001/04/01 ska\r\n\r\nThis style of swapping is incompatible with XMS-Only swapping!\r\n\r\nThis swapping i"
  },
  {
    "path": "err_fcts.h",
    "chars": 3653,
    "preview": "void error_env(int base, int err_no, const char * const var);\r\nvoid error_invalid_switch(char c);\r\nvoid error_invalid_ls"
  },
  {
    "path": "include/batch.h",
    "chars": 2203,
    "preview": "/* A structure to preserve the context of a batch file */\r\n\r\n/*  Added:\r\n   bfnam -- name of batchfile for modifyable sc"
  },
  {
    "path": "include/cmdline.h",
    "chars": 4179,
    "preview": "/*\r\n  Declaration for the command line parsing interface\r\n */\r\n\r\n#ifndef __CMDLINE_H\r\n#define __CMDLINE_H\r\n\r\n/* What quo"
  },
  {
    "path": "include/command.h",
    "chars": 5383,
    "preview": "/* COMMAND.H\r\n * header file for the modules in COMMAND.COM\r\n */\r\n\r\n#ifndef FREECOM_COMMAND_H\r\n#define FREECOM_COMMAND_H"
  },
  {
    "path": "include/context.h",
    "chars": 3148,
    "preview": "/* $id$\r\n\r\n\tContext declarations\r\n\r\n*/\r\n\r\n#ifndef CONTEXT__H_\r\n#define CONTEXT__H_\r\n\r\n#include <portable.h>\r\n\r\n#define M"
  },
  {
    "path": "include/crossjmp.h",
    "chars": 259,
    "preview": "/*\r\n * Allows to longjmp through FreeCOM at abort-type error states.\r\n *\r\n */\r\n\r\n#ifndef FREECOM_CROSSJMP_H\r\n#define FRE"
  },
  {
    "path": "include/cswap.h",
    "chars": 2455,
    "preview": "/*\r\n\tCSWAP.H\r\n*/\r\n\r\n#ifdef FEATURE_XMS_SWAP\r\n\r\n#ifndef __XMS_SWAP_H\r\n#define __XMS_SWAP_H\r\n\r\n#include \"../include/misc.h"
  },
  {
    "path": "include/datefunc.h",
    "chars": 1385,
    "preview": "/*\r\n\r\n   DateFunc -- DOS Date Functions\r\n   Copyright (C) 1998 Rob Lake\r\n\r\n   This program is free software; you can red"
  },
  {
    "path": "include/debug.h",
    "chars": 811,
    "preview": "/*\r\n\tDeclaration & settings for debugging\r\n\r\n\tThe following functions expand to nothing, if DEBUG is not defined,\r\n\tothe"
  },
  {
    "path": "include/infores.h",
    "chars": 1563,
    "preview": "/* $Id$\r\n\r\n\tInfo resource\r\n\r\n\tStructure of the resource:\r\n\t<tag1>\r\n\t<tag2>\r\n\t...\r\n\t<tagN>\r\n\r\n\ta <tag> is of the structur"
  },
  {
    "path": "include/keys.h",
    "chars": 2227,
    "preview": "/*\r\n *\tDefines keys without ASCII representation\r\n *\r\n *\tInternally a key is an (int) value, the low byte encodes the ke"
  },
  {
    "path": "include/kswap.h",
    "chars": 863,
    "preview": "/* Kernel-supported swapping */\r\n\r\n#ifndef FEATURE_XMS_SWAP\r\n\r\n#ifndef H__KSWAP__\r\n#define H__KSWAP__\r\n\r\n#include <porta"
  },
  {
    "path": "include/large.inc",
    "chars": 214,
    "preview": "\r\n; Large header\r\ngroup\tDGROUP\t\t_DATA _BSS\r\nsegment\t_TEXT\t\tclass=CODE\r\nsegment\t_DATA\t\tclass=DATA align=2\r\nsegment\t_BSS\t\t"
  },
  {
    "path": "include/lfnfuncs.h",
    "chars": 3686,
    "preview": "/* \r\n * Header file for the long filename-related functions\r\n */\r\n\r\n#ifndef H__LFNFUNCS_\r\n#define H__LFNFUNCS_\r\n\r\n/*#ifd"
  },
  {
    "path": "include/medium.inc",
    "chars": 215,
    "preview": "\r\n; Medium header\r\ngroup\tDGROUP\t\t_DATA _BSS\r\nsegment\t_TEXT\t\tclass=CODE\r\nsegment\t_DATA\t\tclass=DATA align=2\r\nsegment\t_BSS\t"
  },
  {
    "path": "include/misc.h",
    "chars": 7505,
    "preview": "/*\r\n * MISC.C -- Misc. Functions declarations\r\n *\r\n * 2000/07/13 ska\r\n *\tstarted\r\n */\r\n\r\n#ifndef MISC_H\r\n#define MISC_H\r"
  },
  {
    "path": "include/model.inc",
    "chars": 204,
    "preview": "%ifidni MODEL,s\r\n%include \"small.inc\"\r\n%elifidni MODEL,m\r\n%include \"medium.inc\"\r\n%elifidni MODEL,l\r\n%include \"large.inc\""
  },
  {
    "path": "include/module.h",
    "chars": 344,
    "preview": "/*\r\n *\tSpecial FreeCOM declaration for the module management\r\n *\r\n * 2000/07/12 ska\r\n * started\r\n */\r\n\r\n#ifndef MODULE_H"
  },
  {
    "path": "include/mux_ae.h",
    "chars": 816,
    "preview": "/*\r\n\tDeclaration for Installable COMMAND extensions (MUX-AE)\r\n\r\n\t2000/12/10 ska\r\n\tstarted\r\n*/\r\n\r\n#ifndef FREECOM_MUX_AE_"
  },
  {
    "path": "include/nls.h",
    "chars": 1829,
    "preview": "/*\t$Id$\r\n\r\n\tDeclarations to access the DOS NLS information\r\n\r\n\t$Log$\r\n\tRevision 1.2  2003/03/05 17:43:42  skaus\r\n\tbugfix"
  },
  {
    "path": "include/openf.h",
    "chars": 1200,
    "preview": "/*\r\n *      Prototypes for the CP/M-style device name-aware open functions\r\n */\r\n#ifndef __OPENF_H\r\n#define __OPENF_H\r\n\r"
  },
  {
    "path": "include/res.h",
    "chars": 429,
    "preview": "/*\r\n *\tSpecial FreeCOM declaration for the resource management\r\n *\r\n *\tenumResources()\tenumerates all resources of the s"
  },
  {
    "path": "include/resource.h",
    "chars": 1678,
    "preview": "/*\r\n *\tDeclarations of resource management of FreeCOM\r\n *\r\n *\tSee DOCS\\RESOURCE.TXT\r\n *\r\n *\tenumFileResources()\tenumerat"
  },
  {
    "path": "include/small.inc",
    "chars": 291,
    "preview": "\r\n; Small header\r\n%ifidn __OUTPUT_FORMAT__, obj\r\ngroup\tDGROUP\t\t_DATA _BSS\r\nsegment\t_TEXT\t\tclass=CODE\r\nsegment\t_DATA\t\tcla"
  },
  {
    "path": "include/strings.typ",
    "chars": 552,
    "preview": "/*\r\n * STRINGS.TYP - Shared types of STRINGS.DAT implementation\r\n *\t\trequired to ensure FIXSTRS and FREECOM use the same"
  },
  {
    "path": "include/stuff.inc",
    "chars": 695,
    "preview": "cpu 8086\r\n\r\n;; Multi-Push/Pop\r\n;; Both take the registers in the same order, \"F\"==Flags\r\n;; Push pushes left to right; p"
  },
  {
    "path": "include/timefunc.h",
    "chars": 1495,
    "preview": "/*\r\n\r\n   TimeFunc -- DOS Time Functions\r\n   Copyright (C) 1998 Rob Lake\r\n\r\n   This program is free software; you can red"
  },
  {
    "path": "lib/absfile.c",
    "chars": 782,
    "preview": "/*\t$Id$\r\n\r\n *\tMake the given file spec an absolute path/file name.\r\n *\tReturns in a dynamically allocated buffer (free'e"
  },
  {
    "path": "lib/almemblk.c",
    "chars": 506,
    "preview": "/*\t$Id$\r\n\r\n\tAllocate a block of memory.\r\n\tRemove \"Use UMB\" if forceLow is true.\r\n\r\n\t$Log$\r\n\tRevision 1.1  2004/06/29 21:"
  },
  {
    "path": "lib/alprmblk.c",
    "chars": 1668,
    "preview": "/*\t$Id$\r\n\r\n\tAllocate a permanent block of memory.\r\n\tThese blocks are system memory blocks, if swapping is enabled;\r\n\toth"
  },
  {
    "path": "lib/alsysblk.c",
    "chars": 1857,
    "preview": "/*\t$Id$\r\n\r\n\tAllocate system memory block. This block is not deallocated if\r\n\tthe process dies.\r\n\r\n\tThis file bases on MI"
  },
  {
    "path": "lib/app_get.c",
    "chars": 1561,
    "preview": "/*\t$Id$\r\n\r\n\tEnable DOS/APPEND if it was enabled before.\r\n\r\n\tint appendDisable()\r\n\r\n\tDisable DOS/APPEND and return the pr"
  },
  {
    "path": "lib/app_set.c",
    "chars": 718,
    "preview": "/*\t$Id$\r\n\r\n\tEnable DOS/APPEND if it was enabled before.\r\n\r\n\tvoid appendRestore(int state)\r\n\r\n\tEnable DOS/APPEND if state"
  },
  {
    "path": "lib/beep_l.c",
    "chars": 1552,
    "preview": "/*\t$Id$\r\n\r\n\tissue low beep\r\n\r\n\tThis file bases on MISC.C of FreeCOM v0.81 beta 1.\r\n\r\n\t$Log$\r\n\tRevision 1.3  2006/06/11 0"
  },
  {
    "path": "lib/beep_n.c",
    "chars": 1708,
    "preview": "/*\t$Id$\r\n\r\n * Internally BEEP (getting the user's attention)\r\n * Note: One should consider implementing a _visual_ beep\r"
  },
  {
    "path": "lib/brk_get.c",
    "chars": 1370,
    "preview": "/*\t$Id$\r\n\r\n\tGet Break status\r\n\r\n\tThis file bases on BREAK.C of FreeCOM v0.81 beta 1.\r\n\r\n\t$Log$\r\n\tRevision 1.2  2004/02/0"
  },
  {
    "path": "lib/brk_set.c",
    "chars": 1418,
    "preview": "/*\t$Id$\r\n\r\n\tSet Break status\r\n\r\n\tThis file bases on BREAK.C of FreeCOM v0.81 beta 1.\r\n\r\n\t$Log$\r\n\tRevision 1.2  2004/02/0"
  },
  {
    "path": "lib/c16.mac",
    "chars": 954,
    "preview": "; NASM macro set to make interfacing to 16-bit programs easier -*- nasm -*-\r\n\r\n\r\n\r\n%imacro proc 1\t\t\t; begin a procedure "
  },
  {
    "path": "lib/cbreak.c",
    "chars": 4946,
    "preview": "/*\t$Id$\r\n\r\n * Check if Ctrl-Break was pressed during the last calls\r\n\r\n\tThis file bases on MISC.C of FreeCOM v0.81 beta "
  },
  {
    "path": "lib/cbs.c",
    "chars": 379,
    "preview": "/* $Id$\r\n\r\n\tCut trailing backslashes\r\n\r\n*/\r\n\r\n#include \"../config.h\"\r\n\r\n#include <assert.h>\r\n#include <string.h>\r\n\r\n#inc"
  },
  {
    "path": "lib/cd_dir.c",
    "chars": 2438,
    "preview": "/* $Id$\r\n * CDD & CD handler\r\n */\r\n\r\n#include \"../config.h\"\r\n\r\n#include <assert.h>\r\n#include <stdlib.h>\r\n#include <stdio"
  },
  {
    "path": "lib/cgetch.c",
    "chars": 2425,
    "preview": "/*\t$Id$\r\n\r\n\tGet a character out-of-band and honor Ctrl-Break characters\r\n\tInvisible.\r\n\r\n\tThis file bases on MISC.C of Fr"
  },
  {
    "path": "lib/cgettime.c",
    "chars": 2086,
    "preview": "/*\t$Id$\r\n\r\n\tWaits about N secs for a keypress.\r\n\treturns 0 if none else returns key pressed invisibly.\r\n\r\n\tThis file bas"
  },
  {
    "path": "lib/chgctxt.c",
    "chars": 4600,
    "preview": "/*\t$Id$\r\n\r\n \tchgCtxt():\r\n *  Insert/replace/delete a case-sensitive variable into the specified\r\n *\tcontext\r\n *\r\n *  If "
  },
  {
    "path": "lib/chgdrv.c",
    "chars": 2184,
    "preview": "/*\t$Id$\r\n\r\n\tChange drive and display an appropriate message on error.\r\n\tInput:\t0 == current drive\r\n\t\t\t1..32 == A: ..\r\n\t\t"
  },
  {
    "path": "lib/chgenv.c",
    "chars": 2780,
    "preview": "/*\t$Id$\r\n\r\n \tchgCtxt():\r\n *  Insert/replace/delete a case-sensitive variable into the specified\r\n *\tcontext\r\n *\r\n *  If "
  },
  {
    "path": "lib/chgenvc.c",
    "chars": 1995,
    "preview": "/*\t$Id$\r\n\r\n *  Insert/replace/delete an environment variable\r\n *\r\n *  If the variable already exists within the environm"
  },
  {
    "path": "lib/chgenvr.c",
    "chars": 1676,
    "preview": "/*\t$Id$\r\n\r\n \tchgEnvRemove():\r\n *  Insert/replace/delete a case-sensitive variable into the specified\r\n *\tcontext\r\n *\r\n *"
  },
  {
    "path": "lib/cmdinput.c",
    "chars": 11180,
    "preview": "/* $Id$\r\n *  CMDINPUT.C - handles command input (tab completion, history, etc.)\r\n */\r\n\r\n#include \"../config.h\"\r\n\r\n#inclu"
  },
  {
    "path": "lib/comfile.c",
    "chars": 1603,
    "preview": "/*\t$Id$\r\n\r\n *  Return the absolute filename of the current COMMAND shell\r\n\r\n\tThis file bases on MISC.C of FreeCOM v0.81 "
  },
  {
    "path": "lib/compfile.c",
    "chars": 1779,
    "preview": "/*\t$Id$\r\n\r\n * Construct the path of a file to be located in the same directory\r\n *  as COMMAND.\r\n *  Dynamically allocat"
  },
  {
    "path": "lib/critend.c",
    "chars": 497,
    "preview": "/*\t$Id$\r\n\r\n\tDisplay the result of a CRITER repeat check autofail\r\n\r\n\t$Log$\r\n\tRevision 1.1  2004/09/13 18:59:39  skaus\r\n\t"
  },
  {
    "path": "lib/critrchk.c",
    "chars": 2255,
    "preview": "/*\t$Id$\r\n\r\n\tCriter repeat check interface\r\n\r\n\t$Log$\r\n\tRevision 1.4  2006/07/02 08:15:10  blairdude\r\n\t#if 0'd out 2 unuse"
  },
  {
    "path": "lib/ctxt.c",
    "chars": 138,
    "preview": "/* $Id$\r\n\r\n\tDynamic context of the FreeCOM instance\r\n*/\r\n\r\n#include \"../config.h\"\r\n\r\n#include \"../include/context.h\"\r\n\r\n"
  },
  {
    "path": "lib/ctxt_adr.c",
    "chars": 545,
    "preview": "/* $Id$\r\n\r\n\tReturns the far address to the value of a specified tag item\r\n\r\n*/\r\n\r\n#include \"../config.h\"\r\n\r\n#include <as"
  },
  {
    "path": "lib/ctxt_as.c",
    "chars": 646,
    "preview": "/* $Id$\r\n\r\n\tAdd status entry of a tag into context\r\n\r\n\tsilent\r\n\r\n\tThe status is sizemax encoded like this:\r\n\t\tsizemax | "
  },
  {
    "path": "lib/ctxt_chg.c",
    "chars": 789,
    "preview": "/* $Id$\r\n\r\n\tChange the size of the local context. It will never shrink\r\n\tso that stored data is corrupted. If necessary,"
  },
  {
    "path": "lib/ctxt_clr.c",
    "chars": 780,
    "preview": "/* $Id$\r\n\r\n\tClear all items of a specified context tag\r\n\r\n*/\r\n\r\n#include \"../config.h\"\r\n\r\n#include <assert.h>\r\n#include "
  },
  {
    "path": "lib/ctxt_get.c",
    "chars": 1281,
    "preview": "/* $Id$\r\n\r\n\tGet the n'th item of the specified context tag.\r\n\tIt is duplicated into dynamic memory.\r\n\r\n\tReturns:\t0: OK\r\n"
  },
  {
    "path": "lib/ctxt_inf.c",
    "chars": 712,
    "preview": "/* $Id$\r\n\r\n\tContext status information \r\n\r\n*/\r\n\r\n#include \"../config.h\"\r\n\r\n#include \"../include/context.h\"\r\n\r\nctxt_info_"
  },
  {
    "path": "lib/ctxt_mk.c",
    "chars": 1686,
    "preview": "/* $Id$\r\n\r\n\tCreate local context\r\n\r\n\tThe size is currently fixed to the default sizes of stuff\r\n\tlocated into the contex"
  },
  {
    "path": "lib/ctxt_mkb.c",
    "chars": 809,
    "preview": "/* $Id$\r\n\tCreates a block of memory suiteable to hold the\r\n\tcontext.\r\n\r\n\t$Log$\r\n\tRevision 1.2  2004/06/29 21:57:20  skau"
  },
  {
    "path": "lib/ctxt_mkn.c",
    "chars": 378,
    "preview": "/* $Id$\r\n\r\n\tCreate an item name.\r\n*/\r\n\r\n#include \"../config.h\"\r\n\r\n#include <assert.h>\r\n#include <stdio.h>\r\n\r\n#include \"."
  },
  {
    "path": "lib/ctxt_pop.c",
    "chars": 971,
    "preview": "/* $Id$\r\n\r\n\tPops the last added entry of the specified context tag.\r\n\tIt is duplicated into dynamic memory.\r\n\r\n\tReturns:"
  },
  {
    "path": "lib/ctxt_psh.c",
    "chars": 658,
    "preview": "/* $Id$\r\n\r\n\tPushes a new item to the end of the context tag\r\n\r\n\tReturn:\tE_None, E_NoMem, E_NoItems\r\n*/\r\n\r\n#include \"../c"
  },
  {
    "path": "lib/ctxt_rnu.c",
    "chars": 867,
    "preview": "/* $Id$\r\n\r\n\tRenumbers all items of the context tag\r\n\r\n*/\r\n\r\n#include \"../config.h\"\r\n\r\n#include <assert.h>\r\n#include <str"
  },
  {
    "path": "lib/ctxt_set.c",
    "chars": 565,
    "preview": "/* $Id$\r\n\r\n\tChanges a context tag item \r\n\r\n\tReturn: E_None on success\r\n*/\r\n\r\n#include \"../config.h\"\r\n\r\n#include \"../incl"
  },
  {
    "path": "lib/ctxt_ss.c",
    "chars": 1438,
    "preview": "/* $Id$\r\n\r\n\tScan status from context\r\n\tAssumes that the entries are in \"init\" state!!\r\n\r\n*/\r\n\r\n#include \"../config.h\"\r\n\r"
  },
  {
    "path": "lib/ctxt_vw.c",
    "chars": 1096,
    "preview": "/* $Id$\r\n\r\n\tView all entries of the specified type\r\n\r\n*/\r\n\r\n#include \"../config.h\"\r\n\r\n#include <assert.h>\r\n#include <std"
  },
  {
    "path": "lib/curdatel.c",
    "chars": 2412,
    "preview": "/*\t$Id$\r\n\r\n\tGet the current date in a long format (day_of_week date)\r\n\tin a dynamically allocated buffer\r\n\r\n\tThis file b"
  },
  {
    "path": "lib/curtime.c",
    "chars": 1643,
    "preview": "/*\t$Id$\r\n\r\n\tGet the current time in a dynamically allocated buffer\r\n\r\n\tThis file bases on MISC.C of FreeCOM v0.81 beta 1"
  },
  {
    "path": "lib/cwd.c",
    "chars": 1912,
    "preview": "/*\t$Id$\r\n\r\n *\tRetreive the current working directory including drive letter\r\n *\tReturns in a dynamically allocated buffe"
  },
  {
    "path": "lib/dateget.c",
    "chars": 1763,
    "preview": "/*\t$Id$\r\n\r\n\tGet DOS date (for Turbo C prior v3)\r\n\r\n\tThis file bases on DATEFUNC.C of FreeCOM v0.81 beta 1.\r\n\r\n\t$Log$\r\n\tR"
  },
  {
    "path": "lib/dateset.c",
    "chars": 1785,
    "preview": "/*\t$Id$\r\n\r\n\tSet DOS date (for Turbo C prior v3)\r\n\r\n\tThis file bases on DATEFUNC.C of FreeCOM v0.81 beta 1.\r\n\r\n\t$Log$\r\n\tR"
  },
  {
    "path": "lib/dbg_c.c",
    "chars": 1458,
    "preview": "/*\t$Id$\r\n\r\n *  Defines the functions only necessary while debugging is active\r\n\r\n\tThis file bases on DEBUG.C of FreeCOM "
  },
  {
    "path": "lib/dbg_mem.c",
    "chars": 3391,
    "preview": "/*\t$Id$\r\n\r\n *  Defines the functions only necessary while debugging is active\r\n\r\n\tThis file bases on DEBUG.C of FreeCOM "
  },
  {
    "path": "lib/dbg_prnt.c",
    "chars": 1672,
    "preview": "/*\t$Id$\r\n\r\n *  Defines the functions only necessary while debugging is active\r\n\r\n\tThis file bases on DEBUG.C of FreeCOM "
  },
  {
    "path": "lib/dbg_s.c",
    "chars": 1515,
    "preview": "/*\t$Id$\r\n\r\n *  Defines the functions only necessary while debugging is active\r\n\r\n\tThis file bases on DEBUG.C of FreeCOM "
  },
  {
    "path": "lib/dbg_sn.c",
    "chars": 1501,
    "preview": "/*\t$Id$\r\n\r\n *  Defines the functions only necessary while debugging is active\r\n\r\n\tThis file bases on DEBUG.C of FreeCOM "
  },
  {
    "path": "lib/delay.c",
    "chars": 555,
    "preview": "/*\t$Id: $\r\n\r\n\tdelay function for ia16-elf-gcc with newlib\r\n\tuses _dos_gettime, only for delays < 1 minute (60000 ms)\r\n *"
  }
]

// ... and 550 more files (download for full content)

About this extraction

This page contains the full source code of the FDOS/freecom GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 750 files (2.6 MB), approximately 706.2k tokens, and a symbol index with 724 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!